# Requirements: Dimension47 — Milestone "PWA-Companion" **Defined:** 2026-04-27 **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. ## v1 Requirements ### Level-Up (PF2e regelkonform) - [ ] **LVL-01**: User startet Level-Up auf einem Charakter und sieht einen Wizard mit allen für das neue Level relevanten Wahlpunkten - [ ] **LVL-02**: Attribute Boosts auf Level 5/10/15/20 werden angeboten (4 Boosts pro Boost-Level, +2 unter 18, +1 ab 18; HP-/Skill-Recompute folgt) - [ ] **LVL-03**: Klassentalent-Wahl an jedem geraden Level mit Filter nach Klasse + Level + Voraussetzungen - [ ] **LVL-04**: Fertigkeitstalent-Wahl an jedem geraden Level mit Voraussetzungs-Filter (Übungsstufe, benannte Fertigkeit) - [ ] **LVL-05**: Allgemein-Talent-Wahl an Level 3/7/11/15/19 (Fertigkeitstalente sind optional als Allgemein-Talent wählbar) - [ ] **LVL-06**: Skill-Increase an Level 3 und jedem 2. Level danach mit Cap-Regel (Trained→Expert ab L3, Expert→Master ab L7, Master→Legendary ab L15) - [ ] **LVL-07**: Ancestry-Talent-Wahl an Level 5/9/13/17 mit Filter nach Abstammung + Heritage + Voraussetzungen - [ ] **LVL-08**: Klassenmerkmale werden automatisch aus Class-Progression-Tabelle pro Klasse + Level angewendet (neue DB-Tabelle, gefüttert aus PF2e-Quelldaten) - [ ] **LVL-09**: Voraussetzungen werden über einen DSL-Evaluator geprüft; nicht-evaluierbare Voraussetzungen erscheinen als Warnung, kein Hard-Block - [ ] **LVL-10**: Abgeleitete Werte werden automatisch neu berechnet (HP-Max, Save-Proficiency, AC-Proficiency, Klassen-DC, Wahrnehmung) - [ ] **LVL-11**: User kann den Level-Up-Wizard jederzeit abbrechen oder bisherige Wahlen rückgängig machen, bevor er bestätigt (Draft-Session) - [ ] **LVL-12**: Bestätigtes Level-Up wird atomar persistiert (Transaction) und erzeugt einen nachvollziehbaren Historieneintrag (Snapshot-Before in JSON) - [ ] **LVL-13**: Free-Archetype-Variante kann pro Charakter aktiviert werden; aktiviert zweiten Talent-Slot, der bis zur Dedication frei wählbar und danach archetype-restricted ist - [ ] **LVL-14**: Spellcaster bekommen Slot- und Cantrip-Progression nach Klasse/Tradition; spontane Caster zusätzlich Repertoire-Increment - [ ] **LVL-15**: Deutsche Übersetzungen für neue Talent-Voraussetzungs-Texte und Klassenmerkmal-Beschreibungen werden via bestehender Translation-Pipeline (Claude API + DB-Cache) bereitgestellt ### PWA Foundation - [ ] **PWA-01**: App ist als PWA installierbar (Web App Manifest, Pflicht-Icon-Größen inkl. maskable, Splash, `display: standalone`) - [ ] **PWA-02**: Service Worker via `vite-plugin-pwa` mit `injectManifest`-Strategie; user-scoped Cache-Keys verhindern Cross-User-Cache-Leak - [ ] **PWA-03**: Add-to-Home-Screen-Flow auf Android nutzt `beforeinstallprompt` - [ ] **PWA-04**: Add-to-Home-Screen-Flow auf iOS zeigt geführte Anleitung (Overlay mit Safari-Schritten), da kein programmatischer Prompt verfügbar - [ ] **PWA-05**: Charakterbogen ist offline lesbar (Cache-First für GET `/characters/:id` + abgeleitete Endpunkte) - [ ] **PWA-06**: Inventar, Talente, Aktionen, Alchemie eines bereits geladenen Charakters sind offline lesbar - [ ] **PWA-07**: Service Worker zeigt "Neue Version verfügbar"-Hinweis mit manueller User-Bestätigung; **kein** automatisches `skipWaiting()` - [ ] **PWA-08**: Service-Worker-Update wird während aktiver Battle-Session unterdrückt (kein Mid-Fight-Reload) - [ ] **PWA-09**: TanStack Query persistiert Cache via `idb-keyval` für Offline-Reads über bestehende Hooks - [ ] **PWA-10**: SW-Cache-Einträge werden bei Live-Update-Events via `postMessage` aus Socket-Hooks invalidiert ### Web Push - [ ] **PUSH-01**: Server hat persistente VAPID-Keys (env-konfiguriert, dokumentiertes Rotations-Verfahren) - [ ] **PUSH-02**: User opt-in für Push erfolgt nach expliziter Aktion (Settings-Schalter o.ä.), nicht beim ersten Load - [ ] **PUSH-03**: Push-Subscription wird pro User + Device persistiert (`PushSubscription`-Tabelle, mehrere Devices pro User möglich) - [ ] **PUSH-04**: Service Worker verarbeitet `push`-Events und zeigt Notification mit Titel, Body, Icon, Action-Link - [ ] **PUSH-05**: Server entfernt abgelaufene/ungültige Subscriptions (410 Gone Handling beim Send) - [ ] **PUSH-06**: GM kann gezielten Push an einen einzelnen Spieler oder an alle Spieler einer Kampagne senden - [ ] **PUSH-07**: System sendet Battle-Turn-Alert per Push automatisch, wenn Initiative auf den Charakter eines Spielers wechselt - [ ] **PUSH-08**: Push-Payload enthält Deep-Link in die App (Battle / Charakter / Chat öffnet sich beim Tap) ### Battle Multi-Screen Ausbau - [ ] **BAT-01**: Eigene Display-Route `/battle/:id/display` rendert read-only Spielsicht (keine GM-Controls, keine Drag-Handles, kein GM-Sidebar-Panel) - [ ] **BAT-02**: Server hält separate Sub-Rooms `battle::gm` und `battle::display`; GM-only-Daten werden serverseitig gefiltert, **nicht** clientseitig per Prop ausgeblendet - [ ] **BAT-03**: Display-Mode hat eigenes Auth-Modell (kurzlebiger Display-Token oder dedizierter Display-Pseudo-User), URL-Share leakt keine Daten - [ ] **BAT-04**: Display-Layout ist für querformatigen, eingelassenen Tisch-Bildschirm optimiert (große Schrift, keine Touch-Steuerung nötig) - [ ] **BAT-05**: Initiative-Tracker erscheint als sortierte Liste mit "Wer ist dran"-Highlight, sichtbar in GM- und Display-Mode - [ ] **BAT-06**: GM-"Nächster Zug"-Button rückt Initiative weiter; Event broadcastet an alle Clients (GM + Display + Spieler) - [ ] **BAT-07**: Token-Effekte/-Auren/-Buffs/-Debuffs als Datenmodell (`BattleEffect`-Tabelle mit FK auf Token, Name, optionaler Dauer in Runden) - [ ] **BAT-08**: GM kann Effekte pro Token hinzufügen, entfernen und aktualisieren über Battle-Sidebar - [ ] **BAT-09**: Token-Effekte sind auf Display-Mode sichtbar (Icon/Badge am Token + Liste in der Initiative-Karte) - [ ] **BAT-10**: Token-Add und Token-Remove laufen als WebSocket-Events (`token:added`, `token:removed`); keine Query-Invalidation als Workaround - [ ] **BAT-11**: GM-Control-Layout läuft auf Touch-Tablets benutzbar (Targets ≥ 44 px, kein Pflicht-Mobile-Layout, aber funktional) ### Würfeln - [ ] **DICE-01**: User kann PF2e-Notation eingeben und werfen (z.B. `1d20+7`, `2d6+3`, `4d6kh3`); Parser via `@dice-roller/rpg-dice-roller` - [ ] **DICE-02**: Würfeln ist server-authoritativ (Server würfelt mit `crypto.randomInt`, broadcastet Ergebnis; kein Client-Tampering möglich) - [ ] **DICE-03**: System berechnet PF2e Degree of Success (Crit Success, Success, Failure, Crit Failure) gegen optionale DC mit ±10-Regel - [ ] **DICE-04**: Schaden-Rolls verdoppeln auf Crit die Würfel-Anzahl, **nicht** die Modifikatoren (PF2e-Regel) - [ ] **DICE-05**: Würfe werden in `DiceRoll`-Tabelle persistiert, scoped pro Kampagne und (optional) Battle-Session - [ ] **DICE-06**: Roll-Log ist live für alle Teilnehmer einer Kampagne/Battle (WebSocket-Broadcast über Dice-Gateway) - [ ] **DICE-07**: Jeder Roll trägt Zuordnung: User + Charakter + Label (z.B. "Athletik-Probe") + Zeitstempel + optionale DC ### Chat - [ ] **CHAT-01**: User kann Textnachrichten in einer Kampagne posten (live für alle Mitglieder) - [ ] **CHAT-02**: User kann Textnachrichten in einer Battle-Session posten (live für alle Teilnehmer) - [ ] **CHAT-03**: Chat-Nachrichten werden in `ChatMessage`-Tabelle persistiert (scoped pro Kampagne und/oder Battle) - [ ] **CHAT-04**: Chat-Markdown wird mit `react-markdown` + `rehype-sanitize` gerendert; **kein** `dangerouslySetInnerHTML` ohne Sanitizer - [ ] **CHAT-05**: Würfelergebnisse werden inline im Chat eingebettet (FK `embedRollId` von ChatMessage auf DiceRoll) - [ ] **CHAT-06**: Chat-Verlauf lädt paginiert (Initial + Scroll-Back via Cursor) ### GM Live-Tools - [ ] **GM-01**: GM-Live-Tools-Panel ist als eigene UI-Surface zugänglich (für eingeloggten GM einer Kampagne) - [ ] **GM-02**: GM kann HP eines Spieler-Charakters live setzen (Schaden, Heilung, Direktwert) — nutzt bestehende Char-Events - [ ] **GM-03**: GM kann Conditions auf Spieler-Charakter live hinzufügen, entfernen, aktualisieren - [ ] **GM-04**: GM kann Items aus Equipment-DB an Spieler-Charakter geben (Suche → Auswahl → Übergabe live) - [ ] **GM-05**: GM kann Geld (Credits) eines Spieler-Charakters live anpassen - [ ] **GM-06**: Server-seitige Authorisierung prüft auf allen GM-Live-Tool-Events "Aktor ist GM dieser Kampagne"; bestehende Char-WebSocket-Events werden auditiert und ggf. abgesichert - [ ] **GM-07**: Destruktive Aktionen (z.B. HP auf 0 setzen, Item löschen) erfordern zweistufige Bestätigung - [ ] **GM-08**: GM kann gezielte Push-/Chat-Nachricht an einen Spieler oder alle Spieler senden (kombiniert PUSH-06 + CHAT-01) ### Obsidian Vault (Read-only) - [ ] **VAULT-01**: System verbindet zu einem selbst-gehosteten Vault-Endpoint; konkretes Transport-Protokoll wird in der Vault-Discuss-Phase entschieden (Default-Empfehlung: WebDAV-Proxy via NestJS) - [ ] **VAULT-02**: Vault-Browser zeigt Ordner-Tree-Navigation aus server-seitiger Listing-API - [ ] **VAULT-03**: User kann eine Markdown-Datei aus dem Vault öffnen und gerendert lesen (CommonMark + GFM Tabellen/Codeblöcke/Bilder) - [ ] **VAULT-04**: Wikilinks `[[Note]]` und `[[Note|Alias]]` werden als klickbare Links gerendert (Obsidian-Shortest-Path-Auflösung via `@portaljs/remark-wiki-link`) - [ ] **VAULT-05**: Bild-Embeds `![[image.png]]` werden gerendert; Bilder via Vault-Endpoint geladen (kein direkter Browser-Zugriff auf Vault-Server) - [ ] **VAULT-06**: Vault-Volltextsuche durchsucht Markdown-Inhalte (server-seitig, Postgres FTS oder vergleichbar) - [ ] **VAULT-07**: Server validiert alle Pfade gegen Path-Traversal (kein Escape via `../` aus Vault-Root) - [ ] **VAULT-08**: Zuletzt gelesene Notes (LRU) werden im Service Worker gecacht für Offline-Read - [ ] **VAULT-09**: Markdown-Renderer nutzt Sanitizer durchgehend (DOMPurify oder rehype-sanitize); kein `rehype-raw` ohne Sanitization - [ ] **VAULT-10**: Vault-Endpoint-Authentifizierung läuft serverseitig über bestehende JWT-Auth; Vault-Credentials werden nie an den Browser ausgeliefert ## v2 Requirements Verschoben — anerkannt, aber nicht in dieser Roadmap. ### Level-Up Erweiterungen - **LVL-V2-01**: Level-Up-Historie-Ansicht im Charakterbogen (Was wurde an welchem Level gewählt?) - **LVL-V2-02**: Reverse-Level-Up — bestätigtes Level rückgängig machen ### Battle Polish - **BAT-V2-01**: Cinematic Display-Theme (off-turn dim, large active-turn-card) - **BAT-V2-02**: Animierte Push-Ping-Ankunft mit Vibration + In-App-Initiative-Card-Overlay ### Würfeln Polish - **DICE-V2-01**: GM "Würfelaufforderung anfragen" (kombinierter Push + vorbefüllter Würfel-Button beim Spieler) - **DICE-V2-02**: Roll-History-Export als HTML/PDF (analog Charakterbogen-Export) - **DICE-V2-03**: Auto-Anwendung von Conditions aus Zaubern/Angriffen bei kritischem Erfolg ### Vault Erweiterungen - **VAULT-V2-01**: Frontmatter-NPC-Chips (`npc: true` Notes erscheinen als Hover-Chips in Chat/Battle) - **VAULT-V2-02**: Vault-Offline-FlexSearch-Index für vollständige Offline-Suche ## Out of Scope | Feature | Grund | |---------|-------| | Bidirektionales Vault-Sync | Read-only deckt aktuellen Bedarf; Write-Konflikte sind eigenes Produkt | | Offline-Edit + Sync-Queue | Last-write-wins-Korruption; Spielsessions sind online; Komplexität ohne Mehrwert | | Native iOS/Android-App (Capacitor) | Web Push reicht; PWA-Install ersetzt Native-Bedürfnis; doppelte Codebases | | In-App-Charakter-Erstellung von null | Pathbuilder-Import bleibt der Erstellungspfad; Doppelarbeit gegen 5 Jahre Pathbuilder-Reife | | Andere TTRPG-Systeme als PF2e | Datenmodell und UI sind PF2e-spezifisch; Generalisierung kostet Schärfe | | Öffentlicher Multi-Tenant-Betrieb | Self-hosted für eigene Gruppe; kein Onboarding-Flow nötig | | Presence/Awareness-Indikatoren | Wert klein vs WebSocket-Komplexität, besonders bei Mobile-Lockscreen | | Fog of War / Dynamic Lighting / Token Vision | Spiel passiert in Person mit 3D-Minis auf Tisch-Display; obsolet | | Voice/Video-Chat | Discord existiert und funktioniert | | 3D-Würfel-Physik mit Animation | Burns CPU, lenkt vom Tisch ab; echte Würfel liegen daneben | | Real-time kollaboratives Vault-Editing | Read-only ist explizit Scope-Grenze | | AI-NPCs / AI-Encounter-Generierung | Vault liefert die GM-Vorbereitung | | Auto-Apply Attack-Rolls auf Enemy-HP | Hohe Datenmodell-Kosten; GM macht das via Live-Tools manuell | | Marketplace für Maps/NPCs | Single-Tenant, keine Sharing-Anforderung | ## Traceability | Requirement | Phase | Status | |-------------|-------|--------| | LVL-01 | Phase 1 | Pending | | LVL-02 | Phase 1 | Pending | | LVL-03 | Phase 1 | Pending | | LVL-04 | Phase 1 | Pending | | LVL-05 | Phase 1 | Pending | | LVL-06 | Phase 1 | Pending | | LVL-07 | Phase 1 | Pending | | LVL-08 | Phase 1 | Pending | | LVL-09 | Phase 1 | Pending | | LVL-10 | Phase 1 | Pending | | LVL-11 | Phase 1 | Pending | | LVL-12 | Phase 1 | Pending | | LVL-13 | Phase 1 | Pending | | LVL-14 | Phase 1 | Pending | | LVL-15 | Phase 1 | Pending | | PWA-01 | Phase 2 | Pending | | PWA-02 | Phase 2 | Pending | | PWA-03 | Phase 2 | Pending | | PWA-04 | Phase 2 | Pending | | PWA-05 | Phase 2 | Pending | | PWA-06 | Phase 2 | Pending | | PWA-07 | Phase 2 | Pending | | PWA-08 | Phase 2 | Pending | | PWA-09 | Phase 2 | Pending | | PWA-10 | Phase 2 | Pending | | PUSH-01 | Phase 3 | Pending | | PUSH-02 | Phase 3 | Pending | | PUSH-03 | Phase 3 | Pending | | PUSH-04 | Phase 3 | Pending | | PUSH-05 | Phase 3 | Pending | | PUSH-06 | Phase 3 | Pending | | PUSH-07 | Phase 3 | Pending | | PUSH-08 | Phase 3 | Pending | | DICE-01 | Phase 4 | Pending | | DICE-02 | Phase 4 | Pending | | DICE-03 | Phase 4 | Pending | | DICE-04 | Phase 4 | Pending | | DICE-05 | Phase 4 | Pending | | DICE-06 | Phase 4 | Pending | | DICE-07 | Phase 4 | Pending | | CHAT-01 | Phase 4 | Pending | | CHAT-02 | Phase 4 | Pending | | CHAT-03 | Phase 4 | Pending | | CHAT-04 | Phase 4 | Pending | | CHAT-05 | Phase 4 | Pending | | CHAT-06 | Phase 4 | Pending | | BAT-01 | Phase 5 | Pending | | BAT-02 | Phase 5 | Pending | | BAT-03 | Phase 5 | Pending | | BAT-04 | Phase 5 | Pending | | BAT-05 | Phase 5 | Pending | | BAT-06 | Phase 5 | Pending | | BAT-07 | Phase 5 | Pending | | BAT-08 | Phase 5 | Pending | | BAT-09 | Phase 5 | Pending | | BAT-10 | Phase 5 | Pending | | BAT-11 | Phase 5 | Pending | | GM-01 | Phase 6 | Pending | | GM-02 | Phase 6 | Pending | | GM-03 | Phase 6 | Pending | | GM-04 | Phase 6 | Pending | | GM-05 | Phase 6 | Pending | | GM-06 | Phase 6 | Pending | | GM-07 | Phase 6 | Pending | | GM-08 | Phase 6 | Pending | | VAULT-01 | Phase 7 | Pending | | VAULT-02 | Phase 7 | Pending | | VAULT-03 | Phase 7 | Pending | | VAULT-04 | Phase 7 | Pending | | VAULT-05 | Phase 7 | Pending | | VAULT-06 | Phase 7 | Pending | | VAULT-07 | Phase 7 | Pending | | VAULT-08 | Phase 7 | Pending | | VAULT-09 | Phase 7 | Pending | | VAULT-10 | Phase 7 | Pending | **Coverage:** - v1 requirements: 75 total - Mapped to phases: 75 (Phase 1: 15, Phase 2: 10, Phase 3: 8, Phase 4: 13, Phase 5: 11, Phase 6: 8, Phase 7: 10) - Unmapped: 0 ✓ --- *Requirements defined: 2026-04-27* *Last updated: 2026-04-27 after roadmap mapping*