diff --git a/backend/internal/router/router.go b/backend/internal/router/router.go index f2a26ce..375f204 100644 --- a/backend/internal/router/router.go +++ b/backend/internal/router/router.go @@ -32,6 +32,11 @@ func New(db *sqlx.DB, authMW *auth.Middleware, cfg *config.Config, calDAVSvc *se storageCli := services.NewStorageClient(cfg.SupabaseURL, cfg.SupabaseServiceKey) documentSvc := services.NewDocumentService(db, storageCli, auditSvc) assignmentSvc := services.NewCaseAssignmentService(db) + reportSvc := services.NewReportingService(db) + timeEntrySvc := services.NewTimeEntryService(db, auditSvc) + invoiceSvc := services.NewInvoiceService(db, auditSvc) + billingRateSvc := services.NewBillingRateService(db, auditSvc) + templateSvc := services.NewTemplateService(db, auditSvc) // AI service (optional — only if API key is configured) var aiH *handlers.AIHandler @@ -71,6 +76,11 @@ func New(db *sqlx.DB, authMW *auth.Middleware, cfg *config.Config, calDAVSvc *se eventH := handlers.NewCaseEventHandler(db) docH := handlers.NewDocumentHandler(documentSvc) assignmentH := handlers.NewCaseAssignmentHandler(assignmentSvc) + reportH := handlers.NewReportHandler(reportSvc) + timeH := handlers.NewTimeEntryHandler(timeEntrySvc) + invoiceH := handlers.NewInvoiceHandler(invoiceSvc) + billingH := handlers.NewBillingRateHandler(billingRateSvc) + templateH := handlers.NewTemplateHandler(templateSvc, caseSvc, partySvc, deadlineSvc, tenantSvc) // Public routes mux.HandleFunc("GET /health", handleHealth(db)) @@ -205,6 +215,39 @@ func New(db *sqlx.DB, authMW *auth.Middleware, cfg *config.Config, calDAVSvc *se scoped.HandleFunc("GET /api/caldav/status", calDAVH.GetStatus) } + // Reports — billing permission (partners + owners) + scoped.HandleFunc("GET /api/reports/cases", perm(auth.PermManageBilling, reportH.Cases)) + scoped.HandleFunc("GET /api/reports/deadlines", perm(auth.PermManageBilling, reportH.Deadlines)) + scoped.HandleFunc("GET /api/reports/workload", perm(auth.PermManageBilling, reportH.Workload)) + scoped.HandleFunc("GET /api/reports/billing", perm(auth.PermManageBilling, reportH.Billing)) + + // Time entries — all can view/create, tied to cases + scoped.HandleFunc("GET /api/cases/{id}/time-entries", timeH.ListForCase) + scoped.HandleFunc("GET /api/time-entries", timeH.List) + scoped.HandleFunc("POST /api/cases/{id}/time-entries", timeH.Create) + scoped.HandleFunc("PUT /api/time-entries/{id}", timeH.Update) + scoped.HandleFunc("DELETE /api/time-entries/{id}", timeH.Delete) + scoped.HandleFunc("GET /api/time-entries/summary", timeH.Summary) + + // Invoices — billing permission required + scoped.HandleFunc("GET /api/invoices", perm(auth.PermManageBilling, invoiceH.List)) + scoped.HandleFunc("GET /api/invoices/{id}", perm(auth.PermManageBilling, invoiceH.Get)) + scoped.HandleFunc("POST /api/invoices", perm(auth.PermManageBilling, invoiceH.Create)) + scoped.HandleFunc("PUT /api/invoices/{id}", perm(auth.PermManageBilling, invoiceH.Update)) + scoped.HandleFunc("PATCH /api/invoices/{id}/status", perm(auth.PermManageBilling, invoiceH.UpdateStatus)) + + // Billing rates — billing permission required + scoped.HandleFunc("GET /api/billing-rates", perm(auth.PermManageBilling, billingH.List)) + scoped.HandleFunc("PUT /api/billing-rates", perm(auth.PermManageBilling, billingH.Upsert)) + + // Document templates — all can view/use, manage needs case creation permission + scoped.HandleFunc("GET /api/templates", templateH.List) + scoped.HandleFunc("GET /api/templates/{id}", templateH.Get) + scoped.HandleFunc("POST /api/templates", perm(auth.PermCreateCase, templateH.Create)) + scoped.HandleFunc("PUT /api/templates/{id}", perm(auth.PermCreateCase, templateH.Update)) + scoped.HandleFunc("DELETE /api/templates/{id}", perm(auth.PermCreateCase, templateH.Delete)) + scoped.HandleFunc("POST /api/templates/{id}/render", templateH.Render) + // Wire: auth -> tenant routes go directly, scoped routes get tenant resolver api.Handle("/api/", tenantResolver.Resolve(scoped))