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
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.