package handlers import ( "database/sql" "encoding/json" "net/http" "mgit.msbls.de/m/KanzlAI-mGMT/internal/auth" "mgit.msbls.de/m/KanzlAI-mGMT/internal/services" "github.com/google/uuid" ) type PartyHandler struct { svc *services.PartyService } func NewPartyHandler(svc *services.PartyService) *PartyHandler { return &PartyHandler{svc: svc} } func (h *PartyHandler) List(w http.ResponseWriter, r *http.Request) { tenantID, ok := auth.TenantFromContext(r.Context()) if !ok { writeError(w, http.StatusForbidden, "missing tenant") return } caseID, err := uuid.Parse(r.PathValue("id")) if err != nil { writeError(w, http.StatusBadRequest, "invalid case ID") return } parties, err := h.svc.ListByCase(r.Context(), tenantID, caseID) if err != nil { internalError(w, "failed to list parties", err) return } writeJSON(w, http.StatusOK, map[string]interface{}{ "parties": parties, }) } func (h *PartyHandler) Create(w http.ResponseWriter, r *http.Request) { tenantID, ok := auth.TenantFromContext(r.Context()) if !ok { writeError(w, http.StatusForbidden, "missing tenant") return } userID, _ := auth.UserFromContext(r.Context()) caseID, err := uuid.Parse(r.PathValue("id")) if err != nil { writeError(w, http.StatusBadRequest, "invalid case ID") return } var input services.CreatePartyInput if err := json.NewDecoder(r.Body).Decode(&input); err != nil { writeError(w, http.StatusBadRequest, "invalid JSON body") return } if input.Name == "" { writeError(w, http.StatusBadRequest, "name is required") return } if msg := validateStringLength("name", input.Name, maxTitleLen); msg != "" { writeError(w, http.StatusBadRequest, msg) return } party, err := h.svc.Create(r.Context(), tenantID, caseID, userID, input) if err != nil { if err == sql.ErrNoRows { writeError(w, http.StatusNotFound, "case not found") return } internalError(w, "failed to create party", err) return } writeJSON(w, http.StatusCreated, party) } func (h *PartyHandler) Update(w http.ResponseWriter, r *http.Request) { tenantID, ok := auth.TenantFromContext(r.Context()) if !ok { writeError(w, http.StatusForbidden, "missing tenant") return } partyID, err := uuid.Parse(r.PathValue("partyId")) if err != nil { writeError(w, http.StatusBadRequest, "invalid party ID") return } var input services.UpdatePartyInput if err := json.NewDecoder(r.Body).Decode(&input); err != nil { writeError(w, http.StatusBadRequest, "invalid JSON body") return } updated, err := h.svc.Update(r.Context(), tenantID, partyID, input) if err != nil { internalError(w, "failed to update party", err) return } if updated == nil { writeError(w, http.StatusNotFound, "party not found") return } writeJSON(w, http.StatusOK, updated) } func (h *PartyHandler) Delete(w http.ResponseWriter, r *http.Request) { tenantID, ok := auth.TenantFromContext(r.Context()) if !ok { writeError(w, http.StatusForbidden, "missing tenant") return } partyID, err := uuid.Parse(r.PathValue("partyId")) if err != nil { writeError(w, http.StatusBadRequest, "invalid party ID") return } if err := h.svc.Delete(r.Context(), tenantID, partyID); err != nil { writeError(w, http.StatusNotFound, "party not found") return } w.WriteHeader(http.StatusNoContent) }