Files
KanzlAI-mGMT/backend/internal/router/router.go
m 42a62d45bf feat: add deadline CRUD, calculator, and holiday services (Phase 1C)
- Holiday service with German federal holidays, Easter calculation, DB loading
- Deadline calculator adapted from youpc.org (duration calc + non-working day adjustment)
- Deadline CRUD service (tenant-scoped: list, create, update, complete, delete)
- Deadline rule service (list, filter by proceeding type, hierarchical rule trees)
- HTTP handlers for all endpoints with tenant resolution via X-Tenant-ID header
- Router wired with all new endpoints under /api/
- Tests for holiday and calculator services (8 passing)
2026-03-25 13:31:29 +01:00

79 lines
2.5 KiB
Go

package router
import (
"encoding/json"
"net/http"
"github.com/jmoiron/sqlx"
"mgit.msbls.de/m/KanzlAI-mGMT/internal/auth"
"mgit.msbls.de/m/KanzlAI-mGMT/internal/handlers"
"mgit.msbls.de/m/KanzlAI-mGMT/internal/services"
)
func New(db *sqlx.DB, authMW *auth.Middleware) http.Handler {
// Services
holidaySvc := services.NewHolidayService(db)
deadlineSvc := services.NewDeadlineService(db)
deadlineRuleSvc := services.NewDeadlineRuleService(db)
calculator := services.NewDeadlineCalculator(holidaySvc)
// Handlers
deadlineH := handlers.NewDeadlineHandlers(deadlineSvc, db)
ruleH := handlers.NewDeadlineRuleHandlers(deadlineRuleSvc)
calcH := handlers.NewCalculateHandlers(calculator, deadlineRuleSvc)
mux := http.NewServeMux()
// Public routes
mux.HandleFunc("GET /health", handleHealth(db))
// Authenticated API routes
api := http.NewServeMux()
// Deadline CRUD (case-scoped)
api.HandleFunc("GET /api/cases/{caseID}/deadlines", deadlineH.ListForCase)
api.HandleFunc("POST /api/cases/{caseID}/deadlines", deadlineH.Create)
api.HandleFunc("PUT /api/deadlines/{deadlineID}", deadlineH.Update)
api.HandleFunc("PATCH /api/deadlines/{deadlineID}/complete", deadlineH.Complete)
api.HandleFunc("DELETE /api/deadlines/{deadlineID}", deadlineH.Delete)
// Deadline rules (public reference data, but behind auth)
api.HandleFunc("GET /api/deadline-rules", ruleH.List)
api.HandleFunc("GET /api/deadline-rules/{type}", ruleH.GetRuleTree)
// Deadline calculator
api.HandleFunc("POST /api/deadlines/calculate", calcH.Calculate)
// Placeholder routes (not yet implemented)
api.HandleFunc("GET /api/cases", placeholder("cases"))
api.HandleFunc("GET /api/appointments", placeholder("appointments"))
api.HandleFunc("GET /api/documents", placeholder("documents"))
mux.Handle("/api/", authMW.RequireAuth(api))
return mux
}
func handleHealth(db *sqlx.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if err := db.Ping(); err != nil {
w.WriteHeader(http.StatusServiceUnavailable)
json.NewEncoder(w).Encode(map[string]string{"status": "error", "error": err.Error()})
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
}
func placeholder(resource string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"status": "not_implemented",
"resource": resource,
})
}
}