package handler import ( "github.com/gofiber/fiber/v2" "github.com/google/uuid" "github.com/gosec/gsc-ops-api/internal/middleware" "github.com/gosec/gsc-ops-api/internal/service" "github.com/gosec/gsc-ops-api/pkg/types" ) // DBTenantHandler handles database tenant endpoints type DBTenantHandler struct { svc *service.DatabaseService } // NewDBTenantHandler creates a new DB tenant handler func NewDBTenantHandler(svc *service.DatabaseService) *DBTenantHandler { return &DBTenantHandler{svc: svc} } // List handles GET /api/v1/db/tenants func (h *DBTenantHandler) List(c *fiber.Ctx) error { reqID := middleware.GetRequestID(c) params := types.ListParams{ Limit: c.QueryInt("limit", 50), Offset: c.QueryInt("offset", 0), Search: c.Query("search"), Status: c.Query("status"), } tenants, total, err := h.svc.ListTenants(c.Context(), params) if err != nil { apiErr := types.NewInternal(err.Error()) return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } return c.JSON(types.NewPagedResponse(tenants, total, params.Limit, params.Offset, reqID)) } // Get handles GET /api/v1/db/tenants/:id func (h *DBTenantHandler) Get(c *fiber.Ctx) error { reqID := middleware.GetRequestID(c) id, err := uuid.Parse(c.Params("id")) if err != nil { apiErr := types.NewBadRequest("Invalid tenant ID") return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } tenant, err := h.svc.GetTenant(c.Context(), id) if err != nil { apiErr := types.NewNotFound("Tenant not found") return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } return c.JSON(types.NewDataResponse(tenant, reqID)) } // Create handles POST /api/v1/db/tenants func (h *DBTenantHandler) Create(c *fiber.Ctx) error { reqID := middleware.GetRequestID(c) var req types.TenantCreate if err := c.BodyParser(&req); err != nil { apiErr := types.NewBadRequest("Invalid request body: " + err.Error()) return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } if req.Name == "" || req.Code == "" || req.CustomerID == uuid.Nil { apiErr := types.NewValidation("customerId, code, and name are required") return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } tenant, err := h.svc.CreateTenant(c.Context(), &req) if err != nil { apiErr := types.NewInternal(err.Error()) return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } return c.Status(fiber.StatusCreated).JSON(types.NewDataResponse(tenant, reqID)) } // Update handles PUT /api/v1/db/tenants/:id func (h *DBTenantHandler) Update(c *fiber.Ctx) error { reqID := middleware.GetRequestID(c) id, err := uuid.Parse(c.Params("id")) if err != nil { apiErr := types.NewBadRequest("Invalid tenant ID") return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } var req types.TenantUpdate if err := c.BodyParser(&req); err != nil { apiErr := types.NewBadRequest("Invalid request body: " + err.Error()) return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } tenant, err := h.svc.UpdateTenant(c.Context(), id, &req) if err != nil { apiErr := types.NewInternal(err.Error()) return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } return c.JSON(types.NewDataResponse(tenant, reqID)) } // Delete handles DELETE /api/v1/db/tenants/:id (soft delete) func (h *DBTenantHandler) Delete(c *fiber.Ctx) error { reqID := middleware.GetRequestID(c) id, err := uuid.Parse(c.Params("id")) if err != nil { apiErr := types.NewBadRequest("Invalid tenant ID") return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } if err := h.svc.SoftDeleteTenant(c.Context(), id); err != nil { apiErr := types.NewInternal(err.Error()) return c.Status(apiErr.Status).JSON(types.NewErrorResponse(apiErr, reqID)) } return c.JSON(types.NewDataResponse(fiber.Map{"id": id, "deleted": true}, reqID)) }