|
- package handlers
-
- import (
- "encoding/json"
- "net/http"
- "strconv"
-
- "github.com/go-chi/chi/v5"
-
- "qctextbuilder/internal/buildsvc"
- "qctextbuilder/internal/onboarding"
- "qctextbuilder/internal/templatesvc"
- )
-
- type API struct {
- templateSvc *templatesvc.Service
- onboardSvc *onboarding.Service
- buildSvc buildsvc.Service
- }
-
- func NewAPI(templateSvc *templatesvc.Service, onboardSvc *onboarding.Service, buildSvc buildsvc.Service) *API {
- return &API{
- templateSvc: templateSvc,
- onboardSvc: onboardSvc,
- buildSvc: buildSvc,
- }
- }
-
- func (a *API) Health(w http.ResponseWriter, _ *http.Request) {
- writeJSON(w, http.StatusOK, map[string]any{"status": "ok"})
- }
-
- func (a *API) SyncTemplates(w http.ResponseWriter, r *http.Request) {
- templates, err := a.templateSvc.SyncAITemplates(r.Context())
- if err != nil {
- writeJSON(w, http.StatusBadGateway, map[string]any{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, map[string]any{"count": len(templates), "templates": templates})
- }
-
- func (a *API) ListTemplates(w http.ResponseWriter, r *http.Request) {
- templates, err := a.templateSvc.ListTemplates(r.Context())
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, map[string]any{"count": len(templates), "templates": templates})
- }
-
- func (a *API) GetTemplateDetail(w http.ResponseWriter, r *http.Request) {
- rawID := chi.URLParam(r, "id")
- templateID, err := strconv.ParseInt(rawID, 10, 64)
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": "invalid template id"})
- return
- }
-
- detail, err := a.templateSvc.GetTemplateDetail(r.Context(), templateID)
- if err != nil {
- writeJSON(w, http.StatusNotFound, map[string]any{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, detail)
- }
-
- func (a *API) OnboardTemplate(w http.ResponseWriter, r *http.Request) {
- rawID := chi.URLParam(r, "id")
- templateID, err := strconv.ParseInt(rawID, 10, 64)
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": "invalid template id"})
- return
- }
-
- manifest, fields, err := a.onboardSvc.OnboardTemplate(r.Context(), templateID)
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, map[string]any{
- "manifestId": manifest.ID,
- "fieldCount": len(fields),
- "status": "reviewed",
- })
- }
-
- type updateTemplateFieldsRequest struct {
- ManifestID string `json:"manifestId"`
- Fields []updateTemplateFieldItem `json:"fields"`
- }
-
- type updateTemplateFieldItem struct {
- Path string `json:"path"`
- IsEnabled *bool `json:"isEnabled,omitempty"`
- IsRequiredByUs *bool `json:"isRequiredByUs,omitempty"`
- DisplayLabel *string `json:"displayLabel,omitempty"`
- DisplayOrder *int `json:"displayOrder,omitempty"`
- Notes *string `json:"notes,omitempty"`
- }
-
- func (a *API) UpdateTemplateFields(w http.ResponseWriter, r *http.Request) {
- rawID := chi.URLParam(r, "id")
- templateID, err := strconv.ParseInt(rawID, 10, 64)
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": "invalid template id"})
- return
- }
-
- var req updateTemplateFieldsRequest
- if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": "invalid JSON body"})
- return
- }
- if len(req.Fields) == 0 {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": "fields is required"})
- return
- }
-
- patches := make([]onboarding.FieldPatch, 0, len(req.Fields))
- for _, f := range req.Fields {
- patches = append(patches, onboarding.FieldPatch{
- Path: f.Path,
- IsEnabled: f.IsEnabled,
- IsRequiredByUs: f.IsRequiredByUs,
- DisplayLabel: f.DisplayLabel,
- DisplayOrder: f.DisplayOrder,
- Notes: f.Notes,
- })
- }
-
- manifest, fields, err := a.onboardSvc.UpdateTemplateFields(r.Context(), templateID, req.ManifestID, patches)
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": err.Error()})
- return
- }
-
- writeJSON(w, http.StatusOK, map[string]any{
- "templateId": templateID,
- "manifestId": manifest.ID,
- "fieldCount": len(fields),
- "fields": fields,
- })
- }
-
- func (a *API) StartBuild(w http.ResponseWriter, r *http.Request) {
- var req buildsvc.StartBuildRequest
- if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": "invalid JSON body"})
- return
- }
-
- result, err := a.buildSvc.StartBuild(r.Context(), req)
- if err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusAccepted, result)
- }
-
- func (a *API) GetBuild(w http.ResponseWriter, r *http.Request) {
- buildID := chi.URLParam(r, "id")
- build, err := a.buildSvc.GetBuild(r.Context(), buildID)
- if err != nil {
- writeJSON(w, http.StatusNotFound, map[string]any{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, build)
- }
-
- func (a *API) PollBuildOnce(w http.ResponseWriter, r *http.Request) {
- buildID := chi.URLParam(r, "id")
- if err := a.buildSvc.PollOnce(r.Context(), buildID); err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": err.Error()})
- return
- }
-
- build, err := a.buildSvc.GetBuild(r.Context(), buildID)
- if err != nil {
- writeJSON(w, http.StatusNotFound, map[string]any{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, build)
- }
-
- func (a *API) FetchBuildEditorURL(w http.ResponseWriter, r *http.Request) {
- buildID := chi.URLParam(r, "id")
- if err := a.buildSvc.FetchEditorURL(r.Context(), buildID); err != nil {
- writeJSON(w, http.StatusBadRequest, map[string]any{"error": err.Error()})
- return
- }
-
- build, err := a.buildSvc.GetBuild(r.Context(), buildID)
- if err != nil {
- writeJSON(w, http.StatusNotFound, map[string]any{"error": err.Error()})
- return
- }
- writeJSON(w, http.StatusOK, build)
- }
-
- func writeJSON(w http.ResponseWriter, status int, v any) {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(status)
- _ = json.NewEncoder(w).Encode(v)
- }
|