update process model spec: fix reviewer issues, add data migration, dynamic numbering, antrag checklist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 19:09:06 +01:00
parent 53c230845d
commit 4b2c916407

View File

@@ -10,11 +10,11 @@ Replace the manually-synced `aktueller_schritt` enum with a data-driven process
### Step 1 — Erstgespräch durchführen
One Erstgespräch per therapist, each spanning one or more sessions (date entries). The Erstgespräch carries a diagnosis (text, e.g. "F32.1") and an optional Dringlichkeitscode (boolean). Both can be set or edited after the initial session — PTV11 often arrives later.
One Erstgespräch per therapist (enforced by UNIQUE constraint), each spanning one or more sessions (date entries). The Erstgespräch carries a diagnosis (text, e.g. "F32.1") and an optional Dringlichkeitscode (boolean). Both can be set or edited after the initial session — PTV11 often arrives later.
**Status = erledigt** when at least one sprechstunde has a non-NULL diagnosis.
**UI:** List of existing Erstgespräche (therapist name, diagnosis, Dringlichkeitscode badge, session count). Each expandable to show session dates with "Sitzung hinzufügen". An "Erstgespräch hinzufügen" button opens a form: select therapist, first session date, optional diagnosis + Dringlichkeitscode.
**UI:** List of existing Erstgespräche (therapist name, diagnosis, Dringlichkeitscode badge, session count). Each expandable to show session dates with "Sitzung hinzufügen". An "Erstgespräch hinzufügen" button opens a form: select therapist (from kontakte list — if no therapists exist, show message directing user to create one under Kontakte first), first session date, optional diagnosis + Dringlichkeitscode.
### Step 2 — TSS kontaktieren (conditional)
@@ -22,7 +22,7 @@ Only visible when any sprechstunde has `dringlichkeitscode = TRUE`. The TSS (Ter
**Status = erledigt** when `nutzer.tss_kontaktiert_datum IS NOT NULL`.
**UI:** Single "TSS kontaktiert" button that stamps today's date. Once done, shows the contact date.
**UI:** Single "TSS kontaktiert" button that stamps today's date. Once done, shows the contact date. No undo (matches current behavior for all advance actions).
### Step 3 — Eigensuche durchführen
@@ -44,20 +44,41 @@ Each step independently computes its status:
| Query | SQL |
|---|---|
| hasErstgespraech | `SELECT EXISTS(SELECT 1 FROM sprechstunde)` |
| hasDiagnose | `SELECT EXISTS(SELECT 1 FROM sprechstunde WHERE diagnose IS NOT NULL)` |
| hasDringlichkeit | `SELECT EXISTS(SELECT 1 FROM sprechstunde WHERE dringlichkeitscode = TRUE)` |
| tssKontaktiert | `nutzer.tss_kontaktiert_datum IS NOT NULL` |
| absagenUndKeineAntwort | `SELECT COUNT(*) FROM kontakt WHERE ergebnis IN ('absage','keine_antwort')` |
Step status mapping:
- **erledigt:** prerequisite met (green badge)
- **aktuell:** visible and not yet erledigt
- **offen:** visible but upstream prerequisites not met
- Step 2 not rendered at all when hasDringlichkeit = FALSE
### Step status logic
| Step | erledigt | aktuell | offen | visible |
|---|---|---|---|---|
| 1 — Erstgespräch | hasDiagnose | always (no prerequisites) | never | always |
| 2 — TSS | tssKontaktiert | step 1 erledigt | step 1 not erledigt | only if hasDringlichkeit |
| 3 — Eigensuche | absagenUndKeineAntwort >= 5 | step 1 erledigt | step 1 not erledigt | always |
| 4 — Kostenerstattung | — (terminal) | steps 1+3 erledigt (and 2 if visible) | otherwise | always |
Step numbering is dynamic: when TSS is hidden, steps display as 1, 2, 3. When TSS is visible, steps display as 1, 2, 3, 4.
### Antrag checklist (updated)
The antrag checklist derives all checks from data:
1. "Erstgespräch durchgeführt" — `EXISTS(SELECT 1 FROM sprechstunde WHERE diagnose IS NOT NULL)`
2. "Dringlichkeitscode erhalten" — `EXISTS(SELECT 1 FROM sprechstunde WHERE dringlichkeitscode = TRUE)` (informational, not blocking)
3. "TSS kontaktiert" — `nutzer.tss_kontaktiert_datum IS NOT NULL` (only shown if hasDringlichkeit)
4. "Therapeutensuche dokumentiert" — `COUNT(kontakt WHERE ergebnis IN ('absage','keine_antwort')) >= 5`
5. "Absagenliste exportiert" — tracked locally (unchanged)
## Schema changes (migration 002)
### Data migration
Before dropping columns, migrate existing data:
1. Copy `nutzer.tss_beantragt_datum``nutzer.tss_kontaktiert_datum`
2. Create `sitzung` rows from existing `sprechstunde.datum` values
3. Then drop old columns
### Drop from `nutzer`
`aktueller_schritt`, `dringlichkeitscode`, `dringlichkeitscode_datum`, `tss_beantragt`, `tss_beantragt_datum`
@@ -68,9 +89,10 @@ Step status mapping:
### Modify `sprechstunde`
- Drop `datum` (moves to sitzung)
- Drop `ergebnis` (was always 'erstgespraech', unused)
- Keep: `id`, `therapeut_id`, `diagnose` (text), `dringlichkeitscode` (boolean), `erstellt_am`, `aktualisiert_am`
- Drop `datum` (migrated to sitzung first)
- Drop `ergebnis` (was always 'erstgespraech', vestigial)
- Add `UNIQUE(therapeut_id)` constraint (one Erstgespräch per therapist)
- Keep: `id`, `therapeut_id`, `diagnose` (text), `dringlichkeitscode` (boolean), `erstellt_am`
### New table `sitzung`
@@ -89,13 +111,13 @@ CREATE TABLE sitzung (
## Files changed
- **New:** `src/shared/db/migrations/002_process_model.sql` — schema migration
- **New:** `src/shared/db/migrations/002_process_model.sql` — schema migration with data migration
- **Modify:** `src/shared/db/schema.ts` — remove `prozessSchrittEnum`/`ProzessSchritt`, add `Sitzung` type
- **Modify:** `src/shared/lib/constants.ts` — remove `PROZESS_SCHRITTE` array
- **Delete:** `src/shared/lib/constants.test.ts` — stale test for removed array
- **New/Rewrite:** `src/features/prozess/hooks.ts``useProcessStatus()` hook deriving status from data
- **Rewrite:** `src/features/prozess/components/process-stepper.tsx` — data-driven steps, Erstgespräch list/form, conditional TSS
- **Modify:** `src/features/prozess/components/phase-card.tsx`adapt to new status model if needed
- **Modify:** `src/features/antrag/components/antrag-checklist.tsx` — derive checks from data instead of `nutzer` flags
- **Rewrite:** `src/features/prozess/components/process-stepper.tsx` — data-driven steps, Erstgespräch list/form, conditional TSS, dynamic step numbering
- **Modify:** `src/features/prozess/components/phase-card.tsx`remove index prop, accept dynamic step number
- **Modify:** `src/features/antrag/components/antrag-checklist.tsx` — derive checks from data (see updated checklist above)
- **Modify:** `src/features/einstellungen/scenarios.ts` — seed data rows instead of setting `aktueller_schritt`
- **Modify:** `src/features/onboarding/components/onboarding-form.tsx` — remove `aktueller_schritt` from INSERT