Jeder nötige Knoten zieht seine :#…-Ziele samt Realisierung in die
nötige Menge; gemeinsam Gebrauchtes zählt über die Vereinigung nur
einmal. Verfahren gewählt und benannt (D34): erschöpfende Suche, aber
nur über die GEKOPPELTEN Gruppen (Teilbaum enthält Abhängigkeiten oder
wird gebraucht) — ungekoppelte wählen lokal wie bisher, ohne
Abhängigkeiten bleibt es bei genau einer Auswertung zum alten Preis.
Lexikografischer Odometer, strikt < : bei Gleichstand die erste
Alternative. Oberhalb des Suchlimits (20 000) gierig mit zeilenloser
Warnung cheapApprox statt stillschweigender Pseudo-Optimalität.
Abhängigkeiten ziehen auch optionale und nicht gewählte Ziele (ohne
deren Vorfahren), verworfene nie. Neue API computeCheapPlan {set,exact};
markCheapest entfällt. 8 neue Tests (tests/closure.test.js).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
129 lines
8.2 KiB
Markdown
129 lines
8.2 KiB
Markdown
# Aufgaben
|
|
|
|
Abhaken beim Erledigen; neue Aufgaben unten anfügen.
|
|
|
|
## Phase 1 — Modularisierung & Tests
|
|
- [x] Projektgerüst: `src/` (parser.js, model.js, render.js, app.js),
|
|
`tests/`, `index.html` bindet Module ein; weiterhin ohne Build nutzbar
|
|
(ES-Module) oder mit minimalem Setup (Vite) — Entscheidung dokumentieren.
|
|
→ **Vite** gewählt (D19): `src/` als ES-Module, `npm run build` bündelt zu
|
|
einer self-contained `dist/index.html` (file://-tauglich). Gerüst steht
|
|
(aktuell `src/app.js` + `src/style.css`); Parser/Renderer werden in den
|
|
folgenden Checkboxen herausgelöst.
|
|
- [x] Parser extrahieren; Verhalten exakt wie in `docs/SPEC.md` §1–§8.
|
|
→ `src/parser.js` exportiert `parse`, `STATUS_BY_CODE`, `SIZE_RANK`
|
|
(headless, kein DOM); `app.js` importiert sie.
|
|
- [x] Unit-Tests für den Parser (Vitest): kanonisches Beispiel aus SPEC §10
|
|
als Fixture; Randfälle: gemischte Gates, Tabs/ungleichmäßige Einrückung,
|
|
URL mit `@`, mehrere Wurzeln, leere Labels, `%%` am Zeilenanfang/-ende.
|
|
→ `tests/parser.test.js` (18 Tests).
|
|
- [x] Renderer extrahieren (HTML-String-Erzeugung), Snapshot-Tests für
|
|
Normal- und Vertikalmodus sowie „Untergliederung fehlt“.
|
|
→ `src/model.js` (Baum-/Kostenlogik) + `src/render.js` (`renderTreeHtml`,
|
|
headless); `app.js` reicht UI-State als Parameter herein.
|
|
`tests/render.test.js` (6 Tests, Snapshots). Anm.: der Modus
|
|
(horizontal/vertikal/kompakt) ist reine CSS-Container-Klasse und ändert
|
|
den Renderer-String nicht — ein Snapshot deckt alle drei Modi ab.
|
|
- [x] Warnungs-Modell vereinheitlichen (Zeilennummern, Typen).
|
|
→ strukturierte Objekte `{type, line, ...}` (Renderer emittiert
|
|
`mixedGate`); `src/warnings.js` `formatWarning(w, t)` macht daraus den
|
|
lokalisierten, HTML-escapten Text an einer Stelle. Vorbereitet für
|
|
Phase 2 (`unknownStatus`). `tests/warnings.test.js`.
|
|
|
|
## Phase 2 — Qualität
|
|
- [x] Barrierefreiheit: Fokusreihenfolge, aria-Labels für Status/Größe/Tags.
|
|
→ je Knoten ein sprechender `aria-label` (Label+Status+Aufwand+Zuständige+
|
|
Link, lokalisiert, neue `a11y*`-Keys in allen 9 Sprachen); visuelle Badges
|
|
`aria-hidden`; Knoten `tabindex="0"` (Fokus = Lesereihenfolge) mit
|
|
`:focus-visible`-Rahmen; `#warn` als Live-Region (`role=status`,
|
|
`aria-live=polite`). Snapshots aktualisiert.
|
|
- [x] Druck-Stylesheet (Diagramm ohne Editor-Panel).
|
|
→ `@media print` in `style.css`: blendet Kopf/Editor/Splitter/Bedien-
|
|
elemente/Warnungen/Footer aus, Diagramm füllt die Seite; Statusfarben via
|
|
`print-color-adjust:exact`, `break-inside:avoid`, Pfad-Overlay inklusive.
|
|
- [x] Fehlertolerantes Parsen weiter ausbauen (unbekannte Statuszeichen melden).
|
|
→ Parser erfasst die Statusbox als beliebiges Einzelzeichen, validiert
|
|
gegen `STATUS_BY_CODE`; unbekannte Codes → `unknownStatus`-Warnung (Zeile +
|
|
Code), Knoten neutral, Folgezeilen unberührt. `render()` führt Parser- +
|
|
Renderer-Warnungen zusammen. i18n `unknownStatusWarn` in allen 9 Sprachen.
|
|
`tests/parser.test.js` (5 neue Tests).
|
|
|
|
## Deployment
|
|
- [x] GitHub-Pages-Workflow angelegt (`.github/workflows/pages.yml`,
|
|
siehe docs/DECISIONS.md D16).
|
|
|
|
## Phase 3 — Integrationen (siehe [ROADMAP](ROADMAP.md))
|
|
- [ ] Backend-Gerüst per Spring Initializr in `backend/` anlegen
|
|
(Kotlin, Gradle Kotlin DSL, JDK 21; Konventionen: backend/CLAUDE.md).
|
|
- [ ] SVG-Renderer (Layout-Engine) als gemeinsame Basis für Export und
|
|
Mermaid-Plugin.
|
|
- [ ] Mermaid-Plugin-Spike: Detektor + Registrierung, ein Minimalbaum.
|
|
- [ ] Taiga-Spike: `#ref`-Syntax parsen, Status via REST-API auflösen
|
|
(read-only), Mapping konfigurierbar.
|
|
|
|
## Phase 4 — Vollständiges Lean-Pathfinding (siehe [ROADMAP](ROADMAP.md), D34)
|
|
Reihenfolge ist nicht beliebig: ohne IDs keine Abhängigkeiten, ohne die keinen
|
|
effektiven Status und keine Closure-Rechnung. Jeder Punkt beginnt in
|
|
[SPEC §11](SPEC.md) — die dort benannten offenen Schreibweisen sind zu
|
|
entscheiden, **bevor** Code entsteht.
|
|
- [x] `#`-Doppelrolle auflösen und in SPEC §11 festschreiben.
|
|
→ Durch Wegfall statt Trennregel: Tickets haben Vorrang (`#123`
|
|
numerisch, oft zugleich die natürliche Knoten-ID; notfalls Präfix wie
|
|
`#t123`); Schlagworte gehen auf `&tag` — niedrig priorisiert, gebaut
|
|
erst mit dem ersten Konsumenten (D34-Nachtrag).
|
|
- [x] Knoten-IDs parsen; doppelte ID → Warnung mit Zeilennummer.
|
|
→ Umgesetzt (D36): Zeichenmenge wie `@name`, nur alleinstehend angesetzt
|
|
und nur das erste Token je Zeile (`:#a,#b` und Ticket-Erwähnungen bleiben
|
|
unberührt); Warnung `duplicateId` nennt beide Zeilen; sichtbar im
|
|
Tooltip + `aria-label`; SPEC-§11-Teil nach §1 überführt;
|
|
`tests/ids.test.js`.
|
|
- [x] Abhängigkeiten `:#a,#b` parsen; unbekannte ID → Warnung, Zyklen erlaubt.
|
|
→ Umgesetzt (D37): ein zusammenhängendes Token ohne Leerraum, nur
|
|
alleinstehend angesetzt (eingeklammerte Erwähnungen bleiben Label);
|
|
`deps` als ID-Strings am Knoten, Warnung `unknownDep`, Zyklen bewusst
|
|
ungeprüft; sichtbar als `→ #a, #b` im Tooltip + `a11yDeps`;
|
|
SPEC-§11-Teil nach §1 überführt; `tests/deps.test.js`.
|
|
- [x] Effektiven Status rechnen (intrinsisch + Abhängigkeiten); Darstellung
|
|
entscheiden — die Knotenfarbe zeigt heute den intrinsischen Status.
|
|
→ Entschieden und umgesetzt (D39): Fortschritts-Rang (SPEC §4), effektiv
|
|
= Minimum über die Abhängigkeits-Hülle (Fixpunkt, Zyklen teilen ihr
|
|
Minimum); **Knotenfarbe = effektiver Status**, bei Diskrepanz die eigene
|
|
Statusbox als Marke unten links in den eigenen Farben (auch im Export);
|
|
Tooltip + `a11yEffective`; `tests/effective.test.js`.
|
|
- [x] Günstigsten Pfad auf die Dependency Closure umstellen (gemeinsame
|
|
Abhängigkeiten nur einmal zählen). Erweitert D18; die gierige Wahl je
|
|
Alternativgruppe ist damit nicht mehr optimal — Verfahren wählen und
|
|
**benennen**.
|
|
→ Umgesetzt (D42): erschöpfende Suche über die gekoppelten Gruppen
|
|
(`computeCheapPlan` in model.js), ungekoppelte wählen lokal wie bisher;
|
|
oberhalb des Suchlimits gierig mit zeilenloser Warnung `cheapApprox`.
|
|
Abhängigkeiten ziehen auch optionale/nicht gewählte Ziele, verworfene
|
|
nie; `tests/closure.test.js`.
|
|
- [x] Querverbindungen zeichnen (eigene SVG-Ebene, optisch sekundär);
|
|
bei ausgewähltem Knoten ein-/ausgehende hervorheben.
|
|
→ Umgesetzt (D41): gekrümmte blassgraue Kanten mit Pfeilspitze auf das
|
|
Gebrauchte, hinter den Knoten (`drawDepLinks`); Hervorhebung in Tinte
|
|
für Fokus-Knoten bzw. Cursor-Zeile; Basis-Kanten auch im Export/Druck.
|
|
- [x] Faltmarken `>` / `<` parsen; interaktives Auf-/Zuklappen im Diagramm.
|
|
→ Schreibweise und Export-Verhalten entschieden (D34-Nachtrag): Marke
|
|
hinter dem Zerlegungszeichen (`- > [x] …`), Export/Druck folgen der
|
|
sichtbar eingeklappten Struktur mit Kennzeichnung am Knoten.
|
|
Umgesetzt (D38): `initialCollapsed()` (`<` wandert die Faltung die
|
|
Pfad-Ebenen hinunter, `!!!` holt sich mit hervor); Falt-Zeichen ▾/„▸ n"
|
|
+ Tastatur ←/→; Eingriffe je Label-Pfad, nur für die Sitzung; Warnungen
|
|
aus eingeklappten Teilbäumen bleiben; `tests/fold.test.js`.
|
|
- [x] XOR-Gruppe (`=`) parsen (nur mit folgendem Leerraum, Mischung →
|
|
`mixedGate`), zwei realisierte Alternativen melden.
|
|
→ Zeichen entschieden: `=` statt `x` (D34-Nachtrag). Umgesetzt (D35):
|
|
„realisiert“ = `[~]`/`[/]`/`[x]`/`[^]`, Warnung `xorConflict` je weiterer
|
|
realisierter Alternative; Darstellung als any-of plus „1“-Plakette an der
|
|
Sammelleiste (auch im Grafikexport); Legende + i18n in 9 Sprachen;
|
|
`tests/xor.test.js`.
|
|
- [x] Knotenbeschreibungen: Schreibweise für kurze und lange Form festlegen
|
|
(Einrückung ist bereits Hierarchie), dann Tooltip/Pop-up.
|
|
→ Schreibweise entschieden (D34-Nachtrag): Kurzform als `"`-Zeile unter
|
|
dem Knoten (Leerraum-Regel), Langform als eingerückte ID-Blöcke hinter
|
|
einem `---`-Trenner (SPEC §11). Umgesetzt (D40): Parser (`desc` am
|
|
Knoten, Warnungen `unknownDesc`/`descStray`), Anzeige im Tooltip +
|
|
`aria-label` mit ”-Marke am Knoten; `tests/desc.test.js`.
|