Files
nova-control/ALICIA.md
T

201 lines
7.6 KiB
Markdown
Raw 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.
# ALICIA.md — NOVA Control Reparatur
**Auftrag:** Behebe 26 binäre Gates in `index.html`. Jedes Gate ist ein klares Ja/Nein-Kriterium — erst erfüllt, wenn nachweisbar wahr.
**Repo:** `git@git.datenhimmel.work:danielkrause/nova-control.git`
**Branch:** `master`
**Datei:** Nur `index.html` — eine Datei, kein Framework, keine Libs, kein CDN, offline.
---
## Arbeitsweise
1. **Gate für Gate.** Nicht mehrere auf einmal. Ein Gate → implementieren → testen → commit.
2. **Vor jedem Commit:** `index.html` im Browser öffnen und das Gate manuell verifizieren.
3. **Commit-Message:** `fix: P0.1 Datei-Dialog entfernt` o.ä.
4. **Push nach jeder Phase** (P0, P1, P2) — nicht nach jedem einzelnen Gate.
## Reihenfolge (P0 → P1 → P2)
### P0 — BLOCKER (zuerst, weil App sonst beim Start kaputt)
**P0.1 — Datei-Dialog**
- Zeile mit `document.getElementById('imp').click();` **löschen**
- Test: Seite laden → KEIN Datei-Dialog
**P0.2 — Command-Palette**
- `rp()` wird nie aufgerufen → `cmds` bleibt `[]`
- `rp()` auf ≥8 Befehle erweitern: Board, Streaks, Insights, Neues Task, Import, Export, Reset/Demo, 500 Tasks
- `ld()` ruft am Ende `rp()` auf, dann `inipal()` beim Öffnen der Palette
- Tasks dynamisch als anspringbare Einträge in die Liste
- Test: Cmd+K → Liste zeigt ≥8 Einträge
**P0.3 — Dark Mode**
- `:root` hat nur Hell-Werte, `[data-theme="dark"]`-Block fehlt
- CSS: `[data-theme="dark"]` mit `--bg`, `--surface`, `--text`, `--border`
- `at()`: `matchMedia('(prefers-color-scheme:dark)').addEventListener('change', ...)` für Live-Reaktion
- `localStorage` für Persistenz (existiert via `sv()`)
- Test: 🌙 klicken → Hintergrund dunkel. Reload → bleibt dunkel.
### P1 — KERN-FEATURES
**P1.1 — Maus-Drag & Drop**
- HTML5 DnD API: `draggable="true"` auf `.task`
- `dragstart`/`dragover`/`drop` Events
- Drop-Indikator (gestrichelter Rahmen oder Platzhalter)
- Inter-Spalte (Status wechselt) + Intra-Spalte (Reihenfolge)
- Nach Drop: `sv()` + `rv()`
- Test: Task von Backlog nach Aktiv ziehen. Nach Reload noch da.
**P1.2 — Tastatur-DnD**
- Fokussiertes Task: Ctrl+Alt+Pfeiltasten
- ←→: Spalte wechseln | ↑↓: Position in Spalte
- `<div aria-live="polite">` für Status-Ansagen
- Test: Nur Tastatur, Task durch alle 4 Spalten bewegen.
**P1.3 — Feld-Schema**
- `op()`-Create speichert Fälligkeit als `du`, Board liest `d`
- `du``d` vereinheitlichen (in Create + Edit)
- `ldDemo()` und Render prüfen: benutzen die `d`?
- Test: Task mit Datum anlegen → Reload → Datum noch da.
**P1.4 — Streak-Berechnung**
- Pro Habit: aktuelle Serie + längste Serie
- Regeln: Wert > 0 = erfüllt. Tag mit 0 = Bruch. Heute noch nicht erfüllt = kein Bruch.
- Anzeige im Streak-View
- Test: Serie bricht bei 0, läuft weiter wenn heute noch kein Wert.
**P1.5 — Export**
- `exportData()`: `{version:1, tasks, habits, theme}` als JSON-Blob → Download
- Command "Export" in Palette
- Import validiert `version` + `tasks` Array
- Test: Export → localStorage löschen → Import → identischer Zustand.
**P1.6 — Zweiter Chart + Trend-Wochen**
- `<canvas id="chart2">` für Donut (Prioritätsverteilung)
- Trend-Chart: Monate → Wochen umstellen
- Datenbasis Trend: `df` (Abschlussdatum)
- Legende, Labels, Empty-State
- Test: Insights zeigt 2 Charts. Trend in Wochen.
**P1.7 — Listener-Leak + Fokusverlust**
- `rb()`: KEIN `innerHTML` = Toolbar + alles neu
- Toolbar (Suche + Filter) EINMAL im HTML, nicht pro `rb()`
- Event-Delegation auf `#board-section` EINMAL binden
- Suche: `display:none` statt DOM-Neuaufbau
- Test: 10× Views wechseln → Modal öffnet 1×. Tippen in Suche → Fokus bleibt.
### P2 — POLITUR
**P2.1 — Heatmap 26 Wochen**
- Spalten=Wochen, Zeilen=Mo..So, 26 Wochen zurück
- Hover-Tooltip mit Datum + Wert
- Test: Kein 28-Tage-Streifen mehr, Wochen-Grid sichtbar.
**P2.2 — Responsive**
- `@media (max-width: 768px)`: Layout einspaltig
- `@media (max-width: 480px)`: Board untereinander
- `overflow-x: auto` NUR auf `.board`, nicht `body`
- Test: 360px Breite → kein Body-Scroll.
**P2.3 — prefers-reduced-motion**
- `@media (prefers-reduced-motion: reduce) { ... }`
- Animationen deaktivieren (Toast, Drag-Transitions)
- Test: OS-Einstellung "Reduzierte Bewegung" → keine Animationen.
**P2.4 — Focus-Trap**
- Modal + Palette: Tab/Shift+Tab zyklisch im Dialog
- ESC schließt + Fokus zurück auf Auslöser
- Test: Modal offen → Tab kreist. ESC → Fokus auf Button davor.
**P2.5 — Palette-Tastatur**
- Keydown auf `#pal-q` (Eingabefeld) statt `#pal-list`
- ↑/↓ navigieren Liste, Enter führt aus
- Fokus bleibt im Eingabefeld
- Test: Pfeiltasten bei Fokus im Suchfeld.
**P2.6 — Hash-Routing**
- Navigation setzt `location.hash = '#/' + view`
- `hashchange`-Event schaltet View
- Beim Laden: View aus Hash setzen
- Test: `#/insights` → Insights-View. Reload bleibt. Zurück-Button.
**P2.7 — 500 Tasks**
- `gen500()`: 500 Tasks generieren
- Command in Palette
- Performance: Batch-Rendering, kein 500× Einzel-Push
- Test: 500 Tasks → Board flüssig, Suche filtert sofort.
**P2.8 — Robustheit**
- `ld()`: `nv_t` validieren → `Array.isArray()` + try/catch → Fallback `[]`
- Import: Jeden Task auf `id`, `tl`, `st` prüfen
- Fehlerhafte Einträge → Meldung, bestehende Daten bleiben
- Test: Kaputtes JSON importieren → Fehlermeldung, keine Daten verloren.
---
## Git-Workflow
```bash
git clone git@git.datenhimmel.work:danielkrause/nova-control.git
cd nova-control
# Gate bearbeiten...
git add index.html
git commit -m "fix: P0.1 Datei-Dialog entfernt"
# Nach jeder Phase:
git push
# Nach Abschluss:
git tag v1.0 # alle 26 Gates geschlossen
git push --tags
```
---
## Constraints (unveränderlich)
### Technisch
- ❌ Keine zweite Datei (kein .css, kein .js)
- ❌ Keine externen Libs/CDNs (kein jQuery, kein React, kein Bootstrap)
- ❌ Kein Build-Step, kein npm
- ✅ CSS `<style>` im `<head>`
- ✅ JS `<script>` am Ende von `<body>`
-`localStorage` für Persistenz
- ✅ Eine HTML-Datei, die im Browser per `file://` läuft
### Coding-Regeln (bindend!)
**Variablen & Funktionen — lesbare Namen**
-`C`, `ts`, `fm`, `sv`, `ld`, `at`, `rv`, `rb`, `op`, `cl`, `rs`, `ri`, `rp`, `pf`, `ie`
-`COLUMNS`, `showToast`, `formatDate`, `saveState`, `loadState`, `applyTheme`, `renderView`, `renderBoard`, `openModal`, `closeModal`, `renderStreaks`, `renderInsights`, `registerPalette`, `previousFocus`, `isEditing`
- **Jede Variable und Funktion MUSS einen selbsterklärenden Namen haben.** Keine Abkürzungen unter 4 Zeichen.
**JavaScript**
-`const`/`let` — NIE `var`
-`===` statt `==`
- ✅ Template-Literals `` `Hallo ${name}` `` statt `'Hallo ' + name`
- ✅ Arrow-Funktionen `() => {}` wo sinnvoll
-`for...of` statt `for(var i=0;...)` wo möglich
- ❌ Kein `eval()`, kein `innerHTML` mit ungeprüftem Input
- ❌ Keine globalen Variablen (alles in IIFE oder Modul-Scope)
**CSS**
- ✅ CSS-Variablen (`var(--bg)`) nutzen — NIEMALS Farben hartkodieren
- ✅ Dark Mode NUR über `[data-theme="dark"]` und `prefers-color-scheme`
-`rem`/`em` für Schrift, `px` nur für Borders, `%`/`fr`/`vh`/`vw` für Layout
- ❌ Kein `!important`
- ❌ Keine Inline-Styles im HTML (alles im `<style>`-Block)
**HTML**
- ✅ Semantisch: `<aside>`, `<nav>`, `<main>`, `<section>`, `<dialog>` wo passend
- ✅ ARIA-Labels für interaktive Elemente ohne sichtbaren Text
-`tabindex` nur wo nötig, korrekte Reihenfolge
- ❌ Kein `<div onclick="...">` — immer `addEventListener` in JS
**Kommentare**
- ✅ Jede Funktion hat EINEN Satz darüber, was sie tut
- ✅ Komplexe Logik (Streak, DnD, Chart) hat 2-3 Zeilen Erklärung
- ❌ Keine auskommentierten Code-Blöcke