When a KVNR is entered on a case that has a random-suffix or legacy
Nachname-based fall_id, the fall_id is automatically rebuilt using
the new KVNR.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces Nachname-based fall_ids with KVNR or random 6-char suffix
for all existing cases in the database.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace patient last name in fall_id with KVNR (or random fallback).
Retroactive migration of all existing ~2900 fall_ids.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CaseResponse.nachname was required (str) but the masking function sets
it to None for dak_mitarbeiter. This caused Pydantic validation errors
(500) making the case list empty for non-admin users.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend-enforced field masking for dak_mitarbeiter, disclosure request
workflow with 24h expiry, admin approval page, and frontend adaptations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Design for hiding personal data (name, birthdate) from dak_mitarbeiter
users with backend-enforced filtering and a time-limited disclosure
request mechanism for KVNR error resolution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change stacked bar chart from erstberatungen+unterlagen+gutachten
(overlapping, incorrect) to ablehnungen+keine_rm+gutachten (disjoint
categories that sum to total cases per KW, matching Excel Sheet 1).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add VERSICHERUNG_FILTER="DAK" to config and apply it to all case
queries: list, detail, pending-icd, pending-coding, coding queue,
dashboard KPIs, all 5 report sheets, and excel sync export.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend User and UserResponse interfaces with first_name, last_name,
display_name, avatar_url fields. Add ProfileUpdatePayload,
ChangePasswordPayload, MFASetupResponse, MFAVerifyPayload types.
Add authService functions for profile update, avatar upload/delete,
password change, and MFA setup/verify/disable. Add refreshUser to
AuthContext so components can re-fetch user data after changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 4 new nullable profile fields to support the upcoming account
management (Kontoverwaltung) feature. Includes Alembic migration
that has been applied to production database.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
German Excel/CRM exports often use semicolons instead of commas.
The parser now uses csv.Sniffer to auto-detect the delimiter,
fixing the issue where semicolon-delimited CSVs produced 0 rows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The field was editable in the frontend but missing from the backend
CaseUpdate Pydantic schema, causing changes to be silently dropped.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Radix UI Select.Item does not allow empty string values. The Anrede
dropdown used value="" for the empty option, causing the entire React
app to crash when entering edit mode. Use '__none__' sentinel value
instead and convert to null on selection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace individual field editors (KVNR, ICD) with a unified edit-mode
approach using data-driven field configuration. A single "Bearbeiten"
button toggles all fields into edit mode with dirty-tracking and
split-save (KVNR via dedicated endpoint for all users, remaining fields
via admin-only general update endpoint).
- Extend Case TypeScript interface with 17 missing backend fields
- Add declarative field config (7 sections, 30 fields) in fieldConfig.ts
- Add useInlineEdit hook with dirty-tracking and split-save logic
- Add EditableField dual-mode component (text/date/boolean/select/textarea)
- Refactor CaseDetail to render sections from config
- ICD section retains its own endpoint with separate save button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
get_vorjahr_summary returned a flat dict, but excel_export looked for
data under vj.get("summary", {}), resulting in empty Vorjahr columns.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When generating a report for the same jahr/kw, update the existing
record instead of inserting a duplicate (which caused IntegrityError).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
report_service uses 'summary'/'weekly'/'keine_rm'/'gutachten' but
excel_export expected 'totals'/'weeks'/'keine_rueckmeldung'/
'gutachten_gesamt'. Also fix nested gesamt dict access in sheet3
and icd_codes path from sheet5.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Browser-initiated downloads (window.open) cannot set Authorization
headers. Accept ?token= query parameter as fallback on the report
download and coding-template endpoints.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move Fallgruppen names into a Legend below the chart instead of
inline labels that overflow the container. Reduce pie radius to
leave breathing room.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
.cast(int) uses Python's builtin int, which lacks SQLAlchemy's
_isnull attribute. Replace all occurrences with .cast(Integer).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents a single duplicate fall_id from rolling back the entire
import session. Each row insert now uses db.begin_nested() so
constraint violations are isolated to the offending row.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Node.js entry point that serves static frontend files and proxies
/api/ requests to the FastAPI backend on port 8000.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>