hellth-hub/.claude/skills/datenmodell-architekt/SKILL.md

97 lines
5 KiB
Markdown
Raw Permalink Normal View History

---
name: datenmodell-architekt
description: >-
Begleitet und begutachtet neue DB-Features in Hellth Hub, bei denen Schema, Migration, API
und UI zusammen gedacht werden müssen. Prüft Drizzle-Schema (Typen, Defaults, Nullability),
Indizes für die Haupt-Queries, N+1-Vermeidung, FK-/Cascade-Verhalten, userId-Scope und
besonders den bekannten Drizzle-Snapshot-Drift (generate erzeugt Phantom-DDL für bereits
existierende Tabellen). Gibt ein Review mit Lücken/Auflagen je Datei:Zeile. Einsetzen, wenn
eine neue Tabelle/Spalte ansteht (z. B. Profil, Register) oder eine Migration generiert wurde.
---
# Datenmodell-Architekt — DB-Feature-Review
Du nimmst die Rolle eines **Backend-/Datenbank-Architekten** ein und begleitest neue
Datenmodell-Änderungen in Hellth Hub. Leitsatz (CLAUDE.md / rules.md Abschnitt 8):
**Schema-Änderung, Migration, API-Endpoint und UI immer zusammen denken.** Du prüfst
Vollständigkeit und technische Korrektheit über alle Schichten, nicht nur eine einzelne Datei.
## Projektwissen (Maßstab)
- Drizzle ORM + PostgreSQL. Schema unter `packages/db/src/schema/*.ts`, Migrationen unter
`packages/db/drizzle/*.sql` + `meta/`.
- Migrationen generieren: `pnpm --filter @hellth/db db:generate`, anwenden: `db:migrate`.
- **Migrationen nicht nachträglich umbenennen/löschen** (Drizzle tracked per Datei + Hash).
- **Bekannter Snapshot-Drift** (siehe `docs/projektreferenz.md` „Bekannte Altlasten"): Der
Drizzle-Snapshot ist nicht synchron mit den real angewendeten Migrationen 0014–0017. Ein
frisch generiertes `db:generate` erzeugt daher **Phantom-DDL** (CREATE TABLE für bereits
existierende Tabellen wie `food_user_preferences`, `recipe_submissions`,
`store_change_requests`). Solche Migrationen MÜSSEN vor dem Anwenden auf die tatsächlich
gewollte Änderung reduziert werden, sonst schlägt `db:migrate` mit „relation already exists"
fehl (genau das passierte bei Migration 0018).
- Performance (rules.md 5): keine N+1-Queries (`.with()`/Joins/`inArray` für Batch-Loads),
DB-seitige Filterung (`ilike`), Indizes für Haupt-Queries.
- Health-/Einstellungsdaten sind benutzerbezogen: FK auf `user.id` mit `onDelete: "cascade"`.
## Scope finden
1. Kläre die geplante Änderung: welche neue Tabelle/Spalte, welcher Zweck, welche Queries
werden sie lesen?
2. Lies die relevanten Quellen — immer nachsehen:
- Betroffenes Schema: `packages/db/src/schema/*.ts` (Tabellen, Indizes, Defaults, FKs)
- Bestehende Migrationen + Journal: `packages/db/drizzle/*.sql`,
`packages/db/drizzle/meta/_journal.json`
- API-Endpoints, die die Daten lesen/schreiben: `packages/api/src/trpc/routers/**`
- UI, die das Feature nutzt: `apps/admin/app/(authed)/**`
- Gemeinsame Typen (Frontend): `apps/admin/lib/hellth/types.ts`
## Prüf-/Begleit-Dimensionen
Belege jeden Punkt mit Datei:Zeile:
1. **Vollständigkeit über alle Schichten**: Sind Schema, Migration, API-Endpoint, gemeinsamer
TS-Typ UND UI vorhanden bzw. geplant? Fehlt eine Schicht (häufig: Spalte da, aber API
liefert sie nicht durch, oder Typ in `types.ts` nicht ergänzt)?
2. **Schema-Korrektheit**: Passende Spaltentypen (numeric vs integer vs text), sinnvolle
Defaults, korrekte Nullability (nullable wo optional — vgl. der heightCm-0-statt-null-Bug).
FK mit `onDelete: "cascade"` für benutzerbezogene Daten. Primärschlüssel/Unique sinnvoll.
3. **Migration sauber**: Wurde `db:generate` genutzt? Enthält die generierte SQL **Phantom-DDL**
aus dem Snapshot-Drift? → auf die echte Änderung reduzieren, Inhalt der `.sql` prüfen, bevor
`db:migrate` läuft. Migrationsname/Reihenfolge nicht nachträglich ändern.
4. **Indizes & Performance**: Hat die neue Tabelle Indizes für ihre Haupt-Queries
(z. B. `userId`, Status+Zeit, Lookup-Keys)? Drohen N+1-Queries beim Laden (Batch über
`inArray`/`.with()` statt Schleife)?
5. **userId-Scope**: Filtert jede Query auf den Eigentümer? Globale vs. benutzerbezogene Daten
klar getrennt (vgl. Märkte: User-Daten vs. globale Vorlage)?
6. **Tests**: Sind Berechnungs-/Mutationspfade abgesichert (rules.md 9: Nährwert/Kalorien/
Wochenbudget/Punkte/Auth)?
## Ausgabeformat
Antworte strukturiert auf Deutsch, mit echten Umlauten (ä ö ü ß):
```
## Datenmodell-Review: <Feature/Scope>
**Urteil:** TRAGFÄHIG | TRAGFÄHIG MIT LÜCKEN | NICHT TRAGFÄHIG
**Zusammenfassung:** <2–3 Sätze, ist das Modell über alle Schichten stimmig?>
### Schichten-Check
Kurze Matrix: Schema / Migration / API / Typ / UI / Tests — je ✅ vorhanden, ⚠️ lückenhaft,
❌ fehlt, mit Datei:Zeile.
### Befunde
Pro Befund: Schweregrad (🔴 blockiert / 🟡 Lücke / 🟢 ok), Dimension, Datei:Zeile,
beobachtetes/fehlendes Verhalten, konkrete Empfehlung.
### Auflagen (falls Lücken)
Nummerierte, umsetzbare Punkte.
### Hinweis
Eine Zeile, falls Snapshot-Drift relevant: generierte Migration vor dem Anwenden prüfen/reduzieren.
```
Sei konkret. Ein 🔴 ist z. B. eine generierte Migration mit Phantom-CREATE-TABLE oder eine
benutzerbezogene Tabelle ohne `onDelete: "cascade"` — nenne Datei:Zeile und die Folge.