package handlers import ( "encoding/json" "net/http" "github.com/jmoiron/sqlx" "mgit.msbls.de/m/KanzlAI-mGMT/internal/services" ) // DeadlineHandlers holds handlers for deadline CRUD endpoints type DeadlineHandlers struct { deadlines *services.DeadlineService db *sqlx.DB } // NewDeadlineHandlers creates deadline handlers func NewDeadlineHandlers(ds *services.DeadlineService, db *sqlx.DB) *DeadlineHandlers { return &DeadlineHandlers{deadlines: ds, db: db} } // Get handles GET /api/deadlines/{deadlineID} func (h *DeadlineHandlers) Get(w http.ResponseWriter, r *http.Request) { tenantID, err := resolveTenant(r, h.db) if err != nil { handleTenantError(w, err) return } deadlineID, err := parsePathUUID(r, "deadlineID") if err != nil { writeError(w, http.StatusBadRequest, "invalid deadline ID") return } deadline, err := h.deadlines.GetByID(tenantID, deadlineID) if err != nil { writeError(w, http.StatusInternalServerError, "failed to fetch deadline") return } if deadline == nil { writeError(w, http.StatusNotFound, "deadline not found") return } writeJSON(w, http.StatusOK, deadline) } // ListAll handles GET /api/deadlines func (h *DeadlineHandlers) ListAll(w http.ResponseWriter, r *http.Request) { tenantID, err := resolveTenant(r, h.db) if err != nil { handleTenantError(w, err) return } deadlines, err := h.deadlines.ListAll(tenantID) if err != nil { writeError(w, http.StatusInternalServerError, "failed to list deadlines") return } writeJSON(w, http.StatusOK, deadlines) } // ListForCase handles GET /api/cases/{caseID}/deadlines func (h *DeadlineHandlers) ListForCase(w http.ResponseWriter, r *http.Request) { tenantID, err := resolveTenant(r, h.db) if err != nil { handleTenantError(w, err) return } caseID, err := parsePathUUID(r, "caseID") if err != nil { writeError(w, http.StatusBadRequest, "invalid case ID") return } deadlines, err := h.deadlines.ListForCase(tenantID, caseID) if err != nil { writeError(w, http.StatusInternalServerError, "failed to list deadlines") return } writeJSON(w, http.StatusOK, deadlines) } // Create handles POST /api/cases/{caseID}/deadlines func (h *DeadlineHandlers) Create(w http.ResponseWriter, r *http.Request) { tenantID, err := resolveTenant(r, h.db) if err != nil { handleTenantError(w, err) return } caseID, err := parsePathUUID(r, "caseID") if err != nil { writeError(w, http.StatusBadRequest, "invalid case ID") return } var input services.CreateDeadlineInput if err := json.NewDecoder(r.Body).Decode(&input); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } input.CaseID = caseID if input.Title == "" || input.DueDate == "" { writeError(w, http.StatusBadRequest, "title and due_date are required") return } deadline, err := h.deadlines.Create(r.Context(), tenantID, input) if err != nil { writeError(w, http.StatusInternalServerError, "failed to create deadline") return } writeJSON(w, http.StatusCreated, deadline) } // Update handles PUT /api/deadlines/{deadlineID} func (h *DeadlineHandlers) Update(w http.ResponseWriter, r *http.Request) { tenantID, err := resolveTenant(r, h.db) if err != nil { handleTenantError(w, err) return } deadlineID, err := parsePathUUID(r, "deadlineID") if err != nil { writeError(w, http.StatusBadRequest, "invalid deadline ID") return } var input services.UpdateDeadlineInput if err := json.NewDecoder(r.Body).Decode(&input); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } deadline, err := h.deadlines.Update(r.Context(), tenantID, deadlineID, input) if err != nil { writeError(w, http.StatusInternalServerError, "failed to update deadline") return } if deadline == nil { writeError(w, http.StatusNotFound, "deadline not found") return } writeJSON(w, http.StatusOK, deadline) } // Complete handles PATCH /api/deadlines/{deadlineID}/complete func (h *DeadlineHandlers) Complete(w http.ResponseWriter, r *http.Request) { tenantID, err := resolveTenant(r, h.db) if err != nil { handleTenantError(w, err) return } deadlineID, err := parsePathUUID(r, "deadlineID") if err != nil { writeError(w, http.StatusBadRequest, "invalid deadline ID") return } deadline, err := h.deadlines.Complete(r.Context(), tenantID, deadlineID) if err != nil { writeError(w, http.StatusInternalServerError, "failed to complete deadline") return } if deadline == nil { writeError(w, http.StatusNotFound, "deadline not found") return } writeJSON(w, http.StatusOK, deadline) } // Delete handles DELETE /api/deadlines/{deadlineID} func (h *DeadlineHandlers) Delete(w http.ResponseWriter, r *http.Request) { tenantID, err := resolveTenant(r, h.db) if err != nil { handleTenantError(w, err) return } deadlineID, err := parsePathUUID(r, "deadlineID") if err != nil { writeError(w, http.StatusBadRequest, "invalid deadline ID") return } err = h.deadlines.Delete(r.Context(), tenantID, deadlineID) if err != nil { writeError(w, http.StatusNotFound, err.Error()) return } writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"}) }