# Dimension47

## What This Is

Dimension47 ist eine selbst gehostete Web-App für Pathfinder-2e-Tischrunden auf Deutsch. Sie verwaltet Kampagnen, Charakterbögen mit komplettem PF2e-Regelumfang (HP, Zustände, Inventar, Talente, Aktionen, Alchemie) und stellt einen GM-Battle-Screen mit 3D-Druck-Tisch-Display bereit — alles in Echtzeit synchronisiert. Zielgruppe ist die eigene Spielgruppe, nicht die breite Öffentlichkeit.

## Core Value

Am Tisch funktioniert alles in Echtzeit und regelkonform: Spieler lesen ihren Charakterbogen am Handy, der GM steuert vom Laptop aus den Battle-Screen, der eingelassene Tisch-Display zeigt die Spielsicht — ohne Reibung, ohne falsche Werte, ohne Reload.

## Requirements

### Validated

<!-- Bestand aus existierender Codebase — abgeleitet aus `.planning/codebase/` und CLAUDE.md -->

- ✓ JWT-Auth mit Rollen (ADMIN/GM/PLAYER), Login-Persistenz, animierter Login-Screen — existing
- ✓ Kampagnen-CRUD mit Mitgliederverwaltung und GM-Berechtigungen — existing
- ✓ Pathbuilder-2e-Import als Charakter-Erstellungspfad — existing
- ✓ HP-Management mit Schaden/Heilung/Direkt + Temp-HP, mobile-optimiert — existing
- ✓ Zustände (Conditions) mit PF2e-Datenbank, hinzufügen/entfernen/aktualisieren — existing
- ✓ Fertigkeiten mit deutschen Namen, Rettungswürfe, Wahrnehmung mit korrekter PF2e-Berechnung — existing
- ✓ Inventar mit 5.482-Item-Equipment-DB, Bulk-Tracking, Belastung, Equip-Status, benutzerdefinierte Notizen — existing
- ✓ Talente-Tab mit allen Charaktertalenten kategorisiert (Klasse/Abstammung/Allgemein/Fertigkeit/Bonus/Archetyp) — existing
- ✓ Aktionen-Tab mit 99 PF2e-Aktionen, Suche, Aktionstyp-Icons — existing
- ✓ Alchemie-Tab mit Phiolen, Formelbuch, Vorbereitung, Quick/Craft-Alchemy, Forschungsgebieten, infundierten Items — existing
- ✓ Rest-System mit HP-Heilung, Zustands-Reduktion, Ressourcen-Reset, Alchemie-Reset — existing
- ✓ HTML-Export des Charakterbogens — existing
- ✓ WebSocket-Sync (Socket.io) für HP, Zustände, Inventar, Equip-Status, Geld, Level, Alchemie — existing
- ✓ Battle-Screen MVP: Sessions, Map+Tokens mit Drag-Drop (GM), HP/Init pro Token, Round-Counter, WebSocket-Sync — existing
- ✓ GM-Library für Battle-Maps und NPC-Templates (Combatants) — existing
- ✓ Equipment-DB mit Kategorien-API und Such-Endpunkten — existing

### Active

<!-- Hypothesen für die nächste Ausbaustufe — werden in Phasen geschnitten und validiert. -->

**Level-Up-System (regelkonform PF2e)**
- [ ] Charakter levelt regelkonform auf nächste Stufe mit allen Wahlpfaden (Attribute Boosts, Klassentalente, Allgemeine Talente, Fertigkeitstalente, Skill-Increases, Klassenmerkmale, Archetyp-Optionen)
- [ ] Voraussetzungen werden validiert (z.B. Talent erfordert bestimmte Fertigkeitsstufe oder Vorgängertalent)
- [ ] Level-Up ist undo-bar bis bestätigt; bestätigtes Level-Up erzeugt nachvollziehbare Änderung in Charakterhistorie
- [ ] Stat-Recompute (HP-Max, Save-Boni, Skill-Boni, AC) folgt automatisch aus Level-Up-Wahlen

**Mobile-First-PWA**
- [ ] App ist als PWA installierbar (Manifest, Icons, Splash, Service Worker)
- [ ] Charakterbogen, Inventar, Talente, Aktionen, Alchemie sind offline lesbar (Cache-First für gelesene Charaktere)
- [ ] Web-Push-Notifications für GM→Spieler-Pings (Würfelaufforderung, Battle-Turn-Alert, Custom-Nachrichten)
- [ ] Bestehende Charakter-Screens werden auf Mobile-First-Touch-Targets und Layout durchgegangen, wo nötig poliert

