# Shuffle – Projektkontext für Claude Code Diese Datei wird in jeder Claude-Code-Session automatisch geladen. Sie ist das "Gedächtnis" des Projekts. Halte sie kurz, aktuell und verbindlich. Details gehören nach `docs/` oder in Outline. ## Was ist Shuffle? Shuffle ist eine Brettspiel-App für **iOS, Android und Web** aus einer gemeinsamen Codebasis. Die fachlichen Anforderungen liegen in `requirements/` (Quelle der Wahrheit) und werden als User Stories in Forgejo-Issues umgesetzt. ## Tech-Stack (ADR-0001 angenommen, Hosting ADR-0002) - **Frontend:** Flutter (stable) / Dart 3 – eine Codebasis für iOS, Android, Web - **State-Management:** Riverpod (mit Code-Generierung) - **Navigation:** go_router (Deep Links + Web-URLs) - **Backend:** Supabase (PostgreSQL 16, Auth, Storage, Realtime, Edge Functions), **selbst gehostet auf Hetzner** (ADR-0002); lokal per Supabase CLI. Nur Features nutzen, die auch self-hosted verfügbar sind; Dashboard-Einstellungen im Repo dokumentieren. - **Modelle:** freezed + json_serializable - **Tests:** flutter_test, mocktail, integration_test, Playwright (Web-E2E) - **CI/CD:** Forgejo Actions (`.forgejo/workflows/`) - **Doku:** Outline (Collection „Shuffle“), Architektur-Entscheidungen als ADRs in `docs/adr/` ## Repository-Struktur ``` app/ Flutter-App lib/ core/ Theme, Routing, DI, Fehlerbehandlung, gemeinsame Widgets features// Feature-first: data/ domain/ presentation/ test/ Unit- und Widget-Tests (Spiegel von lib/) integration_test/ supabase/ migrations/ SQL-Migrationen (nur additive Änderungen, nie bestehende editieren) functions/ Edge Functions (TypeScript/Deno) seed.sql tests/database/ pgTAP-Tests für Schema und RLS (`supabase test db`) requirements/ Fachliche Anforderungen (10-anforderungen.md, 20-r1-akzeptanzkriterien.md) docs/ adr/ Architecture Decision Records datenmodell-r1.md Datenmodell R1 inkl. Tabellenstruktur (Migrationen sind maßgeblich) specs/ Technische Feature-Spezifikationen (eine pro Issue) .claude/agents/ Spezialisierte Subagents .claude/commands/ Slash-Commands für Workflows ``` ## Arbeitsweise (verbindlich) 1. **Jede Änderung hat ein Forgejo-Issue.** Kein Code ohne Issue-Nummer. 2. **Branch pro Issue:** `feature/-`, `fix/-`. 3. **Spec vor Code:** Für jedes Feature-Issue entsteht zuerst `docs/specs/-.md` (Agent `architect`). Chris gibt die Spec frei, bevor implementiert wird. 4. **Tests sind Teil des Features**, nicht nachgelagert. Kein PR ohne Tests für neue Logik. 5. **Pull Request in Forgejo**, Review durch Agent `code-reviewer`, Merge **nur durch Chris**. 6. **Conventional Commits:** `feat(collection): ...`, `fix(auth): ...`, `test: ...`, `docs: ...`, mit `Refs #` bzw. `Closes #`. ## Definition of Done - [ ] Akzeptanzkriterien des Issues erfüllt und im PR einzeln abgehakt - [ ] `dart format --set-exit-if-changed .` und `flutter analyze` ohne Befund - [ ] Unit-/Widget-Tests grün, neue Logik getestet - [ ] Läuft auf Android, iOS und Web (oder Abweichung im PR begründet) - [ ] Supabase: Migration + RLS-Policies + Policy-Tests vorhanden, wenn Tabellen betroffen - [ ] Texte über l10n (`app/lib/l10n/*.arb`), keine hartkodierten UI-Strings (Deutsch + Englisch) - [ ] Barrierefreiheit: Semantics-Labels, ausreichende Kontraste, Touch-Ziele ≥ 48dp - [ ] Doku aktualisiert (Spec, ggf. ADR, ggf. Outline-Seite) ## Code-Konventionen - Code, Bezeichner, Commits: **Englisch**. Doku, Specs, Issue-Texte: **Deutsch**. - Feature-first-Struktur, Abhängigkeiten nur nach innen (presentation → domain ← data). - Keine Geschäftslogik in Widgets. Widgets sind dumm, Logik in Notifiern/Use-Cases. - Keine `print`-Aufrufe; Logging über das zentrale Logger-Utility. - Secrets niemals ins Repo. Konfiguration über `--dart-define-from-file=env/.json` (in `.gitignore`). - Sicherheit: Jede Tabelle hat RLS aktiviert. Der Client vertraut niemals Client-Daten für Berechtigungen. ## Agents (siehe `.claude/agents/`) | Agent | Zuständig für | |---|---| | `requirements-analyst` | Anforderungen → User Stories mit Akzeptanzkriterien → Forgejo-Issues | | `architect` | Architektur, Datenmodell, ADRs, Feature-Specs, Aufgaben-Schnitt | | `backend-dev` | Supabase: Migrationen, RLS, Edge Functions, Seeds | | `flutter-dev` | Flutter-UI, State, Navigation, Datenanbindung | | `ui-designer` | Design-System, Theme, Komponenten, UX-Konsistenz, Barrierefreiheit | | `test-engineer` | Teststrategie, Unit-/Widget-/Integration-/E2E-Tests | | `code-reviewer` | Review gegen DoD, Sicherheit, Architektur (nur lesend) | | `devops` | Forgejo Actions, Builds, Releases, Umgebungen | | `docs-writer` | Outline-Doku, Changelog, Release Notes | ## Workflows (Slash-Commands) - `/intake` – neue Anforderungen aus `requirements/` in Stories + Issues überführen - `/feature ` – komplette Pipeline: Spec → Freigabe → Umsetzung → Tests → Review → PR - `/review ` – Review eines PRs - `/adr ` – neue Architekturentscheidung dokumentieren - `/release ` – Release vorbereiten ## Wichtige Befehle ```bash cd app && flutter pub get dart run build_runner build --delete-conflicting-outputs flutter analyze && flutter test flutter run -d chrome --dart-define-from-file=env/dev.json supabase start # lokales Backend supabase db reset # Migrationen + Seed neu einspielen supabase test db # RLS-/pgTAP-Tests ``` ## Werkzeuge (MCP) - **forgejo** – Issues, PRs, Labels, Milestones im Repo `shuffle` - **outline** – Doku-Collection „Shuffle“ - **dart** – Analyse, Tests, pub.dev-Suche, laufende App inspizieren - **playwright** – Web-Build im Browser testen ## Daten & Sicherheit (R1) - Datenmodell: `docs/datenmodell-r1.md`, Migrationen in `supabase/migrations/` (nie bestehende ändern). - Alle Tabellen: `id` (uuid), `created_at`, `updated_at`; FKs nur zwischen verwandten Tabellen (`_id`). - Jede neue Tabelle braucht RLS, Policies und pgTAP-Tests in `supabase/tests/database/`. - In R1 sind alle Nutzerdaten privat; Katalog ist öffentlich lesbar, Pflege nur Admin. - Akzeptanzkriterien werden als „KTO-01 Kriterium 3“ in Tests und PR-Checklisten referenziert. ## Grenzen - Nichts nach `main` pushen. Kein Force-Push. Keine Releases ohne Freigabe von Chris. - Bei unklaren fachlichen Fragen: **nicht raten** – Frage als Kommentar ins Issue schreiben und Label `needs-clarification` setzen.