Update CLAUDE.md: Planer-Tab concept and implementation roadmap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5df03a3915
commit
9ff8139c81
93
CLAUDE.md
93
CLAUDE.md
@ -31,6 +31,10 @@ window.App = { reportCode, fightId, fightStart, fightEnd, phases: [], fights: []
|
|||||||
- `onFightsLoaded(fights)` — wird von `app.js` aufgerufen nach Report-Load (befüllt Vergleichs-Dropdown)
|
- `onFightsLoaded(fights)` — wird von `app.js` aufgerufen nach Report-Load (befüllt Vergleichs-Dropdown)
|
||||||
- `reset()` — wird von `app.js` aufgerufen wenn ein neuer Report geladen wird
|
- `reset()` — wird von `app.js` aufgerufen wenn ein neuer Report geladen wird
|
||||||
|
|
||||||
|
`window.plannerTab` (definiert in `planner.js`) stellt Hooks bereit:
|
||||||
|
- `onTabOpen()` — wird von `tabs.js` aufgerufen wenn der Planer-Tab geöffnet wird
|
||||||
|
- `importFromAnalysis(aoeEvents, refEvents, options)` — wird vom Analyse-Tab aufgerufen beim Export
|
||||||
|
|
||||||
## Dateistruktur
|
## Dateistruktur
|
||||||
```
|
```
|
||||||
index.php — PHP-Logik: Auth-Check, Variablen, require page.php
|
index.php — PHP-Logik: Auth-Check, Variablen, require page.php
|
||||||
@ -41,6 +45,7 @@ templates/
|
|||||||
topbar.php — Topbar mit Logo + Tab-Navigation + Token-Ablaufzeit
|
topbar.php — Topbar mit Logo + Tab-Navigation + Token-Ablaufzeit
|
||||||
tab-report.php — Report-Tab: includes report-form, fight-select, event-explorer, output-card
|
tab-report.php — Report-Tab: includes report-form, fight-select, event-explorer, output-card
|
||||||
tab-analysis.php — Analyse-Tab: Spieler-Grid + Pull-Vergleich + AoE-Timeline HTML
|
tab-analysis.php — Analyse-Tab: Spieler-Grid + Pull-Vergleich + AoE-Timeline HTML
|
||||||
|
tab-planner.php — Planer-Tab: Plan-Liste, Mechanik-Timeline, Job-Aufstellung (in Entwicklung)
|
||||||
report-form.php — Report-Code-Eingabe Card
|
report-form.php — Report-Code-Eingabe Card
|
||||||
fight-select.php — Fight-Auswahl Dropdown Card
|
fight-select.php — Fight-Auswahl Dropdown Card
|
||||||
event-explorer.php — Event Explorer Card (Ability/DataType/EventType/Spieler-Filter)
|
event-explorer.php — Event Explorer Card (Ability/DataType/EventType/Spieler-Filter)
|
||||||
@ -50,10 +55,12 @@ css/
|
|||||||
layout.css — App-Shell, Topbar, Tabs, Login-Overlay, Form-Helpers
|
layout.css — App-Shell, Topbar, Tabs, Login-Overlay, Form-Helpers
|
||||||
components.css — Cards, Inputs, Buttons, Badges, Terminal
|
components.css — Cards, Inputs, Buttons, Badges, Terminal
|
||||||
analysis.css — Spieler-Grid, AoE-Timeline, Mitigation-Icons, HP-Bar, Ref-Row
|
analysis.css — Spieler-Grid, AoE-Timeline, Mitigation-Icons, HP-Bar, Ref-Row
|
||||||
|
planner.css — Planer-Tab: Plan-Liste, Mechanik-Cards, Job-Slots, Ability-Modal (in Entwicklung)
|
||||||
js/
|
js/
|
||||||
app.js — Formular, Fight-Dropdown, Fetch, window.App State, Event Explorer
|
app.js — Formular, Fight-Dropdown, Fetch, window.App State, Event Explorer
|
||||||
tabs.js — Tab-Switching, ruft window.analysisTab.onTabOpen() auf
|
tabs.js — Tab-Switching, ruft window.analysisTab.onTabOpen() auf
|
||||||
analysis.js — Analyse-Tab: Daten laden, Spieler rendern, Timeline rendern, Pull-Vergleich
|
analysis.js — Analyse-Tab: Daten laden, Spieler rendern, Timeline rendern, Pull-Vergleich
|
||||||
|
planner.js — Planer-Tab: localStorage CRUD, Plan-Rendering, Ability-Zuweisung (in Entwicklung)
|
||||||
auth/
|
auth/
|
||||||
start.php — PKCE generieren, Session speichern, Redirect zu FFLogs
|
start.php — PKCE generieren, Session speichern, Redirect zu FFLogs
|
||||||
callback.php — Code gegen Token tauschen, Token in Session speichern
|
callback.php — Code gegen Token tauschen, Token in Session speichern
|
||||||
@ -64,6 +71,9 @@ api/
|
|||||||
debug-events.php — POST-Endpunkt: Raw Events für Event Explorer (mit Filterung)
|
debug-events.php — POST-Endpunkt: Raw Events für Event Explorer (mit Filterung)
|
||||||
assets/
|
assets/
|
||||||
icons/mitigation/ — Lokal gespeicherte Ability-Icons (PNG, von XIVAPI)
|
icons/mitigation/ — Lokal gespeicherte Ability-Icons (PNG, von XIVAPI)
|
||||||
|
data/
|
||||||
|
recast-times.json — Recast-Zeiten pro Ability (in Entwicklung)
|
||||||
|
ability-equivalents.json — Funktionale Äquivalente über Jobs hinweg (in Entwicklung)
|
||||||
debug/
|
debug/
|
||||||
schema.php — Einmaliges Schema-Explorer Tool (nicht produktiv deployen)
|
schema.php — Einmaliges Schema-Explorer Tool (nicht produktiv deployen)
|
||||||
```
|
```
|
||||||
@ -220,7 +230,7 @@ Vollständiges Schema: siehe `debug/schema.php` oder `fflogs-schema.json`
|
|||||||
## Planer-Tab — Konzept & Roadmap
|
## Planer-Tab — Konzept & Roadmap
|
||||||
|
|
||||||
### Ziel
|
### Ziel
|
||||||
Raid-Cooldown-Planer: Welche Mitigation-Ability wird für welche Mechanik eingesetzt? Basierend auf Log-Daten oder manuell aufgebaut. Überlebt Browser-Neustarts via localStorage.
|
Raid-Cooldown-Planer: Welche Mitigation-Ability wird für welche Mechanik eingesetzt? Basierend auf Log-Daten oder manuell aufgebaut. Überlebt Browser-Neustarts via localStorage. Kein Server-State — alles im Browser.
|
||||||
|
|
||||||
### Datenmodell (Plan)
|
### Datenmodell (Plan)
|
||||||
```json
|
```json
|
||||||
@ -236,7 +246,9 @@ Raid-Cooldown-Planer: Welche Mitigation-Ability wird für welche Mechanik einges
|
|||||||
"id": "uuid",
|
"id": "uuid",
|
||||||
"name": "Fourth-Wall Fusion",
|
"name": "Fourth-Wall Fusion",
|
||||||
"timestamp": 83000,
|
"timestamp": 83000,
|
||||||
|
"phase": "Phase 1",
|
||||||
"unmitigatedDamage": 280000,
|
"unmitigatedDamage": 280000,
|
||||||
|
"notes": "",
|
||||||
"assignments": [
|
"assignments": [
|
||||||
{ "ability": "Reprisal", "job": "PLD" },
|
{ "ability": "Reprisal", "job": "PLD" },
|
||||||
{ "ability": "Shield Samba", "job": "BRD" }
|
{ "ability": "Shield Samba", "job": "BRD" }
|
||||||
@ -248,31 +260,42 @@ Raid-Cooldown-Planer: Welche Mitigation-Ability wird für welche Mechanik einges
|
|||||||
|
|
||||||
Mehrere Pläne gespeichert in `localStorage` unter `ff14-planner-plans` als Array.
|
Mehrere Pläne gespeichert in `localStorage` unter `ff14-planner-plans` als Array.
|
||||||
|
|
||||||
### Import-Flow (erster Meilenstein)
|
### Primärer Import-Flow: Export aus dem Analyse-Tab
|
||||||
**Ziel:** Einen bestehenden Log als saubere Mechanik-Vorlage laden — ohne vorhandene Mechaniken zu überschreiben.
|
Der Haupteinstieg ist der Analyse-Tab — der Nutzer hat die Daten bereits geladen und sieht die Timeline.
|
||||||
|
|
||||||
1. Benutzer wählt Report-Code + Kampf (gleicher Flow wie im Report-Tab, eigenes Mini-Formular im Planer)
|
1. Button **"In Planer exportieren"** erscheint im Analyse-Tab sobald Daten geladen sind (auch für den Ref-Log separat)
|
||||||
2. `api/analysis.php` wird aufgerufen → liefert `aoe_events` mit Name, Timestamp, `unmitigatedAmount`
|
2. Dialog mit zwei Entscheidungen:
|
||||||
3. Jedes AoE-Event wird als Mechanik-Kandidat angezeigt (Name + Timestamp + Rohschaden)
|
- **Was importieren?** "Nur Mechaniken" vs. "Mechaniken + erkannte Mitigations als Startpunkt"
|
||||||
4. Benutzer kann einzelne Events auswählen oder alle übernehmen
|
- **Wohin?** Neuen Plan anlegen (Name eingeben) vs. bestehenden Plan überschreiben/mergen (Dropdown)
|
||||||
5. **Merge-Logik:** Beim Import in einen bestehenden Plan werden nur Mechaniken hinzugefügt die noch nicht vorhanden sind — Matching per `abilityName` + Timestamp-Nähe (± 5s). Bestehende Assignments bleiben erhalten.
|
3. Bei Merge: explizite Bestätigung — niemals implizit überschreiben
|
||||||
6. Neue Mechaniken werden an der richtigen Timestamp-Position eingefügt (Timeline bleibt sortiert)
|
4. AoE-Events werden zu Mechaniken; Phase-Information aus `phaseTransitions` wird mitübernommen
|
||||||
|
5. Weiterarbeiten im Planer-Tab
|
||||||
|
|
||||||
**Warum Merge statt Überschreiben:** Progress-Szenario — erster Import enthält Phase 1, späterer Import (weiter im Fight) fügt Phase 2 hinzu ohne Phase-1-Planung zu verlieren.
|
**Merge-Logik:** Mechaniken gelten als identisch wenn `abilityName` gleich und `|timestamp_a - timestamp_b| < 5000ms`. Nur neue Mechaniken werden hinzugefügt, bestehende Assignments bleiben erhalten. Neue Mechaniken werden timestamp-sortiert eingefügt.
|
||||||
|
|
||||||
### Geplante Features (Übersicht)
|
**Warum Merge statt Überschreiben:** Progress-Szenario — erster Import enthält Phase 1, späterer Import fügt Phase 2 hinzu ohne Phase-1-Planung zu verlieren.
|
||||||
|
|
||||||
| Prio | Feature | Beschreibung |
|
### Implementierungs-Reihenfolge
|
||||||
|
|
||||||
|
| Schritt | Feature | Beschreibung |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 1 | **Import-Flow** | Log → Mechanik-Timeline, Merge bei Teilimporten |
|
| 1 | **Datenfundament** | Plan-Datenmodell + localStorage CRUD (create, read, update, delete, copy) |
|
||||||
| 2 | **Jobaufstellung** | 8 Slots (2 Tank, 2 Healer, 4 DPS), Auswahl bestimmt verfügbare Spells |
|
| 2 | **Tab-Grundgerüst** | Leere Tab-Hülle wie Analyse-Tab; Plan-Liste; Mechanik-Timeline (read-only) |
|
||||||
| 3 | **Cooldown-Zuweisung** | Pro Mechanik Abilities zuweisen/entfernen per Klick |
|
| 3 | **Import aus Analyse-Tab** | Export-Button + Dialog (s. oben); `window.plannerTab.importFromAnalysis()` |
|
||||||
| 4 | **DR-Simulation** | `simuliert = unmitigated × ∏(1 − dr_i)` live berechnet beim Toggle |
|
| 4 | **Jobaufstellung** | 8 Slots mit Job-Dropdown; bestimmt verfügbare Abilities in Schritt 5 |
|
||||||
| 5 | **Recast-Tracking** | Recast-Datenbank pro Ability; Konflikt-Warnung wenn CD noch läuft |
|
| 5 | **Ability-Zuweisung** | Pro Mechanik Abilities per Modal-Picker hinzufügen/entfernen |
|
||||||
| 6 | **Coverage-Ansicht** | Gantt-Chart: Mechaniken auf X-Achse, Buff-Dauer als Balken |
|
| 6 | **Recast-Konflikt** | `data/recast-times.json`; rote Warnung wenn CD zwischen zwei Mechaniken noch läuft |
|
||||||
| 7 | **Analyse-Overlay** | Planer-Tab: Vergleich geplanter vs. tatsächlich genutzter CDs (Job-basiertes Matching, nicht Spielername) |
|
| 7 | **DR-Simulation** | `simuliert = unmitigated × ∏(1 − dr_i)`; grün/rot ob Spieler laut Simulation überlebt |
|
||||||
| 8 | **Shield-Schätzung** | Empirisch aus Log-Durchschnitt (`absorbed`-Werte), nicht exakt |
|
| 8 | **Job-Äquivalente** | `data/ability-equivalents.json`; auto-substituieren beim Job-Wechsel |
|
||||||
| 9 | **JSON-Export/Import** | Plan als Datei teilen mit Raidkollegen |
|
| 9 | **Analyse-Overlay** | Vergleich geplanter vs. tatsächlich genutzter CDs im Analyse-Tab |
|
||||||
|
|
||||||
|
Schritte 1–3 = nutzbarer MVP. Schritte 4–6 = praktisch einsetzbar. 7–9 = Power-Features.
|
||||||
|
|
||||||
|
### UI-Paradigma
|
||||||
|
- Visuell dem Analyse-Tab ähneln (Cards, gleiche CSS-Variablen, einheitliches Look & Feel)
|
||||||
|
- Mechaniken als vertikale Timeline-Cards
|
||||||
|
- Ability-Picker als **Modal** (kein Inline-Dropdown)
|
||||||
|
- Nicht für mobile Geräte ausgelegt
|
||||||
|
|
||||||
### Spell-Verfügbarkeit nach Job
|
### Spell-Verfügbarkeit nach Job
|
||||||
Jobaufstellung → verfügbare Abilities (Subset von `MITIGATION_ABILITIES`):
|
Jobaufstellung → verfügbare Abilities (Subset von `MITIGATION_ABILITIES`):
|
||||||
@ -301,17 +324,31 @@ Jobaufstellung → verfügbare Abilities (Subset von `MITIGATION_ABILITIES`):
|
|||||||
| RDM | Addle, Magick Barrier |
|
| RDM | Addle, Magick Barrier |
|
||||||
| PCT | Addle, Tempera Coat, Tempera Grassa |
|
| PCT | Addle, Tempera Coat, Tempera Grassa |
|
||||||
|
|
||||||
### Recast-Zeiten (geplante Datenbank)
|
### Job-Äquivalente (`data/ability-equivalents.json`)
|
||||||
Wird benötigt für Konflikt-Erkennung. Beispiele:
|
Abilities die funktional gleich sind aber unterschiedliche Namen haben — relevant beim Job-Wechsel im Slot:
|
||||||
|
|
||||||
|
| Gruppe | Abilities |
|
||||||
|
|---|---|
|
||||||
|
| 15% Party-Mitigation | Troubadour, Tactician, Shield Samba |
|
||||||
|
| 10% Ground-Barrier | Sacred Soil, Kerachole |
|
||||||
|
|
||||||
|
Reprisal, Feint und Addle sind identische Ability-Namen über Jobs hinweg — kein Mapping nötig, die gleiche Ability bleibt einfach bestehen.
|
||||||
|
|
||||||
|
**Verhalten beim Job-Wechsel:** Assignment wird auto-substituiert wenn Äquivalent für neuen Job existiert (mit Hinweis "automatisch gemappt"). Kein Äquivalent → Assignment ausgegraut (nicht gelöscht, Nutzer entscheidet).
|
||||||
|
|
||||||
|
### Recast-Zeiten (`data/recast-times.json`)
|
||||||
|
Wird für Konflikt-Erkennung benötigt (Schritt 6). Vollständige Liste wird beim Implementieren vervollständigt, Beispiele:
|
||||||
- Reprisal: 60s
|
- Reprisal: 60s
|
||||||
- Feint / Addle: 90s
|
- Feint / Addle: 90s
|
||||||
|
- Dark Missionary / Heart of Light: 90s
|
||||||
- Troubadour / Tactician / Shield Samba: 120s
|
- Troubadour / Tactician / Shield Samba: 120s
|
||||||
- Temperance: 120s
|
- Temperance: 120s
|
||||||
- Dark Missionary / Heart of Light: 90s
|
|
||||||
|
|
||||||
### Technische Entscheidungen
|
### Technische Entscheidungen
|
||||||
- **Persistenz:** `localStorage` — kein Backend nötig, mehrere Pläne möglich
|
- **Persistenz:** `localStorage` unter `ff14-planner-plans` — kein Backend nötig
|
||||||
- **IDs:** `crypto.randomUUID()` für Plan- und Mechanik-IDs
|
- **IDs:** `crypto.randomUUID()` für Plan- und Mechanik-IDs
|
||||||
- **Merge-Matching:** Mechaniken gelten als identisch wenn `abilityName` gleich und `|timestamp_a - timestamp_b| < 5000ms`
|
- **Keine Spielernamen:** Assignments sind Job-basiert (`{ ability, job }`), damit Pläne übertragbar sind
|
||||||
- **Keine Spielernamen im Planer:** Assignments sind Job-basiert (`{ ability, job }`), damit Pläne übertragbar sind
|
- **Kein Ability-Stacking:** FFXIV erlaubt keine doppelte Anwendung derselben Ability — jede Ability kommt pro Mechanik maximal einmal vor, doppelte Instanzen desselben Jobs im Static sind daher kein Sonderfall
|
||||||
- **Analyse-Tab Overlay (Prio 7):** Job aus tatsächlichem Pull → lookup welche Ability dieser Job im Plan hatte → Soll/Ist-Vergleich
|
- **Analyse-Overlay (Schritt 9):** Job aus tatsächlichem Pull → lookup welche Ability dieser Job im Plan hatte → Soll/Ist-Vergleich (kein Spielername-Matching nötig)
|
||||||
|
- **Shield-Attribution:** Aktuell nicht lösbar — `absorbed` im `damage`-Event ist ein Gesamtwert ohne Aufschlüsselung per Shield. Zu untersuchen: ob `calculatedheal`-Events die Shield-Kapazität beim Auftragen mitliefern. Vorerst zurückgestellt.
|
||||||
|
- **Plan kopieren:** Duplicate-Funktion für Plan-Varianten ("Week 3 v2") ohne Original zu verlieren
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user