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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user