Register routes for reports, time entries, invoices, billing rates,
and document templates. All handlers and services already existed but
were not connected in the router.
Permission mapping:
- Reports, invoices, billing rates: PermManageBilling (partners+owners)
- Templates create/update/delete: PermCreateCase
- Time entries, template read/render: all authenticated users
The api client now calls normalizePath() to strip accidental /api/
prefixes. This prevents the recurring /api/api/ double-prefix bug.
Added convention note to .claude/CLAUDE.md so future workers know.
Full event-driven deadline determination system ported from youpc.org:
Backend:
- DetermineService: walks proceeding event tree, calculates cascading
dates with holiday adjustment and conditional logic
- GET /api/proceeding-types/{code}/timeline — full event tree structure
- POST /api/deadlines/determine — calculate timeline with conditions
- POST /api/cases/{caseID}/deadlines/batch — batch-create deadlines
- DeadlineRule model: added is_spawn, spawn_label fields
- GetFullTimeline: recursive CTE following cross-type spawn branches
- Conditional deadlines: condition_rule_id toggles alt_duration/rule_code
(e.g. Reply changes from RoP.029b to RoP.029a when CCR is filed)
- Seed SQL with full UPC event trees (INF, REV, CCR, APM, APP, AMD)
Frontend:
- DeadlineWizard: interactive proceeding timeline with step-by-step flow
1. Select proceeding type (visual cards)
2. Enter trigger event date
3. Toggle conditional branches (CCR, Appeal, Amend)
4. See full calculated timeline with color-coded urgency
5. Batch-create all deadlines on a selected case
- Visual timeline tree with party icons, rule codes, duration badges
- Kept existing DeadlineCalculator as "Schnell" quick mode
Also resolved merge conflicts across 6 files (auth, router, handlers)
merging role-based permissions + audit trail features.
New "KI" tab on case detail page with three sub-panels:
- KI-Strategie: one-click strategic analysis with next steps, risks, timeline
- KI-Entwurf: document drafting with template selection, language, instructions
- Aehnliche Faelle: UPC similar case search with relevance scores
Components: CaseStrategy, DocumentDrafter, SimilarCaseFinder
Types: StrategyRecommendation, DocumentDraft, SimilarCase, etc.
Backend:
- DraftDocument: Claude generates legal documents from case data + template type
(14 template types: Klageschrift, UPC claims, Abmahnung, etc.)
- CaseStrategy: Opus-powered strategic analysis with next steps, risk assessment,
and timeline optimization (structured tool output)
- FindSimilarCases: queries youpc.org Supabase for UPC cases, Claude ranks by
relevance with explanations and key holdings
Endpoints: POST /api/ai/draft-document, /case-strategy, /similar-cases
All rate-limited (5 req/min) and permission-gated (PermAIExtraction).
YouPC database connection is optional (YOUPC_DATABASE_URL env var).
- Create pre-configured Hogan Lovells tenant with demo flag and
auto_assign_domains: ["hoganlovells.com"]
- Add POST /api/tenants/auto-assign endpoint: checks email domain
against tenant settings, auto-assigns user as associate if match
- Add AutoAssignByDomain to TenantService
- Update registration flow: after signup, check auto-assign before
showing tenant creation form. Skip tenant creation if auto-assigned.
- Add DemoBanner component shown when tenant.settings.demo is true
- Extend GET /api/me to return is_demo flag from tenant settings
Backend:
- ReportingService with aggregation queries (CTEs, FILTER clauses)
- 4 API endpoints: /api/reports/{cases,deadlines,workload,billing}
- Date range filtering via ?from=&to= query params
Frontend:
- /berichte page with 4 tabs: Akten, Fristen, Auslastung, Abrechnung
- recharts: bar/pie/line charts for all report types
- Date range picker, CSV export, print-friendly view
- Sidebar nav entry with BarChart3 icon
Also resolves merge conflicts between role-based, notification, and
audit trail branches, and adds missing TS types (AuditLogResponse,
Notification, NotificationPreferences).
Database: time_entries, billing_rates, invoices tables with RLS.
Backend: CRUD services+handlers for time entries, billing rates, invoices.
- Time entries: list/create/update/delete, summary by case/user/month
- Billing rates: upsert with auto-close previous, current rate lookup
- Invoices: create with auto-number (RE-YYYY-NNN), status transitions
(draft->sent->paid, cancellation), link time entries on invoice create
API: 11 new endpoints under /api/time-entries, /api/billing-rates, /api/invoices
Frontend: Zeiterfassung tab on case detail, /abrechnung overview with filters,
/abrechnung/rechnungen list+detail with status actions, billing rates settings
Also: resolved merge conflicts between audit-trail and role-based branches,
added missing types (Notification, AuditLogResponse, NotificationPreferences)
- Database: kanzlai.audit_log table with RLS, append-only policies
(no UPDATE/DELETE), indexes for entity, user, and time queries
- Backend: AuditService.Log() with context-based tenant/user/IP/UA
extraction, wired into all 7 services (case, deadline, appointment,
document, note, party, tenant)
- API: GET /api/audit-log with entity_type, entity_id, user_id,
from/to date, and pagination filters
- Frontend: Protokoll tab on case detail page with chronological
audit entries, diff preview, and pagination
Required by § 50 BRAO and DSGVO Art. 5(2).
1. Tenant isolation bypass (CRITICAL): TenantResolver now verifies user
has access to X-Tenant-ID via user_tenants lookup before setting context.
Added VerifyAccess method to TenantLookup interface and TenantService.
2. Consolidated tenant resolution: Removed duplicate resolveTenant() from
helpers.go and tenant resolution from auth middleware. TenantResolver is
now the single source of truth. Deadlines and AI handlers use
auth.TenantFromContext() instead of direct DB queries.
3. CalDAV credential masking: tenant settings responses now mask CalDAV
passwords with "********" via maskSettingsPassword helper. Applied to
GetTenant, ListTenants, and UpdateSettings responses.
4. CORS + security headers: New middleware/security.go with CORS
(restricted to FRONTEND_ORIGIN) and security headers (X-Frame-Options,
X-Content-Type-Options, HSTS, Referrer-Policy, X-XSS-Protection).
5. Internal error leaking: All writeError(w, 500, err.Error()) replaced
with internalError() that logs via slog and returns generic "internal
error" to client. Same for jsonError in tenant handler.
6. Input validation: Max length on title (500), description (10000),
case_number (100), search (200). Pagination clamped to max 100.
Content-Disposition filename sanitized against header injection.
Regression test added for tenant access denial (403 on unauthorized
X-Tenant-ID). All existing tests pass, go vet clean.
Full system vision document covering 23 features across 4 priority tiers:
- P0 (must-have): audit trail, conflict checks, roles/permissions,
notifications, time tracking, RVG calculator, invoicing, DATEV export
- P1 (should-have): document templates, beA integration, full-text search,
Wiedervorlagen, email integration, reporting
- P2 (differentiator): patent family tracking, claim charts, UPC case law
intelligence via mLex, AI document drafting, AI strategy analysis
- P3 (nice-to-have): client portal, PWA, multi-language, EDA
Includes data model designs (24 new tables), API specifications,
implementation phases, competitive analysis, and risk register.
- Deadline detail page (/fristen/[id]) with status badge, due date,
case context, complete button, and notes
- Appointment detail page (/termine/[id]) with datetime, location,
type badge, case link, description, and notes
- Case event detail page (/cases/[id]/ereignisse/[eventId]) with
event type icon, description, metadata, and notes
- Standalone deadline creation (/fristen/neu) with case dropdown
- Standalone appointment creation (/termine/neu) with optional case
- Reusable Breadcrumb component for navigation hierarchy
- Reusable NotesList component with inline create/edit/delete
- Added Note and RecentActivity types to lib/types.ts
- Create kanzlai.notes table (polymorphic FK with CHECK constraint,
partial indexes, RLS)
- Add Note model, NoteService (ListByParent, Create, Update, Delete),
and NoteHandler with endpoints: GET/POST /api/notes, PUT/DELETE /api/notes/{id}
- Add GET /api/deadlines/{deadlineID} detail endpoint
- Add GET /api/appointments/{id} detail endpoint
- Add GET /api/case-events/{id} detail endpoint (new CaseEventHandler)
- Fix dashboard query: add case_id to upcoming_deadlines SELECT,
add id and case_id to recent_activity SELECT
- Register all new routes in router.go
Comprehensive design covering:
- Dashboard interactivity (click-to-filter traffic lights, clickable timeline,
fixed quick actions, AI summary refresh)
- New detail pages (deadline, appointment, case event)
- Notes system with polymorphic table design
- Case detail URL-based tab navigation
- Breadcrumb navigation system
- Backend API additions and data model changes
- Phased implementation plan for coders
Prevents "M.forEach is not a function" crashes when API returns error
objects or unexpected shapes instead of arrays. Guards all useQuery
consumers with Array.isArray checks and safe defaults for object props.
Files fixed: DeadlineList, AppointmentList, TenantSwitcher,
DeadlineTrafficLights, UpcomingTimeline, CaseOverviewGrid,
AISummaryCard, TeamSettings, and all page-level components
(dashboard, cases, fristen, termine, ai/extract).
Frontend api.ts baseUrl is already "/api", so paths like
"/api/cases" produced "/api/api/cases". Stripped the redundant
prefix from all component calls. Rewrite destination correctly
adds /api/ back for the Go backend.
The middleware was intercepting API proxy requests and redirecting
to /login. API routes should pass through to the Go backend which
handles its own JWT auth.