Merged in feature/textExtractionsPart1 (pull request #192)
all schema and rest apis for text extraction support * in progress * stage 8 complete * phase 9 completed * phase 9 complete * ongoing - s3 path fix * working * optimize ci build * e2e tests * missing test
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
package queryapi
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"queryorchestration/internal/database/repository"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/oapi-codegen/nullable"
|
||||
openapi_types "github.com/oapi-codegen/runtime/types"
|
||||
)
|
||||
|
||||
// CreateFolder creates a new folder for organizing documents.
|
||||
// POST /folders
|
||||
// Takes a FolderCreate request body containing path, clientId, parentId (optional), and createdBy.
|
||||
// Returns the created Folder on success, or an error response.
|
||||
func (s *Controllers) CreateFolder(ctx echo.Context) error {
|
||||
var req CreateFolderJSONRequestBody
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "invalid request body")
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if req.Path == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "path is required")
|
||||
}
|
||||
if req.ClientId == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "clientId is required")
|
||||
}
|
||||
if req.CreatedBy == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "createdBy is required")
|
||||
}
|
||||
|
||||
// Convert parent ID if provided
|
||||
var parentID *uuid.UUID
|
||||
if req.ParentId != nil {
|
||||
id := uuid.UUID(*req.ParentId)
|
||||
parentID = &id
|
||||
}
|
||||
|
||||
folder, err := s.svc.Folder.CreateFolder(ctx.Request().Context(), req.Path, parentID, string(req.ClientId), string(req.CreatedBy))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusCreated, convertRepoFolderToAPI(folder))
|
||||
}
|
||||
|
||||
// RenameFolder updates the path of an existing folder.
|
||||
// PATCH /folders/{folderId}
|
||||
// Takes a FolderRename request body containing the new path.
|
||||
// Returns 204 No Content on success, or an error response.
|
||||
func (s *Controllers) RenameFolder(ctx echo.Context, folderId openapi_types.UUID) error {
|
||||
var req RenameFolderJSONRequestBody
|
||||
if err := ctx.Bind(&req); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "invalid request body")
|
||||
}
|
||||
|
||||
if req.Path == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "path is required")
|
||||
}
|
||||
|
||||
err := s.svc.Folder.RenameFolder(ctx.Request().Context(), uuid.UUID(folderId), req.Path)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return ctx.NoContent(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// GetFolderDocuments retrieves all documents in a specific folder.
|
||||
// GET /folders/{folderId}/documents
|
||||
// Returns a list of documents in the specified folder.
|
||||
func (s *Controllers) GetFolderDocuments(ctx echo.Context, folderId openapi_types.UUID) error {
|
||||
documents, err := s.svc.Folder.GetDocumentsByFolder(ctx.Request().Context(), uuid.UUID(folderId))
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
// ListClientFolders retrieves all folders for a client.
|
||||
// GET /client/{id}/folders
|
||||
// Returns a FolderList containing all folders for the client.
|
||||
// Each folder includes its ID, path, and parentId, allowing clients to reconstruct the folder hierarchy.
|
||||
// Root-level folders will have parentId set to null.
|
||||
func (s *Controllers) ListClientFolders(ctx echo.Context, id ClientID) error {
|
||||
folders, err := s.svc.Folder.GetFoldersByClient(ctx.Request().Context(), string(id))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
// Convert repository folders to API folders
|
||||
apiFolders := make([]Folder, len(folders))
|
||||
for i, f := range folders {
|
||||
apiFolders[i] = convertRepoFolderToAPI(f)
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, FolderList{
|
||||
Folders: apiFolders,
|
||||
})
|
||||
}
|
||||
|
||||
// GetFolderMetrics retrieves processing metrics for a folder including document counts by label.
|
||||
// GET /folders/{folderId}/metrics
|
||||
// Returns FolderMetrics containing total document count and breakdown by label.
|
||||
func (s *Controllers) GetFolderMetrics(ctx echo.Context, folderId openapi_types.UUID) error {
|
||||
metrics, err := s.svc.Folder.GetFolderMetrics(ctx.Request().Context(), uuid.UUID(folderId))
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return ctx.JSON(http.StatusOK, FolderMetrics{
|
||||
FolderId: folderId,
|
||||
TotalDocuments: metrics.TotalDocuments,
|
||||
ByLabel: metrics.ByLabel,
|
||||
})
|
||||
}
|
||||
|
||||
// convertRepoFolderToAPI converts a repository Folder to the API Folder type.
|
||||
func convertRepoFolderToAPI(folder *repository.Folder) Folder {
|
||||
var createdAt time.Time
|
||||
if folder.Createdat.Valid {
|
||||
createdAt = folder.Createdat.Time
|
||||
}
|
||||
|
||||
result := Folder{
|
||||
Id: openapi_types.UUID(folder.ID),
|
||||
Path: folder.Path,
|
||||
ClientId: ClientID(folder.Clientid),
|
||||
CreatedBy: openapi_types.Email(folder.Createdby),
|
||||
CreatedAt: createdAt,
|
||||
}
|
||||
|
||||
if folder.Parentid != nil {
|
||||
result.ParentId = nullable.NewNullableWithValue(openapi_types.UUID(*folder.Parentid))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user