158 lines
4.6 KiB
Go
158 lines
4.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
|
|
"git.ipao.vip/rogee/creator-hub/internal/phasea"
|
|
"github.com/gofiber/fiber/v3"
|
|
)
|
|
|
|
type accountRequest struct {
|
|
ID string `json:"id"`
|
|
ProfileID string `json:"profile_id"`
|
|
CredentialReference struct {
|
|
ID string `json:"id"`
|
|
Provider string `json:"provider"`
|
|
Key string `json:"key"`
|
|
} `json:"credential_reference"`
|
|
}
|
|
|
|
func registerPhaseA(app *fiber.App, store *phasea.Store) {
|
|
app.Post("/api/phase-a/accounts", func(c fiber.Ctx) error {
|
|
var input accountRequest
|
|
if err := decodePhaseA(c, &input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
err := store.CreateAccount(c.Context(), phasea.Account{
|
|
ID: input.ID, ProfileID: input.ProfileID, CredentialReferenceID: input.CredentialReference.ID,
|
|
CredentialProvider: input.CredentialReference.Provider, CredentialKey: input.CredentialReference.Key,
|
|
})
|
|
if err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.Status(fiber.StatusCreated).JSON(map[string]string{"id": input.ID, "profile_id": input.ProfileID})
|
|
})
|
|
|
|
app.Post("/api/phase-a/accounts/:id/pause", func(c fiber.Ctx) error {
|
|
if err := store.PauseAccount(c.Context(), c.Params("id")); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.SendStatus(fiber.StatusNoContent)
|
|
})
|
|
|
|
app.Post("/api/phase-a/runtimes", func(c fiber.Ctx) error {
|
|
var input phasea.RuntimeBinding
|
|
if err := decodePhaseA(c, &input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
if err := store.BindRuntime(c.Context(), input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.Status(fiber.StatusCreated).JSON(map[string]string{"id": input.ID})
|
|
})
|
|
|
|
app.Delete("/api/phase-a/runtimes/:id", func(c fiber.Ctx) error {
|
|
if err := store.ReleaseRuntime(c.Context(), c.Params("id")); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.SendStatus(fiber.StatusNoContent)
|
|
})
|
|
|
|
app.Post("/api/phase-a/drafts", func(c fiber.Ctx) error {
|
|
var input phasea.Draft
|
|
if err := decodePhaseA(c, &input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
if err := store.CreateDraft(c.Context(), input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.Status(fiber.StatusCreated).JSON(map[string]string{"id": input.ID})
|
|
})
|
|
|
|
app.Post("/api/phase-a/confirmations", func(c fiber.Ctx) error {
|
|
var input phasea.Confirmation
|
|
if err := decodePhaseA(c, &input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
if err := store.Confirm(c.Context(), input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.Status(fiber.StatusCreated).JSON(map[string]string{"id": input.ID})
|
|
})
|
|
|
|
app.Post("/api/phase-a/tasks", func(c fiber.Ctx) error {
|
|
var input phasea.Task
|
|
if err := decodePhaseA(c, &input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
task, inserted, err := store.Enqueue(c.Context(), input)
|
|
if err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
status := fiber.StatusOK
|
|
if inserted {
|
|
status = fiber.StatusCreated
|
|
}
|
|
return c.Status(status).JSON(task)
|
|
})
|
|
|
|
app.Post("/api/phase-a/tasks/:id/cancel", func(c fiber.Ctx) error {
|
|
if err := store.CancelTask(c.Context(), c.Params("id")); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.SendStatus(fiber.StatusNoContent)
|
|
})
|
|
|
|
app.Post("/api/phase-a/mock/execute", func(c fiber.Ctx) error {
|
|
var input struct {
|
|
WorkerID string `json:"worker_id"`
|
|
Outcome string `json:"outcome"`
|
|
}
|
|
if err := decodePhaseA(c, &input); err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
execution, err := store.ExecuteMock(c.Context(), input.WorkerID, input.Outcome)
|
|
if err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.JSON(execution)
|
|
})
|
|
|
|
app.Get("/api/phase-a/audit", func(c fiber.Ctx) error {
|
|
events, err := store.Audit(c.Context())
|
|
if err != nil {
|
|
return phaseAError(c, err)
|
|
}
|
|
return c.JSON(events)
|
|
})
|
|
}
|
|
|
|
func decodePhaseA(c fiber.Ctx, destination any) error {
|
|
decoder := json.NewDecoder(bytes.NewReader(c.Body()))
|
|
decoder.DisallowUnknownFields()
|
|
if err := decoder.Decode(destination); err != nil {
|
|
return phasea.ErrInvalid
|
|
}
|
|
if err := decoder.Decode(&struct{}{}); !errors.Is(err, io.EOF) {
|
|
return phasea.ErrInvalid
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func phaseAError(c fiber.Ctx, err error) error {
|
|
status := fiber.StatusInternalServerError
|
|
message := "phase A operation failed"
|
|
switch {
|
|
case errors.Is(err, phasea.ErrInvalid):
|
|
status, message = fiber.StatusBadRequest, phasea.ErrInvalid.Error()
|
|
case errors.Is(err, phasea.ErrConflict):
|
|
status, message = fiber.StatusConflict, phasea.ErrConflict.Error()
|
|
case errors.Is(err, phasea.ErrNotFound):
|
|
status, message = fiber.StatusNotFound, phasea.ErrNotFound.Error()
|
|
}
|
|
return c.Status(status).JSON(map[string]string{"error": message})
|
|
}
|