752 lines
35 KiB
Markdown
752 lines
35 KiB
Markdown
# WOMS „Weißes Design“ P1: Fundament – Umsetzungsplan
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** Nach P1 ist das ganze Ticketsystem weiß und lesbar:
|
||
- Das Menü ist eine Textliste.
|
||
- Das Login ist neu.
|
||
- Alle Dialoge sind weiß.
|
||
- Die neuen Bausteine stehen für P2 bis P9 bereit.
|
||
|
||
Die Innenlayouts der Seiten bleiben vorerst alt.
|
||
|
||
**Architecture:** `src/styles/global.css` bekommt fünf Blöcke:
|
||
|
||
1. Tokens und Aliase
|
||
2. Basis (Reset, Hilfsklassen, Links)
|
||
3. Bausteine (Prototyp-Klassen)
|
||
4. KOMPAT (Altklassen im neuen Look, bis P10)
|
||
5. Bereichs-CSS (Finanzen, Rechtliches), bis auf Pflicht-Fixes unverändert
|
||
|
||
Gleichnamige Altdefinitionen werden vor dem Einfügen der Bausteine gelöscht. Die Komponenten unter `src/components/ui/` behalten ihre Schnittstellen. Neu kommen `Dialog`, `Stat`, `Logo` und `statusTone` hinzu.
|
||
|
||
**Tech Stack:** React 18, react-router-dom 6, Vite 5, reines CSS. Tests mit `node --test`, Screenshots mit dem Werkzeug aus P0.
|
||
|
||
**Spec:** `docs/superpowers/specs/2026-10-04-weisses-design-design.md`, Abschnitte „Gestaltungsregeln“, „Design-Tokens“, „Bausteine“, „Übergangsschicht KOMPAT“ und Paket P1. Die Prototyp-Werte stehen in `/root/reports/ticketsystem-design-2026-10-04/quelle/styles.css`. Globale Regeln, Befehlsregeln (`env.sh`, `check.sh`) und gemeinsame Schnittstellen stehen in `2026-10-05-weisses-design-00-uebersicht.md`.
|
||
|
||
## Global Constraints
|
||
|
||
Es gelten die Regeln der Übersicht. Für P1 kommt hinzu:
|
||
|
||
- Jeder Run-Block beginnt mit `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh`. Danach gelten `$WT`, `$W` und `$TMPDIR`.
|
||
- Werte für Tokens, Abstände, Größen und Schatten werden aus der Spec bzw. aus `quelle/styles.css` übernommen und nicht neu erfunden.
|
||
- Nicht übernommen werden `html[data-accent]`, `.proto*` und `.nav-gap`.
|
||
- Verhalten, Routen und Auth bleiben unverändert. Ausnahmen:
|
||
- Der Footer entfällt.
|
||
- Das Einklappen entfällt.
|
||
- Die Schublade unter 860 px kommt neu dazu.
|
||
- Seiten in `src/pages/*` werden nur dort angefasst, wo dieser Plan es nennt:
|
||
- `LoginPage`
|
||
- `ProjectsPage`: Wurzelklasse
|
||
- `AdminPage`: Wurzelelement
|
||
- `ServerpulsPage`: Diagrammfarben
|
||
- Die Spec erlaubt keine neue `robots`-Meta-Zeile. `index.html` bekommt nur das Favicon.
|
||
|
||
## Review Focus
|
||
|
||
- **Übersichtspunkt 2 (lange Inhalte am Handy):** `overflow-x` ist im Gate `p1` für alle Ansichten scharf.
|
||
- **Übersichtspunkt 4 (Tastatur):** Die Esc- und Sperrlogik des Dialogs prüft ein Lib-Test in Task 7.
|
||
- **Altseiten:** Jede Altseite bleibt mit KOMPAT lesbar. Das prüft das Gate `p1` mit `dark-surface` und `low-contrast`, auch für Verläufe.
|
||
- **Alt-Dialoge:** Die zehn Alt-Dialoge müssen bei 390×700 und 1440×700 bis zum Speichern-Knopf erreichbar sein. Das prüft `submitReachable` in jeder `dlg-*`-Ansicht.
|
||
|
||
---
|
||
|
||
### Task 0: Paketstart
|
||
|
||
- [ ] **Step 1: Stand prüfen**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && git fetch origin && git merge-base --is-ancestor design-p0 HEAD && git log --oneline origin/test..feature/terminplaner-tp2 -- src/styles src/components/ui src/App.jsx src/components/Navbar.jsx src/pages/LoginPage.jsx src/lib/navLinks.js src/lib/ticketStatus.js && git rebase origin/test && "$W/check.sh"`
|
||
Expected:
|
||
- Exit 0.
|
||
- Die TP2-Zeile gibt nichts aus. Gibt sie etwas aus: stoppen und den Eigentümer fragen. Empfehlung: TP2 zuerst nach `test` bringen.
|
||
|
||
### Task 1: `statusTone`
|
||
|
||
**Files:**
|
||
- Modify: `src/lib/ticketStatus.js` (neuer Export nach `statusGroup`)
|
||
- Test: `tests/unit/ticketStatus.test.mjs` (neu)
|
||
|
||
**Interfaces:**
|
||
- Consumes: `statusGroup(status)` aus derselben Datei. Es liefert die Gruppen-ID oder `null`.
|
||
- Produces: `statusTone(status) → '' | 'blue' | 'orange' | 'violet' | 'green' | 'plain'`.
|
||
|
||
- [ ] **Step 1: Failing Test**
|
||
|
||
```js
|
||
const { statusTone } = await loadModule('src/lib/ticketStatus.js')
|
||
test('statusTone: Ton je gespeichertem Wert', () => {
|
||
for (const s of ['Open', '', undefined, null, 'Completed']) assert.equal(statusTone(s), '')
|
||
for (const s of ['Occupied', 'Assigned', 'Added Info', 'In Kontakt']) assert.equal(statusTone(s), 'blue')
|
||
for (const s of ['Awaiting', 'Halted']) assert.equal(statusTone(s), 'orange')
|
||
assert.equal(statusTone('In Test'), 'violet')
|
||
for (const s of ['Closed', 'Zugesagt']) assert.equal(statusTone(s), 'green')
|
||
for (const s of ['Cancelled', 'Aborted', 'Abgesagt']) assert.equal(statusTone(s), 'plain')
|
||
})
|
||
```
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node --test tests/unit/ticketStatus.test.mjs`
|
||
Expected: FAIL, `statusTone is not a function`.
|
||
|
||
- [ ] **Step 2: Implementieren**
|
||
|
||
Zuordnung über `statusGroup`:
|
||
|
||
| Gruppe | Ton |
|
||
|---|---|
|
||
| `open` | `''` |
|
||
| `working` | `'blue'` |
|
||
| `waiting` | `'orange'` |
|
||
| `review` | `'violet'` |
|
||
| `done` | `'green'` |
|
||
| `cancelled` | `'plain'` |
|
||
| `null` | `''` |
|
||
|
||
`statusClass` bleibt bis P2.
|
||
|
||
- [ ] **Step 3: Grün**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node --test tests/unit/ticketStatus.test.mjs && "$W/check.sh" --nur-tests`
|
||
Expected: PASS, Exit 0.
|
||
|
||
- [ ] **Step 4: Commit**
|
||
|
||
```bash
|
||
git add src/lib/ticketStatus.js tests/unit/ticketStatus.test.mjs
|
||
git commit -m "Ticketstatus: statusTone fuer die neuen Badge-Toene" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 2: Tokens, Aliase, Basis, Schrift
|
||
|
||
**Files:**
|
||
- Modify: `src/styles/global.css`
|
||
- Zeilen 1-10 (`@font-face`) löschen
|
||
- `:root`, alte Zeilen 18-71, ersetzen
|
||
- `body`/Scrollbar/`::selection`, alte Zeilen 73-106, ersetzen
|
||
- alte Hilfsregeln `.muted`/`.faint` (um Zeile 1051) ersetzen
|
||
- Modify: `src/pages/AdminPage.css` (Zeilen 2-3, `--admin-line*`, löschen)
|
||
- Delete: `src/assets/fonts/lato-regular.ttf`, `src/assets/fonts/OFL-Lato.txt`
|
||
- Modify (Werkzeug): `$W/views.mjs` bekommt die Ansicht `basis-weiss`
|
||
|
||
**Interfaces:**
|
||
- Produces: alle Tokens und Aliase der Spec, dazu die Basis- und Hilfsklassen aus der Übersicht.
|
||
|
||
- [ ] **Step 1: Prüf-Ansicht (failing)**
|
||
|
||
`basis-weiss` öffnet `/tickets`. Der Schritt prüft, dass `getComputedStyle(document.body).backgroundColor === 'rgb(255, 255, 255)'` und dass `font-family` mit `-apple-system` beginnt.
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/build.sh" "$WT" p1 && "$W/shots.sh" p1 "$W/shots/p1-t2" --only basis-weiss --gate p0`
|
||
Expected: Exit 1 mit `step-failed`.
|
||
|
||
- [ ] **Step 2: `:root` ersetzen**
|
||
|
||
- Den Token-Block der Spec wörtlich übernehmen.
|
||
- Darunter folgt die Alias-Tabelle der Spec. Sie enthält `--admin-line` und `--admin-line-strong`.
|
||
- Die beiden Zeilen in `AdminPage.css` entfallen.
|
||
|
||
- [ ] **Step 3: Basis setzen**
|
||
|
||
Aus `quelle/styles.css` Zeilen 63-91 übernehmen. Zusätzlich gilt:
|
||
|
||
| Regel | Wert |
|
||
|---|---|
|
||
| `html` | `color-scheme: light` |
|
||
| `body` | `font-family: var(--font); font-size: 14px; line-height: 20px; color: var(--text); background: var(--bg); -webkit-font-smoothing: antialiased`, ohne `overflow: hidden` |
|
||
| Formularelemente | `button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer }` und `input, select, textarea { font: inherit; color: inherit }` |
|
||
| `a` | `color: inherit; text-decoration: none` |
|
||
| `a:not([class])` | Unterstrich in `--line-strong`, `text-underline-offset: 3px`, beim Überfahren `text-decoration-color: currentColor` |
|
||
| Hilfsklassen | `.num` (`tabular-nums`), `.muted` (`--text-2`), `.faint` (`--text-3`), `.small` 13px, `.xs` 12/16, `.strong` 600, `.nowrap` |
|
||
| `.link`, `.link:hover`, `.link-danger`, `.link-danger:hover` | Werte aus dem Prototyp |
|
||
| `:focus-visible` | `outline: 2px solid #111111; outline-offset: 2px` |
|
||
| `:disabled` | `opacity: .55; cursor: not-allowed` |
|
||
| `[readonly]` | `background: var(--bg-subtle)` |
|
||
|
||
- [ ] **Step 4: Schrift entfernen**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && git rm -q src/assets/fonts/lato-regular.ttf src/assets/fonts/OFL-Lato.txt && rg -n "lato|Lato" src`
|
||
Expected: keine Treffer.
|
||
|
||
- [ ] **Step 5: Grün**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/build.sh" "$WT" p1 && "$W/shots.sh" p1 "$W/shots/p1-t2" --only basis-weiss --gate p0`
|
||
Expected: Exit 0.
|
||
|
||
- [ ] **Step 6: Commit**
|
||
|
||
```bash
|
||
git add src/styles/global.css src/pages/AdminPage.css
|
||
git commit -m "Design: weisse Tokens, Aliase, Basis und Hilfsklassen, Systemschrift" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 3: Bausteine-CSS
|
||
|
||
**Files:**
|
||
- Modify: `src/styles/global.css`: Altdefinitionen gleichnamiger Klassen löschen, Block „Bausteine“ hinter der Basis anlegen
|
||
|
||
**Interfaces:**
|
||
- Produces: alle Klassen aus der Übersicht („CSS-Klassen in `global.css`“).
|
||
|
||
- [ ] **Step 1: Gleichnamige Altdefinitionen löschen**
|
||
|
||
Gelöscht werden die Regeln dieser Selektoren samt ihrer Varianten (Hover, Kinder, Media-Queries). Die Zeilenangaben beziehen sich auf den Stand 603d08c, gesucht wird nach dem Selektor:
|
||
|
||
| Selektor | Zeilen (603d08c) |
|
||
|---|---|
|
||
| `.btn` und `.btn:hover`, ohne `.btn-dark`/`.btn-teal`/`.btn-green` (die gehen nach KOMPAT bzw. sterben in Task 8) | ab 188 |
|
||
| `.table`, `.table th`, `.table td`, `.table td[rowspan]` | 236-275 |
|
||
| `.overlay` und `.overlay-close` (Neufassung in KOMPAT, Task 4) | ab 563 |
|
||
| `.page` | 867 |
|
||
| `.badge` (Basis) | 909-915 |
|
||
| `.urgent-toggle` | 971-976 |
|
||
| `.list-row` | 997-1005 |
|
||
| `.toolbar` | 1018 |
|
||
| `.seg` | 1019-1024 |
|
||
| `.empty` | 1028 |
|
||
| `.field` | 1032 |
|
||
|
||
Der übrige alte Block „REDESIGN“ (796-1049) bleibt bis Task 4. Dazu gehören `.ui-card*`, `.ui-btn*`, `.badge-*`, `.kpi*`, `.tcard*`, `.ui-table`, `.list`, `.ticket-tabs`/`.ticket-tab*` und die Hilfsregeln `.mt-*`, `.flex*`, `.gap-*`, `.grow`, `.wrap` und `.text-ellipsis`.
|
||
|
||
- [ ] **Step 2: Bausteine übernehmen**
|
||
|
||
Aus `quelle/styles.css` werden diese Abschnitte übernommen:
|
||
- „Grundgerüst“ ohne `.nav-gap`
|
||
- „Seitenkopf“
|
||
- „Knöpfe“
|
||
- „Status-Marken“
|
||
- „Reiter“
|
||
- „Filterzeile“
|
||
- „Tabellen“
|
||
- „Kennzahlen / Schlüsselwerte“
|
||
- „Ticket-Kopf“
|
||
- „Listen“
|
||
- „Dialog“
|
||
- „Anmeldung“
|
||
|
||
Dazu kommen die Media-Queries 1100 und 860. **Ausgeschlossen** sind dort `.proto*`, `.ws*`, `.week`, `.day*` und `.appt` (sie kommen mit P2 und P3) sowie `html[data-accent]`.
|
||
|
||
Zusätzlich:
|
||
|
||
| Regel | Wert |
|
||
|---|---|
|
||
| `.page section + section` | `margin-top: 36px` |
|
||
| `.nav-dot` | `background: var(--nav-dot)` |
|
||
| `.nav-dot.critical` | `background: var(--danger)` |
|
||
| `.dialog-wide` | `max-width: 760px` |
|
||
| `.msg` | 13px |
|
||
| `.msg.err` | Farbe `--red-fg` |
|
||
| `.msg.ok` | Farbe `--green-fg` |
|
||
| `.msg.warn` | Farbe `--orange-fg` |
|
||
| `.loading` | `padding: 56px 0; text-align: center; color: var(--text-2)` |
|
||
| `.v.neg` | Farbe `--red-fg` |
|
||
| `.stat .sub` | `font-size: 12px; line-height: 16px; color: var(--text-2)` |
|
||
| `.badge.plain` | Farbe `--text-2` |
|
||
| `.tab.active`, `.tab[aria-selected="true"]` | aktiver Reiter |
|
||
| `.seg button.on`, `.seg button[aria-pressed="true"]` | aktiver Teil |
|
||
| `.autocomplete-list` | `background: var(--bg); box-shadow: var(--shadow-pop); border-radius: 8px` |
|
||
| `.autocomplete-item.active`, `.autocomplete-item:hover` | `background: var(--bg-hover)` |
|
||
| `.datetime-pair` | zwei Felder nebeneinander, Abstand 8px, kein `color-scheme: dark` |
|
||
| `[aria-invalid="true"]` und `.is-invalid` an `.input`, `.select`, `.textarea`, `.form-control` | `box-shadow: 0 0 0 1px var(--danger), 0 0 0 4px var(--danger-ring)` |
|
||
|
||
- [ ] **Step 3: Jede Basisregel genau einmal**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && for s in btn table overlay page badge urgent-toggle list-row toolbar seg empty field; do printf '%s ' "$s"; rg -c "^\.$s *\{" src/styles/global.css; done`
|
||
Expected: Hinter jedem Namen steht `1`.
|
||
|
||
- [ ] **Step 4: Bauen**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/check.sh" --nur-build`
|
||
Expected: Exit 0.
|
||
|
||
- [ ] **Step 5: Commit**
|
||
|
||
```bash
|
||
git add src/styles/global.css
|
||
git commit -m "Design: Bausteine aus dem Prototyp, gleichnamige Altregeln ersetzt" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 4: KOMPAT und tote Klassen
|
||
|
||
**Files:**
|
||
- Create: `$W/css-klassen.mjs`
|
||
- Create: `docs/superpowers/plans/2026-10-05-weisses-design-p1-tote-klassen.md`
|
||
- Modify: `src/styles/global.css` (Block „KOMPAT“, Legacy löschen)
|
||
|
||
**Interfaces:**
|
||
- Produces:
|
||
- Der KOMPAT-Block nach der Spec-Tabelle „Übergangsschicht KOMPAT“. P10 entfernt ihn.
|
||
- `css-klassen.mjs <worktree> [--ohne-ausnahmen]` gibt JSON aus: `{ defined, used, dead, undefinedUsed }`.
|
||
|
||
- [ ] **Step 1: Skript schreiben**
|
||
|
||
„Benutzt“ ist eine Klasse, wenn eine dieser Bedingungen zutrifft:
|
||
- Sie steht als Wort in einem `className`-Literal oder Template-String in `src/**/*.jsx`.
|
||
- Sie steht in einer Zeichenkette in `src/lib/*.js` oder `src/hooks/*.js`.
|
||
- Ein Template-Präfix deckt sie ab: `xxx-${…}` gilt für `xxx-*`.
|
||
- Sie steht in der Ausnahmeliste: `fin-neg`, `fin-fixed-off`, `legal-tone-*`, `legal-version-*`, `badge-*`, `status-*`, `ticket-tab-active`, `ui-btn-*`, `side-dot-*`, `woms-chat`, `chat-*`. Mit `--ohne-ausnahmen` entfällt diese Liste.
|
||
|
||
„Definiert“ ist eine Klasse, wenn sie in einem Selektor in `global.css`, `chat.css`, `serverpuls.css`, `admin-areas.css` oder `pages/AdminPage.css` steht.
|
||
|
||
- [ ] **Step 2: Liste erzeugen und gegenprüfen**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node "$W/css-klassen.mjs" "$WT" > "$TMPDIR/klassen.json"`
|
||
|
||
Danach für jeden Kandidaten in `dead`: `rg -w <name> src --glob '!*.css'`. Ein Kandidat gilt nur bei 0 Treffern als tot. Die bestätigte Liste kommt mit Klassenname und definierender Datei:Zeile in `2026-10-05-weisses-design-p1-tote-klassen.md`.
|
||
|
||
Expected: etwa 66 Namen. Liegt die Zahl unter 40 oder über 90, wird die Abweichung dort begründet.
|
||
|
||
- [ ] **Step 3: Legacy löschen, KOMPAT anlegen**
|
||
|
||
Gelöscht werden:
|
||
- die Regeln der bestätigten toten Klassen
|
||
- alle verbliebenen `!important`
|
||
- `.side*` außer `.side-count` und `.side-logo` (die gehen nach KOMPAT)
|
||
- `.footer`, `.navbar*`, `.ticket-row*`, `.worksheet-expansion*`, `.slider`, `.drop-zone`, `.modern-card`
|
||
- die Legacy-Responsive-Regeln (alt 789-794)
|
||
- die Keyframes `slideDown`, `fadeIn` und `slideIn`
|
||
- `.kpi*`, weil `Kpi` ab Task 6 `Stat` rendert
|
||
|
||
Danach wird KOMPAT laut Spec-Tabelle angelegt, markiert mit `/* ===== KOMPAT (bis P10) ===== */`. Der Block enthält auch `.page .page` und `.page .main-content`, die Abstand und Breite neutralisieren.
|
||
|
||
- [ ] **Step 4: Keine benutzte Klasse ohne Regel**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node "$W/css-klassen.mjs" "$WT" | node -e "const j=JSON.parse(require('fs').readFileSync(0));console.log(j.undefinedUsed.join('\n'))"`
|
||
Expected: Nur diese Namen tauchen auf:
|
||
- `p-4`, `btn-sm`, `status-filter`, `supporters-editor`, `timeline`
|
||
- die Bootstrap-Namen aus `WorksheetList.jsx` (heute schon wirkungslos)
|
||
|
||
- [ ] **Step 5: Altseiten ansehen**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/build.sh" "$WT" p1 && "$W/shots.sh" p1 "$W/shots/p1-t4" --gate p1; echo "exit $?"`
|
||
Expected: `step-failed` (`submitReachable`) ist auf keiner `dlg-*`-Ansicht mehr gemeldet. Erlaubt sind nur noch Treffer `dark-surface` und `low-contrast` in Dateien aus Task 9.
|
||
|
||
- [ ] **Step 6: Commit**
|
||
|
||
```bash
|
||
git add src/styles/global.css docs/superpowers/plans/2026-10-05-weisses-design-p1-tote-klassen.md
|
||
git commit -m "Design: KOMPAT-Schicht fuer Altklassen, tote Regeln und !important entfernt" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 5: Gerüst, Menü, Logo, Favicon
|
||
|
||
**Files:**
|
||
- Create: `src/components/Logo.jsx`, `public/favicon.svg` (Kopie von `quelle/favicon.svg`)
|
||
- Modify:
|
||
- `src/App.jsx`
|
||
- `src/components/Navbar.jsx`
|
||
- `src/lib/navLinks.js` (`hot: true` am Chat-Unterpunkt)
|
||
- `index.html` (nur `<link rel="icon" href="/favicon.svg" type="image/svg+xml">`)
|
||
- `src/styles/serverpuls.css` (Zeilen 70-74 `.side-dot*` löschen)
|
||
- `src/pages/ProjectsPage.jsx` (Wurzel `main-content` → `page`)
|
||
- `src/pages/AdminPage.jsx` (`<main className="page admin-page">` → `<div className="page admin-page">`, zwei Stellen)
|
||
- Delete: `src/components/Footer.jsx`, `src/lib/sidebar.js`, `tests/unit/sidebar.test.mjs`
|
||
- Test: `tests/unit/navLinks.test.mjs`
|
||
- Modify (Werkzeug): `$W/views.mjs` bekommt die Ansicht `menue-mobil`
|
||
|
||
**Interfaces:**
|
||
- Consumes: Klassen aus Task 3.
|
||
- Produces:
|
||
- `Logo({ size = 24 })` mit `aria-hidden="true"`. Die Pfade kommen aus `quelle/app.js`, Konstante `LOGO`.
|
||
- `Sidebar({ onNavigate })`.
|
||
|
||
- [ ] **Step 1: Test für `hot` (failing)**
|
||
|
||
In `tests/unit/navLinks.test.mjs` die Zeile `assert.equal(kunden.children.find((c) => c.key === 'chat').hot, true)` ergänzen. Die bestehenden `deepEqual` bleiben.
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node --test tests/unit/navLinks.test.mjs`
|
||
Expected: FAIL.
|
||
|
||
- [ ] **Step 2: `navLinks.js` ergänzen, Test grün**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node --test tests/unit/navLinks.test.mjs`
|
||
Expected: PASS.
|
||
|
||
- [ ] **Step 3: Logo und Favicon anlegen**
|
||
|
||
- [ ] **Step 4: Gerüst in `App.jsx`**
|
||
|
||
`AppContent` hält `menuOpen` und baut dieses Gerüst:
|
||
|
||
```jsx
|
||
<div className={`shell${menuOpen ? ' menu-open' : ''}`}>
|
||
<Sidebar onNavigate={close} />
|
||
<div className="scrim" onClick={close} />
|
||
<div className="main">
|
||
<div className="mobile-bar">
|
||
<Link className="brand" to="/tickets"><Logo />WEBklar</Link>
|
||
<button type="button" className="btn btn-quiet" onClick={open} aria-expanded={menuOpen} aria-controls="menue">Menü</button>
|
||
</div>
|
||
<main id="inhalt"><AppRoutes /></main>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
- Ein Effekt auf `location.pathname` (nur darauf) schließt die Schublade und ruft `window.scrollTo(0, 0)` auf.
|
||
- Ein Esc-Listener ist nur bei `menuOpen` aktiv.
|
||
- Der Ladezustand von `ProtectedRoute` ist `<div className="loading">Wird geladen …</div>`.
|
||
|
||
- [ ] **Step 5: `Navbar.jsx` als Textliste**
|
||
|
||
Aufbau: `<aside className="sidebar" id="menue">`, darin `.brand` (Logo und „WEBklar“), `<nav className="nav">` mit `.nav-item` und `.sub` und am Ende `.sidebar-foot`.
|
||
|
||
| Element | Markup |
|
||
|---|---|
|
||
| Pausiert | `<span className="nav-item paused" aria-disabled="true">Leads<span className="nav-count">pausiert</span></span>` |
|
||
| Zähler | `<span className={`nav-count${child.hot ? ' hot' : ''}`}>` |
|
||
| Serverpuls | `<span className={`nav-dot${dot === 'critical' ? ' critical' : ''}`} data-testid="sp-nav-dot" title=…>`, nur wenn `dot` nicht `'ok'` ist. Titeltexte wie heute. |
|
||
| Fuß | `<span className="who text-ellipsis">{user.name \|\| user.email}</span>` und `<button type="button" className="link" onClick={handleLogout}>Abmelden</button>` |
|
||
|
||
Klicks auf Einträge rufen `onNavigate()` auf.
|
||
|
||
Entfernt werden:
|
||
- `@tabler`-Imports und `ICONS`
|
||
- Einklappen und `startsCollapsed`
|
||
|
||
Bleiben:
|
||
- `isActive` und `isLinkActive`
|
||
- das Serverpuls-Polling
|
||
- `useSidebarCounts`
|
||
|
||
- [ ] **Step 6: Altdateien löschen**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && git rm -q src/components/Footer.jsx src/lib/sidebar.js tests/unit/sidebar.test.mjs && rg -n "Footer|startsCollapsed|lib/sidebar" src tests`
|
||
Expected: keine Treffer.
|
||
|
||
- [ ] **Step 7a: Gate `p1` um die Menü-Prüfung ergänzen**
|
||
|
||
In `$W/gates.mjs` bekommt `p1` zusätzlich `scoped['icon-svg'] = { views: ['*'], ignore: ['#inhalt *'] }`. Der vorhandene Eintrag `scoped['overflow-x']` bleibt. Damit prüft `icon-svg` ab hier Menü, Mobil-Leiste und Login auf allen Ansichten, den Seiteninhalt erst im jeweiligen Paket. Commit im Werkzeug-Repo.
|
||
|
||
- [ ] **Step 7: Ansicht `menue-mobil`**
|
||
|
||
Bei 390×844 läuft:
|
||
1. Klick auf „Menü“: `.shell.menu-open` ist da.
|
||
2. Screenshot.
|
||
3. Esc: `.menu-open` ist weg.
|
||
4. Menü erneut öffnen, Klick auf „Projekte“: Der Pfad ist `/projects`, und das Menü ist zu.
|
||
|
||
- [ ] **Step 8: Prüfen**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/check.sh" && "$W/build.sh" "$WT" p1 && "$W/shots.sh" p1 "$W/shots/p1-t5" --only tickets,kunden,serverpuls,menue-mobil --gate p1`
|
||
Expected:
|
||
- Exit 0.
|
||
- Im Menü ist kein `svg` außer dem Logo.
|
||
|
||
- [ ] **Step 9: Commit**
|
||
|
||
```bash
|
||
git add src/App.jsx src/components/Navbar.jsx src/components/Logo.jsx src/lib/navLinks.js tests/unit/navLinks.test.mjs index.html public/favicon.svg src/styles/serverpuls.css src/pages/ProjectsPage.jsx src/pages/AdminPage.jsx
|
||
git commit -m "Design: Geruest mit Textmenue, Schublade fuers Handy, Logo; Footer und Einklappen entfallen" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 6: UI-Bausteine
|
||
|
||
**Files:**
|
||
- Create: `src/components/ui/tones.js`, `src/components/ui/Stat.jsx`
|
||
- Modify:
|
||
- `Button.jsx`, `Badge.jsx`, `Card.jsx`, `PageHeader.jsx`, `Tabs.jsx`, `EmptyState.jsx`, `Field.jsx`, `Kpi.jsx`, `StatusPill.jsx`, `index.js`
|
||
- nur Klasse `form-control` → `input` bzw. `select`: `AutocompleteInput.jsx`, `DateTimeInput.jsx`, `DurationSelect.jsx`
|
||
- Test: `tests/unit/uiTones.test.mjs`
|
||
|
||
**Interfaces:**
|
||
- Produces:
|
||
- die Signaturen aus der Übersicht
|
||
- `badgeToneClass(tone) → string`
|
||
- `BUTTON_CLASSES`
|
||
|
||
Beide liegen in `tones.js`. `Button` setzt keinen eigenen Standard-`type`.
|
||
|
||
- [ ] **Step 1: Failing Test**
|
||
|
||
```js
|
||
const { badgeToneClass, BUTTON_CLASSES } = await loadModule('src/components/ui/tones.js')
|
||
test('badgeToneClass', () => {
|
||
for (const t of ['muted', 'grey', undefined, 'unbekannt']) assert.equal(badgeToneClass(t), 'badge')
|
||
assert.equal(badgeToneClass('info'), 'badge blue')
|
||
assert.equal(badgeToneClass('blue'), 'badge blue')
|
||
assert.equal(badgeToneClass('ok'), 'badge green')
|
||
assert.equal(badgeToneClass('warn'), 'badge orange')
|
||
assert.equal(badgeToneClass('danger'), 'badge red')
|
||
assert.equal(badgeToneClass('violet'), 'badge violet')
|
||
assert.equal(badgeToneClass('plain'), 'badge plain')
|
||
})
|
||
test('Button-Varianten', () => {
|
||
assert.deepEqual(BUTTON_CLASSES, { default: 'btn', ghost: 'btn', primary: 'btn btn-primary', quiet: 'btn btn-quiet', danger: 'link-danger' })
|
||
})
|
||
```
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node --test tests/unit/uiTones.test.mjs`
|
||
Expected: FAIL.
|
||
|
||
- [ ] **Step 2: `tones.js` anlegen, Test grün**
|
||
|
||
- [ ] **Step 3: Komponenten umschreiben**
|
||
|
||
| Komponente | Änderung |
|
||
|---|---|
|
||
| `Card` | ohne Titel und ohne Aktionen nur `<section>` |
|
||
| `PageHeader` | Brotkrumen als `Link`, wenn `to` gesetzt ist. Das letzte Element ist Text, das „/“ steht in `<span className="faint">`. |
|
||
| `Tabs` | `active` und `aria-selected` |
|
||
| `EmptyState` | ohne Inline-Styles |
|
||
| `Field` | Hinweis als `.hint` |
|
||
| `Kpi` | gibt `Stat` zurück |
|
||
| `StatusPill` | ohne `pillBase` |
|
||
|
||
- [ ] **Step 4: Prüfen**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/check.sh" && "$W/build.sh" "$WT" p1 && "$W/shots.sh" p1 "$W/shots/p1-t6" --only tickets,ticket,kunde-overview,finanzen --gate p1`
|
||
Expected: Exit 0. Die Status-Badges in `tickets` zeigen die neuen Töne.
|
||
|
||
- [ ] **Step 5: Commit**
|
||
|
||
```bash
|
||
git add src/components/ui tests/unit/uiTones.test.mjs
|
||
git commit -m "Design: UI-Bausteine rendern die neuen Klassen (Button, Badge, Card, Kopf, Reiter, Stat)" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 7: `Dialog`
|
||
|
||
**Files:**
|
||
- Create: `src/components/ui/Dialog.jsx`, `src/lib/dialogKeys.js`
|
||
- Modify: `src/components/ui/index.js`, `$W/views.mjs` (Ansicht `dlg-probe`)
|
||
- Test: `tests/unit/dialogKeys.test.mjs`
|
||
|
||
**Interfaces:**
|
||
- Consumes: `useDialogFocus(dialogRef)` aus `src/hooks/useDialogFocus.js`, unverändert.
|
||
- Produces:
|
||
- `Dialog` laut Übersicht
|
||
- `shouldCloseOnKey({ key, defaultPrevented }, busy) → boolean`
|
||
|
||
- [ ] **Step 1: Failing Test**
|
||
|
||
```js
|
||
const { shouldCloseOnKey } = await loadModule('src/lib/dialogKeys.js')
|
||
test('Esc schliesst nur ohne Sperre und ohne vorherige Behandlung', () => {
|
||
assert.equal(shouldCloseOnKey({ key: 'Escape', defaultPrevented: false }, false), true)
|
||
assert.equal(shouldCloseOnKey({ key: 'Escape', defaultPrevented: true }, false), false)
|
||
assert.equal(shouldCloseOnKey({ key: 'Escape', defaultPrevented: false }, true), false)
|
||
assert.equal(shouldCloseOnKey({ key: 'Enter', defaultPrevented: false }, false), false)
|
||
})
|
||
```
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node --test tests/unit/dialogKeys.test.mjs`
|
||
Expected: FAIL.
|
||
|
||
- [ ] **Step 2: Implementieren, Test grün**
|
||
|
||
- [ ] **Step 3: `Dialog.jsx`**
|
||
|
||
| Teil | Umsetzung |
|
||
|---|---|
|
||
| Esc | `keydown`-Listener auf `document`, prüft mit `shouldCloseOnKey(e, busy)` und ruft dann `onClose()` auf |
|
||
| Hintergrund | Klick ohne Wirkung |
|
||
| Box | `role="dialog"`, `aria-modal="true"`, `aria-labelledby={titleId}` (`useId()`), `ref`, `tabIndex={-1}` |
|
||
| Overlay | `onKeyDown` aus `useDialogFocus` |
|
||
| `×` | `<button type="button" className="dialog-close" aria-label="Schließen" disabled={busy} onClick={onClose}>×</button>` |
|
||
| `as="form"` | die Box ist `<form onSubmit>` ohne `noValidate` |
|
||
|
||
- [ ] **Step 4: `dlg-probe`**
|
||
|
||
Die Ansicht öffnet `/tickets` und fügt per `page.evaluate` einen statischen Klon des Dialog-Markups ein: ein Titel, drei Felder und ein Fuß mit Absende-Knopf. Geprüft wird nur das CSS:
|
||
- Bei 390 px liegt die Box unten.
|
||
- Das Overlay hat Fenstergröße.
|
||
- `submitReachable` gelingt bei 390×700.
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/shots.sh" p1 "$W/shots/p1-t7" --only dlg-probe --gate p1`
|
||
Expected: Exit 0.
|
||
|
||
- [ ] **Step 5: Commit**
|
||
|
||
```bash
|
||
git add src/components/ui/Dialog.jsx src/components/ui/index.js src/lib/dialogKeys.js tests/unit/dialogKeys.test.mjs
|
||
git commit -m "Design: Dialog-Baustein (Esc, Sperre waehrend Speichern, Fokus, Bottom-Sheet)" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 8: Login
|
||
|
||
**Files:**
|
||
- Modify: `src/pages/LoginPage.jsx` (nur Markup)
|
||
- Delete: `src/components/LetterGlitch.jsx`
|
||
|
||
**Interfaces:**
|
||
- Consumes:
|
||
- `useAuth()` mit `login`, `mfaPending`, `sendCode`, `verifyCode` und `cancelMfa`, unverändert
|
||
- `Logo`
|
||
- die Klassen `.login*`, `.field`, `.input`, `.code-input`, `.btn-primary.btn-block` und `.msg`
|
||
|
||
- [ ] **Step 1: Markup ersetzen**
|
||
|
||
Grundaufbau: `.login > .login-box > <Logo size={40} />`.
|
||
|
||
**Schritt E-Mail und Passwort**
|
||
|
||
| Element | Inhalt |
|
||
|---|---|
|
||
| Überschrift | h1 „Anmelden“ |
|
||
| Unterzeile | `.sub` „Ticketsystem für das WEBklar-Team“ |
|
||
| Feld E-Mail | Label „E-Mail“, `type="email"`, `autoComplete="username"`, Platzhalter `deine@email.com` |
|
||
| Feld Passwort | Label „Passwort“, `type="password"`, `autoComplete="current-password"`, `minLength={8}` |
|
||
| Knopf | `.btn.btn-primary.btn-block` „Weiter“, beim Laden „Login läuft...“ |
|
||
| Fehler | `.msg.err` mit `role="alert"` |
|
||
|
||
**Schritt Code**
|
||
|
||
| Element | Inhalt |
|
||
|---|---|
|
||
| Überschrift | h1 „Code eingeben“ |
|
||
| Text | die beiden Bestandssätze wörtlich |
|
||
| Hinweis | `notice` als `.msg.ok` |
|
||
| Feld | `#mfa-code` mit `className="input code-input"`, Label „Code aus der E-Mail“ |
|
||
| Knopf | „Anmelden“ bzw. „Prüfe…“ |
|
||
| Links | `.login-links` mit zwei `button.link` (`type="button"`): „Code erneut senden“ und „Abbrechen“ |
|
||
|
||
Ohne `challengeId` erscheint stattdessen „Code senden“ bzw. „Sende…“ und darunter „Abbrechen“.
|
||
|
||
**Fuß:** `.login-foot` „Webklar Ticket-Plattform · © {Jahr}“.
|
||
|
||
**Bleibt unverändert:** alle Handler und Zustände.
|
||
|
||
- [ ] **Step 2: `LetterGlitch` löschen und prüfen**
|
||
|
||
Zusätzlich entfällt im Werkzeug die Ausnahme `knownPageError` für LetterGlitch in `$W/shots.mjs` (eigener Commit im Werkzeug-Repo).
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && git rm -q src/components/LetterGlitch.jsx && ! rg -n "LetterGlitch" src && "$W/build.sh" "$WT" p1 && "$W/shots.sh" p1 "$W/shots/p1-t8" --only login,login-code,login-code-senden --gate p1`
|
||
Expected: Exit 0. Im Bild `login-code-senden` steht der Knopf „Code senden“.
|
||
|
||
- [ ] **Step 3: Commit**
|
||
|
||
```bash
|
||
git add src/pages/LoginPage.jsx
|
||
git commit -m "Design: neues Login (weiss, Logo, Code-Schritte), Glitch-Hintergrund entfernt" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 9: Pflicht-Fixes gegen Unlesbares
|
||
|
||
**Files:**
|
||
- Create: `src/components/serverpuls/chartColors.js`, `$W/farben.mjs`
|
||
- Modify:
|
||
- CSS: `src/styles/chat.css`, `src/pages/AdminPage.css`, `src/styles/admin-areas.css`, `src/styles/serverpuls.css`, `src/styles/global.css` (Bereich Finanzen und Rechtliches)
|
||
- Projekt-Bausteine: `src/components/AssignedProjectCard.jsx` (Zeilen 27, 82, 102), `src/components/PreviewBlock.jsx`, `src/components/PreviewLinkButton.jsx`, `src/components/GiteaLinkButton.jsx`, `src/components/AnalyseRow.jsx` (`COLORS`)
|
||
- Arbeitsblätter: `src/components/CreateWorksheetModal.jsx` (Zeilen 194, 262), `src/components/WorksheetTimesModal.jsx` (Zeile 143), `src/components/WorksheetList.jsx` (nur Farben, siehe Step 4)
|
||
- Serverpuls: `src/components/serverpuls/Chart.jsx`, `src/pages/ServerpulsPage.jsx` (Serienfarben)
|
||
- Doku: `docs/superpowers/plans/2026-10-05-weisses-design-p1-tote-klassen.md` (Abschnitt „Bewusst offen“)
|
||
|
||
**Interfaces:**
|
||
- Produces:
|
||
- `CHART` laut Übersicht.
|
||
- `farben.mjs <worktree>` listet je Treffer Datei:Zeile, Literal und Grund:
|
||
- `kontrast<3` (Text auf Weiß)
|
||
- `dunkel-auf-akzent`
|
||
- `weiss` (`#fff`, `#ffffff`, `white`, `rgba(255,255,255,x)` als Text- oder Randfarbe außerhalb von `.btn-primary` und Elementen auf `--accent`)
|
||
- `verlauf` (`linear-gradient` in JSX oder CSS)
|
||
|
||
- [ ] **Step 1: Scan (failing)**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node "$W/farben.mjs" "$WT"`
|
||
Expected: eine Liste mit Treffern aller vier Gründe, unter anderem aus `WorksheetList.jsx`.
|
||
|
||
- [ ] **Step 2: Chat-Variablen**
|
||
|
||
Unter `.woms-chat` in `chat.css`:
|
||
- `--chat-accent: var(--accent)`
|
||
- `--chat-accent-hover: var(--accent-hover)`
|
||
- `--chat-accent-soft: var(--accent-soft)`
|
||
- `--chat-accent-line: rgba(17,17,17,.14)`
|
||
- `--chat-accent-text: var(--accent)`
|
||
- `--chat-on-accent: #ffffff`
|
||
- `--chat-surface: var(--bg)`
|
||
- `--chat-line: var(--line-strong)`
|
||
- `--chat-muted: var(--text-2)`
|
||
|
||
Weitere Regeln:
|
||
- Rand der eigenen Blase: `var(--line)`.
|
||
- `.woms-chat .chat-messages { background: var(--bg) }`.
|
||
- `.woms-chat .chat-composer-note`, `.woms-chat .chat-tray-item.is-error .chat-file-size` und `.woms-chat .chat-audio.is-error .chat-audio-time` bekommen `color: var(--red-fg)`.
|
||
- `.woms-chat .chat-composer-note.is-info` bekommt `color: var(--text-2)`.
|
||
|
||
- [ ] **Step 3: Literale umstellen nach fester Zuordnung**
|
||
|
||
| Literal | Token |
|
||
|---|---|
|
||
| `#a0aec0`, `#cbd5e0`, `#9aa7b4`, `#e2e8f0` (als Text) | `var(--text-2)` |
|
||
| `#34d399`, `#6ee7b7`, `#10b981` (als Text) | `var(--green-fg)` |
|
||
| `#f87171`, `#fca5a5`, `#fecaca`, `#ef4444` (als Text) | `var(--red-fg)` |
|
||
| `#fbbf24`, `#f59e0b` (als Text) | `var(--orange-fg)` |
|
||
| `#818cf8`, `#9d3dfe` | `var(--violet-fg)` |
|
||
| `#3b82f6`, `#60a5fa` | `var(--blue-fg)` |
|
||
| `rgba(255,255,255,x)` als Rand oder Linie | `var(--line)` |
|
||
| `rgba(255,255,255,x)` als Fläche | entfällt bzw. wird `var(--bg-subtle)` |
|
||
| `#05251c`, `#04130d` auf Akzent | `#ffffff` |
|
||
| `rgba(30,41,59,x)` und ähnliche dunkle Flächen | `var(--bg-subtle)` |
|
||
|
||
`.admin-primary-button` bekommt `color: #fff` und beim Überfahren `background: var(--accent-hover)`.
|
||
|
||
- [ ] **Step 4: `WorksheetList.jsx` minimal**
|
||
|
||
Nur die Farben werden geändert:
|
||
- Verläufe und Weiß-Alphas gehen auf Tokens nach der Tabelle oben.
|
||
- Weiße Schrift auf farbigen Köpfen wird `var(--text)` auf `var(--bg-subtle)`.
|
||
|
||
Struktur und Klassen bleiben. Den Umbau macht P2.
|
||
|
||
- [ ] **Step 5: Diagrammfarben**
|
||
|
||
`chartColors.js` wird angelegt. `Chart.jsx` nutzt `CHART.axis`, `CHART.grid` (nur horizontal), `CHART.tick` und als Standard-Serienfarbe `CHART.line`. `ServerpulsPage` setzt:
|
||
- alle Serien `CHART.line`
|
||
- Spitze `CHART.peak` mit `dash: [4, 4]`
|
||
- Füllung `CHART.fill`
|
||
|
||
- [ ] **Step 6: Scan erneut**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && node "$W/farben.mjs" "$WT"`
|
||
Expected:
|
||
- Kein Treffer `kontrast<3`, `dunkel-auf-akzent` oder `weiss`.
|
||
- `verlauf`-Treffer nur dort, wo `.btn-primary` oder ein Canvas sie braucht.
|
||
- Jeder Rest steht unter „Bewusst offen“ im Dokument mit Zielpaket und gemessenem Kontrast von mindestens 3:1.
|
||
|
||
- [ ] **Step 7: Commit**
|
||
|
||
```bash
|
||
git add src/components/serverpuls/chartColors.js src/components/serverpuls/Chart.jsx src/pages/ServerpulsPage.jsx src/styles/chat.css src/pages/AdminPage.css src/styles/admin-areas.css src/styles/serverpuls.css src/styles/global.css src/components/AssignedProjectCard.jsx src/components/PreviewBlock.jsx src/components/PreviewLinkButton.jsx src/components/GiteaLinkButton.jsx src/components/AnalyseRow.jsx src/components/CreateWorksheetModal.jsx src/components/WorksheetTimesModal.jsx src/components/WorksheetList.jsx docs/superpowers/plans/2026-10-05-weisses-design-p1-tote-klassen.md
|
||
git commit -m "Design: Pflicht-Fixes gegen helle Schrift und dunkle Flaechen, Diagrammfarben, Chat-Variablen" -m "Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>"
|
||
```
|
||
|
||
### Task 10: Gate P1, Review, Tag
|
||
|
||
- [ ] **Step 1: Rebase**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && git fetch origin && git rebase origin/test && "$W/check.sh"`
|
||
Expected: Exit 0. Die Testzahl ist 312 − 3 (`sidebar`) + 1 (`statusTone`) + 2 (`uiTones`) + 1 (`dialogKeys`) = 313. Liegen neue Commits auf `test`, kann sie höher sein; die Zahl wird notiert.
|
||
|
||
- [ ] **Step 2: Vollständiger Gate-Lauf**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/build.sh" "$WT" p1 && "$W/shots.sh" p1 "$W/shots/p1" --gate p1`
|
||
Expected: Exit 0 für alle Ansichten aus P0 plus `basis-weiss`, `menue-mobil` und `dlg-probe`. Alle `dlg-*` bestehen `submitReachable` bei 700 px Höhe.
|
||
|
||
- [ ] **Step 3: Bundle-Größe**
|
||
|
||
Die Werte aus der `check.sh`-Ausgabe werden mit P0 verglichen. Das CSS sollte kleiner sein, und die Schrift fehlt.
|
||
|
||
- [ ] **Step 4: Code-Review (sonnet)**
|
||
|
||
Der Diff `603d08c..HEAD` (inklusive P0) wird gegen die Spec geprüft, Abschnitte:
|
||
- „Gestaltungsregeln“
|
||
- „Bausteine“
|
||
- „KOMPAT“
|
||
- Pakete P0 und P1
|
||
|
||
Wichtige Befunde werden behoben. Danach kommt der Rebase aus Step 1 noch einmal und Step 2 als Kurzlauf mit `--only tickets,login`.
|
||
|
||
- [ ] **Step 5: Tag und Übergabe**
|
||
|
||
Run: `source /root/reports/ticketsystem-design-2026-10-04/werkzeug/env.sh && "$W/check.sh" && git tag design-p1 && git log --oneline origin/test..design-p1 && git rev-parse design-p1`
|
||
|
||
Übergabe an den Eigentümer:
|
||
- Screenshots aus `$W/shots/p1` (Login, Tickets, Kunde, Projekte, Finanzen, Serverpuls, ein Alt-Dialog, Menü mobil)
|
||
- Hinweis zu den neuen Statusfarben für das Team
|
||
- Push-Zeile `git -C /home/webklar/apps/ticket.webklar.com/dev-design push origin 'design-p1^{commit}:refs/heads/test'`
|
||
- Rücknahme: `git revert --no-commit 603d08c..design-p1`, Commit und Push durch den Eigentümer
|
||
|
||
- [ ] **Step 6: Nach dem Push (erst, wenn der Eigentümer gepusht hat)**
|
||
|
||
- Im Log von `webklar-ticket-build` steht „Deployment completed successfully“.
|
||
- `curl -s https://ticket.webklar.com/ | grep -o 'assets/index-[^"]*\.js'` stimmt mit `dist/index.html` des Tags überein.
|
||
- Ein lesender Sichttest im Chrome des Eigentümers: Login-Seite und Ticketliste.
|