**Battle-Screen-Ausbau (GM-Laptop + Tisch-Display)**
- [ ] Separater Display-Mode (read-only Player-View) auf eigener Route, optimiert für eingelassenen Tisch-Bildschirm — zeigt nur Map, Tokens, Initiative-Reihenfolge, Token-Status
- [ ] Initiative-Tracker als sortierte Liste mit „Wer ist dran"-Highlight, nicht nur Badges auf Tokens
- [ ] Effekte/Auren/Buffs/Debuffs pro Token (Modell + UI + Echtzeit-Sync)
- [ ] Token-Add/Remove als WebSocket-Event (heute nur Query-Invalidate)
- [ ] Touch-/Tablet-Steuerung am GM-Laptop ist nutzbar (kein Pflicht-Mobile, aber auch nicht kaputt)

**Würfeln & Chat in Echtzeit**
- [ ] In-App-Würfler mit PF2e-Notation (z.B. `1d20+7`, Crit-Erkennung, Persistent Damage)
- [ ] Roll-Log pro Kampagne und pro Battle-Session, sichtbar für alle Teilnehmer
- [ ] In-Game-Chat pro Kampagne und Battle, Echtzeit, mit Roll-Einbettung

**GM-Live-Tools**
- [ ] GM kann live HP/Conditions/Items/Geld bei Spieler-Charakteren setzen (über bestehendes WebSocket-Modell, neue GM-UI)
- [ ] GM kann gezielte Push-/Chat-Nachrichten an einzelne oder alle Spieler senden

**Obsidian-Vault-Anbindung (Read-only Browser)**
- [ ] App liest Markdown aus selbst-gehostetem Vault-Endpoint (vermutlich eigener Server, Protokoll noch zu wählen)
- [ ] Vault-Browser in der App: Ordner-Navigation, Datei-Lesen, Suche
- [ ] Markdown-Rendering inkl. Wikilinks (klickbar zu anderer Note), eingebetteten Bildern, Code-Blöcken
- [ ] Vault-Inhalte sind auch offline lesbar (zuletzt gelesene Notes gecacht)

### Out of Scope

- **Bidirektionales Vault-Sync** — schreibender Zugriff in den Vault wurde bewusst auf später verschoben; reine Lese-App reicht für aktuelle Nutzung
- **Offline-Bearbeiten mit Sync-Queue** — kein Edit ohne Netz; Offline-Modus deckt nur Lesen ab. Konflikt-Logik wäre teuer und das Spiel passiert sowieso live am Tisch
- **Native iOS/Android-App über Capacitor o.ä.** — Web Push reicht; PWA-Installation ersetzt Native-App-Bedürfnis
- **Charakter-Erstellung von null in der App** — Pathbuilder-Import bleibt der Erstellungspfad; in-App-Erstellung wäre Doppelarbeit
- **Andere TTRPG-Systeme als PF2e** — Datenmodell und UI sind PF2e-spezifisch, kein Generalisierungs-Ziel
- **Öffentlicher Mehrmandanten-Betrieb** — App läuft für die eigene Gruppe selbst gehostet; kein Account-Onboarding-Flow, keine Marketing-Site
- **Presence/Awareness-Indikatoren** („wer ist online", „wer schaut wo hin") — wurde bewusst aus den geplanten WebSocket-Erweiterungen ausgeschlossen, weil Mehrwert klein und Komplexität hoch

## Context

**Bestehende Codebase:** Reife Brownfield-App. NestJS 11 + React 19 + Prisma 7 + PostgreSQL + Socket.io + Tailwind v4. TypeScript strict mode überall. Codebase ist gemappt unter `.planning/codebase/` (ARCHITECTURE.md, STACK.md, STRUCTURE.md, CONVENTIONS.md, INTEGRATIONS.md, CONCERNS.md, TESTING.md).

**Domain-Spezifika:**
- PF2e ist regelseitig komplex (Action-Economy, drei Aktionen pro Runde, Proficiency-Stufen, Boost-Regeln alle 5 Level, Archetypen, Free Archetype). Equipment-DB hat 5.482 Items, Aktionen-DB hat 99 Einträge, deutsche Übersetzungen werden via Claude-API on-demand generiert und in Translation-Tabelle gecacht.
- Spielgruppe nutzt 3D-gedruckte Miniaturen auf einem in den Spieltisch eingelassenen Bildschirm. Battle-Screen muss zwei Sichten bedienen: GM-Steuerung (Laptop) und Tisch-Display (read-only Spielsicht).

