hellth-hub/.claude/skills/datenmodell-architekt/SKILL.md
Sebastian Mayer 61a3f980bf
Some checks are pending
CI / Lint, Typecheck, Test, Build (push) Waiting to run
Skills: Datenschutz-Prüfer, Security-Auditor, Datenmodell-Architekt
Drei projektspezifische Begutachtungs-Skills analog zum
ernaehrungswissenschaftler:

- datenschutz-pruefer: DSGVO/Privacy für sensible Gesundheitsdaten
  (userId-Scope, keine Leaks, Privacy-by-Default, Lösch-/Export-Pfade).
- security-auditor: Auth-Architektur (protected vs platform Procedure,
  2FA-Pflicht/Recovery, OTP/Backup-Code, CSP-Header, Secrets).
- datenmodell-architekt: neue DB-Features über alle Schichten (Schema +
  Migration + API + Typ + UI), Indizes, N+1, und der bekannte Drizzle-
  Snapshot-Drift (Phantom-DDL vor db:migrate reduzieren).

Hilfreich besonders vor dem geplanten Profil-/Register-/OAuth-Feature.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 11:51:21 +02:00

96 lines
5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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.