package queryapi import ( "net/http" "time" "queryorchestration/internal/database/repository" "github.com/google/uuid" "github.com/labstack/echo/v4" openapi_types "github.com/oapi-codegen/runtime/types" ) // ApplyLabel applies a workflow label to a document. // POST /documents/{documentId}/labels // Takes a LabelApplication request body containing label and appliedBy. // Returns the created LabelRecord on success, or an error response. func (s *Controllers) ApplyLabel(ctx echo.Context, documentId openapi_types.UUID) error { var req ApplyLabelJSONRequestBody if err := ctx.Bind(&req); err != nil { return echo.NewHTTPError(http.StatusBadRequest, "invalid request body") } // Validate required fields if req.Label == "" { return echo.NewHTTPError(http.StatusBadRequest, "label is required") } if req.AppliedBy == "" { return echo.NewHTTPError(http.StatusBadRequest, "appliedBy is required") } label, err := s.svc.Label.ApplyLabel(ctx.Request().Context(), uuid.UUID(documentId), req.Label, string(req.AppliedBy)) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) } return ctx.JSON(http.StatusCreated, convertRepoLabelToAPI(label)) } // GetDocumentLabels retrieves all labels applied to a specific document. // GET /documents/{documentId}/labels // Returns a list of LabelRecord objects ordered by most recent first. func (s *Controllers) GetDocumentLabels(ctx echo.Context, documentId openapi_types.UUID) error { labels, err := s.svc.Label.GetDocumentLabels(ctx.Request().Context(), uuid.UUID(documentId)) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) } // Convert to API response format apiLabels := make([]LabelRecord, len(labels)) for i, lbl := range labels { apiLabels[i] = convertRepoLabelToAPI(lbl) } return ctx.JSON(http.StatusOK, map[string]interface{}{ "labels": apiLabels, }) } // GetDocumentsByLabel retrieves all documents with a specific label for a client. // GET /labels/{labelName}/documents?clientId={clientId} // Returns a list of document summaries that have the specified label. func (s *Controllers) GetDocumentsByLabel(ctx echo.Context, labelName string, params GetDocumentsByLabelParams) error { if labelName == "" { return echo.NewHTTPError(http.StatusBadRequest, "labelName is required") } documents, err := s.svc.Label.GetDocumentsByLabel(ctx.Request().Context(), string(params.ClientId), labelName) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) } // Convert to API response format apiDocs := make([]DocumentSummary, len(documents)) for i, doc := range documents { apiDocs[i] = DocumentSummary{ Hash: doc.Hash, Id: openapi_types.UUID(doc.ID), } } return ctx.JSON(http.StatusOK, map[string]interface{}{ "documents": apiDocs, }) } // convertRepoLabelToAPI converts a repository Documentlabel to the API LabelRecord type. func convertRepoLabelToAPI(label *repository.Documentlabel) LabelRecord { var appliedAt time.Time if label.Appliedat.Valid { appliedAt = label.Appliedat.Time } return LabelRecord{ Id: openapi_types.UUID(label.ID), DocumentId: openapi_types.UUID(label.Documentid), Label: label.Label, AppliedBy: openapi_types.Email(label.Appliedby), AppliedAt: appliedAt, } }