**Current state:**
- Battle-Screen ist heute nicht mobil benutzbar (fixe Sidebar-Layouts, Maus-Drag-Drop, kein Display-Mode). Bewusst gewollt — bleibt Laptop+Tisch-Bildschirm-Anwendung.
- Charakterbogen ist heute mobile-optimiert mit 44 px+ Touch-Targets.
- WebSocket-Infrastruktur ist solide — Erweiterungen folgen bestehendem Gateway-Pattern.

**Philosophie (aus CLAUDE.md übernommen):** Qualität vor Geschwindigkeit. Keine Shortcuts. Prisma-Migrations statt `db push`. Daten in DB, nicht aus JSON. Proper Error Handling. Keine `any`-Types. Deutsch in der UI. Keine Emojis.

## Constraints

- **Tech-Stack**: NestJS 11 + React 19 + Prisma 7 + PostgreSQL + Socket.io + Tailwind v4 — gesetzt durch Bestand, kein Stack-Wechsel sinnvoll
- **Sprache**: Deutsche UI durchgehend — alle neuen Texte ebenfalls Deutsch
- **Design**: Mobile-First für alle nutzerseitigen Screens (Charakterbogen, Vault-Browser, Würfler, Chat); Battle-GM-Screen darf desktop-fokussiert bleiben; Tisch-Display ist eigener Layout-Modus
- **Daten-Persistenz**: Alle PF2e-Daten gehören in die DB (Prisma-Seeds aus JSON), nichts wird zur Laufzeit aus JSON-Dateien gelesen
- **Migrationen**: Schema-Änderungen ausschließlich über `prisma migrate dev`, niemals `db push`
- **Code-Qualität**: TypeScript strict, keine `any`-Types, kein Quick-Fix der später wehtut
- **Hosting-Modell**: Self-hosted für eigene Spielgruppe — keine Multi-Tenant-/SaaS-Anforderungen
- **Push-Plattform**: Web Push (Service-Worker-basiert), kein FCM/APNs-Native-Wrapper
- **Vault-Endpoint**: Selbst-gehosteter Endpoint (vermutlich auf eigenem Server) — konkretes Protokoll wird in der Vault-Phase entschieden, nicht jetzt

## Key Decisions

| Decision | Rationale | Outcome |
|----------|-----------|---------|
| Level-Up wird voll regelkonform implementiert (statt Re-Import-only) | Volle Kontrolle in der App, weniger Reibung am Tisch, validierte Werte | — Pending |
| PWA mit Web Push, kein Native-Wrapper | Funktioniert plattformübergreifend (Android-Chrome, iOS-Safari ab installierter PWA), kein Build-/Store-Aufwand | — Pending |
| Offline-Bearbeiten ist explizit raus, nur Offline-Lesen | Konflikt-Logik wäre teuer; Spielsessions sind online | — Pending |
| Battle-Screen bleibt Laptop+Tisch-Display, kein Pflicht-Mobile | Spielablauf am realen Tisch mit 3D-Minis braucht großen Screen | — Pending |
| Obsidian-Anbindung ist v1 nur lesend | Lesen deckt 100 % des aktuellen Bedarfs; Schreiben verdoppelt Komplexität | — Pending |
| Vault wird selbst-gehostet (statt Git-Repo / Cloud-Storage) | User hat eigenen Server; passt zum Self-Hosted-Charakter der App | — Pending |
| Keine Eile, Qualität zählt | Übernommen aus CLAUDE.md-Philosophie; bestimmt Phasen-Schnitt (lieber breite Phasen sauber als hektisch) | — Pending |

## Evolution

This document evolves at phase transitions and milestone boundaries.

**After each phase transition** (via `/gsd-transition`):
1. Requirements invalidated? → Move to Out of Scope with reason
2. Requirements validated? → Move to Validated with phase reference
3. New requirements emerged? → Add to Active
4. Decisions to log? → Add to Key Decisions
5. "What This Is" still accurate? → Update if drifted

**After each milestone** (via `/gsd-complete-milestone`):
1. Full review of all sections
2. Core Value check — still the right priority?
3. Audit Out of Scope — reasons still valid?
4. Update Context with current state

---
*Last updated: 2026-04-27 after initialization*
