- ExtractionForm: PDF dropzone (react-dropzone) + text textarea + case selector
- ExtractionResults: review table with edit/remove per row, confidence color-coding
- Page at /ai/extract: upload -> analyze -> review -> adopt deadlines to case
- Extended API client with postFormData for multipart uploads
- Added ExtractedDeadline and ExtractionResponse types
Add two Claude API-powered endpoints:
- POST /api/ai/extract-deadlines: accepts PDF upload or JSON text, extracts
legal deadlines using Claude tool_use for structured output
- POST /api/ai/summarize-case: generates AI summary from case events/deadlines,
caches result in cases.ai_summary
New files:
- internal/services/ai_service.go: AIService with Anthropic SDK integration
- internal/handlers/ai.go: HTTP handlers for both endpoints
- internal/services/ai_service_test.go: tool schema and serialization tests
Uses anthropic-sdk-go v1.27.1 with Claude Sonnet 4.5. AI service is optional —
endpoints only registered when ANTHROPIC_API_KEY is set.
GET /api/dashboard returns aggregated data:
- deadline_summary: overdue, due this/next week, ok counts
- case_summary: active, new this month, closed counts
- upcoming_deadlines: next 7 days with case info
- upcoming_appointments: next 7 days
- recent_activity: last 10 case events
Uses efficient CTE query for summaries. Also fixes duplicate
writeJSON/writeError declarations in appointments handler.
- 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)
Tenant management:
- POST /api/tenants — create tenant (creator becomes owner)
- GET /api/tenants — list tenants for authenticated user
- GET /api/tenants/:id — tenant details with access check
- POST /api/tenants/:id/invite — invite user by email (owner/admin)
- DELETE /api/tenants/:id/members/:uid — remove member
- GET /api/tenants/:id/members — list members
New packages:
- internal/services/tenant_service.go — CRUD on tenants + user_tenants
- internal/handlers/tenant_handler.go — HTTP handlers with auth checks
- internal/auth/tenant_resolver.go — X-Tenant-ID header middleware,
defaults to user's first tenant for scoped routes
Authorization: owners/admins can invite and remove members. Cannot
remove the last owner. Users can remove themselves. TenantResolver
applies to resource routes (cases, deadlines, etc.) but not tenant
management routes.
- CaseService: list (paginated, filterable), get detail (with parties,
events, deadline count), create, update, soft-delete (archive)
- PartyService: list by case, create, update, delete
- Auto-create case_events on case creation, status change, party add,
and case archive
- Auth middleware now resolves tenant_id from user_tenants table
- All operations scoped to tenant_id from auth context
- AppointmentService with tenant-scoped List, GetByID, Create, Update, Delete
- List supports filtering by case_id, appointment_type, and date range (start_from/start_to)
- AppointmentHandler with JSON request/response handling and input validation
- Router wired up: GET/POST /api/appointments, PUT/DELETE /api/appointments/{id}
New direction: law firm management (Fristen, Termine, case tracking)
instead of UPC case law search. Updated all references, Go module
path, and deployment info.
Port 3000 conflicts with Dokploy. Traefik routes traffic via
Docker network, so expose is sufficient. Also remove env_file
refs since Dokploy injects env vars directly.