Changelog
Audit-Trail aller inhaltlichen Änderungen — je PR ein Eintrag: Datum · PR-Nummer (Link) ·
kurze Beschreibung inkl. getroffener Entscheidungen. Neueste zuerst. Verbindlich gepflegt
(siehe docs/konventionen/agents.md §5.1, Root-CLAUDE.md → Repo/Audit-Trail). Tiefe/Begründung je Thema:
HANDOFF.md §4 (Offene Punkte) + docs/fachlich/Lastenheft.md. Repo: drkv-com/taktano.
2026-07-26
- Branch
claude/next-steps-8vmq5d([PR folgt]) — Rollen-Auswahl im Menü (interim self-declared roles, OP-AUTH-1 A-1.5) +KOSTEN_ADMIN_EMAILS-Allowlist entfernt — MINOR0.156.0, OP-AUTH-1/OP-COST-1/OP-COST-3. PO: A-2 (Better Auth) geparkt; stattdessen ein einfacher, sofort wirksamer Interim. Gebaut: im ⚙-Menü wählt man seine Rolle (Werker · Buchhaltung · Werkstattleitung · Inhaber/Chef) → als?rolle=-Query beim WebSocket-Verbinden (+ Chronik-Fetch) übergeben; der Server leitet daraus die A-1-Fähigkeiten ab (capsAusRolle— damit ist derdarf()-Seam live): Werker=keine · Buchhaltung=kosten· Werkstattleitung=verwaltung· Inhaber/Chef=alle drei. Rollenwechsel lädt neu (frischer Socket). Das (bisherkosten+verwaltungvermischende)kostenAdmin-Flag um ein eigenesverwaltung-Flag gespalten (Administration/Chronik/Verwaltung-Nav gaten aufverwaltung, Kosten aufkosten). Altlast entfernt (PO): die E-Mail-AllowlistKOSTEN_ADMIN_EMAILS(+kostenAdminFuer, Env-Feld,wrangler.toml-Block) — Autorisierung kommt jetzt aus der Rolle. Cloudflare Access bleibt als Netz-Gate (Golden Rule) +X-Taktano-User-Audit-Actor. OP-COST-3 (Allowlist-Aktivierungs-Runbook) damit hinfällig → erledigt. ⚠ Sicherheits-Charakter (bewusst, interim, RISK-12): die Rolle ist selbst-deklariert (jeder hinter Access kann „Inhaber/Chef" wählen) — kein echtes Berechtigungsmodell, sondern Demo/Pilot-Zwischenstand hinter dem Access-Netz-Gate; verifizierte Durchsetzung (Rolle aus Better-Auth-JWT) + Gate-Nachzug der ungegateten Stammdaten-Handler kommen mit A-3. Live-DO-verifiziert (WS-Probe: alle 4 Rollen + ungültig→werker korrekt; end-to-end: chef/werkstattleitung → Administration sichtbar, werker → gesperrt; ⚙-Dropdown rendert + zeigt aktuelle Rolle). Reiner Client (RolleService neu + Shell-Dropdown + verwaltung-Gates) + Server (connCaps/tailorState//audit/liste-Gate). Verifiziert:ng buildprod + No-Hex +tsc(Server) + No-Console grün + Screenshots. Doku: OP-AUTH-1 (A-1.5), Kosten.md (§Gate/§12), OP-COST-1/-3, RISK-12, HANDOFF/Timesheet. - Branch
claude/next-steps-8vmq5d(PR #741) — ⚙-Menü: „Auf Kurs %"-Statuszeile entfernt — PATCH0.155.2, OP-REDESIGN-1. PO-Feedback: die „Auf Kurs 100 %"-Zeile (samt „N gefährdet"-Indikator) im ⚙-Zahnrad-Popover raus — die Auf-Kurs-/Gefährdet-Info lebt bereits prominenter im TN-Strip der Top-Bar (Auslastung/Fahrzeuge/verortet) und in den Entscheiden-/Fluss-Sichten; im kompakten Einstellungs-/Status-Popover war sie redundant (Einfachheit). Popover trägt jetzt nur noch Einstellungen (Ansicht · Feedback · Alarm-Ton) · Foto-Queue (nur bei wartenden Uploads) · Verbindung (Neu synchronisieren). UngenutzteaufKursProzent-Computed mitentfernt. Live-DO-verifiziert (Hell: „Auf Kurs" weg, Menü intakt). Reiner Client (1 Datei) +version.ts. Verifiziert:ng buildprod + No-Hex grün + Screenshot. - Branch
claude/next-steps-8vmq5d(PR #739) — Scope-Entscheidung: Voll-Offline-Write kategorisch ausgeschlossen + Background-Sync als OP-OFFLINE-2 angelegt — reine Doku, kein Version-Bump, OP-OFFLINE-1/OP-OFFLINE-2. PO-Entscheidung 2026-07-26: Voll-Offline-Write (beliebige Aktionen offline absetzen) ist kategorisch ausgeschlossen — nicht „Backlog", sondern außerhalb des Produkt-Scopes: der Durable Object bleibt live-verbundene Single Source of Truth, die Idempotenz-/Replay-/Konflikt-Komplexität widerspricht dem Leitprinzip Einfachheit und zahlt auf keine True-North-Frage ein (Auslastung/Standort/Kapazität setzen Server-Autorität + harte Gates QS/Vier-Augen/Live-Taktung ohnehin voraus); einziger gerechtfertigter Offline-Write bleibt der enge, idempotente Foto-Upload. Background Sync (Foto-Uploads nach Tab-Schließen abschließen) — bisher nur als „Folge-Schritt" notiert — als eigener offener OPOP-OFFLINE-2(prio: spaeter, betrifft nur den bestehenden idempotenten Foto-Upload, klar getrennt vom ausgeschlossenen Voll-Offline-Write) ausgegliedert. Doku:ops/OP-OFFLINE-2.md(neu),ops/OP-OFFLINE-1.md,architektur/Offline-PWA.md(§„Bewusst NICHT"),IDs.md,Offene-Punkte.md(gen-ops), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #738) — CodeRabbit-Nachzug zu #737 — PATCH0.155.1, OP-OFFLINE-1. 7 Findings, 3 valide behoben (Rest = Doku-Konsistenz). (1, echter Bug): die client-seitige Cache-SCHEMA-Konstante blieb1, obwohlLeitstandState.schemaVersionin #737 Pflichtfeld wurde → vor-0.155.0-Snapshots [ohne das Feld] würden noch hydriert;SCHEMA1→2 verwirft Alt-Snapshots beimload()[genau der in #737 dokumentierte stille Selbstheilungs-Mechanismus, nur nicht ausgelöst]. (2):StateCacheService.clear()schluckte IndexedDB-Fehler → Schein-Resync möglich; gibt jetztbooleanzurück [OP-LOG-1], beifalsekein Reload. (3):neuSynchronisieren()verwarf den Cache allein aufnavigator.onLine→ bei Aussetzer Verlust von Cache+App-Shell; neue Same-Origin-Erreichbarkeits-Probe [HEAD/no-store, 3xx/4xx=erreichbar] vor dem Verwerfen + ehrlicher „nicht neu synchronisiert"-Toast bei Nicht-Erreichbarkeit. Bewusst NICHT der schwere in-page-Resync-Umbau [Hard-Reload spiegelt das akzeptiertehartNeuLaden()-Verhalten, Probe deckt die Lücke proportional]. Timesheet/CHANGELOG-Konsistenz mitgezogen. Verifiziert:ng buildprod + No-Hex +tsc(Server) + doc-consistency--strictgrün. Reiner Client (3 Dateien) +version.ts. - Branch
claude/next-steps-8vmq5d(PR #737) — Offline-Resilienz: Schema-Broadcast + „↻ Neu synchronisieren" (Offline-Stand verwerfen + Voll-Resync) — MINOR0.155.0, OP-OFFLINE-1. Deckt den PO-Fall ab: „Server per Ping erreichbar, aber das Datenmodell lässt sich nicht synchronisieren" bzw. „lokale Offline-Variante passt nicht mehr zum Server-Build → alles neu laden". Drei Bausteine: (1) Schema-Broadcast — der Server sendet die Daten-Schema-Version (SCHEMA_VERSION, DO-Persistenz) alsschemaVersionim State (DTO +snapshot()); der Client stempelt jeden Offline-Snapshot mit dieserserverSchema(StateCacheService.save/load) → Cache selbstbeschreibend/inkompatibilität erkennbar. (2) Stiller Selbstschutz — die client-seitige Cache-SCHEMA-Konstante verwirft inkompatible Alt-Snapshots beimload(); der DO schickt beim Verbinden ohnehin immer den vollen, autoritativen State → Daten heilen bei Reconnect automatisch (läuft still, immer sicher). (3) Bewusste Nutzer-Aktion —VerbindungService.neuSynchronisieren()= View-Cache verwerfen (StateCacheService.clear()) +hartNeuLaden(); zwei Zugänge: Sekundär-Link im Offline-Banner und ⚙-Menü-Eintrag „Verbindung → Neu synchronisieren · Offline-Stand verwerfen". Entscheidungen/Leitplanken (PO-Defaults): wird nie automatisch/still ausgelöst (kein gültiger Cache ungefragt verworfen → immer nur anbieten); an vorhandenes Netz gebunden (sonst ehrlicher Toast); die persistente Foto-Upload-Queue (taktano-offline-fotos) bleibt unberührt (clear()löscht nur den View-State-Key). Live-DO-verifiziert:schemaVersion=22im State-Broadcast, ⚙-Menü-Eintrag rendert (Hell). Reiner Client (4 Dateien) + 1 Server-Feld. Doku: OP-OFFLINE-1,architektur/Offline-PWA.md, CHANGELOG, HANDOFF §2, Timesheet,version.ts(0.155.0).
2026-07-25
- Branch
claude/next-steps-8vmq5d(PR #736) — Governance: A-1 als Zwischenstand + interim-Betreiber/Admin festgelegt (reine Doku, kein Version-Bump, OP-AUTH-1). PO-Entscheidung 07-25: OP-AUTH-1 A-1 bleibt der Zwischenstand (kein A-2/A-3 vorerst); interim-Betreiber/Admin = der PO (m.kirchhof@drkv.com). Als Entscheidung/Audit-Trail inops/OP-AUTH-1.mdfestgehalten — inkl. der zwei Deploy-Voraussetzungen, damit es greift (beide nicht im Repo, PII/Secret-Regel): (1)KOSTEN_ADMIN_EMAILS= Betreiber-E-Mail viawrangler secret put; (2) Access aktiv (ACCESS_TEAM_DOMAIN+ACCESS_AUD) — sonstaccessAktiv=false→ alle sind Admin (Allowlist wirkungslos). Caveat notiert: wegen des bekannten A-1-Gaps (ungegatete Stammdaten-Handler) ist „nur der PO ist Admin" erst mit A-3 voll durchgesetzt. Von der Session aus nicht setzbar (keine CF-Credentials/wrangler login) → Deploy-Aktion beim PO/CI/CF-Dashboard. Reine Governance-Doku (ops/OP-AUTH-1.md), kein Code. Doku: OP-AUTH-1, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #735) — A-1 CodeRabbit-Nachzug (Doku-Konsistenz + Coverage-Ehrlichkeit) (APP_VERSION0.154.1 → 0.154.2, PATCH — Fix/Nachzug). Nachzug der 4 validen CodeRabbit-Findings zu #734 (kamen, als der PR schon gemergt war → Follow-up-PR, frischer Branch vonmain). (1) Timesheet-Summen (Minor): Kernaussage/„Investierte Zeit gesamt" — Kopf-Summe stimmte nicht mit den Komponenten überein (100.6 + 151.5 ≠ 253.5); KW27–30-Aggregat auf 152.9 h korrigiert → 100.6 + 152.9 = 253.5 h (jetzt konsistent). (2) Lastenheft §11.5 IdP (Major): „Verworfen: Clerk/WorkOS" widersprachops/OP-AUTH-1.md(dort Fallback nur falls „schnell ohne Ops"/SAML-SSO dominiert) → Lastenheft auf die nachrangig/Fallback-Formulierung angeglichen + „Maßgeblich = ops/OP-AUTH-1.md". (3) HANDOFF Rollen-Mapping (Minor):Inhaber=alle→Inhaber/Chef=alle drei(deckungsgleich zu Lastenheft/OP). (4)verwaltung-Coverage ehrlich gemacht (Major, Security-Befund): derdarf-Doc-Kommentar überzeichnete die Abdeckung — mehrere Stammdaten-Handler (employee.create/update/setVerfuegbarkeit/addAbwesenheit, Skill-CRUD,teilschritt.update,leistung.update) sind ungegatet (CodeRabbit korrekt). Bewusst KEINE Gates ergänzt: das ist ein vorbestehender Zustand (nicht durch A-1 eingeführt; die Handler waren nie gegatet, der Refactor blieb verhaltensgleich), und ein Gate ohne besetzte Admin-Rolle würde die Stammdaten-Pflege in Prod aussperren (bei leererKOSTEN_ADMIN_EMAILSist niemand Betreiber). Stattdessen: Doc-Kommentar +ops/OP-AUTH-1.mdsagen jetzt ehrlich, welche Handler heute gegatet sind und dokumentieren den ungegateten Rest als bekannten A-1-Gap, der mit A-3 (zusammen mit der echten Rollen-Zuweisung) geschlossen wird — sonst Prod-Aussperrung. Verifiziert:tsc(Server) + No-Console + doc-consistency--strictgrün. Reine Doku + 1 Code-Kommentar (kein Verhaltens-/Logik-Change). Doku:server/party/leitstand.ts(darf-Kommentar),ops/OP-AUTH-1.md,docs/fachlich/Lastenheft.md, HANDOFF §2, Timesheet, CHANGELOG. - Branch
claude/next-steps-8vmq5d(PR #734) — OP-AUTH-1 A-1: Rollen-/Fähigkeits-Naht —istKostenAdmin→darf(conn, faehigkeit)(APP_VERSION0.154.0 → 0.154.1, PATCH — verhaltensgleicher Server-Refactor, OP-AUTH-1). Erster Schritt Richtung echtes User-Management (PO: „nur a-1"). Das Interim-Auth-GateistKostenAdminwar überladen — dieselbe E-Mail-Allowlist-Prüfung trug drei verschiedene Bedeutungen (Kosten-Admin · Stammdaten-/Konfig-Mutation · Chef-Override). Umbau: eine neuedarf(conn, faehigkeit)-Funktion mit benannten Fähigkeiten —kosten(Infra-Kosten sehen/erfassen + Kosten-Sicht) ·verwaltung(Stammdaten-/System-/Konfig-Mutation: Mitarbeiter·Skills·Prozesse·Buchten·Taxonomien·Schichten·Nacht-Halle·Editier-Präsenz·Datenbestand-Reset·OTLP-Test) ·chef(G-4/OP-QS-6: Vier-Augen-Abweichung + Notfall-Klärfall-Auflösung). Alle 28 Gate-Call-Sites (server/party/leitstand.ts) vonistKostenAdmin(conn)aufdarf(conn, "<fähigkeit>")umgestellt (7 kosten · 19 verwaltung · 2 chef). Verhaltensgleich:darflöst interim für alle Fähigkeiten auf denselben Betreiber-Gate (istKostenAdmin→ Access-E-Mail-Allowlist) auf → kein Verhaltens-Change;void faehigkeitmarkiert die Naht, an der A-3 (Better Auth) die rechte Seite je Fähigkeit durch die rollenbasierte Verbindungs-Projektion ersetzt. Gewinn: die Gates sind jetzt selbsterklärend (welche Berechtigung sie verlangen), und das Rollenmodell hat einen sauberen Einhak-Punkt. Geplantes Rollen→Fähigkeit-Mapping (Design, noch ohne Runtime — kommt mit A-3): Inhaber/Chef = alle drei · Werkstattleitung =verwaltung(+opt.kosten) · Buchhaltung =kosten· Werker = keine. Offen (A-2+, PO-Entscheidung): ob jeder Mitarbeiter ein eigenes Login bekommt (Employee↔User-Verknüpfung) oder nur die Leitung. Verifiziert:tsc(Server) + No-Console + Scheduler-Self-Test (npm run spike, verhaltensgleich) + doc-consistency--strictgrün. Reiner Server (leitstand.ts: neuedarf-Methode + 28 Call-Site-Umstellungen), kein Client/DTO/Schema. Doku-Konsistenz mitgezogen:ops/OP-AUTH-1.md(A-1 ✅ + Slices A-1…A-5 + Rollen-Mapping) · Lastenheft §11.5 (stale IdP-Kandidaten „Zitadel/Ory" → Better-Auth-Entscheidung nachgezogen). Doku: CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #733) — Top-Bar-Menü prototype-treu: „⋯" → Verwaltung direkt + Zahnrad-Popover (APP_VERSION0.153.0 → 0.154.0, MINOR — IA-Feinschliff, OP-REDESIGN-1). PO-Feedback: „Das Menü ist nicht wie im Design-Prototyp." Befund: die Flusslinie-Prototyp-Top-Bar ist minimal — Logo · 4 Orte-Tabs + „⋯" öffnet direkt die Verwaltung (verwaltungAuf, „Stammdaten & Selten-Gebrauchtes") · True-North-Strip · Leitstand|Werkstatt-Segment · Uhr; kein Bereichs-Dropdown, keine Einstellungen/Status in der Bar. Mein 4A-Übergangsstand hatte „···" dagegen als großes gruppiertes Overflow-Menü (alle Bereiche + Einstellungen + Status) gebaut — als Gerüst, bis die IA konsolidiert ist. Da die IA jetzt komplett ist (4A–4E), ist das Gerüst überflüssig. Umbau: (1) „⋯" ist jetzt ein direkter Verwaltung-Link (routerLink="/verwaltung", roter Aktiv-Underline; die Verwaltungs-Seite gated Nicht-Betreiber selbst) — das Bereichs-Dropdown entfernt (die 4 Orte sind Tabs, Verwaltung ist „···", das Werkstatt-Terminal der Rollen-Umschalter → keine Bereichs-Navigation im Menü mehr nötig). (2) Die realen App-/Geräte-Steuerungen, die der Prototyp nicht in der Bar führt (Ansicht/Theme · Feedback-Anzeige · Alarm-Ton · Auf-Kurs · Foto-Queue), wandern in ein kompaktes Zahnrad-Popover (⚙, rechts neben der Uhr, rechts-anchored) — erreichbar, aber außerhalb der Navigations-Orte (Einfachheit; bewusste, begründete Abweichung, weil der Prototyp diese Steuerungen als reines Mock auslässt). DienavGroups-Liste bleibt als Routen-Titel-Registry für den Workspace-Sub-Header (flatNav→active), rendert aber kein Menü mehr. Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Playwright, Hell + Dunkel: „⋯"-Klick →/verwaltung/leistungen; ⚙-Popover zeigt nur Einstellungen [Ansicht/Feedback/Alarm-Ton] + Auf-Kurs, keine Bereichs-Gruppen; keine Page-Errors). Reiner Client (shell.component.ts: „⋯"→Link, Zahnrad-Button + repositioniertes Popover, navGroups-Rendering raus), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod + doc-consistency--strictgrün + Live-Screenshots. Doku:design/WORKSPACES.md(Top-Bar),design/CLAUDE.md(Shell),docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #732) — Metrik-Trends: Termintreue + Ø Durchlaufzeit (2 neue Review-KPIs) (APP_VERSION0.152.0 → 0.153.0, MINOR — neues Feature, OP-AUDIT-1/OP-COST-1 · OP-DATA-1). Erweitert die Metrik-Persistenz (diemetrik_snapshots-DO-SQLite-Tabelle) um die letzten beiden bei #722 als „nachgelagert" markierten Trend-Kennzahlen — jetzt 5 Tages-Snapshot-KPIs in der Review-Sicht. Definitionen (ehrlich, aus den Ist-Zeiten der fertigen Aufträge): Termintreue = % fertiger Aufträge mittatsaechlicheFertigstellung ≤ urspruenglicherAbholtermin(bis zum ursprünglich zugesagten Abholtermin fertig — es gibt keinen Ist-Abhol-Zeitpunkt, „bis Zusage fertig" ist die tragfähige Näherung); Ø Durchlaufzeit = Mittel austatsaechlicheFertigstellung − tatsaechlicheAnlieferungüber fertige Aufträge mit beiden Ist-Zeiten (Minuten gespeichert, Client zeigt Tage). Beide NULL ohne Basis (ehrliche Lücke, D-2). Datenlücke geschlossen:tatsaechlicheAnlieferung(Ist-Ankunft) war ein deklariertes, aber nie gestempeltes Feld → wird jetzt beim Fahrzeug-Check-in (auftrag.checkin→angeliefert) gesetzt (epoch Minuten, nur beim ersten Mal); der Demo-Seed setzt es (≈ Bringtermin, −2 Tage) → die Durchlaufzeit demonstriert real. Schema: Drizzle-Schemametrik_snapshots+=termintreue_pct/durchlaufzeit_min(Single Source), generierte Migrationdrizzle/0002_*.sql(2×ALTER TABLE ADD COLUMN); Runtime-Tabellenanlage um additive Spalten-Auto-Migration erweitert (PRAGMA table_info→ fehlende Spalten per ALTER, kein Exception-Spam) — bestehende Tabellen ziehen live nach. Producer/Reader (aktuelleMetrikWerte/Insert/metrikVerlaufDTO) + DTO (Server + Client) erweitert. Client (lage-review.component.ts): 2 weitere Sparklines; die Trend-Reihe kann jetzt nicht-Prozent-Einheiten (Dauer/Tage) — eigene Einheit, Fenster-Max-Skalierung der Balken, eine Nachkommastelle, Delta in der Reihen-Einheit statt fix „pp". Grid 3→5 Spalten. Live-DO-verifiziert (wrangler dev --local+ frischer Demo-Seed + Playwright, Hell + Dunkel: Review zeigt alle 5 KPIs — Auslastung 0 % · FPY 33 % · Nacharbeit 67 % · Termintreue 100 % · Ø Durchlaufzeit 2.0 Tage — mit Sparkline + korrekter Einheit/Skalierung, keine Page-Errors). Client + Server + DO-SQLite (Schema/Migration, DO-Producer/Reader, Check-in-Stempel, Seed, DTO beidseitig, Consumer). Verifiziert: No-Hex +tsc(Server) +ng buildprod + Persistenz-Gate (db:check, Schema↔Migration sync) + No-Console + doc-consistency--strictgrün + Live-Screenshots. Doku:docs/architektur/Persistenz.md(metrik-Spalten),docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. Damit sind die Review-Trend-KPIs vollständig (keine „nachgelagert"-Lücke mehr). - Branch
claude/next-steps-8vmq5d(PR #731) — Redesign „Flusslinie" Phase 4E: Aufräumen — Verwaltung 3-Wege-Split + Chronik (Audit-Panel) → „IA-komplett" (APP_VERSION0.151.0 → 0.152.0, MINOR — IA/Screen + Server-Lesepfad, OP-REDESIGN-1 / OP-AUDIT-1). Der letzte Voll-IA-Schritt. (1) Verwaltung 3-Wege-Split: der frühere Sammel-Screen „Stammdaten & System" wird als drei Ort-Sub-Tabs geführt — Buchten & Hof (Arbeitsplätze · Sperren · Nacht-Halle) · Schichten (Arbeitszeitfenster · Reserve) · System (Taxonomien · Mandant · Datenbestand/Purge). Entscheidung (Einfachheit, PO 07-25 „Taxonomie ganz auf System"): eine route-parametrisierte Komponente (administration.component.tsliestdata.bereichviatoSignal(route.data), Template@if (bereich() === …)) statt drei Dateien — so bleibt die geteilte OP-EDIT-1-Quittungs- (editResult) + Präsenz-Verdrahtung ungeteilt (kein 3×-Duplikat); da die Taxonomien ganz auf „System" bleiben, besitzt jeder Bereich genau eine Edit-Domäne. Routenplaetze/schichten/system(+stammdaten→plaetze-Redirect,/administration→/verwaltung/plaetze); Verwaltung-Sub-Sidebar jetzt 7 Tabs. (2) Chronik (Audit-Panel, OP-AUDIT-1 Slice 3): der bisher disabled „folgt"-Tab ist gebaut — mit echtem Server-Lesepfad: das Audit-Log (audit_entries, D1) war write-only, jetzt liefertGET /audit/liste(DO-onRequest, admin-gegated viakostenAdminFuer, eigenes Gate — nicht der breitere Assistent-Kreis) die jüngsten Events (server-seitigerSELECT … ORDER BY ts DESC LIMITüber den(tenant,ts)-Index, nursummary— PII-arm, Detail-Diffs bleiben in der zugriffsgeschützten D1). NeuerAuditEintragDTO/AuditListe(Server- + Client-Spiegel),svc.ladeAuditVerlauf(), neuer read-onlychronik.component.ts(Zeitachse Wann · Was · Wer nach Prototyp; ehrlicher Leer-/Dormant-Zustand ohne D1-Binding statt Fake). Damit ist die 4-Orte-IA komplett (kein „folgt"-Platzhalter mehr). Live-DO-verifiziert (wrangler dev --local+ lokale D1-Migration + 3 seed-Audit-Zeilen + gebauter Client + Playwright, Hell + Dunkel: 7-Tab-Sub-Sidebar, System zeigt nur Taxonomien+Purge [Arbeitsplätze/Schichten/Nacht-Halle korrekt auf ihre Tabs verschoben], Chronik rendert die 3 echten D1-Audit-Zeilen [Tom Wend archiviert · Infra-Kosten · Sina Falk Urlaub] mit Event-Typ/Actor/Resource + „Detail-Diffs bleiben in der D1"-Fußnote, keine Page-Errors; der Chronik-Fetch ist same-origin in Prod — lokal viaASSISTENT_CORS_ORIGINSfreigeschaltet). Client + Server (route-param.administration, neuechronik.component.ts, Verwaltung-Tabs/Routen, Server-onRequest-Route +auditListe()-DO-Methode + DTOs, Service-Fetch), kein Schema-Change (nur Lesepfad auf bestehende Tabelle —db:checkgrün). Verifiziert: No-Hex +tsc(Server) +ng buildprod + No-Console + doc-consistency--strictgrün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(4E ✅ / „IA-komplett"),docs/architektur/Audit-Log.md(Slice 3 ✅ Lesepfad),design/WORKSPACES.md,docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #730) — Redesign „Flusslinie" Phase 4D: Team-Seite (lesender Karten-Überblick) (APP_VERSION0.150.0 → 0.151.0, MINOR — IA/Screen, OP-REDESIGN-1). Vorletzter Voll-IA-Schritt. Der Team-Ort (/staff) war bisher direkt der volle Editor (StaffComponent, 1037 Zeilen: anlegen/bearbeiten, Skills, Schichten, Abwesenheiten, Beförderungen) — der Prototyp macht daraus einen lesenden Überblick „wer kann was, wer macht was". NeuerTeamComponent(client/src/app/leitstand/pages/team.component.ts) = Karten-Grid (sm:2/xl:3): Avatar (Ink) · Name/Rolle · Status-Pille (arbeitet · Frei · Pause · krank · Urlaub; Prototyp-Wort „arbeitet" = abgeleiteterAktiv) · Aktuell (Employee.currentTask) · Als Nächstes (frühester geplanter Teilschritt, dem der Mitarbeiter zugewiesen ist — Haupt-/Helfer-Rolle — über alle Live-Aufträge, Queue-Semantik/startwie die Tafel OP-OPT-9, alscomputedeinmal je State vorberechnet) · Skill-Chips mit Niveau (kann was) · read-only Status-Filter (Alle + je Status mit Zähler). Entscheidung — Editor deflektiert, NICHT dupliziert (Einfachheit): die volle Pflege bleibt derStaffComponent-Editor unter Verwaltung → Team & Skills (/verwaltung/team, Phase 4B) — der Team-Ort trägt oben einen „Pflegen: Verwaltung → Team & Skills →"-Deflektor + einen Inline-Link bei fehlenden Skills; Route-Repoint/staff→TeamComponent(Alt-Deep-Links landen auf dem Überblick, Editieren ein Klick weiter). Onboarding-Hinweis + „···"-Menü-Label (Mitarbeiter→Team, sub „Wer kann was, wer macht was") mitgezogen. Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Demo-Seed + Playwright, Hell + Dunkel: Team-Tab aktiv [roter Underline], 4 Mitarbeiter-Karten, „arbeitet"/„Frei"/„Urlaub"-Pillen, Aktuell/Als-Nächstes je Karte, Skill-Chips, Filter Alle/arbeitet/Frei/Urlaub mit Zählern, Deflektor-Link, keine Page-Errors; body-bg Ink im Dark bestätigt). Reiner Client (1 neue Komponente +app.routes.ts-Repoint + Onboarding-/Shell-Label), kein Server/DTO/Schema — alle Kartendaten liegen bereits auf den DTOs. Verifiziert: No-Hex +ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(4D ✅),design/WORKSPACES.md,docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. Offen: 4E Aufräumen (administration-3-Wege-Split + Chronik-Screen) → „IA-komplett". - Branch
claude/next-steps-8vmq5d(PR #729) — Redesign „Flusslinie" Phase 4C: Fluss konsolidieren (APP_VERSION0.149.1 → 0.150.0, MINOR — IA/Screen, OP-REDESIGN-1). Dritter Voll-IA-Schritt. Befund (Explore): der Fluss (orders) war bereits ~90% konsolidiert — Linie (5-Spalten-Board) · Karte (bettet<app-occupancy/>= Belegung ein) · Risiko-Timeline · Entscheiden-Spalte (geteilteEntscheidenComponent: Konflikte · Klärfälle · Ortung · Vorschläge) · Auswahl-Panel (3d-24) · QS-Modal (3d-28) existieren schon. 4C = die eine echte Lücke füllen + Nav falten (kein Neubau): (a) Annahme-Einstieg aus dem Fluss — neuer „+ Neuer Auftrag — ein Satz genügt"-Button öffnet das geteilte 720px-Annahme-Overlay (AnnahmeOverlayComponent, bisher Lage-only) direkt im Fluss (orders.component.ts: Import +annahmeOffen-Signal + Button in der Segment-Leiste + Mount); (b)/occupancy(= Fluss·Karte) +/tafelvon der Lage in den Fluss-Ort verschoben —shell.component.tsorte-paths(fluss: +/occupancy+/tafel;lage: nur noch/overview+/annahme) und die „···"-Gruppen (Belegung/Tafel von Lage → Fluss) → der Fluss-Tab ist jetzt auf/occupancy//tafelaktiv. Entscheidung — bewusst NICHT gelöscht: die tiefen Workspaces conflicts (688-Zeilen-Hebel-Engine mit Konsequenz-Simulation + Bulk-Löser) · recommendations (Pain/Gain-Detail) · quality (voller QM-Screen: KPI/Queue/Checkliste/Ausgang) bleiben als Drill-downs hinter der Entscheiden-Triage bzw. dem QS-Modal — die Entscheiden-Karten routen dorthin (Triage-Fläche, kein Ersatz der Tiefe; der Prototyp hat diese Deep-Workspaces so nicht). Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Playwright, Hell + Dunkel: Fluss zeigt „+ Neuer Auftrag" [Fluss-Tab aktiv], Klick → Annahme-Overlay [Scrim + Satz-Input] öffnet,/occupancy→ Fluss-Tab aktiv, keine Page-Errors). Reiner Client (orders.component.ts+shell.component.ts), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod + doc-consistency--strictgrün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(4C ✅),design/WORKSPACES.md,docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. Offen: 4D Team-Seite · 4E Aufräumen (administration-3-Wege-Split + Chronik-Screen) → „IA-komplett". - Branch
claude/next-steps-8vmq5d(PR #728) — Phase 4B — CodeRabbit-Nachzug (APP_VERSION0.149.0 → 0.149.1, PATCH — Fix/Nacharbeit). 6 valide CodeRabbit-Findings zu #727 (kamen als der PR schon gemergt war → Follow-up-PR, frischer Branch vonmain). (1) A11y (verwaltung.component.ts):ariaCurrentWhenActive="page"am aktiven Sub-Tab-Link (Screen-Reader kündigt die aktive Route an). (2) Doku↔Code (Major,design/WORKSPACES.md): die stale Crystal-Bar-Region-Tabelle (Menü-Toggle · Rail-Cluster · Auf-Kurs-Ring · Live-Status-Fuß · Rail-Screenshots) war nach der Top-Bar-Umstellung (4A) noch als aktuell beschrieben → entfernt + durch eine knappe „Archiv (pre-Phase-4A, abgelöst)"-Notiz ersetzt (keine widersprüchliche Navigations-Spec mehr). (3) Label (shell.component.ts): „···"-Verwaltung-UntertitelStammdaten · Kosten · Chronik→Prozesse · Team · Stammdaten · Kosten · Chronik(die zwei zusätzlichen Editoren auffindbar). (4) True-North (Critical): die Verwaltung beantwortet die 3 Leitfragen nicht direkt — als PO-freigegebene Ausnahme dokumentiert (Navigations-/IA-Umstellung des PO-mandatierten Redesigns + Stammdaten steuern Taktung/Machbarkeit → indirekt Auslastung/Kapazität); bewusst kein True-North-Widget auf der Admin-Fläche (Einfachheit). Rationale im Component-Doc-Kommentar. (5/6) Doku-Feinschliff: FunktionsumfangChronik[folgt]→Chronik (folgt); Timesheet-Kernaussage4B–4E offen→4C–4E offen(4B ist ✅). Verifiziert: No-Hex +ng buildprod + doc-consistency--strictgrün. Reiner Client + Doku. Doku: CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #727) — Redesign „Flusslinie" Phase 4B: Verwaltung-Seite (Sub-Sidebar + nested Routing) (APP_VERSION0.148.0 → 0.149.0, MINOR — IA/Screen, OP-REDESIGN-1). Zweiter Schritt der Voll-IA (nach 4A Top-Bar): das „···"-Overflow bekommt eine echte Verwaltung-Heimat statt einer flachen Bereichsliste. NeueVerwaltungComponent(client/src/app/leitstand/pages/verwaltung.component.ts) = linke Sub-Tab-Sidebar + verschachteltes<router-outlet>— das erste nested Routing der App. Hostet die bestehenden Editoren unverändert (reuse): Leistungen & Abläufe (processes) · Team & Skills (staff) · Stammdaten & System (administration: Buchten/Schichten/Mandant, eine Scroll-Seite) · Kosten (costs) · Chronik = disabled „folgt" (Audit-Verlauf net-new, OP-AUDIT-1). Modernist: flach, 2px, radius 0, Ink-Selektion mit rotem Links-Rand am aktiven Sub-Tab. Routing:verwaltungvon Redirect → Component-Route mit Children (''→leistungen·leistungen/team/stammdaten/kostenlazyloadComponent); Alt-Deep-Links/administration→/verwaltung/stammdaten,/costs→/verwaltung/kosten(nichts verwaist). Shell-„···"-Menü: die Verwaltung-Gruppe (bisher Administration + Kosten einzeln) → ein Eintrag/verwaltung(declutter). Entscheidung (minimal + reuse): Phase 4B hostet die vorhandenen Editoren, ohne die 869-Zeilen-administrationin 3 Screens (Buchten&Hof · Schichten&Abwesenheiten · System) aufzuspalten und ohne den Chronik-Screen neu zu bauen — beides ist eigener Aufwand und bewusst als Nachzug (Phase 4E / OP-AUDIT-1) markiert (ehrlich, keine erfundene Fläche → „folgt"-Eintrag). Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Playwright, Hell + Dunkel:/verwaltung→/verwaltung/leistungen[Sub-Sidebar 5 Einträge, Leistungen&Abläufe aktiv/roter Links-Rand,processes-Editor im Outlet], Klick „Kosten"→/verwaltung/kosten[costsim Outlet, Aktiv-Wechsel], Sub-Header „Verwaltung", Top-Bar intakt, keine Page-Errors). Reiner Client (1 neue Komponente +app.routes.ts+ Shell-Menü-Eintrag), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod + doc-consistency--strictgrün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(4B ✅),design/WORKSPACES.md,docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. Offen: 4C Fluss konsolidieren · 4D Team · 4E Aufräumen (admin-Split + Chronik) → „IA-komplett". - Branch
claude/next-steps-8vmq5d(PR #726) — Redesign „Flusslinie" Phase 4A: Shell Rail → 62px-Top-Bar (APP_VERSION0.147.0 → 0.148.0, MINOR — Shell/IA-Umbau, OP-REDESIGN-1). Anlass + Korrektur: Der PO wies darauf hin, dass die Navigation im Flusslinie-Design eine Top-Bar ist, die App aber noch die alte linke Icon-Rail trug — mein früheres „OP-REDESIGN-1 UI-komplett" (#721) war auf der Shell-/IA-Dimension zu optimistisch (die 4 Orte existierten nur als Rail-Gruppen, nicht als Top-Bar). Prototyp-Analyse ergab: der Prototyp konsolidiert die 15 Workspaces in 4 Orte (Sub-Screens via Lanes/Modals/Drawer, keine Sub-Tab-Reihe) — Konflikt mit der bestehenden 15-Routen-Architektur → PO-Entscheidung: Voll-IA nach Prototyp, phasiert (ops/OP-REDESIGN-1.mdPhase 4). Diese PR = Phase 4A (Shell):shell.component.tslinke Icon-Rail → 62px-Top-Bar (2px-Divider, sticky): Logo · Lage·Fluss·Takt·Team-Tabs (roter 3px-Aktiv-Underline, Fluss-Count-Badge = offene „Entscheiden"-Punkte) · „···"-Overflow (alle Bereiche gruppiert + Einstellungen [Ansicht/Feedback/Alarm-Ton] + Status [Auf-Kurs/Foto-Queue]) · True-North-Strip · Leitstand|Werkstatt-Segment (= Werker-Modus) · Uhr+Live-Punkt; darunter ein schlanker Workspace-Sub-Header (Titel + „?"). Alle 15 Screens bleiben erreichbar (Tabs → Ort-Hauptfläche, Rest über „···"/Deep-Link) — Übergang bis 4B–4D. Rail-Code (.railwrap/Proximity-Reveal/☰-Touch-Toggle/expanded/ring/sweepKey) entfernt; die Foto-Queue-Detailliste + alle Toggles ins „···" verlagert (kein Funktionsverlust). Entscheidung: Phase 4A ist bewusst reiner Shell-/Nav-Umbau (keine Screen-Änderung), damit die Top-Bar sofort steht und nichts unerreichbar wird; die Ort-Konsolidierung folgt in 4B (Verwaltung-Seite) · 4C (Fluss) · 4D (Team) · 4E (Aufräumen + „IA-komplett"). Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Playwright, Hell + Dunkel: 62px-Bar, 4 Tabs [Lage aktiv/Underline, Fluss-Badge 63], „···"-Menü listet alle Bereiche + Einstellungen, Leitstand|Werkstatt-Segment, TN-Strip, keine Rail mehr, keine Page-Errors). Reiner Client (shell.component.tsneu strukturiert), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(Phase 4 + „UI-komplett"-Korrektur),design/CLAUDE.md,design/WORKSPACES.md(Top-Bar-Sektion löst Crystal-Bar ab),docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #725) — Verbindungs-Wiederherstellung + Auto-Update (Offline-PWA) (APP_VERSION0.146.1 → 0.147.0, MINOR — neue Funktion, OP-OFFLINE-1). Schließt eine echte Betriebslücke: Weil der PWA-Service-Worker die App-Shell cached (navigationUrls: "/**"), lädt ein normaler Reload Dokument+JS aus dem Cache und geht nicht zum Server — er kann darum eine abgelaufene Cloudflare-Access-Session (die App ist per Golden Rule „Zero Trust vor Public" Access-gated; nach ~24 h WS-Upgrade 401) oder einen frisch deployten Client nicht einspielen; der WebSocket bleibt hängen, und der Offline-Cache verdeckt die Access-Anmelde-Umleitung (genau das Symptom „Reload verbindet nicht neu"). NeuerVerbindungService(client/src/app/services/verbindung.service.ts,providedIn:'root') + Shell-Wiring: (1) das Offline-Banner bekommt „↻ Erneut verbinden" →hartNeuLaden()= SW-umgehender Neustart (SW deregistrieren + reload) → Dokument frisch vom Server → Access-Re-Login / neuer Client → WS verbindet (der SW re-registriert sich beim nächsten erfolgreichen Laden, Offline-Fähigkeit kehrt zurück); nur bei vorhandenem Netz (navigator.onLine) — sonst ehrlicher Toast „kein Netz" (PartySocket reconnectet bei echtem Offline ohnehin automatisch, kein Cache-Nuke ohne Nutzen). (2)SwUpdate-Auto-Update: bei Netz-Rückkehr (online) / Tab-Fokus (visibilitychange)checkForUpdate(); beiVERSION_READYerscheint das Banner „Neue Version — neu laden" (activateUpdate()+ reload) → der Stale-Client-Fall ist proaktiv behoben (bisher aktivierte der SW eine neue Version erst nach Schließen aller Tabs). Entscheidung:hartNeuLadenderegistriert bewusst den SW (bulletproof gegen jede Cache-/Auth-Klemme) statt auf einen Cache-Bust-Query zu setzen; nur netz-gated, damit der Offline-Cache bei echtem Ausfall erhalten bleibt. Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Playwright, Hell: WS-Abriss → Offline-Banner mit „↻ Erneut verbinden"-Button, keine Page-Errors; das Neue-Version-Banner + der Reload-Pfad sindSwUpdate/unregister-Standard, tsc/build-verifiziert). Reiner Client (1 neue Service-Datei + Shell: Import/Inject/Handler + 2 Banner-Blöcke), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün + Live-Screenshot. Doku:ops/OP-OFFLINE-1.md,docs/architektur/Offline-PWA.md,docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #723) — Metrik-Persistenz — CodeRabbit-Nachzug zu #722 (APP_VERSION0.146.0 → 0.146.1, PATCH — Fix/Nacharbeit). Nachzug der 6 validen CodeRabbit-Findings zu #722 (kamen als der PR schon gemergt war → als Follow-up-PR, frischer Branch vonmain). (1) Fix (Major, Correctness): die Review-Trend-Fensterlogik inlage-review.component.ts— (a)tagVor()bildete die Fenster-Grenze in der Runtime-Zeitzone, während der Server dietag-Buckets in Europe/Berlin schreibt → das Fenster konnte um einen Tag verrutschen; jetzt formatiert der Client die Grenze ebenfalls Europe/Berlin (deckungsgleich zulokalerTag). (b)trendReihenbaute die Punkte nur aus vorhandenen Zeilen — ein Tag ohne Snapshot fiel weg, statt als null-Lücke gerendert zu werden (Widerspruch zum eigenen Doc-Kommentar). Jetzt: explizite Kalendertag-Liste übers Fenster + Nachschlagen je Tag → fehlende Tage = leerer Balken (ehrlich, keine erfundenen Zahlen). (2) Perf (leitstand.ts):metrikVerlaufDTO()lief je Broadcast (inkl. 30-s-Solver-Ping) neu gegen die DO-SQLite, obwohl die Zeilen sich max. 1×/Tag ändern → Tages-Cache (metrikVerlaufCache, Muster wiekapazitaetCache), invalidiert beim Schreiben eines neuen Snapshots. (3–6) Doku/Metadaten: #722-Einträge in CHANGELOG + Timesheet als klickbare PR-Links (Audit-Regel);ops/OP-COST-1.mdfrontmatterbezug+= OP-DATA-1;docs/architektur/Persistenz.mdPilot-Status synchronisiert — D5-3 „angelaufen" (diemetrik_snapshots-Tabelle validiert die DO-SQLite-Mechanik live, Pilot-Kern = Migration einer bestehenden State-Klasse bleibt offen), Ist-Zustand-Stand 0.16.0 → 0.146.0. Bewusst nicht: kein neuer Selbsttest (Nachzug ohne neue Prüf-Oberfläche). Verifiziert: No-Hex +tsc(Server) +ng buildprod + Persistenz-Gate + No-Console + doc-consistency--strictgrün. Doku: CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #722) — Metrik-Persistenz: Review-Trend-KPIs (Auslastung · First-Pass-Yield · Nacharbeitsquote) (APP_VERSION0.145.0 → 0.146.0, MINOR — neues Feature). Schaltet die bisher deferred Trend-Kennzahlen der Review-Sicht (3d-26 hatte dort eine ehrliche Hinweis-Karte, keine Fake-Zahlen) frei — mit echter Verlaufs-Persistenz statt Live-Snapshot. Speicher-Entscheidung (PO): direkt DO-SQLite (die lautPersistenz.md§3 entschiedene Langzeit-Heimat für Snapshots), nicht der interim Blob — erste DO-SQLite-Runtime-Tabelle des Repos:metrik_snapshots(tenant-lokal,ctx.storage.sql). Drizzle-Schemaserver/src/db/schema.ts= Single Source (imdb:check-Gate, generierte Migrationdrizzle/0001_*.sql); Runtime-AnlageCREATE TABLE IF NOT EXISTSinonStart(idempotent, analog zum Audit-Pfad — Drizzle bleibt Schema-Beweis, Runtime roh). Producer: ein Tages-Snapshot je Tag (Europe/Berlin, guarded per In-Memory-Merker + PK-Idempotenz, kein Alarm) bei Boot + erster Persistenz des Tages; nur Fakten (die gemessene Quote), Prozent = NULL wenn keine Basis (ehrliche Lücke, keine erfundene 0 — D-2). Metrik-Umfang (PO): die 3 heute ableitbaren — Auslastung (zeitbasierte Buchten-Quote,auslastungsQuote-Block in eine geteilte Methode extrahiert, von Broadcast + Producer genutzt) · First-Pass-Yield + Nacharbeitsquote (server-seitig aus den fertigen Aufträgen = SoT;quality.componentzeigt sie live). Broadcast trägtmetrikVerlauf(jüngste 90 Tage), Retention 400 Tage; der Client rendert je KPI eine Sparkline über Woche/Monat (lage-review.component.tsersetzt die Hinweis-Karte, honester Leer-/Ein-Tag-Zustand). Best-effort — die Erfassung bricht den Laufzeitpfad nie. Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Demo-Seed + Playwright, Hell + Dunkel: DO legt die Tabelle an + schreibt beim Boot den Tages-Snapshot [Auslastung 1 % · FPY 33 % · Nacharbeit 67 % aus dem Seed], Broadcast liefertmetrikVerlauf, Review-Sicht zeigt „1 Tag erfasst" + die 3 KPIs mit Sparkline + ehrlichem Hinweis). Client + Server + DO-SQLite (Schema/Migration, DO-Producer/Reader, LeitstandState-DTO beidseitig, Service-Selektor, Consumer). Verifiziert: No-Hex +tsc(Server) +ng buildprod + Persistenz-Gate (Drizzle-Schema↔Migration sync,db:generateidempotent) + No-Console grün. Entscheidung — bewusst kein neuer OP: getrackt unter den Owning-OPs OP-AUDIT-1/OP-COST-1 (dort war die Persistenz-Voraussetzung notiert). Offen (nachgelagert): Termintreue + Ø Durchlaufzeit (brauchen abgeleitete Auftrags-Historie Fertigstellung vs. Plan). Doku:ops/OP-COST-1.md(Slice-Eintrag),docs/architektur/Persistenz.md(Ist-Zustand-Tabelle: erste DO-SQLite-Runtime-Tabelle),docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #721) — Redesign „Flusslinie/Modernist" 3d-28: Quality-Check-Modal — OP-REDESIGN-1 UI-komplett (APP_VERSION0.144.1 → 0.145.0, MINOR — net-new Layout-Feature + Redesign-Abschluss). Der letzte Redesign-Baustein: die Endkontrolle in-context als 720px-Modernist-Modal (neuerclient/src/app/leitstand/qs-modal.component.ts), geöffnet aus dem Fluss-Auswahl-Panel über einen „✓ Quality-Check"-Button, der erscheint, sobald das Fahrzeug in der QS-Queue steht (imQs). Reiner View über den geteiltenQsChecklisteService(3d-27): dieselbe Sichtprüfungs-Checkliste (✓/✕) und dasselbe server-harte QS-Gate (offenePunkte/abnahmebereit— in diesem Slice ebenfalls in den Service hochgezogen + im Workspace delegiert) wie der volle Qualität-Workspace → kein Duplikat-State, ein Prüf-Stand. Inhalt: Prozess-Vollständigkeit (Gate-Blocker), Sichtprüfung (4 Punkte), Freigabe-Gate „✓ Freigeben" (server-bestätigt viasvc.auftragAktion 'abholen', gated auf allePass + abnahmebereit +erlaubteAktionen) · „→ Volle Endkontrolle" (Mängel/Nacharbeit-Erfassung bleibt der vollen Fläche). Entscheidung (PO-Freigabe Option A, zweistufig): erst der verhaltensgleiche State-Refactor (3d-27, sicherheitskritischer Vier-Augen-Gate G-4 isoliert), dann das Modal darauf. Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Demo-Seed + Playwright, Hell + Dunkel: Modal öffnet, Prozess-Vollständigkeit listet die echten offenen Punkte, Checkliste ✓/✕ toggelt über den Service, Freigeben korrekt disabled; scharfe Kanten/2px/radius 0). Weil der Demo-Seed kein Fahrzeug in der QS-Queue hält, wurde das Modal zur Screenshot-Verifikation über zwei temporäre Gate-Lockerungen sichtbar gemacht und danach wieder zurückgesetzt (committeter Code: Button/Modal anqmAuftraegegebunden). Damit ist OP-REDESIGN-1 UI-komplett (alle Phasen Token→Shell/IA→Screens→Farbsystem→Ink-Gantt→Layout-Features 3d-20…3d-28 gebaut+gemergt); nachgelagert bleiben nur die Review-Trend-KPIs nach der Metrik-Persistenz (OP-AUDIT-1/OP-COST-1). Reiner Client (1 neue Datei +QsChecklisteService-Erweiterung um die Gate-Funktionen + orders-Wiring), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(3d-28 ✅, UI-komplett),design/WORKSPACES.md,docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #720) — Redesign „Flusslinie/Modernist" 3d-27: QS-Checklisten-State in Service hochgezogen (Fundament fürs QS-Modal) (APP_VERSION0.144.0 → 0.144.1, PATCH — verhaltensgleicher Refactor). Der Refactor-Schritt vor dem QS-Modal (PO-Freigabe Option A: State hochziehen statt duplizieren). Der client-ephemere Sichtprüfungs-Scratchpad der Endkontrolle (✓/✕ je Prüfpunkt, keyed per QS-Rundeid:runde, startet nach jeder Nacharbeit frisch) lag component-lokal inquality.component.ts→ in den neuenQsChecklisteService(client/src/app/services/qs-checkliste.service.ts,providedIn:'root') hochgezogen:checkState-Signal +state/setzePruef/markiereBehoben/reset/allePass/anyFail+ckey+ die exportiertenQS_CHECKS/Pruef.quality.component.tsdelegiert jetzt an den Service — identische Methoden-Signaturen → kein Template-Change, kein Verhaltens-Change; das server-harte QS-Gate (Prozess-Vollständigkeit/Mängel aus demAuftragDTO) bleibt getrennt und unangetastet. Entscheidung: bewusst als eigener, isolierter Slice vor dem Modal, weil der QS-Screen den sicherheitskritischen Vier-Augen-Freigabe-Gate (G-4) trägt — so ist der riskante Umbau isoliert verifizierbar. Zweck: Workspace und das künftige QS-Modal teilen denselben Prüf-Stand (eine Wahrheit, keine Duplikat-Logik). Der Scratchpad bleibt bewusst client-ephemer (pre-Freigabe-Arbeitsstand, kein Server-Persist). Verifiziert: No-Hex +tsc+ng buildprod grün + Live-DO-Render-Smoke (Qualität-Workspace rendert fehlerfrei über den Service; KPIs/Empty-States korrekt). Der ✓/✕-Interaktions-Pfad ist byte-gleiche Delegation — ein QS-Auftrag zum Anklicken stellt der Demo-Seed nicht her (alle Autos am Annahme-Start), daher tsc/build/Render-verifiziert. Reiner Client (1 neue Service-Datei + quality-Delegation), kein Server/DTO/Schema. CodeRabbit-Nachzug (in diesem PR):state()gibt eine Defensiv-Kopie zurück (keine externe Mutation des Signal-Arrays); neueentruempelt-Prune bindet dieid:runde-Keys an die lebende QS-Queue (derroot-Service akkumulierte sonst über die SPA-Lebensdauer). Selber PR (#720) trägt zusätzlich die Timesheet-Management-Summary (Gesamt-Stand) + Wochen-Rollup KW27–30 (Doku-Pflege, s.docs/betrieb/Timesheet.md-Kopf) — Doku + Refactor waren auf einem Branch gestapelt und werden bewusst als ein PR gemergt. Doku:ops/OP-REDESIGN-1.md(3d-27 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #718) — Redesign „Flusslinie/Modernist" 3d-26: Lage · Review-Sicht (Woche/Monat) (APP_VERSION0.143.1 → 0.144.0, MINOR — net-new Layout-Feature). Die Lage bekommt einen Heute/Woche/Monat-Umschalter (DD: „Review als eigener Zustand von Lage, kein eigener Workspace"): Heute = der operative Loop (3-TN-Karten · Heute-Streifen · Hof-Radar, unverändert), Woche/Monat = ein Rückblick (neuerlage-review.component.ts, inoverview.component.tsgemountet). Entscheidung (PO-Freigabe „ehrlicher Client-Teil"): der Review zeigt nur echt aus dem Live-Stand ableitbare Daten — Team-Entwicklung (laufende Ausbildungsziele je Mitarbeiter, Skill aktuell★→ziel★ mit Fortschrittsbalken · Beförderungen im Zeitfenster ausEmployee.befoerderungen[].ts, echte Historie · XP) und Klärfall-Ursachen (aktuell offene Klärfälle nach Grund gruppiert, Live-Snapshot, Notfall rot). Die Trend-Kennzahlen des Prototyps (Termintreue · Ø Durchlaufzeit · Auslastungs-Verlauf) brauchen persistierte Verlaufsdaten, die der Live-Stand (nur der aktuelle Zustand, „Derived State nie speichern") nicht vorhält → ehrliche Hinweis-Karte statt erfundener Zahlen (Prototype-Fixtures werden nie gebunden,design/CLAUDE.md); sie folgen mit der Metrik-Persistenz (OP-AUDIT-1/OP-COST-1). Fenster: Woche = letzte 7 Tage, Monat = letzte 30 Tage (Beförderungs-Historie). Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Demo-Seed + Playwright, Hell + Dunkel: Umschalter · „Rückblick — die Woche/der Monat" · Team-Entwicklung mit echten Ausbildungszielen · Klärfall-Ursachen · ehrliche Trend-Hinweis-Karte; Heute-Rückkehr stellt den operativen Loop wieder her). Reiner Client (1 neue Dateilage-review.component.ts+ overview-Wiring: Import, Toggle, Mount,lageSicht/reviewSicht-Signale), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(3d-26 ✅),design/WORKSPACES.md,docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #717) — Redesign „Flusslinie/Modernist" 3d-25: Warn-Entkopplung screen-by-screen (APP_VERSION0.143.0 → 0.143.1, PATCH — Fix/Accessibility). Weil Rot in Taktano jetzt Primär- und Warnfarbe ist (DD-003), dürfen Warnungen nicht rein farblich kodiert sein. Nach einem vollständigen Audit aller Page- + geteilten Komponenten (Kategorie A „schon entkoppelt" [Glyph/Problemwort/role=alert/Blink] vs. B „nur Farbe") die echt farb-nur Warnungen mit persistentem Nicht-Farb-Signal versehen (⚠-Glyph + Problemwort/title): (B1) Fluss-Kanban „spät" — der pulsierende rote Punkt war unterprefers-reduced-motionunsichtbar (→ farb-nur) → persistentes „⚠ spät" (orders.component.ts); (B2) WIP-Limit-Zähler → „⚠" vorN/4 WIPbei Erreichen/Überschreiten; (B5) „Entscheiden"-Stapel-Badge → „⚠" vor der Zahl wenn Danger enthalten (entscheiden.component.ts); (B6) überbelegter Platz → persistenter „⚠ überbelegt"-Chip (occupancy.component.ts) + „⚠"-Präfix amN/Kap-Wert im Umpark-Ziel-Picker (repark-modal.component.ts); (Obs) OTLP „Letzter Export" fehlgeschlagen → „⚠" am Wert (costs.component.ts). Entscheidung — bewusst NICHT geändert: die roten Zähl-Badges an Nav/Tabs (Fluss&Risiko, Konflikte&Klärfälle, Risiko-Tab, Klärfälle=Amber) — ein Benachrichtigungs-Badge mit Zahl in der Alarm-Position neben einem Domänen-Wort („Risiko"/„Konflikte"/„Klärfälle") ist selbst schon ein Nicht-Farb-Signal; ein ⚠ im 15-px-Kreis wäre Dekor-Clutter (Leitprinzip Einfachheit, „nichts dekorativ"). Live-DO-verifiziert (wrangler dev --local+ gebauter Client + Demo-Seed + Playwright, Hell + Dunkel: „⚠ spät" auf den Fluss-Karten [4×] + „⚠"-Entscheiden-Badge in beiden Themes; B2/B6 stellt der Demo-Seed nicht her → tsc/build-verifiziert). Reiner Client (5 Dateien, nur Template-Signale), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(3d-25 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #715) — Neuer offener Punkt OP-AI-6: Struktur-Vorlagen je Textfeld (Stammdaten) → KI-Neuformulierung (keinAPP_VERSION-Bump — reine OP-Erfassung). PO-Vorgabe (25.07.): für jedes freie Textfeld eine typische Struktur/Vorlage in den Stammdaten hinterlegbar (admin-editierbar, G-1); die In-App-KI (OP-AI-4) nutzt sie beim Neu-Formulieren der Eingabe → betriebsweit einheitliche Strukturen. Abgegrenzt zu OP-TEXTBLOCK-1 (Antipp-Bausteine = einfügen; OP-AI-6 = KI formt Freitext in die Ziel-Struktur). Alsops/OP-AI-6.mderfasst (pyramidal, Bausteine/offene Entscheidungen/Empfehlung „kleinste Stufe zuerst über OP-AI-4"), Bezug OP-TEXTBLOCK-1/OP-AI-3/OP-AI-4/OP-SEED-1/G-1;drkv_standard: kandidat— beim nächsten Template-Sync in den drkv-Standard (everything-as-code-template, G-2) übernehmen (In-App-Assistent + Stammdaten sind bereits Standard-Bausteine; Template-Repo außerhalb der Session-Scope → hier nur markiert).docs/betrieb/Offene-Punkte.mdneu generiert (189 → 190 OPs). Docs-only, kein Code/DTO/Schema. Doku:ops/OP-AI-6.md,docs/betrieb/Offene-Punkte.md, CHANGELOG. - Branch
claude/next-steps-8vmq5d(PR #714) — Redesign „Flusslinie/Modernist" 3d-24: Fluss inline-Auswahl-Panel (APP_VERSION0.142.1 → 0.143.0, MINOR — net-new Layout-Feature). Das volle-Breite-Auswahl-Panel unter dem Fluss-Board (orders.component.ts) auf die Modernist-Flusslinie-Sprache gebracht (DD-002/DD-008): die runde Punkt-/Cyan-Puls-Phasen-Leiste ersetzt durch den 5-Stationen-Strip (Annahme · Vorbereitung · Produktion · Quality-Check · Abholung als Position auf der Flusslinie: 9×9-Quadrat je Station — vorbei = Tinte-gefüllt + Tinte-Konnektor · aktuell = Akzent--tk-brand· kommend = leer +--tk-text-faint, uppercase-Label, 2px-Konnektor), konsistent mit dem Akten-Cockpit-Drawer (3d-22). Neuer „Alle Details →"-Knopf in der Aktionszeile öffnet den geteilten Akten-Cockpit-Drawer (620px, 3d-22) ohne konkreten Teilschritt-Fokus — neuesdetailOffen-Signal, der Drawer-Mount honoriertpanelInstanzId() || detailOffen(), der Close räumt beide. Neuer Helferstufen(a)(Position je Station aus dem bestehendenstage(a)). Die klickbare 🚗-Fortschritts-Kette (FortschrittsIndikator, Teilschritt-Sprung ins Fly-in) bleibt daneben erhalten. Entscheidung: die Phasen-Leiste auf die Stationen-Position-Sprache angleichen und einen direkten Drawer-Einstieg schaffen — kein Refactor des funktional reichen Panels (alle Aktionen, Ausbildung/Helfer bleiben). Live-DO-verifiziert am laufenden Stack (wrangler dev --local+ gebauter Client + Demo-Seed + Playwright, Hell + Dunkel: quadratischer Stationen-Strip mit rotem „Annahme"-Aktuell + leeren Folge-Quadraten; „Alle Details →" öffnet den 620px-Akten-Cockpit-Drawer korrekt in beiden Themes). Reiner Client (1 Datei), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(3d-24 ✅),docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet.
2026-07-24
- Branch
claude/next-steps-8vmq5d(PR #713) — Annahme-Overlay 3d-23a: CodeRabbit-Review-Nachzug (Timer-Cleanup · Autofokus · toter Import · Motion-Token) (APP_VERSION0.142.0 → 0.142.1, PATCH — Fix). Nacharbeit der validen CodeRabbit-Findings zu #712 (kamen als das PR schon per Auto-Merge durch war), amannahme-overlay.component.ts: (1) Ressourcen-Cleanup (repo-Standard „Timer aufräumen") — der entprellte Dry-Run-Timer wird jetzt auch beim Nicht-mehr-bereit abgebrochen (sonst feuerte eine stalepruefeAuftragnach, wenn der Satz wieder unvollständig wurde) und viaDestroyRef.onDestroybeim Schließen des Overlays; (2) Autofokus — beim Öffnen springt der Cursor perviewChild+afterNextRenderdirekt in den Satz-Input (Touch-/Tastatur-Ergonomie); (3) toter Code — ungenutzterTERMINKLASSE_LABEL-Import +TK-Groundwork-Feld entfernt; (4) Motion-Token — die hartkodierten.18s/.25s-Animationsdauern →var(--tk-dur-fast)/var(--tk-dur-card)(client/CLAUDE.md: Motion-Dauern aus--tk-*). Bewusst nicht geändert (mit Begründung): der „#711-Bullet wiederherstellen"-Hinweis war ein False-Positive (der Eintrag ist vorhanden, #712 wurde darüber eingefügt — append-only intakt); die Zeitzonen-„Vereinheitlichung" nutzt dieselben geteilten Time-Helper wie die bestehende/annahme-Fläche (pre-existing, kein Slice-Scope); der OpenGrep-child_process.exec-Fund ist ein False-Positive (die Komponente hat keinchild_process). Reiner Client (1 Datei), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün. Doku: CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #712) — Redesign „Flusslinie/Modernist" 3d-23: Annahme-Overlay „ein Satz genügt" (APP_VERSION0.141.0 → 0.142.0, MINOR — net-new Layout-Feature). Der Schnell-Intake als 720px-Modernist-Modal direkt aus der Lage (DD-001): neuerannahme-overlay.component.ts+ Primärbutton „+ Neuer Auftrag — ein Satz genügt" aufoverview.component.ts. Satz → 3 Pflicht-Tags (Kunde · Leistung · Abholung; erkannt = Ink-gefüllt, fehlend = Outline) via geteilte HeuristikparseAnnahmeSatz→ echter Server-Dry-Run (svc.pruefeAuftrag→auftragPruefResult, seq-gated damit nur die eigene Anfrage angezeigt wird): Machbarkeit · Slot · Reserve · Preis → ✓ Annehmen (svc.createAuftrag); Fehlerfall ohne Sackgasse mit zwei Auswegen (→ Alternativ-Anlieferung übernehmen · ⚠ Trotzdem annehmen — wird Klärfall); Erfolg „AU-nnn ist im Takt" + „Auf dem Radar zeigen →" + „Nächster Satz". Entscheidung: ein reiner View über die geteilte Intake-Logik (Parse-Util + Service-Methoden) — keine Duplikation der Fachlogik und kein Refactor der bestehenden/annahme-Vollfläche (bleibt inkl. „🚗 Fahrzeug da"-Tab erreichbar); die IA-Richtung (Annahme = Overlay aus der Lage, nicht eigener Ort — DD-001) wird additiv umgesetzt, die alte Route als Fallback/Deep-Link behalten. Modernist: radius 0 (Modal-scoped-Regel), 2px-Kante, 720px zentriert, Ink-Tags, rote Primär-Aktion,tk-rise-Einblendung, Esc/Scrim/×-Schließen. Live-DO-verifiziert am laufenden Stack (wrangler dev --local+ gebauter Client + Playwright, Hell + Dunkel: „▶ Beispiel einsetzen" → Tags Kaya GmbH / Vollfolierung Premium / Fr 31.07. → Machbarkeits-Panel „✓ passt in den Takt · Slot Mo 27.07. 08:00 · Waschplatz 1 · +3 T Reserve · 3.200 € · ✓ Annehmen"). Reiner Client (1 neue Dateiannahme-overlay.component.ts+ overview-Wiring: Import, Button, Mount, Signal), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(3d-23 ✅),design/WORKSPACES.md(§0 Annahme),docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #711) — Redesign „Flusslinie/Modernist" 3d-22: Auftrag-Detail „Akten-Cockpit" (620px-Drawer) + Design-Handoff-Import (APP_VERSION0.140.0 → 0.141.0, MINOR — net-new Layout-Feature + Doku-Import). Umsetzung des Auftrag-Detail-Drawers aus dem Claude-Design-Handoff „Flusslinie" (Screenshot 09, „Akten-Cockpit"): der geteilteauftrag-detail-panel.component.tsauf die Modernist-Sprache gebracht — Breite 420 → 620px (min(calc(100vw-48px),620px)), 2px-Tinte-Kante links, radius 0 durchgehend (Drawer-scoped-CSS-Regel[class*="rounded"]{border-radius:0}neutralisiert die hartkodierten Tailwind-rounded-*); die 🚗-Fortschritts-Kette ersetzt durch den 5-Stationen-Strip (Annahme · Vorbereitung · Produktion · Quality-Check · Abholung als Position auf der Flusslinie, DD-002/DD-008: 9×9-Quadrat je Station — vorbei = Tinte-gefüllt + Tinte-Konnektor · aktuell = Akzent--tk-brand· kommend = leer +--tk-text-faint); die runden farbigen Teilschritt-Status-Chips ersetzt durch Lifecycle-Marken als Form (10×10, 2px Kontur, DD-003: ■ läuft/erledigt · ◪ pausiert · □ wartet). Neue Helferstationen/stgIndex/markeBg/markeBorder/markeTitle;FortschrittsIndikatorComponent-Import entfernt. Alle Funktionen erhalten (Kunde/Fahrzeug-Nachtrag, Foto-Doku, Doku-Gate, Vier-Augen-Freigabe, Klärfall/Notfall/Verzögerung/Notiz, Aktions-Hub, Verlauf) — reine visuelle Modernist-Angleichung, keine Feature-Reduktion. Entscheidung: die reiche bestehende Funktionalität behalten und nur die Design-Sprache (Form statt Farbe, Phase = Position, radius 0, 620px) angleichen — der Prototyp ist ein vereinfachter Mock, die App bleibt funktional reicher. Live-DO-verifiziert am laufenden Stack (wrangler dev --local+ gebauter Client + injizierter Auftrag via WS + Playwright, Hell + Dunkel: 5-Stationen-Strip mit rotem „Annahme"-Aktuell, quadratische Marken, scharfe Kanten, 620px, alle Panels theme-aware). Doku-Import in diesem PR: (1) der Design-Decision-Log (DD-001…008, ADR-Stil) →docs/produkt/Design-Entscheidungen.md(Frontmatter/Landkarte/Footer nach Repo-Konvention, ausdocs/README.mdverlinkt; das WARUM hinter dem Redesign — Vier-Orte-IA, Flusslinie, Form-statt-Farbe, Achsentrennung, Modernist); (2) der Flusslinie-Prototyp (.dc.html+Taktano Wording.md+ 22 Screenshots) →design/prototype/flusslinie/als neue visuelle Referenz (neben v3), referenziert ausdesign/CLAUDE.md. Reiner Client (1 Datei) + Doku/Referenz-Import, kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(3d-22 ✅),design/COMPONENTS.md(Akten-Cockpit-Rezept),design/CLAUDE.md,docs/produkt/Design-Entscheidungen.md,docs/README.md,docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #710) — Redesign „Flusslinie/Modernist" 3d-21: Lage · „Heute kommt/geht"-Streifen (APP_VERSION0.139.0 → 0.140.0, MINOR — net-new Layout-Feature). Zweiter net-new Layout-Schnitt (Live-DO): unter den 3-TN-Karten auf der Lage-Landing (overview.component.ts) ein zweispaltiger Tages-Digest — ↓ Kommt heute (Anlieferungen:status==='geplant'·bringterminim Heute-Fenster ·tatsaechlicheAnlieferung==null) · ↑ Geht heute (Abholungen:abholterminim Heute-Fenster); je Zeile Uhrzeit · AU-Nr · Kunde, Klick fokussiert das Fahrzeug im Radar (fokusAuf); ⚠ spät (rot, Termin-Achse) markiert Abholungen, derengeplanteFertigstellung > abholtermin. Max 5/Spalte („+N weitere"), Leer-Zustände („Keine Anlieferung/Abholung heute"). Neue HelferkommtHeute/gehtHeute/heuteFenster/istSpaet/fmtT— rein aus dem Live-State abgeleitet, kein neuer State. Entscheidung: der Tages-Digest ergänzt die statischen TN-Karten um die zeitliche „was bewegt sich heute?"-Sicht (True-North Q2/Q3) direkt auf der Landing; „⚠ spät" nutzt die bestehende Konflikt-Prädikate-Logik (konsistent mit „Braucht dich"/Konflikte). Live-DO-verifiziert am laufenden Stack (wrangler dev --local+ gebauter Client + 2 via WebSocket injizierte Heute-Aufträge + Playwright, Hell + Dunkel: Kommt 2 [16:00 Berger · 17:30 Sahin] · Geht 2 [beide ⚠ spät] — die spät-Aufträge erscheinen konsistent auch in „Braucht dich"). Reiner Client (1 Datei), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün + Live-Screenshots. Mit-Fix (2 CodeRabbit-Nits aus #709):design/WORKSPACES.mdquoteFarbe-Schwellen60–<90 %/≥90 %(Off-by-boundary: bei genau 90 % ist es amber) ·docs/betrieb/Funktionsumfang.mdVersion0.139→0.139.0. Doku:ops/OP-REDESIGN-1.md(3d-21 ✅),design/WORKSPACES.md(§1),docs/betrieb/Funktionsumfang.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #709) — Redesign „Flusslinie/Modernist" 3d-20: Lage · 3-True-North-Karten-Reihe (APP_VERSION0.138.0 → 0.139.0, MINOR — net-new Layout-Feature). Der erste net-new Layout-Schnitt aus dem OP-REDESIGN-1-Rest (Live-DO): die Lage-Landing (overview.component.ts) führt jetzt oben über Board+Sidebar mit drei flachen Antwort-Karten (answer-first/Minto) für die drei Leitfragen — Frage 1 Auslastung (Engpass-Quote = die engere von Mitarbeiter/Buchten, Farbe viaquoteFarbe: <60 % dim · 60–90 %--tk-brand· >90 %--tk-amber) · Frage 2 Fahrzeuge (aktive Aufträge; „✓ alle verortet" grün bzw. „⚠ N ohne Standort →" amber mit Link zu Konflikte) · Frage 3 Nächste Kapazität (früheste machbare Leistung „ab" + Name). Zwei neue Helfer-Computeds tnAuslastung/tnKapNext, Frage 2 ausaktiveAuftraege/ohneStandortCount— rein aus den Live-Insights abgeleitet, kein neuer State; die bestehenden detaillierten Sidebar-Panels (Auslastungs-Quote, Nächste freie Kapazität, Standorte, …) bleiben als Drill-down. Entscheidung: die Lage-Landing soll answer-first mit den drei Leitfragen führen (True-North direkt/schneller ablesbar) statt erst mit dem Radar-Board; Redundanz zum Header-True-North-Strip (3d-19/Phase 2b) ist gewollt — die Karten sind der prominente Landing-Anker, der Strip der ständig sichtbare Kopf. Live-DO-verifiziert am laufenden Stack (wrangler dev --local+ gebauter Client + Demo-Seed + Playwright, Hell + Dunkel: Q1 1 % · Q2 5 ✓ verortet · Q3 „ab heute 14:42 · Vollfolierung Premium inkl. Keramik"). Reiner Client (1 Datei), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün + Live-Screenshots. Doku:ops/OP-REDESIGN-1.md(3d-20 ✅),design/WORKSPACES.md(§1 Überblick), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #706) — Redesign „Flusslinie/Modernist" 3d-19: Design-Doku Prosa-Modernisierung (WORKSPACES/COMPONENTS ↔ Code) (keinAPP_VERSION-Bump — reine Doku im selben PR wie 3d-18). Die Design-Doku trug noch die v3-Prototyp-Ära-Sprache, die der Code seit 3d-1..3d-18 nicht mehr abbildet — aktive Doku↔Code-Widersprüche (OP-DOCS-9, goldene Regel „every feature ships with its docs"). Bereinigt indesign/WORKSPACES.md+design/COMPONENTS.md(+design/CLAUDE.md/ops/OP-REDESIGN-1.mdPhasen-Stand): JETZT-Linie „cyan, Glow" → rot (--tk-brand, 3d-1); Selektion (Kachel-Border · geklickter Schritt „ringed cyan" · Drop-Ziel „glow cyan" · Drag-Ghost · Standort-Wert · Master-Detail-Aktivzeile) → Ink (--tk-text, 3d-8/3d-9/3d-13); die 12 Workspace-Signaturfarben (— #hex-Suffix je Screen-Überschrift, Nav-„signature color glow bar", Header-Dot, Empty-State-Glyph, Segmented-Control-Hex) → entfernt/Ink (3d-14/3d-15); Glass/Glow/radius-hero/Gradient-CTA → flach, radius 0, Rot-CTA (Phase 1); Konflikte/Klärfälle-Rohhex →--tk-red/--tk-amber-Token; das Ink-Gantt-Block-Encoding (Outline=geplant · gefüllt=läuft/erledigt · grau=pausiert) im Gantt-Rezept ergänzt (3d-18). Bewusst behalten:.tk-pchip-Cyan-Puls (reserviertes Live-/Präsenz-Signal, 3d-11) + funktionale Status-/Gantt-Hues (Farbe = Information). Entscheidung: nur hoch-sichere, in OP-REDESIGN-1 dokumentierte Korrekturen; nicht statisch verifizierbare Farbdetails (Szenario-Profil-Hues, Annahme-Parse-Chips) bewusst unangetastet (kein neuer Widerspruch). Reine Doku (2 Design-Docs + 2 Status-Docs), kein Code/DTO/Schema. Doku:ops/OP-REDESIGN-1.md(3d-19 ✅), CHANGELOG, HANDOFF §2, Timesheet.
2026-07-23
- Branch
claude/next-steps-8vmq5d(PR #706) — Redesign „Flusslinie/Modernist" 3d-18: Ink-Gantt (Dual-Theme → Token + Block-Stil, Live-DO-verifiziert) (APP_VERSION0.137.1 → 0.138.0, MINOR — Design-Refactor + Dark-Mode-Fix). Teil B — Block-Stil (Ink-Gantt): die Füll-Optik der Gantt-Blöcke trägt jetzt den Arbeitsstand des Teilschritts (Hue bleibt die Auftrags-Status-Farbe): Outline =geplant(„wartet" — 13%-Tint-Füllung + farbiger Rahmen + farbige Schrift, de-emphasiert) · gefüllt =in_arbeit/erledigt(solide + weiße Schrift, betont — läuft/fertig) · grau =pausiert(gedämpfte Graufüllung + dunkle Schrift).uebersprungenerscheint nicht im Gantt (gefiltert). Neue HelferblockBg/blockBorder/blockText(gantt.component.ts); Konflikt-/Spät-Glows (blockShadow) koexistieren. Verifiziert am Live-Stack (Hell+Dunkel): geplante Blöcke jetzt Outline (leicht), aktive/fertige gefüllt (prominent) — klare visuelle Hierarchie. Bewusst: die funktionalen Status-Hues bleiben (Farbe = Auftrags-Phase), nur die Füll-Optik kodiert zusätzlich den Schritt-Stand. Der Gantt (gantt.component.ts) trug als einzige Komponente noch die Vor-Modernist-Dual-Theme-Logik: ~22[class.…-slate-…]="!dark()"/[class.…-tk-…]="dark()"-Paare (hartkodierteslate/whiteim Hell-Modus) + fünf@if(dark())-gegatete Features (JETZT-Linie, ⚑/⚡/⏰-Legende, Wunsch-Abholung-Flaggen, JETZT-Kopf-Badge, Auslastungs-Heatmap), die im Hell-Modus unsichtbar waren; die Optik hing am Angular-dark-Input-Signal (austheme.isDark()) statt an den theme-aware--tk-*-Tokens. Fix: alle Dual-Theme-Paare auf--tk-*-Tokens kollabiert (dark-Pfad byte-identisch, Hell-Pfad nutzt jetzt die verifizierten Modernist-Neutralen stattslate/white) + die fünf Feature-Blöcke entgated (zeigen in beiden Themes). Das ungenutztedark-Input samt Parent-Binding[dark]="theme.isDark()"+ThemeService-Injection inplanning.component.tsentfernt (keindark()mehr im Gantt-Template). Behobener Bug: im Dark-Mode war der Gantt vorher ein weißes Grid auf dunklem Cockpit (Signal↔CSS-Theme entkoppelt) — jetzt folgt er demdata-themekorrekt. Verifiziert am laufenden Stack (wrangler dev--local + gebauter Client + Demo-Seed + Playwright): Vorher/Nachher-Screenshots Hell + Dunkel — Dark-Gantt jetzt korrekt dunkel, JETZT-Linie/Heatmap in Hell sichtbar. Bewusst NICHT geändert: die funktionalen Block-/Ausfall-Farben (geplant/angeliefert/in-Arbeit/pausiert · Krank/Urlaub/Wartung) bleiben — Farbe = Information; der optionale „gefüllt=läuft · Outline=geplant"-Block-Stil ist eine eigene, opinionierte Folge-Entscheidung. Reiner Client (2 Dateien, Template-Farb-/Klassen-Werte + Dead-Code), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(3d-18 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #705) — Redesign „Flusslinie/Modernist" 3d-17: Warn-Entkopplung Toasts (nicht-rein-farbliche Ton-Kennzeichnung) (APP_VERSION0.137.0 → 0.137.1, PATCH — Fix). Erster Baustein der Warn-Entkopplung (OP-REDESIGN-1: weil Rot jetzt Primär-/Markenfarbe und Warnfarbe ist, dürfen Warnungen nicht rein farblich kodiert sein). Der Toast-Ton war rein über die Farbe kodiert ([style.color]="tone(t)") mit Default-Glyph fix✓— eindanger-Toast (rot) war so von einembrand-Toast (ebenfalls rot) nur an der Farbe unterscheidbar, und ein icon-loser danger-Toast zeigte sogar das Erfolgs-✓in Rot. Fix: Default-Glyph je Ton (TONE_ICON:ok ✓ · brand ✦ · warn ⚠ · danger ⚠ · info ℹ) → die Form unterscheidet den Ton (⚠ vs ✦ vs ✓), nicht mehr nur die Farbe; ein vom Aufrufer gesetztest.icongewinnt weiterhin. Audit-Befund: die übrigen roten Stellen tragen bereits ein Nicht-Farb-Signal (Text-Labels „getrennt"/„N ohne Standort"/„über Termin",⚠/⚑-Glyphen,role="alert", ganze Sätze) oder sind rote Aktionen (kein Warn-Fall) — der Toast war die klare Lücke. Reiner Client (1 Datei + COMPONENTS.md-Rezept), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc+ng buildprod grün. Offen (braucht Live-DO): vollständiger screen-by-screen Warn-Sicht-Durchlauf + Dark-Mode. Doku:ops/OP-REDESIGN-1.md,design/COMPONENTS.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #704) — Redesign „Flusslinie/Modernist" 3d-16: Token-Hygiene — tote ws-Tokens raus, Hover tokenisiert, Störung-Achse-Farbe korrigiert (APP_VERSION0.136.0 → 0.137.0, MINOR — Design-System-Bereinigung). Aufräum-Schritt nach der Rainbow-Ablösung: (1) die 14 ungenutzten--tk-ws-*-Workspace-Signaturfarben aus dem Token-Layer entfernt —tokens.json(color.workspace-Block),build.mjs(Name-Map), regenerierttokens.css(98 → 84 Tokens,tokens:check-Round-Trip grün); kein--tk-ws-*mehr in Token-Layer oder App-Code. (2) 23× hardcodierteshover:bg-white/[.03](Weiß-Alpha, im Hell-Modus quasi unsichtbar, vom No-Hex-Gate nicht erfasst da Tailwind-Utility) →hover:bg-tk-hover(theme-aware Token) incosts/processes/staff. (3) Korrektur: der Klärfälle-Zähler-Badge war in 3d-15 versehentlich auf Rot gesetzt — zurück auf Amber (--tk-amber), gemäß der dokumentierten Zwei-Achsen-Regel (Termin/Konflikte = Rot, Störung/Klärfälle = Amber/Gold, bewusst nicht rot, COMPONENTS.md). (4) Design-Docs synchronisiert (goldene Regel Doku↔Code):DESIGN_TOKENS.md(ws-Tabelle → „⛔ entfernt"),design/CLAUDE.md(Signaturfarben-Regel durchgestrichen + Phasen-Stand),WORKSPACES.md+COMPONENTS.md(tote--tk-ws-*-Referenzen →--tk-red/--tk-amber/--tk-text). Entscheidung: tote Tokens statt „deprecated" entfernt (Single-Source sauber); Störung=Amber wiederhergestellt (Info-tragende Achsen-Unterscheidung). Reiner Client + Design-System (Token-Layer + 4 Screens/Komponenten-Farbwerte + 4 Docs), kein Server/DTO/Schema. Verifiziert: No-Hex +tokens:check+ng buildprod grün. Doku:ops/OP-REDESIGN-1.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #703) — Redesign „Flusslinie/Modernist" Phase 3d-15: ws-Signaturfarben — Screens (Rainbow-Ablösung abgeschlossen) (APP_VERSION0.135.0 → 0.136.0, MINOR — Design-Angleich). Abschluss des ws-Signaturfarben-Feinschliffs: alle 10 verbliebenen Screens (costs·recommendations·conflicts·processes·orders·quality·planning·annahme·staff·overview) von der 14-farbigen Workspace---tk-ws-*-Rainbow befreit — kein--tk-ws-*mehr in irgendeinem Screen. Einheitliche Regel: Tab-Umschalter, Selektions-Highlights, Dekor-Glyphen/Ränder, Chips, Fortschritts-/Anteils-Balken, „neu"-Badges, Preise, Links → Ink (--tk-text); solide Primär-CTAs → Rot (--tk-brand): „✓ Übernehmen" (Vorschläge/Planung), „▶ Starten" (Team), „+ Posten" (Kosten), „✓ Freigeben" (Qualität), „🚗 Fahrzeug angeliefert" + „✓ Annehmen"-Haupt-CTA (Annahme); Konflikt-/Klärfall-Alarm-Indikatoren → Rot (--tk-red, Gefahr-Konvention aus 3d-2): Klärfälle-Zähler-Badge + Konflikt-Hebel-Fläche. Damit ist die Workspace-Rainbow-Palette komplett durch Ink+Rot ersetzt (nur die Token-Definitionen bleiben unbenutzt bestehen). Entscheidung: ein mechanischer Blanket-Durchlauf (ws→Ink) + gezielte Rot-Promotion der Primär-CTAs/Alarm-Badges — Rainbow-IA endgültig abgelöst (Modernist monochrom+rot). Reiner Client (10 Dateien, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-15 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #702) — Redesign „Flusslinie/Modernist" Phase 3d-14: ws-Signaturfarben — geteilte Komponenten (APP_VERSION0.134.0 → 0.135.0, MINOR — Design-Angleich). Start des ws-Signaturfarben-Feinschliffs (die 14-farbige Workspace-Rainbow-Palette--tk-ws-*, die Modernist zugunsten Ink+Rot ablöst — 3d-2 entfärbte die Nav) auf die geteilten Komponenten (überall sichtbar, größter Konsistenz-Hebel): Auftrag-Detail-Panel — die zwei „Speichern"-Buttons (Kunde/Fahrzeug, waren--tk-ws-annahme-Vollfläche) → Rot (--tk-brand, Primär-Aktion), CRM-Link + „✦ Vorziehen vorschlagen"-Outline → Ink; Shell — Werker-Modus-Indikator ⬣ (--tk-ws-werker) → Rot (passend zum roten Werkstatt-Terminal 3d-5), die drei restlichen Nav-Badge-Farben (Annahme/Vorschläge/Qualität) → neutral Ink (--tk-text-dim— der deferrte Badge-Feinschliff aus 3d-2; Gefahr-Badges bleiben rot); Tafel (Leer-Glyph + „Auftrag annehmen"-Link), Klärung-Einplanen + Klärfall-Lösen (Container/Chips), Nächste-Aufgaben (Tab-Aktiv) → Ink. Entscheidung: ws-Vollflächen-Primär → Rot · ws-Dekor/Outline/Toggle → Ink (analog 3d-6). Reiner Client (6 Dateien, nur Farbwerte, per perl-Ersetzung + Kommentar-Nachzug), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-14 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #701) — Redesign „Flusslinie/Modernist" Phase 3d-13: Takt/Planung-Chrome, Gantt-Bedienung & Klärfall-Palette — Cyan-Feinschliff abgeschlossen (APP_VERSION0.133.0 → 0.134.0, MINOR — Design-Angleich). Der letzte Cyan-Feinschliff auf die verbliebene interaktive UI-Chrome: Planung/Takt (planning.component.ts) — „Alle Profile identisch"-Info-Box + ℹ → Ink, „✎ Entwurf"-Modus-Banner (Rahmen+Text) → Rot (--tk-brand, aktive Bearbeitung = Aufmerksamkeit, konsistent mit „Plan ändern" 3d-3), Testdaten-Checkbox → Rot, Optimierungs-Metrik-Farbe (3. Kennzahl) → Ink; Gantt-Bedienung (gantt.component.ts) — Zoom-Preset-Toggle aktiv + „Klick → Details"-Hinweis → Ink, Drag-Vorschau-Ghost (gültige Platzierung war Cyan) → Ink (ungültig bleibt Rot ⚠ — klarer Kontrast gültig/ungültig); Klärfall-Lösen-Palette (klaerfall-loesen.component.ts) — die mittleren Routen „Sprung zu QS" (war Cyan) + „Anderer Schritt" (war Violett) → Ink (Rainbow entschärft; „← Zurück"=Grün [sicher] + „✕ Abbruch"=Rot [destruktiv] behalten ihre semantische Farbe, die Icons ←/✓/↷/✕ tragen den Rest). Damit ist der Cyan→Ink/Rot-Feinschliff des gesamten Cockpits abgeschlossen. Bewusst als Cyan erhalten (dokumentiert, kein Rest-Aufwand): [a] funktionale Lifecycle-Status-Hues (labels.tsangeliefert/Termin-Klasseziel,phase.tsAbholung,staff.tsartFarbeSchicht-Typ,gantt.tswunschfrei-Block) — der Phase-1-Brief bewahrt funktionale Status-/Gantt-Hues (Farbe trägt hier Information, True-North Q2); [b] Live-/Präsenz-Signale (✎ „wird gerade bearbeitet", ⏺ „tippt/parst"-Puls, Lade-Spinner,istUmparken„parkt gerade um") — Cyan = reserviertes Echtzeit-Signal. Reiner Client (3 Dateien, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Offen in OP-REDESIGN-1: der Gantt-Block-Stil-Refactor (Dual-Themedark()→Token + status-gefärbt→Ink-Gantt, braucht Live-DO zum visuellen Verifizieren) · ws-Signaturfarben-Reste (Avatar-Violett, ws-annahme) · 3-True-North-Karten-Reihe/Lage-Rest/Overlays. Doku:ops/OP-REDESIGN-1.md(Phase 3d-13 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #700) — Redesign „Flusslinie/Modernist" Phase 3d-12: Bild-Gate & Shell-Reste Modernist (APP_VERSION0.132.0 → 0.133.0, MINOR — Design-Angleich). Cyan-Feinschliff auf das Foto-Gate (bild-upload-gate.component.ts+bild-schutz.component.ts— On-device-Prüfung Personen/Kennzeichen vor Upload, OP-QS-2) + Shell-Reste: Bild-Gate — Prüf-Kriterien-Text-Emphase (Qualität/Personen/Inhalt), Hover-/Focus-Rahmen, Auto-Geprüft-Punkt (auto war Cyan; manuell=Amber bleibt), Markier-Modus-Toggle → Ink; die Markierungs-Nummern-Badges (Bildschirm) + die ins Bild gebrannten Marker-Kreise (Canvas-Export) → Rot (--tk-brand, hohe Sichtbarkeit + Marke für markierte Personen/Kennzeichen-Regionen); der primäre „Hochladen"-Button (freigegeben) → Rot (Primär-Aktion); Shell — Theme-Umschalt-Glyph (☀/☾) + „Auf-Kurs"-Fortschritts-Ring → Ink. Entscheidung: Selektion/Toggle/Info/Progress → Ink · Primär-Upload + Marker → Rot (Marker müssen sichtbar sein, Rot = Marke + Kontrast); manuell-Amber bleibt (Aufmerksamkeit). Reiner Client (3 Dateien, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-12 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #699) — Redesign „Flusslinie/Modernist" Phase 3d-11: Annahme & Prozesse Modernist (APP_VERSION0.131.0 → 0.132.0, MINOR — Design-Angleich). Cyan-Feinschliff auf Annahme (annahme.component.ts— „Takt-Kommando"-Intake) + Prozesse (processes.component.ts— Prozess-/Schritt-Stammdaten): Annahme — Kommandozeilen-Glow entfernt (Modernist flach), Alternativ-Vorschlag-Button → Ink, „Auf dem Radar zeigen"-CTA-Glow (war Cyan an rotem Button) → Rot (angeglichen), Info-Chips (Anlieferung/Abholung/Termin-Härte-Default) → Ink; Prozesse — Info-Hinweis-Tint, Mindest-Niveau-★, Abhängigkeits-Toggle, „Foto-Vorgabe"-Outline,.tk-flag.tk-on-Toggle → Ink, Arbeitsplatz-Typ-Checkbox → Rot. Bewusst Cyan behalten: der ⏺ „tippt/parst"-Live-Puls + der Lade-Spinner in der Annahme — beides echte Live-/Verarbeitungs-Signale (konsistent mit der Live→Cyan-Regel). Entscheidung: Selektion/Toggle/Info → Ink · Checkbox → Rot · Live/Processing → Cyan; Glows raus (flach), CTA-Schatten in Marken-Rot statt Cyan. Reiner Client (2 Dateien, nur Farbwerte + 1 entfernter Glow), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-11 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #698) — Redesign „Flusslinie/Modernist" Phase 3d-10: Belegung & Fluss-Gruppe Modernist (APP_VERSION0.130.0 → 0.131.0, MINOR — Design-Angleich). Cyan-Feinschliff auf die Belegungs-/Karte-Sicht (occupancy.component.ts— die „wo stehen die Fahrzeuge"-Karte, Q2) + die restliche Fluss-Gruppe (conflicts.component.ts,quality.component.ts): Belegung — Drag&Drop-Hinweis-Emphase, „Wareneingang — Annahme"-Zone (Rahmen/Label/Zähler), Drag-Over-/Drag-Aktiv-Ziel-Highlight, „✓ da"/📍/🅿️-Aktions-Icons → Ink; Konflikte — Info-Box, 📝-Notiz-Button, Standort-Wert, Avatar-Farb-Rotation → Ink; Qualität — KPI „Offene Prüfungen" + Mangel-Statusin_nacharbeit(war Cyan;offen=Amber/behoben=Grün bleiben funktional) → Ink. Entscheidung: Selektion/Interaktion/neutrale Info → Ink; funktionale Status-Hues (Amber-Warnung, Grün-OK, Rot-Doppelbelegung) bleiben — nur das arbiträre Cyan weicht. Drop-Ziel-Highlight bewusst Ink statt Rot (neutrale „hier ablegen"-Führung, kein Alarm). Reiner Client (3 Dateien, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-10 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #697) — Redesign „Flusslinie/Modernist" Phase 3d-9: Detail-Panel & geteilte Modals/Overlays Modernist (APP_VERSION0.129.0 → 0.130.0, MINOR — Design-Angleich). Der Cyan-Feinschliff auf die geteilten Komponenten (die überall im Cockpit auftauchen) nach der Feinschliff-Regel: Auftrag-Detail-Panel (auftrag-detail-panel.component.ts— Teilschritt-Fokus-Auswahl, „angeklickt"-Label, 📝-Notiz-Toggle, „Produktion starten"-Outline, Notiz-Popin-Rahmen) → Ink; Umparken-Modal (repark-modal.component.ts— Slot-Auswahl [empfohlen + weitere], „✓ passt"-Label, „Empfohlen"-Kopf, Auftragsnummer) → Ink (die ✅/✓-Glyphen tragen die „passt"-Bedeutung, nicht die Farbe); Assistent-Chat (chat-panel.component.ts— Pin-/Issues-Toggles → Ink; User-Sprechblase → Rot--tk-brandals Marken-/Eigen-Akzent, heller Text erhalten); Feedback-Formular (Art-Auswahl + Hover → Ink); Modal-Dialog (primärer Bestätigen-Button → Rot, nicht-Gefahr = Primär-Aktion); Toastbrand-Ton → Rot (war fälschlich Cyan); Feedback-Pin-/Screenshot-Region-Overlay (Markier-Rechteck → Ink, neutrale Selektion); Fortschritts-Indikator (Fokus-Ring → Ink); Werkstatt-Terminal Umpark-Karten-Rahmen → Ink. Bewusst offen: die 4-farbige Klärfall-Lösen-Options-Palette (grün/cyan/violett/rot) = semantisches Farbset, kommt als eigene Entscheidung (nicht halb entfärben); ws-Signaturfarben + Status-Hues separat. Entscheidung: Selektion → Ink · Primär/Marke/„Du" → Rot · Live/Präsenz → Cyan — die geteilten Bausteine ziehen konsistent nach, sodass das Cockpit überall gleich „spricht". Reiner Client (10 Dateien, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-9 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #696) — Redesign „Flusslinie/Modernist" Phase 3d-8: Fluss & Lage Modernist (APP_VERSION0.128.0 → 0.129.0, MINOR — Design-Angleich). Die beiden zentralen True-North-Sicht-Screens (orders.component.ts= Fluss / „wo & wann",overview.component.ts= Lage/Hof-Radar) folgen der Feinschliff-Regel: Auftrags-/Slot-/Avatar-/Nachbar-Auswahl (Card-Rahmen+Tint, Slot-Kachel, Mitarbeiter-Avatar-Ring, Nav-Fokus, aktueller Prozess-Schritt, Standort-Wert) → Ink (--tk-textstatt Cyan); die animierte „Flusslinie" (Radar-Sweep) → Rot (--tk-brand, brand-konform — die namensgebende Fluss-Linie ist jetzt rot) mit entferntem Glow (Modernist flach); die Selektions-Glows (Slot-Kachel, Avatar) entfernt (flach); der „Produktion starten"-Outline-Link (Cyan) → Ink. Bewusst unberührt:tk-cyan2(=--tk-brand, war schon rot: Auslastungs-Wert, Eingang, früheste Anlieferung); funktionale Status-Hues (grün „erledigt", ws-annahme „reserviert") bleiben (eigener ws-Farb-Feinschliff). Entscheidung: Selektion durchgängig Ink (hoher Kontrast, kein Alarm), Flusslinie als Marken-Rot, Glows raus (flach) — Rot bleibt Aktion/Marke. Reiner Client (2 Dateien, nur Farbwerte + 2 entfernte box-shadows), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-8 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #695) — Redesign „Flusslinie/Modernist" Phase 3d-7: Team-Editor Modernist (APP_VERSION0.127.0 → 0.128.0, MINOR — Design-Angleich). Der Team-Screen inkl. Mitarbeiter-Editor (staff.component.ts) folgt jetzt der Feinschliff-Regel: Vertrauens-★-Auswahl (Anlegen + Bearbeiten), Skill-Niveau-★, sowie die Abwesenheits-Toggles (Wunschfrei weich · Einfacher Wunsch · Genehmigt · Ganzer Tag/Bestimmte Schichten) im gewählten Zustand → Ink (--tk-textstatt Cyan, 15 Bindungen); die Schicht-Checkboxen (accent-color) → Rot (--tk-brand); XP-Badge + Fairness-Zähler + Abwesenheits-Info-Tint → Ink (neutrale Stat/Info); das weiche Abwesenheits-Typ-Label (war Cyan) → Ink (das harte bleibt Rot — hart/weich-Kontrast erhalten); „✓ genehmigt" → Ink. Bewusst Cyan behalten: die „✎ wird gerade bearbeitet"-Präsenz + der „parkt gerade um"-Live-Status (istUmparken, Echtzeit-Tätigkeit) +artFarbe-Schicht-Typ-Farbe (Schicht/Gantt-Visualisierung → eigener Ink-Gantt/Schedule-Slice). Entscheidung: Feinschliff-Regel unverändert (Selektion/Toggle → Ink · Primär/Checkbox → Rot · Live/Präsenz → Cyan); Schicht-Farbcodierung bleibt bei der Gantt-Slice. Reiner Client (1 Datei, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-7 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #694) — Redesign „Flusslinie/Modernist" Phase 3d-6: Verwaltung Modernist (APP_VERSION0.126.0 → 0.127.0, MINOR — Design-Angleich). Der Verwaltungs-Screen (administration.component.ts) ist entfärbt: die Config-Auswahl-Chips (Taxonomie-Art · Skill-Eignung · Wochentage · Nachbar-Buchten) tragen im gewählten Zustand jetzt gefüllte Ink-Chips (--tk-textstatt Cyan) — die selbsterklärende Modernist-Selektion; die „+ Arbeitsplatz"/„+ Schicht"-Primär-Buttons (trugen die Workspace-Signaturfarben--tk-ws-bays/--tk-ws-staff) → Rot (--tk-brand); die Sekundär-Outline-Buttons „+ Sperre" / „Neu laden" (Cyan-Rahmen+Text) → Ink; die „aktiv"-Checkboxen (accent-color) → Rot. Bewusst Cyan behalten: die drei „✎ wird gerade bearbeitet"-Badges — Cyan bleibt das eine reservierte Live-/Präsenz-Signal (jemand editiert diesen Datensatz gerade, Echtzeit-Kollaboration), konsistent mit 3d-1. Entscheidung (Feinschliff-Regel, aus 3d-1/3d-3 fortgeführt): Selektion/Config-Toggle → Ink · Primär-Aktion → Rot · Live/Präsenz → Cyan — Rot bleibt selten & bedeutungstragend. Reiner Client (1 Datei, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün. Doku:ops/OP-REDESIGN-1.md(Phase 3d-6 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #693) — Redesign „Flusslinie/Modernist" Phase 3d-5: Werkstatt-Terminal Modernist-Akzent (APP_VERSION0.125.0 → 0.126.0, MINOR — Design-Angleich). Die Werker-Fläche „Meine Arbeit" (meine-arbeit.component.ts) trug als einzigen Akzent die Workspace-Signaturfarbe--tk-ws-werker(Indigo) — jetzt auf Rot (--tk-brand) gezogen (8 Stellen: aktiver Werker-Auswahl-Chip [Rahmen/Fläche/Text], Avatar-Tönung, Offen-Zähler-Badge, Leer-Zustand-Glyph ⬢, Status-Pille). Damit ist das Werkstatt-Terminal durchgängig monochrom + rot (Modernist). Reiner Client (1 Datei, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +ng buildprod grün + Live-Screenshot (roter ⬢-Leer-Glyph). Doku:ops/OP-REDESIGN-1.md(Phase 3d-5 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #692) — Redesign „Flusslinie/Modernist" Phase 3d-4: Team · Kann-was-Matrix (APP_VERSION0.124.0 → 0.125.0, MINOR — neues Feature). Der Team-Screen (staff.component.ts) führt oben eine Kann-was-Matrix: Tabelle Mitarbeiter × Skills — Zeilen = aktive Mitarbeiter, Spalten = aktive Skills (Katalog), Zellen = Könner-Stufe als ★ (Niveau 1–3,·= kein), plus eine Ausbildungsziel-Spalte („★2 → ★3 ·", erstes offenes Ziel). Ganze Zeile klickbar → bestehender Mitarbeiter-Editor ( oeffneBearbeiten, Reuse);aria-labelje Zeile, sticky Name-Spalte, horizontal scrollbar, Leer-Guard (ohne Mitarbeiter/Skills ausgeblendet). Rein aus Live-Signalen (svc.employees()·svc.skills(), keine Fixtures). Entscheidung: die Matrix als Team-Landing (Brief: „Team = Kann-was-Matrix") — die vorhandenensterne()/oeffneBearbeiten()/Skill-Daten wiederverwendet, kein neuer State (Einfachheit); Doppel-sterne()beim Bau erkannt + entfernt. True-North: „wer kann was" auf einen Blick = Grundlage für Zuteilung & Auslastung (Q1). Reiner Client (staff-Template + 3 Helfer/Computed), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc -p tsconfig.app.json+ng buildprod grün; Team-Screen rendert Modernist (Leer-Guard greift ohne Seed-Daten). Visuell mit Daten: braucht ein laufendes DO (wie der Ink-Gantt) — Logik ist an echte DTOs gebunden, build-verifiziert. Doku:ops/OP-REDESIGN-1.md(Phase 3d-4 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #691) — Redesign „Flusslinie/Modernist" Phase 3d-3: Takt-Controls Modernist (APP_VERSION0.123.0 → 0.124.0, MINOR — Design-Angleich). Die Toolbar-Toggles des Takt/Planung-Screens (planning.component.ts) sind entfärbt:asap/jitaktiv (war Cyan) +Auto-Nachführung an(war Grün) → Ink (--tk-text, monochromer Aktiv-Zustand);Plan ändern(Entwurfs-/Drag-Modus, war Cyan) → Rot (--tk-brand— aktive Bearbeitung = Aufmerksamkeit, brief-konform). „⟲ Optimierung vorschlagen" war bereits rot (3d-1), der Konflikt-Sprung-Button bereits rot. Entscheidung: monochrome Toggles (Ink) für neutrale Modi, Rot nur für den aktiven Bearbeitungs-Modus — „Rot = Bedeutung". Reiner Client (planning.component.ts, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc -p tsconfig.app.json+ng buildprod grün + Live-Screenshot (Ink-Toggles asap/Auto, roter „Plan ändern"-Entwurf). Hinweis/offen: der Gantt selbst (gantt.component.ts) trägt noch die Vor-Token-Dual-Theme-Logik (dark()→ hartkodierteslate/whiteim Hell-Modus, ~24 Bindungen) + status-gefärbte statt Ink-Gantt-Blöcke (gefüllt=läuft/erledigt · Outline=geplant · grau=pausiert) — das ist eine eigene größere Slice (Dual-Theme→Token + Block-Stil; braucht Live-Daten zum visuellen Verifizieren). Doku:ops/OP-REDESIGN-1.md(Phase 3d-3 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #690) — Redesign „Flusslinie/Modernist" Phase 3d-2: Monochrome Ort-Chips (Nav) (APP_VERSION0.122.0 → 0.123.0, MINOR — Design-Angleich; erledigt den deferrten Teil von Phase 2b). Die Navigations-Rail zeigt nicht mehr die Rainbow---tk-ws-*-Signaturfarben je Ort, sondern monochrome Ink-Chips (--tk-text-dim); der aktive Ort wird rot (--tk-brand, via.tk-nav.tk-active { --chip: var(--tk-brand) }— Chip + Stripe + Text). Zusätzlich: Header-Platz-Punkt (das „aktueller Ort"-Signal) + Logo-Kachel-Tönung von Cyan → Rot; der Stripe-Glow entfernt (Modernist ist flach). Badges bleiben farbig (rot für Gefahr — Konflikte/Klärfälle; die restlichen Badge-Farben sind Feinschliff).shell.component.tsnavGroups()-Item-colorper gezieltem sed (Zeilenbereich der Computeds) auf Ink —badgeColor(Groß-C) bewusst unberührt. Entscheidung: „monochrom + Rot" nach Brief — die 4 Orte tragen keine Eigenfarbe mehr (die 12-Workspace-Signaturfarben waren an die alte IA gebunden), der aktive Ort ist der einzige farbige (rote) Akzent. Reiner Client (nurshell.component.ts, Farbwerte + eine CSS-Regel), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc -p tsconfig.app.json+ng buildprod grün + Live-Screenshot (Ink-Chips, aktiver „Lage"-Ort rot, Header-Punkt rot). Doku:ops/OP-REDESIGN-1.md(Phase 3d-2 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #689) — Redesign „Flusslinie/Modernist" Phase 3d-1: Accent-Sweep — Primär-Aktionen → Rot (APP_VERSION0.121.0 → 0.122.0, MINOR — Design-Angleich). Modernist verlangt „Rot ist Bedeutung — Akzent nur für Primäraktion". Deshalb sind die solidenbackground: var(--tk-cyan)-Füllungen (27 Stellen in 13 Dateien) aufvar(--tk-brand)(Rot) gezogen: Primär-Aktions-Buttons (Assistent-FAB · „⟲ Optimierung vorschlagen" · „Pin vormerken" · „Notiz speichern" · Konflikt-/Annahme-/Umpark-Bestätigungen …), die JETZT/Now-Linien (Brief: „rote JETZT-Linie" — Gantt + Risiko-Timeline) und Highlight-Badges (z. B. „HQ"); die zugehörigen Glows (FAB, Now-Marker) wurden mitgezogen (Rot statt Cyan). Bewusst NICHT angefasst (eigener Feinschliff): cyan Outlines/Text/Tints (Selektion/Live), die Toggle-Aktiv-Zustände (? 'var(--tk-cyan)', ~63 Stellen) und--tk-green/--tk-ws-*— diese folgen als „Selektion → Ink, Toggle-Aktiv → Rot/Ink"-Slice. Entscheidung: gezielt nur die soliden Füllungen (= Primär-Aktionen/Now-Linien) geflippt — ein grep-sicheres Muster, das Primäres trifft ohne die semantische Selektions-/Live-Cyan blind mitzureißen (kein Bedeutungsverlust). Cyan bleibt vorerst der funktionale Selektions-/Live-Akzent (Phase-1-Entscheidung), der Rest ist Feinschliff. Reiner Client (13 Component-Templates, nur Farbwerte), kein Server/DTO/Schema. Verifiziert: No-Hex (nur--tk-*) +tsc -p tsconfig.app.json+ng buildprod grün + Live-Screenshot (Takt: „Optimierung vorschlagen" + FAB jetzt rot). Doku:ops/OP-REDESIGN-1.md(Phase 3d-1 ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #688) — Redesign „Flusslinie/Modernist" Phase 3c: Lage · „Braucht dich"-Digest (APP_VERSION0.120.0 → 0.121.0, MINOR — neues Feature). Die Lage-Landing (overview.component.ts) führt oben in der Sidebar jetzt einen „Braucht dich"-Digest: die dringendsten „Entscheiden"-Einträge (max 4 — Klärfälle/Notfälle zuerst, dann Termin-Konflikte, dann fehlende Ortung) mit Typ-Label VERSAL + 3px-Ton-Kante (danger--tk-red/ warncolor-mix(--tk-red 45%)), plus ein roter Zähler „N → Entscheiden"; jeder Eintrag + der Zähler verlinken in den Fluss, wo die vollständige „Entscheiden"-Ablage inkl. Aktionen liegt. Rein aus Live-Signalen abgeleitet (svc.klaerfaelle·konflikte·ohneStandort), Leer-Zustand „✓ Alles im Takt.". Entscheidung: die Lage zeigt „was zu entscheiden ist" vorab (direkter True-North-Treffer: Q2 „wo/was braucht Aufmerksamkeit"), die eigentliche Aktion bleibt im Fluss (kein doppelter Aktions-Ort). Reiner Client (overview-Template + 2 Computeds), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc -p tsconfig.app.json+ng buildprod grün (nach Fix eines Template-Parse-Fehlers: deutsche Anführungszeichen imtitle-Attribut entfernt) + Live-Screenshot (Sidebar „BRAUCHT DICH" oben, Leer-Zustand). Offen (3c-Rest/3d): 3 True-North-Karten in einer Reihe · „Heute kommt/geht" · Review-Sicht · Annahme-Overlay · 620px-Drawer · QS-Modal · Takt/Team/Verwaltung/Terminal. Doku:ops/OP-REDESIGN-1.md(Phase 3c ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #687) — Redesign „Flusslinie/Modernist" Phase 3b: Fluss · Linie/Karte-Toggle (APP_VERSION0.119.0 → 0.120.0, MINOR — neues Feature). Der Fluss-Screen (orders) hat statt „Fluss · Risiko" jetzt die Sicht-Umschaltung „Linie · Karte · Risiko" (orders.component.ts): Linie = 5-Stationen-Pipeline (bestehend), Karte = die bestehende Belegungs-Flächeapp-occupancyeingebettet (Halle/Buchten + Hof/Parkplätze, Umparken per Drag&Drop + Park-Dialog), Risiko = Dringlichkeits-Timeline (bestehend); dazu eine kontextuelle Hinweiszeile je Sicht. Entscheidung (Einfachheit/Reuse): die Karte nicht neu gebaut, sondern die vorhandeneOccupancyComponent(self-contained, liest den Service) über ihren Selektorapp-occupancyeingebettet — die „Entscheiden"-Spalte bleibt in allen Sichten rechts stehen (Fluss-Karte + Entscheiden = Spec-Layout). Kein Zirkel-Import (occupancy importiert orders nicht). Reiner Client (orders-Template + Tab-Enum'fluss'|'karte'|'risiko'), kein Server/DTO/Schema. Verifiziert: No-Hex +tsc -p tsconfig.app.json+ng buildprod grün + Live-Screenshot (Toggle Linie/Karte/Risiko, Karte-Grid mit Drag&Drop-Hinweis + Entscheiden-Spalte). Offen (3c+): inline-Auswahl-Panel unter der Linie · 620px-Auftrag-Drawer · Quality-Check-Modal. Doku:ops/OP-REDESIGN-1.md(Phase 3b ✅),design/WORKSPACES.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #686) — Redesign „Flusslinie/Modernist" Phase 2b: True-North-Strip im Header (APP_VERSION0.118.0 → 0.119.0, MINOR — neues Feature). Die drei True-North-Leitfragen stehen jetzt immer sichtbar in der Kopfzeile (shell.component.ts): „Auslastung X % · N Fzg · alle verortet / N ohne Standort · frei ‹Leistung›". Rein aus den Live-Insights abgeleitet (svc.insights().auslastungsQuote[Engpass = engere der Gruppen Mitarbeiter/Buchten, 0..1→%],.kapazitaet[erste machbare Leistung],aktiveAuftraege().length,ohneStandortCount()) — kein neuer State. Fehlende Ortung erscheint rot (Warnung; behält die nicht-rein-farbliche Trennung über das Label „ohne Standort"). Strip ablg-Breite (auf schmalen Terminals ausgeblendet, kein Umbruch). Entscheidung: die always-on True-North-Antwort in die Shell gezogen (direkter True-North-Treffer, aus vorhandenen Signalen); die strukturelle Rail→62px-Top-Tab-Bar-Umstellung + monochrome Ort-Chips bleiben ein eigener, größerer Schnitt — die gruppierte Rail liefert die 4-Orte-IA bereits Modernist-gestylt, ein Big-Bang-Shell-Rewrite wäre unnötig riskant. Reiner Client-View (nurshell.component.ts); keine Server-Verhaltens-/DTO-/Schema-/Migrations-Änderung — die einzige Server-Datei istversion.ts(reine Versions-MetadatenAPP_VERSION). Verifiziert: No-Hex (nur--tk-*) +tsc -p tsconfig.app.json+ng buildprod grün + Live-Screenshot (Header „… · 0 Fzg · alle verortet · …"). Doku:ops/OP-REDESIGN-1.md(Phase 2b ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #685) — Redesign „Flusslinie/Modernist" Phase 3a: Fluss · „Entscheiden"-Spalte (APP_VERSION0.117.0 → 0.118.0, MINOR — neues Feature/Screen). Die konzeptionelle Mitte des Redesigns ist gebaut: „System entscheidet, Mensch bestätigt". Neue geteilteEntscheidenComponent(client/src/app/leitstand/entscheiden.component.ts) als rechte Spalte (360px, xl+) auf dem Fluss-Screen (orders). Sie sammelt ausschließlich Live-Signale (svc.klaerfaelle·konflikte·ohneStandort·vorschlaege, keine Fixtures) zu Vorschlagskarten: 3px-Topline nach Ton (danger=--tk-redfür Klärfall/Notfall/Termin, warn=color-mix(--tk-red 45%)für Ortung, idee=--tk-linefür Optimierer-Vorschlag), Typ-Label VERSAL, Titel/Body, optionaler „Vorschlag"-Block (Tinte-Kante), Buttons „✓ So machen" (primär--tk-brand) / „Später", Leer-Zustand „Alles im Takt.". Aktions-Semantik (ehrlich): „So machen" wendet echte Mutationen direkt an, wo sie existieren (vorschlagVorziehenbei Vorschlag-Typ „vorziehen"), sonst springt es in die zuständige Ansicht, wo die Mutation lebt (Klärung/conflicts?tab=klaerfaelle· Konflikt/Ortung/conflicts· Idee/recommendations); „Später" blendet die Karte je Sitzung aus (kommt bei neuer Ableitung wieder — nichts geht verloren). Entscheidung: die „Entscheiden"-Ablage zuerst gebaut (größter True-North-/Konzept-Hebel, aus vorhandenen Signalen ableitbar, kein Server-Change) — Linie/Karte-Toggle, Auswahl-Panel, 620px-Auftrag-Drawer und Quality-Check-Modal bewusst als Phase 3b+. Reiner Client, kein Server/DTO/Schema/Migration. Verifiziert: No-Hex-Gate (nur--tk-*/color-mix) +tsc -p tsconfig.app.json+ng buildprod (16 s) grün + Live-Screenshot (Fluss-Linie 5 Stationen links + „ENTSCHEIDEN"-Spalte rechts, Leer-Zustand „Alles im Takt."). Doku (goldene Regel):design/COMPONENTS.md(Entscheiden-Pattern),design/WORKSPACES.md(§4 Fluss-Hinweis),ops/OP-REDESIGN-1.md(Phase 3a ✅), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #684) — Redesign „Flusslinie/Modernist" Phase 2: Informationsarchitektur auf 4 „Orte" (APP_VERSION0.116.0 → 0.117.0, MINOR — IA-Umbau). Die Navigation ist von den früheren „Kern-Loop/Weitere"-Clustern auf die 4 „Orte" Lage · Fluss · Takt · Team + Verwaltung (admin-gegated) + Werkstatt-Terminal umgestellt (shell.component.tsnavGroups()). Zuordnung (nichts verwaist): Lage = Hof-Radar · Annahme · Belegung · Tafel; Fluss = Fluss&Risiko · Konflikte&Klärfälle · Vorschläge · Quality-Check; Takt = Planung/Gantt; Team = Mitarbeiter · Prozesse; Verwaltung = Administration · Kosten; Werkstatt-Terminal = Meine Arbeit. Alias-Routen/lage→overview,/fluss→orders,/takt→planning,/team→staff,/verwaltung→administration,/terminal→meine-arbeit; alle bestehenden Workspace-Routen + Deep-Links bleiben intakt (die Views selbst sind unverändert). True-North-Badges (Konflikte/Klärfälle/QM/Vorschläge-Counts) erhalten. Entscheidung: additive IA-Umstellung ohne Screen-Umbau — die Rail-Struktur/Rendering bleibt, nur Gruppierung/Labels + Routen ändern sich (kleinstmögliche, rückwärtskompatible Änderung; Einfachheit). Bewusst offen (Phase 2b/3): die Rail → 62px-Top-Tab-Bar-Optik, monochrome Ort-Chips statt Rainbow---tk-ws-*, und die zusammengeführten Ort-Screens (Fluss „Entscheiden"-Spalte, Ink-Gantt, Auftrag-Drawer, Annahme-/Quality-Overlays). Verifiziert:tsc -p tsconfig.app.json+ng buildprod grün + Live-Screenshot (Header „Lage · Hof-Radar", Rail-Gruppen = Lage/Fluss/Takt/Team/Werkstatt-Terminal). Reiner Client (Shell-Nav + Routen), kein Server/DTO/Schema. Doku:ops/OP-REDESIGN-1.md(Phase 2 Nav/IA ✅),design/CLAUDE.md, CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #683) — Redesign „Flusslinie/Modernist" Phase 1: Token-Layer (APP_VERSION0.115.0 → 0.116.0, MINOR — neue Design-Sprache). Der--tk-*-Token-Layer ist auf Modernist umgestellt und LIGHT-first:design/tokens/tokens.jsonträgt jetzt den Hell-Wert als Basis-$value(→:root, Default), den Dunkel-Wert unter$extensions.taktano.dark→ generiert nach:root[data-theme="dark"](+prefers-color-scheme:darkfür „system"). PO-Entscheidung 07-23: Dark-Mode mitgeneriert (beide Themes aus einer Quelle, OP-R9-9 gewahrt — nur die Basis-Achse invertiert von dark-first zu light-first). Modernist-Identität: Marke = Rot#ec3013(--tk-brand/--tk-red; Cyan ist nicht mehr Marke), Hintergrund#f3f2f2/ Text#201e1d, alle--tk-radius-*= 0, Font Archivo für UI und Daten (Zahlen/Zeiten via.font-mono+font-variant-numeric: tabular-nums— löst „Mono für Daten" ab), kein Ambient-Glow (--tk-backdrop-glow: none), Glow-Dots aus. Funktionale Status-/Gantt-Hues (blue/green/amber/orange/cyan/violet) bleiben erhalten, aber auf den hellen Warm-Neutral-Grund getunt (die bestehenden Hell-Werte wurden zur Basis, die Dunkel-Werte zur Dark-Override — tuned Paare erhalten). Mechanik:build.mjsinvertiert (Light-Basis →:root, Dark-Override →[data-theme="dark"], Extension-Key.light→.dark);ThemeService(System-Achseprefers-color-scheme: dark,isDark/isLightneu);index.html(Archivo statt Space Grotesk/JetBrains Mono,theme-color/Favicon#ec3013, Favicon radius 0);styles.css(color-schemeinvertiert +.font-mono { tabular-nums }). Warnungen brauchen fortan eine nicht-rein-farbliche Kennzeichnung (Rot nicht mehr warn-exklusiv) — Umsetzung in den Komponenten-Phasen. Verifiziert:npm run tokens:check(98 Tokens, round-trip), No-Hex-Gate,tsc -p tsconfig.app.json,ng build(prod, 655 kB initial) grün + Live-Screenshot bestätigt (Body-BGrgb(243,242,242), Font Archivo, radius 0, rote Uhr/Alerts). Reiner Design-Token-/Theming-Change — kein Server/DTO/Schema, keine Migration. Bewusst offen (Phase 2/3): Workspace-Signaturfarben (bis 4-Orte-IA), Glass/Glow-Komponentenklassen, Assistent-FAB-Cyan, 2px-Divider, Wordmark/Icon-Assets. Doku:ops/OP-REDESIGN-1.md(Phase 1 ✅),design/CLAUDE.md(Vertrag aktualisiert — abgelöste Regeln markiert),design/DESIGN_TOKENS.md(Phase-1-Banner), CHANGELOG, HANDOFF §2, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #681) — Redesign „Flusslinie/Modernist": PO-Entscheidung + Phasen-Roadmap (Phase 0, docs-only) (APP_VERSION0.114.0 → 0.115.0, MINOR — neue Produktrichtung). Der PO hat entschieden (in Anwendung der 07-23-Konvention aus PR #680): das Claude-Design-Projekt „Taktano Neu v2 – Flusslinie" (Design-System „Modernist") löst das bisherige Design-System und die Marke vollständig ab — bewusst, in Phasen (Tokens → Shell/IA → Screens), jede Phase einzeln grün + mergebar. Konflikte bewusst zugunsten Modernist aufgelöst: Cyan-Marke → Rot#ec3013als Primär-/Markenfarbe; Dark → Light-Default (#f3f2f2/#201e1d); 12 signaturfarbene Workspaces → 4 „Orte" (Lage · Fluss · Takt · Team) + Verwaltung + Werkstatt-Terminal; Radius-Skala → radius 0; Space Grotesk/JetBrains Mono → Archivo; Glass/Glow → flache 2px-Linien. Golden-Rule-Ausnahme (bewusst, begründet): „Rot nur für Warnungen" bleibt drkv-Default und gilt in den Schwester-Repos (MED-/SERA-) unverändert; Taktano ist die dokumentierte Ausnahme (Rot = Primär) → Warnungen brauchen fortan eine nicht rein-farbliche Kennzeichnung. Phase 0 (dieser PR, docs-only, kein Code/Schema): Entscheidung + Roadmap alsops/OP-REDESIGN-1.md(OP-REDESIGN-1,status: offen); Root-CLAUDE.md§ Design-Prinzipien (Taktano-lokale Rot-Ausnahme);design/CLAUDE.md(Umbau-Banner + neuer Brand-/Kontrakt-Kopf, bisherige Regeln „gültig bis Phase X ersetzt"). Kein Screen-Umbau, keine visuelle Regression. Nächster Schritt: Phase 1 = Token-Layer (Modernist) als eigener PR. Doku:ops/OP-REDESIGN-1.md,docs/betrieb/Offene-Punkte.md(regeneriert), CHANGELOG, HANDOFF, Timesheet. - Branch
claude/next-steps-8vmq5d(PR #680) — Konvention: neues Design-System aus Claude Design → bei Konflikten fragen (docs-only, kein Code-/Schema-Change,APP_VERSIONunverändert). Stehende PO-Vorgabe (07-23) als verbindliche Design-Governance-Regel indesign/CLAUDE.md(§Non-negotiable design rules) festgehalten: wird ein neues/aktualisiertes Design-System aus Claude Design übernommen (z. B. ein neuer Design-Component/Prototype), das früheren Entscheidungen widerspricht (Marken-/Farbregeln — Cyan-Signatur, Rot nur für Warnungen —,--tk-*-Tokens, Radius-Skala, Komponenten-Rezepte, Workspace-Signaturfarben oder andere getroffene Design-Entscheidungen), wird der Konflikt nicht still aufgelöst/überschrieben — der konkrete Konflikt wird benannt und der PO entscheidet. Ergänzt die Rückfragen-Regel der Root-CLAUDE.md(„nur an echten Weggabelungen fragen") um den Design-System-Fall. Everything-as-Code: Entscheidung landet als.md-Commit (Audit-Trail), nicht nur im Chat. - Branch
claude/next-steps-8vmq5d(PR #679) — OP-EDIT-1 Abschluss: Leistungen/Teilschritte — Ko-Bearbeiter-Präsenz (Slice A architektonisch N/A) → Rollout KOMPLETT (APP_VERSION0.113.0 → 0.114.0, MINOR — neues Feature). Der letzte offene OP-EDIT-1-Editor ist bewertet und abgeschlossen. Befund (Architektur): der Prozesse-Editor (processes.component.ts) ist durchgängig sofort-anwendend inline — jede Feld-Änderung (Toggle, Blur-Input, Chip, Prozess-Komposition viasetLeistungProzess) feuert unmittelbar einteilschritt.update/leistung.updatemit Ein-Feld-Patch; es gibt kein „Bearbeiten→Speichern"-Formular und keinbaseRev. Damit hat die optimistische Nebenläufigkeit (Slice A) hier nichts zu bewachen: kein Fenster, in dem ein veraltetes Formular einen Änderungs-Stapel still überschreiben könnte — jede Mutation ist atomar und wird sofort an alle gebroadcastet (last-write-wins gilt nur pro Ein-Feld-Klick, was bei Sofort-Anwendung gewollt ist);rev/baseRevje Feld wäre faktisch wirkungslos (der Client hat nach jedem Broadcast stets die frische Version). Force-Fit bewusst abgelehnt (Leitprinzip Einfachheit — keine Komplexität ohne True-North-Nutzen). Gebaut — Slice B adaptiert (echter Nutzen): solange jemand im Prozesse-Editor ist (editEnter('prozesse','config')beim Betreten via Constructor,editLeaveviaDestroyRef.onDestroy— generische, bereich-agnostische Präsenz-Infra, kein Server-Change), sehen andere ein Ko-Bearbeiter-Banner oben im Workspace („wird gerade auch bearbeitet von … — Änderungen wirken sofort für alle, bitte abstimmen"). Das adressiert das reale Risiko dieser geteilten, taktungs-harten Live-Konfig (zwei Admins stampfen sich sonst feldweise unbemerkt). Präsenz admin-gegated. Reiner Client-Change (Prozesse-Component) — kein Server/DTO/Schema, keine Migration. Entscheidung: Slice A dokumentiert N/A statt force-gefittet; Auslöser für späteres Slice A hier = eine etwaige Umstellung des Prozesse-Editors auf einen formular-basierten „Anzeigen→Bearbeiten→Speichern"-Flow. Damit ist der OP-EDIT-1-Rollout über ALLE Stammdaten-Editoren abgeschlossen (Arbeitsplatz-Referenz · Schicht · Mitarbeiter · Taxonomie mit Slice A+B; Leistungen/Teilschritte mit Slice B, Slice A N/A) —ops/OP-EDIT-1.mdstatuserledigt.tsc(Server + Client) + No-Hex + No-Console grün (ng buildin CI). Verifikations-Grenze: UI/Präsenz durch Typecheck belegt; ein Live-Zwei-Fenster-Banner bräuchte ein laufendes DO. Doku:ops/OP-EDIT-1.md(Rollout KOMPLETT ✅, status erledigt), Lastenheft §11-Anker,docs/betrieb/Offene-Punkte.md(regeneriert), CHANGELOG, HANDOFF §2/Footer, Timesheet. True North: die geteilte Prozess-Konfig wird koordiniert bearbeitet statt still gegenseitig überschrieben. - Branch
claude/next-steps-8vmq5d(PR #678) — OP-EDIT-1 Rollout: Taxonomie-Editor bekommt optimistische Nebenläufigkeit + Präsenz-Warnung (APP_VERSION0.112.0 → 0.113.0, MINOR — Feature-Rollout). Das OP-EDIT-1-Muster ist jetzt auch auf den inline Taxonomie-Editor (administration.component.ts, „Umbenennen") ausgerollt. Slice A (optimistische Nebenläufigkeit):TaxonomyValueträgt einen monotonen, nur serverseitig erhöhtenrev; der Client schickt beim Umbenennen die Basis-Version (baseRev) mit;taxonomie.updateprüft sie viarevVeraltet(bestehender Kernserver/src/operativ/edit-parallel.ts,test:edit) → veraltete Basis wird abgelehnt (edit.result {ok:false}), Erfolg quittiert{ok:true}. Slice B (Edit-Präsenz): über die bereich-agnostische InfraeditEnter('taxonomie', id)/editLeave(kein Server-Change):✎-Live-Badge in der Liste am gerade umbenannten Wert. Inline-Konflikt-UX (angepasst an den Nicht-Modal-Editor): anders als bei den Formular-Editoren (Arbeitsplatz/Schicht/Mitarbeiter) schließt der Inline-Edit bei Ablehnung und ein Banner oben in der Taxonomien-Karte meldet den Konflikt — die Liste zeigt via Broadcast bereits den Gewinner-Stand, erneutes „Umbenennen" holt die frischerev. Entscheidungen: (a) der Aktiv-Quick-Toggle bleibt bewusst ohnebaseRev(Ein-Feld-Aktion, kein Formular für Konflikt-UX — analogschichtToggle); (b) alle Schließ-Pfade (OK-Erfolg/Abbrechen/Konflikt) auf eineschliesseTaxEdit()-Methode zentralisiert, die die Präsenz zuverlässig räumt; (c)revoptional → keine Migration (fehlend = 0, rückwärtskompatibel). Damit ist der OP-EDIT-1-Rollout auf 4 von 5 Editor-Gruppen (Arbeitsplatz-Referenz · Schicht · Mitarbeiter · Taxonomien); offen bleibt nur noch Leistungen/Teilschritte.tsc(Server + Client) +test:edit/test:do-migrations+ No-Hex + No-Console + Persistenz-Gate grün. Verifikations-Grenze: rev-Kern pertest:editbelegt und dertaxonomie.update-Handler spiegelt den verifiziertenschicht.update/employee.update-Handler 1:1; ein Live-Zwei-Fenster-Konflikt bräuchte ein laufendes DO. Doku:ops/OP-EDIT-1.md(Taxonomie-Rollout ✅), Lastenheft §11-Anker, CHANGELOG, HANDOFF §2/Footer, Timesheet. CI-Hinweis: läuft jetzt auf GitHub-gehosteten Runnern (CI_RUNNER=ubuntu-latest, gesetzt nach dem self-hosted-Runner-Ausfall bei #677). True North: auch die Taxonomie-Pflege wird konfliktsicher — parallele Umbenennungen überschreiben nicht mehr still.
2026-07-22
- Branch
claude/next-steps-8vmq5d(PR #677) — OP-EDIT-1 Rollout: Mitarbeiter-Editor bekommt optimistische Nebenläufigkeit + Präsenz-Warnung (APP_VERSION0.111.0 → 0.112.0, MINOR — Feature-Rollout). Das OP-EDIT-1-Querschnittsmuster gegen stilles last-write-wins-Überschreiben ist jetzt auch auf den Mitarbeiter-Editor (staff.component.ts, Bearbeiten-Dialog) ausgerollt. Slice A (optimistische Nebenläufigkeit):Mitarbeiterträgt einen monotonen, nur serverseitig erhöhtenrev; der Client schickt beim Speichern die Basis-Version (baseRev) mit;employee.updateprüft sie viarevVeraltet(bestehender Kernserver/src/operativ/edit-parallel.ts,test:edit) → veraltete Basis wird abgelehnt (nicht angewendet, nicht gebroadcastet), der Speichernde bekommtedit.result {ok:false}→ Dialog bleibt offen mit Konflikt-Hinweis; Erfolg quittiert{ok:true}→ Dialog schließt (kein Race durch fremde Broadcasts). Slice B (Edit-Präsenz): über die schon vorhandene, bereich-agnostische InfraeditEnter('mitarbeiter', id)/editLeave(kein Server-Change — dieeditPraesenz-Map ist generisch): Warn-Banner „wird gerade auch bearbeitet von …" im Dialog (blockt nicht) +✎-Live-Badge in der Liste. Slice C entfällt: der Mitarbeiter-Editor ist bereits view-first (Karte read-only + expliziter „✎ Bearbeiten"-Knopf öffnet erst den Dialog). Entscheidungen: (a) derrevguardt gezielt das Stammdaten-Speichern (Name/Abteilung/Funktion/Verfügbarkeit/Vertrauensstufe) — die additiven Sub-Aktionen im selben Dialog (Skill zuweisen, Ausbildungsziel, Abwesenheit) bleiben eigenständige Messages und hebenrevnicht an (Granularität „je Stammdaten-Save", kein falscher Konflikt beim parallelen Skill-Zuweisen); Konsistenz-Fix (CodeRabbit): die Live-Pfade, die ein Editor-Vertragsfeld ändern (verfuegbarkeit/statusviaemployee.setVerfuegbarkeit+employee.startRecommendation), hebenrevebenfalls an, damit ein veralteter Editor-Save eine zwischenzeitliche Live-Statusänderung nicht still zurücksetzt; (b) alle drei Dialog-Schließpfade (Backdrop/×/Schließen) auf eineschliesseBearbeiten()-Methode zentralisiert, die die eigene Präsenz zuverlässig räumt; (c)revoptional → keine Migration (fehlend = 0, rückwärtskompatibel — ohnebaseRevbleibt es beim alten Verhalten). Der Rollout auf die übrigen Editoren (Taxonomien · Leistungen/Teilschritte) bleibt als mechanische Folge offen.tsc(Server + Client) +test:edit/test:do-migrations+ No-Hex + No-Console + Persistenz-Gate grün (ng buildin CI — lokal Node-Version-Limit). Verifikations-Grenze: rev-Kern pertest:editbelegt und deremployee.update-Handler spiegelt den verifiziertenschicht.update/arbeitsplatz.update-Handler 1:1; ein Live-Zwei-Fenster-Konflikt bräuchte ein laufendes DO. Doku:ops/OP-EDIT-1.md(Mitarbeiter-Rollout ✅), Lastenheft §11-Anker, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North: Stammdaten-Pflege wird auch beim Mitarbeiter-Editor konfliktsicher — parallele Bearbeitung überschreibt nicht mehr still.
2026-07-21
- Branch
claude/next-steps-8vmq5d(PR #676) — OP-EDIT-1 Rollout: Schicht-Editor bekommt optimistische Nebenläufigkeit + Präsenz-Warnung (APP_VERSION0.110.0 → 0.111.0, MINOR — Feature-Rollout). Das in OP-EDIT-1 an der Referenz (Arbeitsplatz-/Bucht-Editor) gebaute Querschnitts-Muster gegen stilles last-write-wins-Überschreiben ist jetzt auch auf den Schicht-Editor (administration.component.ts) ausgerollt. Slice A (optimistische Nebenläufigkeit):SchichtKatalogträgt einen monotonen, nur serverseitig erhöhtenrev; der Client schickt beim Speichern die Basis-Version (baseRev) mit;schicht.updateprüft sie viarevVeraltet(bestehender Kernserver/src/operativ/edit-parallel.ts,test:edit) → veraltete Basis wird abgelehnt (nicht angewendet, nicht gebroadcastet), der Speichernde bekommt eine gezielte Quittungedit.result {ok:false}→ Formular bleibt offen mit Konflikt-Hinweis + „Neu laden"; Erfolg quittiert{ok:true}→ Formular schließt (kein Race durch fremde Broadcasts). Slice B (Edit-Präsenz): über die schon vorhandene, bereich-agnostische InfraeditEnter('schicht', id)/editLeave(kein Server-Change — dieeditPraesenz-Map ist generisch): beim Betreten des Bearbeiten-Modus zeigt ein Warn-Banner die fremden Bearbeiter („wird gerade auch bearbeitet von …" — blockt nicht), ein✎-Live-Badge in der Liste markiert aktive Bearbeitung. Slice C entfällt: der Schicht-Editor ist bereits view-first (Liste read-only + expliziter „Bearbeiten"-Knopf → kein versehentliches Editieren beim Ansehen). Entscheidungen: (a)revoptional → keine Migration (fehlend = 0, rückwärtskompatibel — ohnebaseRevbleibt es beim alten last-write-wins); (b) den quick-Toggle „aktiv" in der Liste bewusst ohnebaseRevgelassen (Ein-Feld-Aktion, kein Formular für Konflikt-UX); (c) den bestehenden Quittungs-Effekt um einenschicht-Zweig erweitert statt zu duplizieren. Der Rollout auf die übrigen Editoren (Taxonomien · Mitarbeiter · Leistungen/Teilschritte) bleibt als mechanische Folge offen.tsc+test:edit/test:do-migrations/test:bereitschaft/test:ausfall/test:schicht-reserve+ng build+ No-Hex + No-Console + Persistenz-Gate grün. Verifikations-Grenze: rev-Kern pertest:editbelegt; ein Live-Zwei-Fenster-Konflikt bräuchte ein laufendes DO. Doku:ops/OP-EDIT-1.md(Schicht-Rollout ✅), Lastenheft §11-Anker, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North: Stammdaten-Pflege wird auch beim Schicht-Editor konfliktsicher — parallele Bearbeitung überschreibt nicht mehr still.
2026-07-20
- Branch
claude/next-steps-8vmq5d(PR #675) — OP-SCHICHT-1 Slice 4: Schicht-Ende-Aufräum-Checkliste (APP_VERSION0.109.0 → 0.110.0, MINOR — neues Feature). Eine konsolidierte To-do-Liste im Überblick („🧹 Schicht-Ende-Aufräumen"), die vor Feierabend alle offenen Nebenaufgaben an einer Stelle zeigt — statt sie über mehrere Karten/Workspaces verteilt zu lassen. Rein aus dem Live-State abgeleitet (D-2) und — wie schon Slice 2 — als reine Client-Komposition gebaut (kein Server-/DTO-Change, nichts gespeichert): die Karte aggregiert drei bereits gebroadcastete Signale — (1) 📍 Fahrzeuge ohne Standort (ohneStandortCount, mit Link in den Konflikte-Workspace), (2) 🌙 hochwertige Fahrzeuge nicht in der Halle (nachtHalle.resteaus Slice 2/3), (3) 🅿️ offene Umpark-Aufträge (umparkAuftraege, noch unterwegs). Summenanzeige „⚠ N offen" (amber) bzw. „✓ bereit fürs Schichtende" (grün) bei 0. Bewusst kein „Abhaken"/keine Persistenz — die offene Arbeit ist der Punkt; jede Zeile verschwindet automatisch, sobald die Lücke geschlossen ist (Standort erfasst / Fahrzeug in der Halle / Umparken quittiert), das braucht keinen gespeicherten „erledigt"-Zustand (D-2, keine neue Zustandsfläche). Reihenfolge = Dringlichkeit (Sicherheit/Standort zuerst). Entscheidung (Einfachheit): Konsolidierung über bestehende Signale statt neuer Server-Ableitung — der Nutzen (ein Blick vor Feierabend) entsteht rein aus Komposition.ng build(Overview-Chunk +~0,4 kB, kein Budget-Warning) + No-Hex + No-Console grün. Verifikations-Grenze: UI durch Build belegt; die Live-Zahlen bräuchten ein laufendes DO mit Belegungs-/Umpark-Daten. Damit ist die sichtbare Schicht-Ende-Sicht von OP-SCHICHT-1 komplett (Reserve · Nacht-Halle · Konfig · Checkliste); offen bleibt nur der große Scheduler-Planungsziel-Baustein. Doku:ops/OP-SCHICHT-1.md(Slice 4 ✅), Lastenheft §11-Anker, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: „Wo stehen die Fahrzeuge?" mündet vor Feierabend in eine klare, abarbeitbare Liste. - Branch
claude/next-steps-8vmq5d(PR #674) — OP-SCHICHT-1 Slice 3: Nacht-Halle-Konfig — Schwelle & Nacht-Hallen-Buchten admin-editierbar (APP_VERSION0.108.0 → 0.109.0, MINOR — neues Feature). Schließt die in Slice 2 bewusst offen gelassene Konfig-Lücke: der Admin bestimmt jetzt, ab welcher Güteklasse ein Fahrzeug „hochwertig" ist und welche Buchten die Nacht-Halle bilden. Modell: neues optionales persistiertes FeldnachtHalleKonfig { abGueteklasse: 1–3; buchtIds: string[] }(PersistedState, fehlend ⇒ Default Schwelle 2 + leere buchtIds → keine Migration,schemaVersionunverändert; onStart reicht es durch). Reine, testbare Kern-Helfer (insights.ts):nachtHalleKonfigEffektiv(Klemmung Güteklasse 1…3, Default 2) +istNachtHalleSlot— buchtIds-Allowlist (nur die gewählten Buchten zählen) ODER, wenn leer, Fallback auf den Indoor-Typ (INDOOR_TYP_RE, wie Slice 2). So bleibt das Default-Verhalten (unkonfiguriert = Indoor-Buchten) erhalten und wird gezielt überschreibbar. DO: wendet die Konfig in der Insight-Projektion an (istNachtHalleSlotje Fahrzeug-Bucht +abGueteklasseals Schwelle), emittiert die effektive Konfig im State-DTO; Admin-MessagenachtHalleKonfig.update(istKostenAdmin-gated, validiert/klemmt die Schwelle, filtertbuchtIdsauf existierende Bucht-IDs + dedupliziert). UI: neue Karte „🌙 Nacht-Halle (Schicht-Ende)" im Administration-Workspace — Güteklasse-Select + Bucht-Chips (leer = „alle Indoor-Buchten automatisch"), sofort-anwendend (wie der Aktiv-Toggle). Die Überblick-Karte übernimmt die konfigurierte Schwelle automatisch (nachtHalle.schwelle). Entscheidungen (Einfachheit): (a) ein zentrales Konfig-Objekt statt Konfig über alle Buchten verstreut; (b) buchtIds leer = Fallback, damit Bestands-Setups ohne Konfig unverändert laufen; (c) sofort-anwendend ohne Speichern-Button (kleiner Scope, wieschichtToggle/autoOptAktiv). Selbsttest intest:insightserweitert (Schwelle-Klemmung 0/9→1/3, Allowlist vs. Indoor-Fallback).tsc+test:insights/test:do-migrations/test:assistant-tools/operativ+ng build+ No-Hex + No-Console + Persistenz-Gate grün. Verifikations-Grenze: Logik per Selbsttest belegt; ein Live-Klick (Editor speichert → Überblick-Karte reagiert) bräuchte laufendes DO. Doku:ops/OP-SCHICHT-1.md(Slice 3 ✅), Lastenheft §11-Anker,docs/betrieb/Tests.md, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: die Nacht-Halle-Sicht ist jetzt betriebs-passend konfigurierbar statt fix verdrahtet. - Branch
claude/next-steps-8vmq5d(PR #673) — OP-SCHICHT-1 Slice 2: Nacht-Halle-Check — hochwertige Fahrzeuge (noch) nicht in der Halle (APP_VERSION0.107.0 → 0.108.0, MINOR — neues Feature). Ein abgeleiteter Schicht-Ende-Check beantwortet: welche hochwertigen Fahrzeuge stehen zum Schichtende noch draußen und sollten in die Halle? Reine Insight-FunktionnachtHalleReste(server/src/insights/insights.ts, D-2 — nichts gespeichert): aktive Aufträge mit Güteklasse ≥ Schwelle (Default 2 = Premium/Super-Premium; Standard = 1 darf draußen bleiben), deren Standort keine Halle/Indoor-Bucht ist — oder unbekannt — werden gelistet, dringlichste (höchste Güteklasse) zuerst, je mit Grund (nicht_in_halle/standort_unbekannt). „Halle" ohne neues Modell: der Leitstand markiert Indoor-Buchten über das schon bestehende Bucht-Typ-Label (INDOOR_TYP_RE, dieselbe Erkennung wie die Cool-down-Indoor-Pflicht) und löst den Indoor-Status pro Auftrag über die tatsächliche Bucht (Zugehörigkeit, nicht Namens-Join → robust gegen doppelte Bucht-Namen, CodeRabbit) auf →InsightAuftrag.standortIndoor; die Insight bekommt zusätzlichInsightAuftrag.gueteklasse(beide optional, rückwärtskompatibel). UI: neue Überblick-Karte „🌙 Nacht-Halle" neben der Standorte-Karte (True-North-Frage 2) — grün „✓ alle in der Halle" bzw. amber „⚠ N nicht in der Halle" + Liste (Auftragsnr · Güteklasse · Standort/„unbekannt"); Amber (Hinweis), nicht Rot. Entscheidungen (Einfachheit/Ehrlichkeit): (a) rein abgeleitet über bestehende Signale (Güteklasse + Indoor-Typ-Regex) — kein neues persistiertes Modell, keine Migration; (b) Schwelle-Default 2 als Parameter der reinen Funktion; (c) die Konfigurierbarkeit (Schwelle und dedizierte Nacht-Hallen-Buchten über die Typ-Regex hinaus) bleibt bewusst Folge-Slice — sie braucht einen Konfig-Speicher, der hier nicht mitgebaut wird (ehrlich als offen ausgewiesen statt halb angefangen). Selbsttest intest:insightserweitert (Schwelle 2 vs. 3, drinnen/draußen/Standard/unbekannt/abgeschlossen, Entwarnung).tsc+test:insights/test:assistant-tools/test:matching+ng build+ No-Hex + No-Console + Persistenz-Gate grün. Verifikations-Grenze: Logik per Selbsttest belegt; ein Live-Blick auf die Karte bräuchte laufendes DO mit Belegung. Doku:ops/OP-SCHICHT-1.md(Slice 2 ✅ + Folge-Slices präzisiert), Lastenheft §11-Anker,docs/betrieb/Tests.md, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: „Wo stehen die Fahrzeuge?" um die Sicherheits-/Nacht-Sicht erweitert — die teuren Autos sind auf einen Blick verortet, bevor die Schicht endet. - Branch
claude/next-steps-8vmq5d(PR #672) — OP-SCHICHT-1 Slice 1: Aufräum-Reserve am Schichtende (Default 30 Min, admin-konfigurierbar) + Gantt-Anzeige (APP_VERSION0.106.0 → 0.107.0, MINOR — neues Feature). Jede Schicht reserviert die letzten X Minuten fürs Schicht-Ende-Aufräumen (Einparken/Nacht-Zustand) — der Scheduler plant dort keine reguläre Arbeit mehr. Neues FeldaufraeumReserveMinaufSchichtKatalog(Default 30, admin-editierbar pro Schicht, 0…120), umgesetzt über den ganzen heterogenen Stack. Scheduler (der Clou): der Abzug sitzt an genau einer Stelle —mitarbeiterAvailability(server/src/scheduler/availability.ts) verkürzt das planbare Fenster am spätesten Slot (= Schichtende; Pausen-Slots bleiben voll planbar). Weil der CP-SAT-Solver die von dort vorab expandiertenavail-Intervalle konsumiert (solver/problem.ts→solver-service/model.py), wirkt der Abzug paritätisch auf TS-Fallback-Scheduler UND Python-Solver — eine TS-only-Änderung, keine Solver-Anpassung nötig. Gantt: die Reserve erscheint als eigenes grünes Bandart:'aufraeumen'(„Aufräumen",scheduler/ausfall.ts+AUSFALL_COLOR/AUSFALL_LABEL) am Schichtende — der Nutzer sieht die reservierte Zeit. Schicht-Editor: Minuten-Eingabe (type=number, 0…120) im Administration-Workspace, Anzeige „🧹 X min" je Schicht. Server-Plumbing:SchichtPatch+schicht.create/update-Handler mit Validierung/Klemmung (klemmeReserve, 0…120, gerundet), DTO-Builder emittiert den effektiven Wert (inkl. Default 30). Entscheidungen (Einfachheit): (a) Abzug nur am spätesten Slot (Schichtende), nicht an jedem Slot — sonst würde ein Vormittags-Slot vor der Mittagspause fälschlich gekürzt; (b) Reserve uniform auf alle Schicht-Arten inkl. Überlauf/Bereitschaft (einfachste konsistente Regel); (c) Default 30 via?? 30greift auch für Bestand ohne Feld → keine Migration nötig (optionales Feld,schemaVersionunverändert); explizite 0 wird respektiert (??nicht||). Blast-Radius bewusst geprüft: der Default 30 verschiebt Makespans in Test-Fixtures — die betroffenentest:ausfall/test:bereitschaft-Fixtures wurden explizit aufaufraeumReserveMin: 0gepinnt (isolieren ihre Ausfall-/Bereitschafts-Assertions), die volle Server-Test-Suite ist grün. Neuer Selbsttesttest:schicht-reserve(14 Prüfungen: Default/Klemmung, Verkürzung am spätesten Slot, Pausen-Slot bleibt voll, Gantt-Band) als CI-Gate.tsc+ alle Server-Tests +ng build+ No-Hex + No-Console + Persistenz-Gate grün. Verifikations-Grenze: Scheduler-Abzug + Band per Selbsttest belegt; ein Live-Gantt-Klick bräuchte laufendes DO. Doku:ops/OP-SCHICHT-1.md(Slice 1 ✅), Lastenheft §11-Anker,docs/betrieb/Tests.md,.github/workflows/ci.yml, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #1/#3: definierter Nacht-Zustand + ehrliche Kapazität — die Schicht-Endzeit ist nicht mehr „bis zur letzten Minute verplant", das Aufräumen hat seinen festen, sichtbaren Platz.
2026-07-19
- Branch
claude/next-steps-8vmq5d(PR #671) — OP-UMPARK-3 Slice 2: Umpark-Empfehlung nach Skill-Eignung gewichten (APP_VERSION0.105.0 → 0.106.0, MINOR — Optimierung eines bestehenden Features). Slice 1 empfahl Zielbuchten nur nach Bucht-Typ + freier Kapazität; jetzt rankt die Empfehlung zuerst nach Skill-Eignung — Buchten, die den vom aktuellen/nächsten Schritt geforderten Skill anbieten (Arbeitsplatz.skillIds⊇ {Skill}), stehen oben, mit „🎯"-Badge; die Überschrift nennt „· Skill ". Warum entscheidend: laut Scheduler (§6.1) kann ein Schritt nur in einer Bucht laufen, die seinen Skill anbietet — eine typ-gleiche Bucht ohne den Skill ist gar kein gültiges Ziel, Slice 1 konnte also eine unbrauchbare Bucht empfehlen. Die Verfeinerung macht die Empfehlung fachlich korrekt, nicht nur typ-plausibel. Rein Client ( repark-modal.component.ts): der geforderte Skill kommt aus demteilschritteKatalog(Instanz →teilschrittId→benoetigteSkillId+ aufgelöster Name), die Bucht-Skills ausarbeitsplaetze().skillIds— beide schon im State, kein Server-/DTO-Change. Zwei-Stufen-Sort (Skill zuerst, dann freieste Kapazität) → nie leere Liste, wenn Skill-Tags fehlen (Fallback = Typ-Empfehlung wie Slice 1); fordert der Schritt keinen Skill (z. B. Logistik), bleibt es bei der reinen Typ-Empfehlung. Entscheidungen (Einfachheit/Ehrlichkeit): (a) von den drei OP-Faktoren (Skill · Ausstattung · Nähe) nur Skill umgesetzt — der einzige mit real matchbaren Daten und echter Scheduler-Relevanz; (b) Ausstattung bewusst nicht gewichtet — ein Teilschritt deklariert keine geforderte Ausstattung (nur Typ + Skill), es gäbe nichts zu matchen (bräuchte Datenmodell-Feld); (c) Nähe/G-4 bewusst nicht berechnet — Buchten tragen keine Standort-/Zonen-Info, eine erfundene Distanz wäre unehrlich (bräuchte Layout-/Zonen-Modell); beide als Folge-OP dokumentiert.ng build(occupancy-Chunk unverändert, kein Budget-Warning) + No-Hex grün. Verifikations-Grenze: UI durch Build belegt; ein Klick-Durchlauf (skill-passende Bucht steht oben mit 🎯) bräuchte Live-DO. Doku:ops/OP-UMPARK-3.md(Slice 2 ✅ + Offen-Punkte präzisiert), Lastenheft §11-Anker, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #1/#3: der fachlich richtige Zielplatz zuerst → bessere Bucht-Auslastung, kein Fehl-Rangieren auf eine Bucht, in der der nächste Schritt gar nicht laufen darf. - Branch
claude/next-steps-8vmq5d(PR #670) — OP-STEP-1 Slice 4: Server-Backstop gegen out-of-order-Schritt-Abschluss (APP_VERSION0.104.1 → 0.105.0, MINOR — neue, rückwärtskompatible Absicherung). Das Sequenz-Gating aus Slice 1 (nur der aktuelle Schritt der Reihenfolge ist abschließbar) galt bisher nur im Client; jetzt lehnt der Server-Handlerteilschritt.aktion 'erledigen'einen out-of-order-Abschluss ebenfalls ab (Defense-in-Depth — ein manipulierter/veralteter Client kann die Reihenfolge nicht mehr umgehen). Umsetzung: zwei reine, testbare Prädikate inserver/src/operativ/auftrag.ts—istOffenerSchritt(geplant/in_arbeit/pausiert) undistAktuellerSchritt(auftrag, instanzId)(spiegelt die Client-Frontier-Logik: laufende Schritte sind immer aktuell, ein geplanter nur, wenn er die früheste Startzeit unter den offenen Schritten teilt → echte Parallel-Schritte bleiben beide abschließbar, strikt spätere sind gesperrt). Der Gate greift vor dem Doku-/Foto-Gate (Sequenz zuerst, wie PO-Entscheid 07-19) und verwirft still (der Client bietet gesperrte Schritte gar nicht an). Entscheidungen: (a) nurerledigengaten, nichtstarten— Parallelität/Vorziehen bleiben erlaubt (Einfachheit, kein Über-Sperren); (b) Frontier per Startzeit-Heuristik statt expliziter G-1-Abhängigkeit im DTO — einfachste tragfähige Näherung, deckungsgleich mit dem Client; die explizite Abhängigkeit ist eine bedingte Folge-Verfeinerung. Rein Server, keine DTO-/Schema-Änderung (nutztstatus/startder Instanz). Selbsttesttest:step-gate(20 Prüfungen: Front-Sequenz, erledigte Vorstufe rückt vor, laufend/pausiert immer aktuell, echte Parallelität, Robustheit unbekannte Id) → als CI-Gate im Server-Job.tsc --noEmitgrün. OP-STEP-1 damit erledigt (alle 4 Slices); offen nur die bedingte „feinere Parallelität". Doku:ops/OP-STEP-1.md(Slice 4 ✅, Status erledigt), Lastenheft §11-Anker,docs/betrieb/Tests.md,.github/workflows/ci.yml, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: der Bearbeitungsstand bleibt korrekt — Schritte werden nur in echter Reihenfolge abgeschlossen, auch wenn ein Client danebengreift. - Branch
claude/next-steps-8vmq5d— OP-UMPARK-4 abgeschlossen: „Umparken"-Sichtbarkeit geklärt + Wortlaut vereinheitlicht (APP_VERSION0.104.0 → 0.104.1, PATCH — Klärungs-OP + kleiner UX-Tweak). Ist-Bestandsaufnahme (Explore) aller 8 Auslöse-Stellen von „Umparken": Belegung/Hofplan (📍 Standort-Zuweisung · Fahrzeug-Chip 📍 · 🅿️ Freiräumen · Drag&Drop), Konflikte (📍 Standort zuweisen · 📍 Umparken bei geparkt_gesperrt/_vor_sperre), Auftrag-Detail-Panel (📍 Umparken), Meine Arbeit (✓ Angekommen). Kern-Erkenntnis: das Grundgerüst ist bereits sauber — ein gemeinsamerReparkService+ ein global gemountetes Repark-Modal; die Verteilung ist kontextrichtig (überall, wo man ein Fahrzeug im Blick hat) und bleibt bewusst. Entscheidungen (PO 07-19, im OP festgeschrieben): (1) zwei sprechende Begriffe — „Standort zuweisen" (Fahrzeug ohne Platz einweisen) vs. „Umparken" (Platz→Platz); der einzige Ausreißer „📍 Standort" (Belegung) ist auf „📍 Standort zuweisen" angeglichen (deckungsgleich mit der Konflikte-Sektion); (2) die zwei Direkt-Pfade (Drag&Drop-Geste + 🅿️ Freiräumen-Ein-Klick) bleiben bewusst als Komfort-Features, die übrigen 6 Trigger laufen einheitlich über das gemeinsame Modal; (3) Sichtbarkeitsregeln = Ist-Referenztabelle im OP (Trigger nur zeigen, wenn im Kontext sinnvoll — nicht „immer"). Umsetzung: reiner Wortlaut-Angleich (occupancy.component.ts) + festgeschriebene Ist-/Soll-Referenz — keine Verhaltens-/Pfad-Änderung.ng build(649,4 kB) + No-Hex + No-Console grün. Doku:ops/OP-UMPARK-4.md(Ist-Tabelle + Entscheidung, Status erledigt), Lastenheft §11-Anker, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: „Umparken" einheitlich benannt + dort, wo der Nutzer es erwartet. - Branch
claude/next-steps-8vmq5d(PR #668) — OP-UMPARK-3 Slice 1: Umparken empfiehlt passende Buchten nach aktuellem Schritt (APP_VERSION0.103.0 → 0.104.0, MINOR — neues Feature). Baut auf OP-STEP-1 („aktueller Schritt") auf: das Repark-Modal zeigt oben eine Empfehlungs-Gruppe — die Buchten, die zum aktuellen/nächsten Schritt des umzuparkenden Auftrags passen (Bucht vom geforderten Typ mit freier Kapazität, freieste zuerst), mit Begründung „✅ Empfohlen für „" · braucht ". Statt einer generischen, unsortierten Liste sieht der Nutzer sofort den fachlich richtigen Zielplatz (z. B. Folierbucht für die anstehende Vollfolierung). Der aktuelle Schritt = laufender ( in_arbeit/pausiert), sonst der offene mit der frühesten Startzeit (Frontier, analog OP-STEP-1). Rein Client (repark-modal.component.ts:aktuellerSchritt/geforderteTypen/empfohlen): gematcht wird über die bereits vorhandenen Label-Felder — der Teilschritt-DTO liefertbenoetigteBuchtTypenals Labels,BelegungSlotDTO.typLabelebenso → kein Server-/DTO-Change nötig. Die empfohlenen Buchten werden aus der „Weitere Ziele"-Liste ausgeblendet (keine Doppelanzeige). Entscheidungen: (a) nur Buchten empfehlen (Parkplätze sind keine Arbeitsplätze für den nächsten Schritt); (b) keine Auto-Vorwahl — die Empfehlung ist sichtbar, der Nutzer wählt bewusst (Selbsterklärbarkeit, keine Magie); (c) Match per Typ-Label als einfachste tragfähige Näherung — Skill/Ausstattung/Nähe-Gewichtung (G-4) ist Folge-Verfeinerung. Prozess-Pause (Teil B der OP) ist weitgehend vorhanden: Umparken eines laufenden Auftrags auf einen Parkplatz setzt schonmodus: 'pausieren'(OP-UMPARK-1), Transit-Puls + „Angekommen"-Quittung existieren.ng build(649,2 kB, kein Budget-Warning) + No-Hex + No-Console grün. Verifikations-Grenze: UI durch Build belegt; ein Klick-Durchlauf (Umparken öffnen → Empfehlung passt zum nächsten Schritt) bräuchte Live-Backend (DO). Doku:ops/OP-UMPARK-3.md(Slice 1 ✅ + Pause-Status), Lastenheft §11-Anker, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #1/#3: der richtige Platz zur richtigen Zeit — bessere Bucht-Auslastung, weniger Fehl-Rangieren. - Branch
claude/next-steps-8vmq5d— OP-STEP-1 Slice 3: Foto-Vorgaben je Teilschritt als Stammdaten pflegen (APP_VERSION0.102.0 → 0.103.0, MINOR — neues Feature). Schließt die Lücke aus Slice 2 („nach Vorgabe" hatte oft keine Daten): im Prozesse-Workspace sind jetzt je Teilschritt die Pflicht-Foto-Perspektiven + Mindestanzahl editierbar (Perspektive mit VorschlagslisteFront/Heck/Seite links/…via<datalist>+ freier String G-1, Anzahl ≥1, Hinzufügen/Entfernen), dazu ein Doku-Pflicht-Toggle. Die Vorgaben speisen direkt die Abschluss-Checkliste (Slice 2) und die Foto-Pflicht-Gates im Werker-Flow. Rein Client: der Server nahm den Patch längst an (teilschritt.update→setzeTeilschrittFeldernormalisiertfotoPflicht/dokuPflicht/dokuAspekte— Anzahl≥1, Perspektiven getrimmt/dedupliziert) und emittierte die Werte bereits im Katalog-DTO (buildProzessKatalog/buildTeilschrittKatalog); es fehlten nur die Client-DTO-Felder (ProzessSchrittDTO.{dokuPflicht,fotoPflicht,dokuAspekte}), der erweiterteupdateTeilschritt-Patch und der Editor (processes.component.ts:fotoAdd/fotoSetAnzahl/fotoRemove,TeilschrittRow+zuRowerweitert). Entscheidungen: (a) Editor im Prozesse-Workspace (dort leben die Teilschritt-Stammdaten), nicht in der Administration; (b)<datalist>-Vorschläge statt hartem Enum (G-1: freier Perspektiven-String bleibt erlaubt); (c) Server-Normalisierung ist die Wahrheitsquelle (Client sendet roh,fotoAnforderungensäubert) — pro-Zeile eindeutigedatalist-ID (kein Duplikat im@for).ng build(646,8 kB, processes-Chunk 27,7→31,5 kB, Initial unverändert) + No-Hex + No-Console grün. Verifikations-Grenze: UI durch Build belegt; ein Klick-Durchlauf (Vorgabe setzen → im Werker-Abschluss erscheint die Perspektive) bräuchte Live-Backend (DO). Damit sind OP-STEP-1 Slices 1–3 (aktueller Schritt · geführter Abschluss · Vorgabe-Pflege) gebaut — OP bleibt „offen" nur für den optionalen Server-Backstop (out-of-order-Ablehnung). Doku:ops/OP-STEP-1.md(Slice 3 ✅), CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: die Nachweis-Vorgabe ist jetzt pflegbar statt hartcodiert/leer. - Branch
claude/next-steps-8vmq5d(PR #666) — OP-STEP-1 Slice 2: geführter Foto-/Doku-Abschluss (sprechende Restliste) (APP_VERSION0.101.0 → 0.102.0, MINOR — neues Feature). Adressiert den zweiten Teil des PO-Befunds („bei Abschluss müssen Fotos nach Vorgabe ergänzt werden"). Die Foto-Pflicht-Mechanik existierte bereits (t.fotoPflicht/fotoPflichtErfuellt, „Fertig" gesperrt bis erfüllt), war aber optisch schwach: nur ein vages „📷 Pflicht-Fotos fehlen noch". Neu (reiner Client,auftrag-detail-panel.component.ts): der Abschluss-Dialog zeigt eine sprechende Restliste —abschlussReste(t)listet die konkret fehlenden Pflicht-Foto-Perspektiven (📷) + die Pflicht-Doku (📝), live aktualisiert beim Tippen/Fotografieren; ist alles da, erscheint grün „✓ Alles erfasst — Schritt kann abgeschlossen werden". Der Pflicht-Foto-Block trägt jetzt die Überschrift „📷 Pflicht-Fotos (Vorgabe)". Leere Vorgabe (weder Pflicht-Foto noch Pflicht-Doku) wird klar benannt („Keine Foto-/Doku-Vorgabe hinterlegt — Abschluss ohne Nachweis; Vorgabe je Leistung/Schritt pflegbar") statt kommentarlos zu fehlen — Übergang zu Slice 3 (Vorgabe-Pflege). Entscheidung: die Restliste spiegelt exakt das bestehende „Fertig"-Disabled-Gate ( (dokuPflicht && kein Kommentar) || !fotoPflichtErfuellt) → keine zweite Wahrheitsquelle, nur sprechender gemacht.ng build(646 kB, kein Budget-Warning) + No-Hex + No-Console grün. Verifikations-Grenze: UI-Fluss durch Build belegt; ein Klick-Durchlauf (Foto aufnehmen → Restliste schrumpft → Fertig) bräuchte Live-Backend (DO) mitFOTOS-Binding. Doku:ops/OP-STEP-1.md(Slice 2 ✅), CHANGELOG, HANDOFF §2/Footer, Timesheet. Offen: Slice 3 (Foto-Vorgaben als Stammdaten pflegen), Server-Backstop. True North #2: der Abschluss erzwingt den Nachweis sichtbar statt ihn zu hoffen. - Branch
claude/next-steps-8vmq5d— OP-STEP-1 Slice 1: nur der aktuelle Prozessschritt ist fertigmeldbar (Reihenfolge sichtbar) (APP_VERSION0.100.0 → 0.101.0, MINOR — neues Feature) + drei neue OPs erfasst. Befund (PO, am Auftrag-Detail-Panel): jeder offene Schritt bot gleichzeitig „✓ Fertig (mit Doku)" — man konnte außer der Reihe abschließen, der aktuelle Stand war unklar. Fix (Slice 1, reiner Client): nur der aktuelle Schritt ist fertigmeldbar und hebt sich ab („▶ jetzt dran"); spätere offene Schritte sind gesperrt mit Hinweis „🔒 kommt später — erst nach". Der aktuelle Schritt = laufender ( in_arbeit/pausiert) oder der offene Schritt mit der frühesten Startzeit (front); da der Scheduler Parallelität in die Startzeiten kodiert, teilen echte Parallel-Schritte die früheste Startzeit und bleiben beide aktionierbar, strikt spätere werden gesperrt (auftrag-detail-panel.component.ts:istAktuellerSchritt/istGesperrterSchritt/aktuellerSchrittName,kannSchrittErledigenverschärft — gated Fertig-Knopf + Foto-/Doku-UI). Entscheidungen: (a) PO-Wahl „hart" (nur aktueller Schritt, nicht nur optisch); (b) Startzeit-Frontier als einfachste tragfähige Näherung — nutzt vorhandene DTO-Felder (status/start), kein Server-/Schema-Change; die exakte G-1-Abhängigkeit (nach_vorherigem/parallel/frei) lebt auf dem ProzessSchritt und ließe sich für exaktes Gating ins Instanz-DTO heben (Folge-Slice); (c) Server-Backstop (out-of-order-Ablehnung) + geführter Foto-/Doku-Abschluss (Slice 2) + Vorgabe-Pflege (Slice 3) bleiben offen. Die Foto-Pflicht-Mechanik existiert bereits (t.fotoPflicht/fotoPflichtErfuellt, „Fertig" gesperrt bis erfüllt) — Slice 2 macht sie prominenter/geführt.ng build(645 kB, kein Budget-Warning) grün. Verifikations-Grenze: UI-Fluss durch Build belegt; ein Klick-Durchlauf bräuchte ein Live-Backend (DO). Neue OPs erfasst (Doku): OP-STEP-1 (Parent, Slices 1–3), OP-UMPARK-3 (Umparken schlägt passendste Plätze nach aktuellem Schritt vor + pausiert den Prozess), OP-UMPARK-4 (klären, wo „Umparken" sichtbar/erreichbar ist). Doku:ops/OP-STEP-1.md,ops/OP-UMPARK-3.md,ops/OP-UMPARK-4.md, Lastenheft §11-Anker, Offene-Punkte regeneriert, CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: klarer, wo das Fahrzeug in der Bearbeitung steht. - Branch
claude/next-steps-8vmq5d(PR #661) — OP-EDIT-1 Slice C: View-first — read-only Detailansicht + expliziter Bearbeiten-Schritt (APP_VERSION0.99.0 → 0.100.0, MINOR — neues Feature). Dritter und letzter geplanter Baustein von OP-EDIT-1: der Arbeitsplatz-/Bucht-Editor öffnet einen Datensatz jetzt zuerst read-only, Bearbeiten ist ein bewusster Schritt (statt direkt ins Formular) — die übrigen Stammdaten-Editoren folgen erst mit dem noch offenen Rollout. Referenz-Implementierung am Arbeitsplatz-/Bucht-Editor: die Liste öffnet einen Datensatz über „Anzeigen" in einer read-only Detailansicht (Kapazität, Status, Skills/Ausstattung als sprechende Namen statt IDs, geplante Sperren,rev-Version); erst „✎ Bearbeiten" dort wechselt ins Formular (editEnter-Präsenz, Slice B), „Abbrechen"/erfolgreiches Speichern kehrt in die Anzeige zurück. Synergie mit A+B: die Präsenz-Warnung (Slice B) erscheint schon in der Anzeige (man sieht vor dem Bearbeiten, wer drin ist), ein✎-Live-Badge in der Liste zeigt aktive Fremd-Bearbeitung. Entscheidungen: (a) Detail read-only als eigener Zustand (ansichtId), Formular hat Vorrang, wenn beide zuträfen (ansichtOffen = ansichtId && !formOffen); (b) Referenz zuerst am Arbeitsplatz-Editor (wo A+B leben) — der Rollout auf die übrigen Editoren (Taxonomien, Schichten, Mitarbeiter, Leistungen) ist mechanische Musteranwendung und bleibt offen; (c) Löschen bleibt als eigene Aktion in der Liste (kein „Editieren"). Reiner Client, kein Server/Schema/Solver (nutzt die vorhandenen DTO-Felder + Slice-B-Präsenz).ng build(643,8 kB, admin-Chunk 39→44 kB, Initial dank OP-PERF-1 unverändert) + No-Hex (/60-Opacity-Muster wie im Bestand) + No-Console grün. Damit sind die drei geplanten OP-EDIT-1-Slices (A optimistische Nebenläufigkeit · B Edit-Präsenz · C View-first) gebaut — OP bleibt „offen" nur für den Editor-Rollout. Verifikations-Grenze: UI-Fluss durch Build/Typecheck belegt; ein Klick-Durchlauf (Anzeigen→Bearbeiten→Abbrechen/Speichern) bräuchte ein Live-Backend (DO). Doku:ops/OP-EDIT-1.md(Slice C ✅ Referenz + Rollout offen), CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: sichere, bewusste Stammdaten-Pflege ohne versehentliche Änderungen.
2026-07-18
- Branch
claude/next-steps-8vmq5d— OP-EDIT-1 Slice B: Edit-Präsenz — Warnung bei gleichzeitigem Bearbeiten (APP_VERSION0.98.0 → 0.99.0, MINOR — neues Feature). Baut auf Slice A (optimistische Nebenläufigkeit) auf und liefert die zweite Hälfte der PO-Anforderung: „warnen, wenn ein anderer Benutzer/ein anderes Fenster den Datensatz bereits bearbeitet". Mechanik: der Server führt eine transiente Präsenz-Map je Verbindung (editPraesenz) → im State alsbearbeitungen: EditPraesenzDTO[]gebroadcastet (live, nicht persistiert). Der Client meldet beim Betreten/Verlassen des Bearbeiten-Modusedit.enter/edit.leavemit einer stabilen, in-memory erzeugtenfensterId(crypto.randomUUID, interim ohne echte Identität bis OP-AUTH-1); der Server räumt die Präsenz beiedit.leaveundonClose(verwaiste Sitzung nach Verbindungsabbruch). Im Arbeitsplatz-Editor zeigt ein oranges Warn-Banner die fremden Bearbeiter (Name oder kurzer Fenster-Tag), sobald ≥1 anderes Fenster denselben Datensatz offen hat — live reaktiv (erscheint/verschwindet, wenn jemand ein-/aussteigt). Blockt bewusst nicht (Schreiben bleibt möglich; erst der erste Speichervorgang entwertet die anderen via Slice A → dort kommt der „bitte neu laden"-Hinweis). Entscheidungen: (a) Präsenz als eigener transienter Live-State (analogconnections), nicht inPersistedState→ kein Migrations-/Persistenz-Aufwand; (b) Selbst-Ausschluss client-seitig über die eigenefensterId(der Server muss dem Client nicht seine conn-Id mitteilen — die Broadcast-Zwei-Varianten-Optimierung bleibt unangetastet); (c)edit.enteradmin-gegated (nur berechtigte Editoren, kein Spoofing gefälschter Präsenz); (d) Präsenz-Timeout für Zombie-Sitzungen bewusst später (onClose deckt den Normalfall).tsc+ng build(643,7 kB, kein Budget-Warning) + No-Hex + No-Console +persistence:check(kein Schema-Change) +test:do-migrations(v0→v22, keine Migration) grün. Verifikations-Grenze: die Präsenz-/Broadcast-Logik ist durch Typecheck/Build belegt; ein voller Zwei-Sitzungen-Durchlauf (Fenster A + B) braucht ein Live-Backend (DO). Slice C (View-first-Toggle über alle Editoren) bleibt offen. Doku:ops/OP-EDIT-1.md(Slice B ✅ + C offen), CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #2: Stammdaten-Pflege ohne stille Kollisionen bei paralleler Arbeit am Leitstand. - Branch
claude/next-steps-8vmq5d(PR #659) — OP-PERF-1: Initial-Bundle via Route-Level-Lazy-Loading reduziert — OP-PERF-1 abgeschlossen (APP_VERSION0.97.0 → 0.98.0, MINOR — Optimierung). Der echte Fix zur Sofortmaßnahme aus OP-ALERT-1 Slice 3 (damals nur Budget angehoben = Headroom): alle Workspaces außer der Shell + dem Landing-Raum Überblick laufen jetzt überloadComponent-Lazy-Routing (client/src/app/app.routes.ts) → jeder der 14 übrigen Räume ist ein eigener Chunk und landet erst beim Öffnen im Browser. Gemessen (ng build): Initial-Chunk 935,7 kB → 558,8 kB, Initial-Total 1,02 MB → 643 kB (Transfer ~218 → ~155 kB, −37 %); schwerste ausgelagerte Chunks Planung/Gantt (62 kB) · Mitarbeiter (54 kB) · Annahme/Administration (je 38 kB) · Konflikte/Qualität (je ~35 kB). Budget wieder gestrafft (client/angular.json):maximumWarning1 mb → 750 kb,maximumError1,25 mb → 900 kb (fängt Regressionen, ~107 kB Warn-Headroom). Entscheidungen: (a) Landing-Raum eager lassen (garantierter Erst-View → kein Lazy-Flash auf dem kritischen Pfad); (b) alle übrigen Räume uniform lazy (einfachste, gleichförmige Regel, maximale Reduktion); (c) Deep-Link-Pfade unverändert (kein Bruch bestehender Links/Redirects inkl.klaerfaelle→conflicts). Reiner Client, kein Server/Schema/Solver.ng build(643 kB, kein Budget-Warning) + No-Hex grün. Verifikations-Grenze: die Route-Auflösung ist durch den erfolgreichen Build mit 14 generierten Lazy-Chunks belegt; ein voller Klick-Durchlauf aller Räume braucht Live-Backend (DO). Doku:ops/OP-PERF-1.md(Umsetzung + Messung, Status erledigt), CHANGELOG, HANDOFF §2/Footer, Timesheet. True North #1–#3: schnellere Erst-Ladezeit am Leitstand/Terminal. - Branch
claude/next-steps-8vmq5d— OP-EDIT-1 Slice A: optimistische Nebenläufigkeit für den Arbeitsplatz-Editor (APP_VERSION0.96.0 → 0.97.0, MINOR). Erster Baustein gegen stilleslast-write-wins-Überschreiben (Auslöser: OP-UMPARK-2 Slice B, Sperren-Editor „ganze Liste patchen"). Jeder Arbeitsplatz/Bucht-Datensatz trägt jetzt einen monotonen Versionsstempelrev(nur serverseitig erhöht); der Client schickt beim Speichern die Basis-Version (baseRev) mit. Reiner, testbarer KernrevVeraltet/naechsteRev(server/src/operativ/edit-parallel.ts,npm run test:edit, 9 Prüfungen): ist die Basis veraltet (jemand anderes hat zwischenzeitlich gespeichert), wird das Speichern abgelehnt — nicht angewendet, nicht gebroadcastet. Quittung per Verbindungedit.result {ok}: ok=false → Formular bleibt offen mit Konflikt-Hinweis + „Neu laden"; ok=true → Formular schließt. Entscheidungen: (a) Ack-basiert statt Broadcast-Heuristik — erst die per-Verbindungs-Quittung schließt das Formular, so schließt kein fremder Broadcast es vorzeitig (Race) und keine abgelehnte Änderung verpufft still; (b) rückwärtskompatibel — ohnebaseRev(Alt-Client) bleibt es beim bisherigen Verhalten; (c) Granularität je Datensatz (nicht je Feld), Empfehlung der OP. Kein Migrations-/State-Aufwand (revnested-optional, Alt-Datensätze = 0). Slice B (Edit-Präsenz-Broadcast) + Slice C (View-first-Toggle über alle Editoren) bleiben offen.tsc+ng build(1,02 MB, bekanntes OP-PERF-1-Headroom) + No-Hex +test:edit/test:konfliktegrün. Doku:ops/OP-EDIT-1.md(Slice A ✅ + B/C offen), CHANGELOG, HANDOFF §4, Timesheet,docs/betrieb/Tests.md. True North #2: Stammdaten-Pflege ohne stille Datenverluste bei paralleler Arbeit am Leitstand. - Branch
claude/next-steps-8vmq5d— Zwei neue OPs festgehalten (PO, Doku-only → kein Bump): OP-EDIT-1 — Bearbeiten-Modus & gleichzeitiges Editieren von Stammdaten (View-first · explizit editieren · Edit-Präsenz-Warnung wenn ein anderer Benutzer/ein anderes Fenster den Datensatz bearbeitet · optimistisches Schreiben: Schreiben bleibt möglich, der erste Schreibvorgang entwertet die konkurrierenden Sitzungen → Meldung „bitte neu laden"; Versionsstempel je Datensatz). Löst den „last-write-wins"-Vorbehalt aus OP-UMPARK-2 Slice B; Querschnitts-Muster für alle Stammdaten-Editoren. OP-OPT-10 — Scheduler-Abwägung „Auto in der Bucht warten lassen vs. ausparken" (CP-SAT-Automatisierung des manuellen Hebels aus OP-UMPARK-2 Slice C). Doku:ops/OP-EDIT-1.md,ops/OP-OPT-10.md, Lastenheft §11-Anker, Offene-Punkte regeneriert. - Branch
claude/next-steps-8vmq5d— OP-UMPARK-2 Slice B + C: geplante Sperre zur Laufzeit + Bucht-Freiräumen — OP-UMPARK-2 damit abgeschlossen (APP_VERSION0.95.0 → 0.96.0, MINOR). Slice B (geplante Sperre + Vorlauf): Bucht-Sperren (ZeitfensterSperre[beginn,ende]) sind jetzt zur Laufzeit anlegbar/entfernbar — derarbeitsplatz.update-Patch trägtsperren(ganze Liste ersetzen), server-validiert über die reine, testbarevalidiereSperren(server/src/operativ/sperre.ts: gültigersperre_grund+beginn<ende, ISO-parsebar; Ungültiges wird verworfen);ArbeitsplatzDTO.sperrenexponiert; Sperren-Editor im Administration-Workspace (Grund-Dropdown aus dersperre_grund-Taxonomie + Von/Bis alsdatetime-local+ optionale Beschreibung + Entfernen; 🔒-Badge in der Liste). Neuer Vorlauf-Konfliktgeparkt_vor_sperre(Mittel,konflikteGeparktVorSperre): parkt ein Auto in einer noch aktiven Bucht mit kommender/laufender Sperre → „rechtzeitig umparken" mit „📍 Umparken"-Direktknopf (ergänztgeparkt_gesperrt/sperre_kollidiert). Slice C (Bucht freiräumen): in der Belegung trägt ein wartendes Auto (kein laufender Prozess) in einer Bucht einen „🅿️ Freiräumen"-Knopf, der es per Klick auf den ersten freien Parkplatz umparkt — über den bestehenden G-4-Umpark-Auftrag (OP-UMPARK-1, inkl. Transit-Puls + Quittung). Entscheidungen: (a) Sperren als ganze Liste patchen (einfachster robuster Editor-Vertrag) statt Index-Ops; (b) Slice C als manueller Hebel — die CP-SAT-Abwägung „warten lassen vs. ausparken" bleibt bewusst spätere Solver-Optimierung (heute hält der TS-Scheduler die Bucht viainBayStays). Selbsttesttest:konflikteerweitert (Vorlauf-Konflikt + Sperre-Validierung). Kein Migrations-/State-Aufwand (Sperre-Feld existierte bereits).tsc+ng build(1,02 MB) + No-Hex + No-Console +persistence:check+operativ/do-migrationsgrün. Doku:ops/OP-UMPARK-2.md(Slices B+C, Status erledigt), CHANGELOG, HANDOFF §4, Timesheet,docs/betrieb/Tests.md. True North #2: Sperren/Wartungen planbar + Bucht-Auslastung ohne stille Blockade. - Branch
claude/next-steps-8vmq5d(PR #653) — OP-ALERT-1 Slice 6: Alarm-Ton am Leit-Bildschirm — OP-ALERT-1 damit abgeschlossen (APP_VERSION0.94.0 → 0.95.0, MINOR). Sobald ein neues Fahrzeug gesperrt wird (Notfall), ertönt ein akustisches Signal — zusätzlich zur immer sichtbaren Alarm-Optik (Slice 2). Entscheidung: Ton per Web-Audio (Oszillator, dringender Zwei-Ton × 3) erzeugt statt einer Audio-Datei — kein Binär-Asset (Everything-as-Code), kein Bundle-Ballast, keine Design-Token-Berührung. Browser-Autoplay-Policy respektiert: derAudioContextwird erst nach der ersten User-Geste (pointerdown/keydown, once) entsperrt — davor bleibt der Alarm rein visuell (ehrliche Degradation). Stummschaltbar als Geräte-Einstellung (localStorage tk-alarm-stumm, Toggle 🔔/🔕 im Rail, analog Werker-Modus); beim ersten Laden ertönt nichts (Basislinie, kein Ton für bereits gesperrte Fahrzeuge). NeuerAlarmtonService(Root-Singleton, Effect aufgesperrteCount, im Shell injiziert). Reiner Client, kein Server/Schema. Damit ist der Alarm-Kern von OP-ALERT-1 rund (auslösen · sichtbar/persistent · Foto-Pflicht · Werker-Knopf · Leitungs-Freigabe · Ton) → OP-ALERT-1 = erledigt. Ausgegliedert (PO-Entscheid 07-18): die Video-Beweiserfassung wird als eigener OP-ALERT-2 geführt (Video-Upload-Pfad ohne Foto-Kompressions-Varianten; ggf. später auf QS-Mängel/Schritt-Doku verallgemeinern).ng build(1,01 MB) + No-Hex + No-Console + Server-tscgrün. Doku:ops/OP-ALERT-1.md(Slice 6, Status erledigt),ops/OP-ALERT-2.md(neu), CHANGELOG, HANDOFF §4, Timesheet. - Branch
claude/next-steps-8vmq5d— Anführungszeichen-Konvention: gerade ASCII-Zeichen als Standard + CodeRabbit ruhiggestellt (Tooling/Doku-only → keinAPP_VERSION-Bump). PO-Entscheid: gerade"/'sind der Projekt-Standard in Code, Doku und UI-Strings; keine typografischen Anführungszeichen in neuem Text (Bestehendes bleibt, kein retroaktiver Umbau)..coderabbit.yamlerhält globaletone_instructions, den Anführungszeichen-Stil nie mehr zu beanstanden und keine Umwandlung vorzuschlagen; Konvention indocs/konventionen/agents.md§5.1 verankert. Grund: CodeRabbit monierte wiederkehrend den Anführungszeichen-Stil — reines Review-Rauschen ohne inhaltlichen Wert. - Branch
claude/next-steps-8vmq5d— OP-ALERT-1 Slice 5: Freigabe-Workflow der Leitung (APP_VERSION0.93.0 → 0.94.0, MINOR). Das Aufheben der Notfall-Fahrzeug-Sperre ist eine Leitungs-Entscheidung: nur der Chef/die Werkstattleitung darf sie freigeben — server-hart imklaerfall.loesen-Gate (interim Chef-Gate wie OP-QS-6 Vier-Augen, = Kosten-Admin-Allowlist bis OP-AUTH-1). Ein Versuch ohne Leitungs-Recht wird abgelehnt (Chronik) und auditiert (notfall.freigabe.abgelehnt, D1). Das Beweisfoto (Slice 3) bleibt für alle Pflicht — auch die Leitung kann ohne Foto nicht freigeben (Reihenfolge: Chef-Gate, dann Foto-Gate). Client-Vorgriff (Einfachheit, wie OP-QS-1 den Abnahme-Gate spiegelt): der Freigabe-Knopf ist geblockt mit klarem Grund statt stiller Server-Ablehnung — „🔒 Freigabe: nur Leitung" (Nicht-Chef) bzw. „🔒 Freigabe: 📷 Foto nötig" (Chef ohne Foto), im Detail-Panel und im Klärfälle-Detail (notfallFreigabeBlockiert+istChef); ist der Klärfall ein Notfall, heißt der Knopf „✓ Sperre aufheben …". Entscheidung: Client-Spiegel statt Rejection-Message-Roundtrip — der Client kenntchef+notfallFotosbereits, der Server-Gate bleibt Backstop (Defense-in-Depth).tsc+ng build(1,01 MB) + No-Hex + No-Console +test:notfall/operativ/test:abnahme(Regression) grün. Doku:ops/OP-ALERT-1.md(Slice 5), CHANGELOG, HANDOFF §4, Timesheet. Offen (OP-ALERT-1): Video-Erfassung · Alarm-Ton (OP-KOMM-1). - Branch
claude/next-steps-8vmq5d— OP-ALERT-1 Slice 4: Alert-Knopf im Werker-Modus (APP_VERSION0.92.0 → 0.93.0, MINOR). Der Werker entdeckt den unerwarteten Schaden am Fahrzeug — er muss den Alarm direkt auslösen können, nicht nur der Leitstand. Neu: 🚨-Notfall-Knopf je Schritt-Karte in „Meine Arbeit" (neben „⚠ Klärfall") mit Grund-Presets (Beule/Kratzer/Teil gebrochen/Schaden unter dem Auto) + Pflicht-Freitext; gleicher Server-Pfad wie das Panel (auftrag.klaerfallmitart:'notfall', der auslösende Teilschritt wandert als Kontext mit — nichts dupliziert). Solange das Fahrzeug gesperrt ist, ist das Beweisfoto (Slice 3) direkt im Werker-Flow erfassbar (📷-Knopf + „Sperre erst nach Dokumentation aufhebbar",uploadNotfallFoto). Reiner Client, kein Server/Schema — voll verifizierbar (der Auslöse-Pfad braucht kein R2; nur der Foto-Upload ist ohneFOTOS-Binding dormant).ng build(1,01 MB, unter dem angehobenen 1,25-MB-Budget) + No-Hex + No-Console grün. Doku:ops/OP-ALERT-1.md(Slice 4), CHANGELOG, HANDOFF §4, Timesheet. Offen (OP-ALERT-1): Video · Alarm-Ton · Freigabe-Workflow der Leitung · Reject-Toast. - Branch
claude/next-steps-8vmq5d— OP-ALERT-1 Slice 3: Foto-Pflicht am Alarm (APP_VERSION0.91.0 → 0.92.0, MINOR). Der Kern der OP („Foto-Pflicht + Stopp + Eskalation"): ein Notfall/Schaden muss mit ≥1 Beweisfoto dokumentiert werden, und die Fahrzeug-Sperre lässt sich erst danach aufheben — server-hart imklaerfall.loesen-Gate (notfallBeweisfotoErfuellt,server/src/operativ/auftrag.ts). Neues Foto-Ziel CnotfallanFotoAttachment(polymorph nebenteilschrittInstanzId|mangelId): Entscheidung — bewusst getrennt vom QS-Mangel modelliert, damit ein pre-existenter/unerwarteter Schaden nicht die Mangel-Auswertung je Skill/Mitarbeiter verfälscht (Selbsterklärbarkeit). Server: Upload-Endpoint akzeptiert?notfall=1(r2Keyfotos/<auftrag>/notfall/…, Drei-Wege-XOR),foto.registriertlöst das Notfall-Ziel auf (braucht offenen Notfall-Klärfall),snapshotgruppiert Notfall-Fotos je Auftrag →AuftragDTO.notfallFotos. Client:uploadNotfallFoto(Direkt-Upload, analoguploadMangelFoto) + im Detail-Panel — solange gesperrt — „📷 Beweisfoto aufnehmen", Pflicht-Hinweis „Sperre erst nach Dokumentation aufhebbar" + Thumbnails. Selbsttesttest:notfallerweitert (Freigabe blockt ohne Foto, frei mit ≥1, regulärer Klärfall ohne Pflicht). Nebenbei: das Client-Initial-Bundle überschritt die bisherige harte Angular-Budget-Grenze (1 MB) um wenige KB → Budget bewusst aufmaximumWarning 1mb/maximumError 1.25mbangehoben (Headroom, kein Fix) + neuer Folge-OP OP-PERF-1 (Initial-Bundle via Lazy-Loading der Workspaces reduzieren).tsc+ng build+ No-Hex + No-Console +persistence:check+test:do-migrations(v0→v22, keine Migration — nested-optionales Feld) +operativ/test:abnahme(Regression) grün. R2-Roundtrip dormant (keinFOTOS-Binding) → Live-R2 nachziehen. Doku:ops/OP-ALERT-1.md(Slice 3),ops/OP-PERF-1.md, CHANGELOG, HANDOFF §4, Timesheet, Tests.md, IDs.md. Offen (OP-ALERT-1): Video-Erfassung · Alarm-Ton (OP-KOMM-1) · Alert-Knopf im Werker-Modus · Freigabe-Workflow der Leitung · Toast bei abgelehnter Freigabe. - Branch
claude/next-steps-8vmq5d— OP-ALERT-1 Slice 2: Alarm-Sichtbarkeit — der Notfall-Alarm „darf nicht verschwinden" (APP_VERSION0.90.0 → 0.91.0, MINOR). Adressiert die PO-Sorge, dass ein ausgelöster 🚨-Alarm bisher nur im Klärfälle-Tab auftauchte und dort optisch gleich wie ein regulär eskalierter Klärfall aussah (nur „⚠ eskaliert"). Neu: (1) globaler, immer sichtbarer Alarm-Indikator in der Kopfzeile — rot, pulsierend (.tk-pulse), „🚨 N gesperrt", aus jedem Workspace sichtbar solange ≥1 Fahrzeug gesperrt ist, Klick → Klärfälle-Tab (shell.component.ts); (2) in der Klärfälle-Liste + Detail ein eigenes 🚨-„gesperrt"/„Fahrzeug gesperrt"-Badge (rot Vollton, klar unterscheidbar vom regulären „⚠ eskaliert"); (3) Sortierung: Notfall vor eskaliert vor Wartezeit (klaerfaelleSortiert). Rein abgeleitet (D-2): neue ComputedsgesperrteFahrzeuge/gesperrteCount(= klaerfaelle mit art==='notfall') — der Alarm bleibt bestehen, bis der Notfall-Klärfall bewusst gelöst wird, verschwindet also nie still. Entscheidung: da ein Notfall serverseitigeskalierterzwingt, ersetzt das 🚨-Badge das „⚠ eskaliert" (kein Doppel-Label); Rot = Warnung (Marken-Regel eingehalten). Reiner Client, kein Server/Schema/Migration. Deckt einen Teil der „Alarm-Optik am Leit-Bildschirm" (OP-KOMM-1) ab.ng build+ No-Hex + No-Console + Server-tscgrün. Doku:ops/OP-ALERT-1.md(Slice 2), CHANGELOG, HANDOFF §4, Timesheet. Offen (OP-ALERT-1): Foto-/Video-Zwang am Alarm (OP-QS-1) · Alarm-Ton (OP-KOMM-1) · Alert-Knopf im Werker-Modus · Freigabe-Workflow der Leitung.
2026-07-17
- Branch
claude/next-steps-8vmq5d— OP-UMPARK-2 Slice A: Fahrzeug in gesperrter Bucht → Umparken erzwungen (APP_VERSION0.89.0 → 0.90.0, MINOR). Schließt die Lücke, dass eine Bucht-Sperre bisher still über ein dort physisch geparktes Auto hinweggehen konnte: Konflikt-Erkennung (sperre_kollidiert/arbeitsplatz_fehlt) prüfte nur geplante Arbeit (teilschritt.bayId), nie die physischebelegung. Neuer Konflikt-Typgeparkt_gesperrt(Hoch) über die reine, abgeleitete FunktionkonflikteGeparktInGesperrt(arbeitsplaetze, belegung)(server/src/operativ/konflikte.ts) — greift automatisch bei jedem Broadcast, sobald eine belegte Bucht aufgesperrt/in_wartunggesetzt wird (D-2, kein State/Migration). Client: Typ-Label + Direkt-Knopf „📍 Umparken" an der Konfliktkarte (öffnet das bestehende Repark-Modal aus OP-UMPARK-1, nur bei eindeutigem Fahrzeug). Entscheidung/Policy (PO 07-17): eine Bucht mit geparktem Auto lässt sich nicht still sperren — der Umpark-Bedarf bleibt als Konflikt sichtbar, bis umgeparkt ist; Sofort-Sperre → sofort umparken (G-4), geplante Sperre → vorbeginn(Slice B, offen); „Bucht zwischen zwei Leistungen freiräumen" bleibt Standard „Auto wartet in Bucht" + späterer Hebel/Solver-Abwägung (Slice C, offen). Selbsttestnpm run test:konflikteerweitert (gesperrt+Auto → Konflikt, aktiv/leer → keiner, Wartung/mehrere → sammelnd ohne Einzel-Link).tsc+ng build+ No-Hex + No-Console grün. Doku:ops/OP-UMPARK-2.md, Lastenheft §11.1,docs/betrieb/Tests.md. Zusätzlich als eigener OP festgehalten: OP-SCHICHT-1 (Schicht-Ende-Aufräumen: hochwertige Fahrzeuge in die Halle [konfigurierbar], nächste Schicht vorbereiten, möglichst wenig über Nacht in Arbeit außer Cool-down/Nachruhe) — bewusst getrennt vom Umpark-Slice, da eigenes Scheduler-/Schicht-Thema.
2026-07-16
- Branch
claude/next-steps-8vmq5d(PR #646) — OP-QS-1 Slice 4 / M05: Dedizierte mangel-eigene Foto-Erfassung (APP_VERSION0.88.0 → 0.89.0, MINOR). Ein Beweisfoto kann jetzt direkt am Mangel erfasst werden (nicht nur projiziert vom Teilschritt) — schließt die Lücke, wenn ein Mangel an einem Schritt ohne Foto-Pflicht entdeckt wird und das Pflicht-Foto (schwer/kritisch, Slice 3) sonst nicht erfüllbar wäre.FotoAttachmentträgt jetzt eine polymorphe Ziel-Referenz (teilschrittInstanzIdodermangelId; beide optional, genau eines gesetzt;server/src/model/types.ts). Server: Upload-Endpoint/api/foto/uploadakzeptiert?mangel=(r2Key-Pfadfotos/<auftrag>/mangel/<id>/…);foto.registriert-Message bindet ans Teilschritt- oder Mangel-Ziel (löst beide auf, verwirft ohne gültiges Ziel); DTO merged je Mangel Schritt-Fotos (projiziert, M05 Slice 2) + mangel-eigene (fotosByMangel, dedupliziert nach id); das Abnahme-Gate (istAbnahmebereit) zählt beide Quellen fürs Pflicht-Foto. Entscheidung: mangel-eigene Fotos laufen als Direkt-Upload (uploadMangelFoto) im verbundenen QS-Kontext — bewusst nicht durch die Werker-Offline-Queue (IndexedDB/3 Varianten/ack-Drain), da am QS-Platz keine Offline-Resilienz nötig ist; das hält den zweiten Pfad minimal und das Regressionsrisiko am funktionierenden Schritt-Foto-Pfad klein. Client: 📷-Aufnahme-Knopf je aktivem Mangel im QS-Workspace (Toast bei Erfolg/Fehler). Liefert zugleich die Beweismittel-Mechanik für den Notfall-Alert (OP-ALERT-1 Foto-Zwang) — der Upload-Pfad ist einmal gebaut, beide Features nutzen ihn. Selbsttestnpm run test:beweisfoto(CI-Gate, +3 Fälle): mangel-eigenes Foto erfüllt das Pflicht-Foto (auch ohne Schritt-Bezug), leer bleibt blockiert.tsc+ng build+ No-Hex + No-Console +test:do-migrations(v0→v22, keine Migration nötig — nested-optionale Felder) +operativ/test:abnahme(Regression) grün. Verifikations-Grenze: der R2-Byte-Roundtrip ist ohneFOTOS-Binding dormant (identisch zur bestehenden Schritt-Foto-Funktion) — Live-R2 in einer Umgebung mit Binding nachziehen. Doku: Lastenheft §11.1 (Slice 4),ops/OP-QS-1.md,docs/betrieb/Tests.md. Offen: Video-Erfassung · manuelles „behoben"-Setzen + Vier-Augen (G-4/OP-QS-6) · Mangel-Auswertung · admin-Kategorien (G-1).
2026-07-15
- Branch
claude/next-steps-8vmq5d(PR #645) — OP-QS-1 Slice 3: Pflicht-Beweisfoto für schwere Mängel (APP_VERSION0.87.0 → 0.88.0, MINOR). Baut auf M05 (Slice 2) auf: ein schwerer/kritischer Mangel (M03) braucht jetzt ≥1 Beweisfoto für die saubere Beweislage. Das server-harte QS-Abnahme-Gate (istAbnahmebereit, OP-QS-GATE) blockt die Abholung, bis das Foto dokumentiert ist — auch wenn der Mangel bereits behoben ist (das Beweismittel muss vor Abholung vorliegen). Entscheidung: leichte/mittlere Mängel bleiben ohne Foto-Zwang (geringe Friktion — nur bei echtem Haftungsrisiko erzwingen); der Foto-Check gilt statusunabhängig (offen/in Nacharbeit/behoben), da die Beweislage unabhängig von der Behebung dokumentiert sein muss. Neuer pure HelpermangelBrauchtBeweisfoto(schwere)+ Gate-Regel (server/src/operativ/auftrag.ts); das Beweisfoto ist ein Foto des Teilschritts, an dem der Mangel entdeckt wurde (M05 — diefotosByInstanz-Anzahl im Gate). Client:offenePunkte()spiegelt die Gate-Regel (sonst zeigt die UI „abnahmebereit", bevor der Server ablehnt) + QS-Workspace zeigt „📷 Beweisfoto nötig (Pflicht bei schwer/kritisch)" am betroffenen Mangel (amber, kein Rot — Marken-Regel). Selbsttest-Erweiterungnpm run test:beweisfoto(CI-Gate): schwer/kritisch → Beweisfoto-Pflicht, leicht/mittel nicht; Gate blockt schwer+behoben ohne Foto, ok mit Foto, ok leicht ohne Foto, blockt kritisch ohne Schritt-Bezug.tsc+ng build+ No-Hex grün,test:abnahme(Regression) grün. Doku: Lastenheft §11.1 (Slice 3),ops/OP-QS-1.md,docs/betrieb/Tests.md. Offen: dedizierte mangel-eigene Foto-Erfassung (R2-Upload-Pfad) für Mängel ohne Schritt-Foto — speist auch OP-ALERT-1. - Branch
claude/next-steps-8vmq5d— OP-QS-1 Slice 2 / M05: Beweisfotos am Mangel (APP_VERSION0.86.0 → 0.87.0, MINOR). Jeder QS-Mangel trägt jetzt in der QS-Sicht die Beweisfotos des Teilschritts, an dem er entdeckt wurde. Entscheidung (Leitprinzip Einfachheit): bestehende Teilschritt-Fotos wiederverwenden statt einen zweiten Upload-Pfad durch die intricate Offline-Foto-Queue (IndexedDB, 3 Varianten, ack-getriggerter Drain) zu fädeln — das vermeidet Regressionsrisiko am funktionierenden Foto-Pfad und ist ohne Live-R2 verifizierbar. Neuer pure HelperbeweisfotosZuMangel(mangel, fotosByInstanz)(server/src/operativ/auftrag.ts, abgeleitet/D-2 — nichts gespeichert; ohne Schritt-Bezug leer). DTO: geteilterFotoRefDTO+toFotoRef-Mapper (dedupliziert die zuvor inline im Teilschritt-DTO gemappten Foto-Metadaten) +MangelDTO = Mangel & { fotos };AuftragDTO.maengelreicht die Beweisfotos je Mangel durch (server/party/leitstand.ts). Client:Mangel.fotos+ QS-Workspace zeigt eine Thumbnail-Leiste je aktivem Mangel (Klick → volle Anzeige,fotoUrl-Passthrough). Selbsttestnpm run test:beweisfoto(CI-Gate): Fotos des betroffenen Schritts projiziert, isoliert je Schritt, leer ohne Bezug.tsc+ng build+ No-Hex grün,operativ/test:qs-nacharbeit/test:leistung/test:mangel-status(Regression) grün. Doku: Lastenheft §11.1 (M05-Umsetzungsnotiz),ops/OP-QS-1.md(Slice 2),docs/betrieb/Tests.md. Offene Folge-Slices: dedizierte mangel-eigene Foto-/Video-Erfassung (getrennt von Schritt-Fotos) + Pflicht-Foto für schwere Mängel — speist dann auch den Notfall-Alert (OP-ALERT-1).
2026-07-14
- Branch
claude/next-steps-8vmq5d(PR #643) — OP-QS-1 Slice 1: Mangel-Status-Workflow (APP_VERSION0.85.0 → 0.86.0, MINOR). Der QS-Mangel-Status (M06) ist jetzt 3-stufigoffen → in_nacharbeit → behoben(zuvor nuroffen/behoben). Entscheidung (Zuschnitt): die 3-Stufen-Statusmaschine vor die Foto-Doku gezogen — rein domänen-/testbar (kein Live-R2-Upload, der hier nicht verifizierbar ist), explizit in OP-QS-1 gelistet, und macht die zuvor nur implizite „in Nacharbeit"-Stufe (existiert ein verknüpfter Nacharbeitsschritt?) zu echtem, sichtbarem Zustand. Übergänge: ein Mangel wechselt offen → in_nacharbeit, sobald ein Nacharbeitsschritt für ihn eingeplant wird (neuer Domänen-HelfermarkiereMangelInNacharbeit; verdrahtet inauftrag.nacharbeitEinplanen+ die einstufigeqs.nacharbeitErfassenerzeugt den Mangel direkt alsin_nacharbeit), und → behoben, sobald der verknüpfte Schritt erledigt wird (bestehendeerledige-Logik, Bedingung von=== 'offen'auf!== 'behoben'geweitet). Das server-harte QS-Abnahme-Gate (istAbnahmebereit, OP-QS-GATE) blockt jetzt bis der Mangel behoben ist (offen und in_nacharbeit blocken, mit eigenem Meldetext „in Nacharbeit"). Client: QS-Workspace zeigt statt „Offene Mängel" alle noch nicht behobenen Mängel mit Status-Badge (offen=amber · in Nacharbeit=cyan · behoben=grün — Rot bleibt Warnungen vorbehalten, Marken-Regel). Migration v22 hebt Bestands-Mängel mit laufendem Schritt aufin_nacharbeit. Selbsttestnpm run test:mangel-status(CI-Gate): markieren (idempotent, kein Rückschritt) · behoben bei Schritt-Abschluss · Gate blockt bis behoben.tsc+ng build+ No-Hex-Gate grün,test:do-migrations(v0→v22) +operativ+test:qs-nacharbeit/test:nacharbeit/test:abnahme/test:leistung(Regression) grün. Doku: Lastenheft M06 + §11.1-Umsetzungsnotiz,ops/OP-QS-1.md→ in-arbeit,docs/betrieb/Tests.md. Offene Folge-Slices: Foto-Beweismittel am Mangel (M05 — speist auch OP-ALERT-1) · manuelles „behoben"-Setzen + Vier-Augen-Frage (G-4/OP-QS-6) · Mangel-Auswertung je Kategorie/Skill/MA über die Zeit · admin-editierbare Kategorien (G-1). - Branch
claude/next-steps-8vmq5d(PR #642) — OP-ALERT-1 Slice 1: Notfall-/Schaden-Alert (APP_VERSION0.84.0 → 0.85.0, MINOR). Notfall-Knopf für einen unerwarteten, nicht vom Betrieb verursachten Fahrzeugschaden (Meeting 12.07.2026, Holger/Dominik). Entscheidung (Leitprinzip Einfachheit): der Alert ist keine Parallel-Mechanik, sondern eine Variante des Klärfalls (OP-R3-1) — neuer Diskriminatorart: 'regulaer' | 'notfall'amKlaerfallKontextstatt eines eigenen Systems. Zusatzregeln des Notfalls ggü. dem regulären Klärfall: (1) Hard-Stop aller laufenden Schritte (pausiereLaufendeSchritte), (2) erzwungene Eskalation (Flag harttrue, nicht opt-in), (3) Fahrzeug gesperrt — abgeleitetfahrzeugGesperrt=art === 'notfall'(D-2, nie gespeichert). Neuer Domänen-HelfermeldeNotfall(server/src/operativ/auftrag.ts); DO-Messageauftrag.klaerfallumart?: 'notfall'erweitert → eigener Zweig mit Chronik + Audit-Eventnotfall.gemeldet(Grund + gestoppte Schritte); Migration v21 backfilltart: 'regulaer'auf bestehende Klärfälle. Client:auftragNotfall(...)im Service; auffälliger 🚨 Notfall / Schaden-Knopf (Vollfläche rot) + Pflicht-Grund-Formular im geteiltenauftrag-detail-panel; Kopf-Badge 🚨 Fahrzeug gesperrt statt „⚠ Klärfall", solange der Notfall offen ist. Ein einmal erklärter Notfall lässt sich nicht per regulärem Update herabstufen. Selbsttestnpm run test:notfall(CI-Gate): Hard-Stop · Eskalation erzwungen · Sperre · regulärer Klärfall sperrt nicht · keine Herabstufung · Lösen hebt die Sperre auf.tsc --noEmit+ng buildgrün,test:do-migrations(v0→v21) +operativgrün, No-Hex-Gate grün. Neues Design-Docdocs/architektur/Notfall-Alert.md(pyramidal, Mermaid-State, Slice-Plan) + Landkarte + Lastenheft §5.1;ops/OP-ALERT-1.md→ in-arbeit. Offene Folge-Slices: Foto-/Video-Zwang (OP-QS-1) · Alarm-Optik/-Ton am Leit-Bildschirm (OP-KOMM-1) · Alert-Knopf im Werker-Modus · Freigabe-Workflow der Leitung. - Branch
claude/r7-p1-fortschritts-indikator(PR #641) — R7-P1: Auftrags-Fortschritts-Indikator (APP_VERSION0.83.0 → 0.84.0, MINOR). Neue geteilteFortschrittsIndikatorComponent(client/.../leitstand/fortschritts-indikator.component.ts) — eine 🚗-Kette Annahme→Teilschritte→Ausgabe je Auftrag, Farbe je Schritt-Status. Entscheidung: Emoji-Glyphen tragen selbst keine CSS-Farbe (colorwirkt nicht auf Farb-Emoji) — Status wird stattdessen über einen satt eingefärbten Chip + Ring hinter dem Symbol kommuniziert, nicht über die Emoji-Farbe selbst; „läuft"-Schritte pulsieren (tk-pchip, dieselbe Konvention wie der bestehende 5-Stufen-Strip). Dedupe:teilschrittStatusColor/teilschrittStatusIconneu inlabels.ts(eine Quelle statt der bisherigen Kopien inorders.component.ts+auftrag-detail-panel.component.ts). Verdrahtet an 3 Stellen (Lastenheft-Vorgabe „Liste/Karte und Detail"): kompakt auf der Fluss-Karte (ersetzt die alte reine Prozent-Leiste — strikt informativer, da je Schritt statt nur aggregiert), kompakt im Fly-in-Header (auftrag-detail-panel.component.ts), ausführlich im Aufträge-Detailpanel (ersetzt die alte flache Klick-Liste — Klick öffnet weiterhin das geteilte Detail-Fly-in, fokussiert auf den Schritt). HTML-Fallstrick vermieden: Knoten sind<span role="button">statt<button>, da die Kette auf der Fluss-Karte innerhalb eines bereits klickbaren<button>sitzt (verschachtelte<button>wären ungültiges HTML).ng buildgrün; Live End-to-End verifiziert (wrangler dev+ng serve, Playwright): Karten-Kette, Detailpanel-Kette (Klick öffnet Fly-in fokussiert) und Fly-in-Kopf-Kette alle korrekt gerendert/verlinkt.docs/fachlich/Lastenheft.md§7.1 (R7-P1) +design/WORKSPACES.md(Aufträge-Sektion) nachgezogen.
2026-07-13
- Branch
claude/runner-desktop-preferred(PR #639) — Self-hosted Runner-Fallback'hot'→'desktop'(Infra-only, kein App-Bump). Nutzer-Auftrag: „prefer selfhosted runner with label desktop". Der literale Fallback in${{ vars.CI_RUNNER || 'hot' }}(greift, wenn das Repo-Actions-VariableCI_RUNNERNICHT gesetzt ist — hat sonst Vorrang) in allen 17runs-on-Stellen (7 Workflow-Dateien:auto-rerun/ci/docs-deploy/fly-deploy/sync-ops/sync-pr-logs/weekly-audit) auf'desktop'geändert. Hinweis (kein Code-Fix möglich): falls das Repo-Actions-VariableCI_RUNNERbereits explizit gesetzt ist (z. B. auf'hot'), hat es Vorrang vor diesem Fallback und muss zusätzlich in den GitHub-Repo-Settings → Actions → Variables angepasst werden. YAML aller 7 Dateien lokal geparst (valide). - Branch
claude/op-r8-1-slice2-ressourcen(PR #637) — OP-R8-1 Slice 2: Mitarbeiter fehlt · Arbeitsplatz fehlt · Sperre kollidiert (APP_VERSION0.82.0 → 0.83.0, MINOR). Vervollständigt die Konflikt-Typ-Enum aus Slice 1 (#627) um die letzten 3 der 6 Lastenheft-Beispiel-Typen. Die Slice-1-Einschätzung „brauchen echten NEUEN Abgleich, deutlich größerer Slice" (ops/OP-R8-1.md) erwies sich als zu pessimistisch: der Abgleich Zuweisung↔Ausfallband existierte bereits —mitarbeiterAusfall/bayAusfall(scheduler/ausfall.ts) fassen Status/Abwesenheiten bzw. KonfigStatus/Sperren schon zu einem einheitlichen Ausfall-Modell zusammen (bislang nur fürs Gantt-Ausfallband genutzt). Keine neue Erkennungslogik — prüft je offenem (geplant/in_arbeit) Teilschritt, ob die zugewiesene Ressource im geplanten Zeitfenster einen bei der Planung noch unbekannten HARTEN Ausfall hat: Mitarbeiter fehlt (Hoch) — eingeplanter Mitarbeiter ist krank/im Urlaub/inaktiv (gefiltert auf harte Arten; Pause/Geschlossen respektiert der Scheduler schon, Wunschfrei ist weich) · Arbeitsplatz fehlt (Mittel) — eingeplante Bucht ist als Ganzes außer Betrieb (KonfigStatus ≠ aktiv) · Sperre kollidiert (Mittel) — ein Sperr-Fenster einer sonst aktiven Bucht überschneidet das geplante Zeitfenster (z. B. eine Sperre, die erst nach der Planung eingetragen wurde), sich gegenseitig ausschließend mit „Arbeitsplatz fehlt" (kein Doppel-Eintrag). Neue FunktionenkonflikteMitarbeiterFehlt/konflikteArbeitsplatzFehlt/konflikteSperreKollidiert(server/src/operativ/konflikte.ts), inweitereKonflikteverdrahtet (server/party/leitstand.ts); Client-Typ-Union + Label-Map ergänzt.npm run test:konflikte(8 neue Fälle) +tsc --noEmit+ng buildgrün, keine Regression innpm run operativ. Live End-to-End verifiziert (wrangler dev+ng serve, WebSocket-Test + Playwright):arbeitsplatz.updateaufin_wartunggesetzt → alle 10 betroffenen Vest-Seed-Aufträge korrekt als „Arbeitsplatz fehlt" im Feed erkannt (UI-Badge + Beschreibung korrekt), danach zurückgesetzt; „Mitarbeiter fehlt" nur per Unit-Test verifiziert (keine Mutations-Message für Mitarbeiter-Status existiert aktuell, nurarbeitsplatz.updateist admin-editierbar — dieselbe Server-Funktion in beiden Fällen).ops/OP-R8-1.mdin-arbeit (beide Slices ✅, Feed-Filter + Hebel-Wizard-Integration als Folge-Slices offen). - Branch
claude/sbom-architektur-diagramm—docs/architektur/Architektur-Uebersicht.mdverbindlich eingeführt (Doku-only). Neue Datei mit Mermaid-Systemgrafik (Access · Client · Worker/DO · Solver-Service · D1/DO-SQLite · OTel, gestrichelt: TS-Optimierer-Fallback) + SBOM-Sektion (verweist auf den bereits bestehenden CI-Jobsbom,OP-SBOM-1) — Taktano hatte den SBOM-Job bereits, aber noch keine Systemgrafik/keine Doku-Fundstelle für die SBOM.CLAUDE.md§Compliance + Tiefenquellen ergänzt. Übernommen aus Template (dortige D-53). Docs-only, kein App-Bump. - Branch
claude/taktano-nested-claude-md-split— Instruktions-Scoping-Regel angewendet: nestedCLAUDE.mdfürclient//server//solver-service/angelegt (Doku-only). Neu:client/CLAUDE.md(Angular 22/Tailwind v4-Stack, Build/Test, Verweis aufdesign/CLAUDE.md),server/CLAUDE.md(Cloudflare Worker/DO, Build/Test/Typecheck, Persistenz-/Logging-Konventionen),solver-service/CLAUDE.md(Python/CP-SAT, Run, Solver↔Worker-Vertrag).design/CLAUDE.md-Header um den Pflicht-Rückverweis „Governance siehe Root" ergänzt (Rest unangetastet). Root-CLAUDE.mdentsprechend getrimmt: „Architektur / Stack" verweist jetzt auf die drei nested Files statt Details zu duplizieren; „Design-Prinzipien" auf die repo-weite Brand-Regel (Rot nur Warnungen) verkürzt, Token-/Komponenten-Details leben nur noch inclient/CLAUDE.md/design/CLAUDE.md. Tiefenquellen-Tabelle ergänzt.bash scripts/check-doc-consistency.shlokal grün (nur bestehende, unveränderte Warnungen). Docs-only, kein App-Bump. - Branch
claude/nested-claude-md-scoping— Instruktions-Scoping-Regel (Nested CLAUDE.md). Neue Sektion inCLAUDE.md— Root bleibt einzige Stelle für stack-unabhängige Governance (True North,G-n, ID-System, Compliance, Repo-Konventionen), nestedCLAUDE.mdje eigenständigem Tech-Stack-Unterverzeichnis (client/Angular,server/Worker,solver-service/Python — Taktano ist der heterogenste der vier Repos, Referenzfall) nur für stack-lokale Build/Test/Lint-Details, mit festem Skelett + Pflicht-Rückverweis. Übernommen aus Template (dortige D-9), repo-übergreifend vereinheitlicht. Docs-only, kein App-Bump. - Branch
claude/op-r8-19-reihenfolge(PR #633) — Neuer OP-R8-19: Reihenfolge-Abhängigkeit bei „Alle automatisch lösen" (Doku-only, kein Bump). Nutzer-Rückfrage nach OP-R8-7-Merge (#629): „müsste das nicht der Solver besser bewerten können?" — berechtigter Punkt, präzisiert statt nur in Prosa im PR-Chat beantwortet. Klargestellt: jeder einzelne Hebel-Wert IST solver-/scheduler-gestützt berechnet (konfliktHebel→planeJointMitEil/simuliereGewinnDurchFreigabe); was fehlt, ist eine gemeinsame Optimierung über MEHRERE gleichzeitige Konflikte hinweg —loeseAlleKonflikte()verarbeitet sie greedy in Auftrags-Array-Reihenfolge statt nach Dringlichkeit/Options-Anzahl, wodurch ein früh verbrauchter Hebel einen späteren Konflikt unnötig ungelöst lassen kann. Neuerops/OP-R8-19.md(bezug: OP-R8-7, OP-OPT-9) mit konkretem Fehlerbild-Beispiel + Lösungsrichtung (CP-SAT-Meta-Modell über die Konflikt-Menge, alternativ einfachere Zwischenstufe „nach Options-Anzahl sortieren") + explizitem Bau-Trigger (YAGNI — erst bei wiederholt beobachteten Fällen, auditierbar über die bestehendekonflikt.alleGeloest-D1-Audit-Zeile).ops/OP-R8-7.md„Garantie-Grenze" von vager Prosa auf den präzisen Cross-Link geschärft.docs/betrieb/Offene-Punkte.mdregeneriert (179 OPs).check-doc-consistency.sh --strictunverändert bei den 5 bekannten Warnungen. - Branch
claude/concurrency-vereinheitlicht—concurrencyrepo-übergreifend vereinheitlicht (Infra-only).auto-rerun.yml/docs-deploy.yml/fly-deploy.yml/sync-ops.yml/weekly-audit.yml(hatten gar keinenconcurrency-Block) auf den inci.ymlbereits etablierten Standardgroup: ${{ github.workflow }}-${{ github.ref }}/cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}gehoben.sync-pr-logs.ymlbewusst nicht angefasst — dessen Group-Key ist PR-spezifisch (sync-pr-logs-<PR-Nummer>), mitgithub.refwürden parallele PR-Syncs sich gegenseitig canceln. YAML aller 6 Dateien lokal geparst (valide). Docs/Infra-only, kein App-Bump. - Branch
claude/runs-on-vereinheitlicht—runs-onrepo-übergreifend vereinheitlicht (Infra-only).auto-rerun.yml/docs-deploy.yml/fly-deploy.yml/sync-ops.yml/sync-pr-logs.yml/weekly-audit.yml(bisher${{ vars.CI_RUNNER || 'self-hosted' }}bzw.${{ vars.CI_RUNNER || 'hot' }}, ohne Fork-Gate) auf den inci.ymlbereits etablierten Standard-Ausdruck gehoben:${{ github.event.pull_request.head.repo.fork && 'ubuntu-latest' || vars.CI_RUNNER || 'hot' }}— jetzt an jedem Job in jedem Workflow identisch. Keinpull_request-Trigger aus Forks bei diesen sechs Workflows, das Fork-Gate ist dort inert, schadet aber nicht und stellt Einheitlichkeit her. YAML lokal geparst (valide). Docs/Infra-only, kein App-Bump. - Branch
claude/golden-rule-zero-trust— Golden Rule „Zero Trust vor Public".CLAUDE.md: neue Compliance-Regel unter „Compliance, Sicherheit & Risiko" — jedes Online-Deployment wird zunächst per Cloudflare Zero Trust (Access) von der Öffentlichkeit abgeschottet, offener Zugriff ist begründete Ausnahme statt Default. Repo-übergreifend in sera/medidentas/taktano/everything-as-code-template vereinheitlicht. Hinweis ergänzt:automotivo.de-Analyse und produktive Kundenzugänge (Vest-POC) bleiben Access-gated. Docs-only, kein Code-Change. - Branch
claude/op-r8-7-alle-loesen(PR #629) — OP-R8-7 Slice 1: Header-Aktion „Alle automatisch lösen" mit Sicherheits-Garantie (APP_VERSION0.81.0 → 0.82.0, MINOR). Löst per Klick JEDEN Termin-Konflikt automatisch, statt eine eigene Simulation zu bauen — nimmt dieselbe Hebel-Liste, die der manuelle Konflikt-Lösen-Wizard schon anzeigt (konfliktHebel, OP-R8-2/3), und wählt daraus je Konflikt den wirksamsten SICHEREN Hebel über die neue reine FunktionwaehleSicherenHebel(server/src/operativ/konflikt-auto-resolve.ts,npm run test:konflikt-autoloese). Rang (wirksamster zuerst): optionalen Schritt überspringen (skip) > Eilauftrag (eil) > Preemption/Unterbrechen (unterbrechen) > Wunsch-Abholtermin anpassen (abholtermin, letzter Ausweg — löst nur „auf dem Papier"). Die Garantie: ein Hebel gilt nur als sicher, wenn er keinen zu Beginn des Bulk-Laufs UNKONFLIKTIERTEN Auftrag neu in Terminverzug bringt (Prüfung gegen die Baseline-Menge der bereits bekannten Konflikte — bereits konfliktierte Aufträge dürfen weiter/stärker betroffen sein). Ohne sicheren lösenden Hebel bleibt der Konflikt unverändert für den manuellen Wizard offen — kein Rätselraten, keine stille Verschlechterung. Bewusste Entscheidung gegen eine neue Simulation: die Garantie-Prüfung nutzt dieselbe Simulieren-dann-Anwenden-Reihenfolge, die der Einzel-Wizard immer schon nutzt (synchron im selben DO-Message-Handler, kein Zustand ändert sich dazwischen) — keine kombinatorische Joint-Optimierung über alle Konflikte hinweg (wäre ein eigener, deutlich größerer Slice, dokumentiert als Garantie-Grenze inops/OP-R8-7.md). Server: neue Messagekonflikt.alleLoesen→loeseAlleKonflikte()wendet je Konflikt den bestehendenloeseKonflikt()mit dem gewählten Hebel an, quittiert der auslösenden Verbindung ehrlich{ geloest, offen }(kein optimistisches Raten, mirroring dasauftrag.stornieren.result-Muster) + D1-Audit. Client:LeitstandService.konfliktAlleLoesen()+konfliktAlleLoesenResult-Signal; Konflikte-Tab zeigt die Header-Aktion „⚡ Alle automatisch lösen" (nur bei ≥1 Termin-Konflikt) mit Toast-Bilanz. Live End-to-End verifiziert (wrangler dev+ng serve, Playwright + direkter WebSocket-Test): mehrere real erzeugte Termin-Konflikte automatisch aufgelöst, Toast „✓ 1 Konflikt automatisch gelöst" + Konflikt-Feed korrekt aktualisiert (Badge-Zähler runter, „Keine Termin-Konflikte"-Leerzustand).tsc --noEmit(Server) +ng buildgrün, keine Regression innpm run operativ. Bewusst offen (Folge-Slice): Überstunden-/Kapazitäts-Modellierung als anwendbarer Engpass-Hebel würde die Trefferquote erhöhen (aktuell istengpassnur ein Hinweis, nie automatisch wählbar). - Branch
claude/id-naming-conventions-912st8— Projekt-KürzelTKTbei neuen IDs jetzt verbindlich. Taktano hatte bisher als einziges Schwester-Repo keine Projekt-Kürzel-Klausel im ID-System (CLAUDE.md); jede neue ID trägt künftigTKT-als Prefix (TKT-D-n,TKT-OP-Rn-n, Session-IDTKT-<Datum>-<branch-slug>), analogMED-/SERA-in den Schwester-Repos. Bestehende IDs (OP-Rn-netc.) bleiben unverändert — kein retroaktiver Umbau. Gleichzeitig in sera/medidentas/everything-as-code-template auf „verbindlich" (statt „empfohlen") vereinheitlicht. Kein Code-/Schema-Change. - Branch
claude/op-r8-1-konflikt-typen(PR #627) — OP-R8-1 Slice 1: Konflikt-Typ-Enum definiert + 3 wiederverwendbare Typen im Feed (APP_VERSION0.80.0 → 0.81.0, MINOR). Bis dahin gab es nur EINEN Konflikt-Typ (Termin-Konflikt) — die im Lastenheft (§5.2.3) beispielhaft genannten 6 Typen existierten als Enum gar nicht. Jetzt:KonfliktTyp = 'termin' | 'ueberbuchung' | 'skill_luecke' | 'standzeit'als Datenmodell (neuesserver/src/operativ/konflikte.ts, reine/testbare Funktionen,npm run test:konflikte). Für die drei neuen Typen keine neue Erkennungslogik — jeweils eine bereits vorhandene Berechnung wird nur in den Konflikt-Feed gehoben statt dupliziert: Überbuchung (dasueberbelegt-Flag der Hallen-/Hofplan-Belegung, bisher nur visuell) · Skill-Lücke (dieselbe Engpass-Logik wie der Hebel-Wizard-Hinweis „Engpass beheben", jetzt für ALLE offenen Aufträge statt nur bereits terminlich konfliktierte) · Standzeit-Verletzung (derselbebringtermin + standzeitStunden-Vergleich, den der Scheduler fürabholbereitnutzt, jetzt gegen den Wunsch-Abholtermin geprüft). Server broadcastetweitereKonflikte: KonfliktEintrag[]im State;conflicts.component.tszeigt sie als eigene Karte (Typ-Badge, Schwere-Farbe hoch/mittel) neben der bestehenden Termin-Master-Liste — die bleibt unverändert Termin-spezifisch (Hebel-Wizard, OP-R8-2/3). Tab-Badge-Zähler kombiniert Termin- + weitere Konflikte. Live im Browser verifiziert (wrangler dev+ng serve, Playwright): Vest-Seed zeigt 5 Skill-Lücken-Konflikte (Fahrzeugannahme/Keramikversiegelung nur 1 aktive Fachkraft) korrekt im Feed.ng build+tsc --noEmitgrün. Bewusst offen (Folge-Slices,ops/OP-R8-1.md): „Mitarbeiter fehlt"/„Arbeitsplatz fehlt"/„Sperre kollidiert" — brauchen echten NEUEN Abgleich Zuweisung↔Ausfallband/Sperre statt Wiederverwendung, deutlich größer; Filter „Typ/Schwere/Datum" im Feed; Hebel-Wizard-Integration der neuen Typen; admin-editierbare Taxonomie (G-1) — bewusst noch TS-Union wieAusfallArt, erst bei echtem Mehrfach-Betrieb-Bedarf.
2026-07-12
- Branch
claude/next-steps-f1buws(#623) — OP-R8-4 Slice 1: Gantt-Drag&Drop mit Sofort-Feedback (geometrische Validierung) (APP_VERSION0.79.0 → 0.80.0, MINOR). Der Entwurfs-Modus-Drag im Planungs-Gantt (Bucht-/Zeit-Neuzuweisung) validierte bislang nur asynchron über einen vollen Solver-Lauf ("Konsequenzen berechnen") — ein Drop auf eine offensichtlich unmögliche Position (Überlappung, außerhalb der Schicht) erzeugte trotzdem einen Pin und musste erst über den Server-Roundtrip als "nicht erfüllbar" (ohne Grund) verworfen werden. Jetzt:gantt.component.tsprüft während des Ziehens live gegen den bereits geladenen Plan — keine Überlappung mit belegter Bay-Zeit (laufender Plan und andere vorgemerkte Pins, inkl. Cool-down) und nicht innerhalb eines Ausfall-/Sperr-Bandes der Ziel-Bucht ("innerhalb Schichten"); der Geist-Block wird bei Verletzung rot (⚠) statt cyan (✎), ein ungültiger Drop erzeugt keinen Pin, sondern einen Warn-Toast mit dem konkreten Grund (pinRejected-Output, inplanning.component.tsverdrahtet). Gilt gleichermaßen für den Maus-Drag und den Tastatur-Pfad (moveBestaetigen, Barrierefreiheit). Bewusst unverändert: Skill-Match (hart) und feine Cool-down-Konsistenz bleiben Sache des echten Solver-Laufs bei "Konsequenzen berechnen" (Single Source of Truth — keine doppelte Constraint-Logik im Client, Einfachheits-Leitprinzip). Live im Browser verifiziert (wrangler dev+ng serve, Playwright-Treiber): Drop auf belegte Zeit → roter Geist + Toast "Verschiebung nicht möglich" + kein Pin; Drop auf freie Zeit → normaler Pin, Konsequenzen-Berechnung unverändert nutzbar.ng buildgrün.ops/OP-R8-4.mdals Folge-Slices offen (Beschriftung „Neuzuweisung" ggf. auf Mitarbeiter-Zeilen ausweiten, konkrete Solver-Fehlgründe für Skill/Cool-down). CI-Nachzug (2 Runden):scripts/check-doc-consistency.shscheiterte imdoc-consistency-Gate auf dem macOS-Runner (Apple-bash3.2) mit einem Syntax-Fehler beicontinue— eingegrenzt auf eincase … esacinnerhalb einesfor-Loops, der wiederum innerhalb einer Prozess-Substitution<( … )steht (Runde 1: Umstellung auf Mehrzeilen-Form traf die falsche Diagnose — zwei harmlose, flacherecase-Stellen liefen in beiden Läufen nie an; Runde 2: die tief verschachtelte Stelle per Vorfilterunggrep -vE '/_[^/]+$'stattcase/continueentfernt — sidestept die Bash-3.2-Eigenart, statt sie zu erraten). Lokalbash -n+--strictunverändert grün (gleiche 5 Warnungen). - Branch
claude/meeting-notes-integration-qcf9mg— Besprechungsnotizen 12.07.2026 ins Repo überführt (reine Doku,APP_VERSIONunverändert 0.79.0). Teilnehmer: Queckenstedt · Tieder · May · Kirchhof. Erstes Meeting-Protokoll angelegt (docs/betrieb/meetings/2026-07-12-produktiv-launch-app-review.md, pyramidal aus dem Notion-Export: TL;DR · Beschlüsse B1–B7 · Action Items A1–A8 · Diskussion · True-North-Bezug) + Index-Zeile inmeetings/README.md, HANDOFF-Zeile aktualisiert. Beschlüsse an ihre verbindlichen Orte gespiegelt: OP-VERTRIEB-3 — konkreter Launch-Fahrplan (Aug Parallelbetrieb Vest · Sep Echtbetrieb · Okt 2–3 Pilotkunden ~2 Mon. · dann Vertrieb; kritische Größe ~50 Kunden); OP-PILOT-1 — erster externer Pilot „Lars von Mattwerk“ bestätigt + Feedback-Kriterium + Onboarding-Zweck; OP-ORTUNG-1 — Ortungs-Entscheidung (Fahrzeuge + Zuschnitt-Kartons per AirTag, Mitarbeiter über Arbeits-iPads/Betriebsvereinbarung, Alternativen wie Chipolo POP/aufladbare Karten prüfen); OP-I18N-1 — EU-Expansions-Sprachen NL/FR/ES/EN bestätigt; OP-BRAND-2 — Automotivo-Schutz + „made in Germany“, Owner Holger. Drei neue OPs: OP-ALERT-1 (Notfall-/Alert-Knopf bei unerwarteten Fahrzeugschäden: Stopp + Foto-Pflicht + Chef-Eskalation), OP-VERTRIEB-5 (Folienhersteller-Partnerschaft Suntec/Legend — Konditionen/Exklusivität-nur-Folien-Segment/Exit), OP-VERTRIEB-6 (Zielgruppen/Betriebsarten „Flavours“ + Zielländer).docs/produkt/Markt-und-Markteintritt.mdum Meeting-Input-Callout ergänzt. gen-ops regeneriert (Offene-Punkte.md). Reine Doku, kein Bump. - Branch
claude/docs-review-process-automation-soolri(#620) — Dependabot-Backlog abgearbeitet +OP-DEPS-1(TS-7-Hold) angelegt (Doku/Prozess,APP_VERSIONunverändert 0.79.0; kein Code-Diff — GitHub-Operationen + lokale Verifikation). Gebaut/entschieden: (1) Welle 1 — 4 unabhängige Dependabot-PRs (#309paths-filter 3→4 ·#424server-minor-patch inkl. partyserver 0.0.66→0.5.8 [DO-Framework, Runtime] ·#425·#431) rebased + Auto-Merge (SQUASH) aktiviert (getrennte Verzeichnisse → keine Lockfile-Konflikte; mergen selbstständig auf grünem CI). (2) Zwei Majors lokal gegenmainverifiziert (tsc --noEmit+ Server-Smoke-Suite spike/operativ/replan/solve/teilplan — beide grün):#311@cloudflare/workers-types4→5 (types-only, kein Runtime-Effekt) → gemergt (Auto-Merge);#312typescript5.9.3→7.0.2 → gehalten (PO-Entscheid). Befund #312: trotz Branch-Name…typescript-6.0.3real der native tsgo-Compiler (TS 7) — Einfachheits-Leitprinzip + keine Server↔Client-TS-Divergenz (Client bleibt TS~6.0.3) → nicht jetzt, sondern gebündelt mit dem Client-TS-Bump. Alsops/OP-DEPS-1.md(offen · spaeter · technik) verankert, damit der grün-verifizierte Hold nicht im flüchtigen PR-Kommentar verloren geht. ops/-Bestand 174→175 OPs. Verifikation:gen-ops(175) ·check-doc-consistency --strict·smooth-logs. - Branch
claude/docs-review-process-automation-soolri(#619) — Session-Wrap: HANDOFF-Stand/Footer nachgezogen (reine Doku,APP_VERSIONunverändert 0.79.0). Abschluss der Doku-Review-/OP-Modell-Strecke des Tages: Footer + §2-OP-Management-Zeile spiegeln jetzt den Ist-Stand — OP-Archiv vollständig migriert (166 Alt-OPs →ops/<ID>.md, §4 = Pointer, Lastenheft §11 = fachliches Detail), Board vollständig (~142 offene OPs gespiegelt,prio:/status:-Filter), Grooming/Diskussion als agentgetriebene on-demand-Tasks (agents.md §6.2a), Sync skaliert (Core-List + Backoff).smooth-logs+--strictgrün. - Branch
claude/docs-review-process-automation-soolri— OP-Grooming/Diskussion als agentgetriebene Tasks verankert + Board-Sync vervollständigt (#617) (Doku,APP_VERSIONunverändert 0.79.0). Kontext: nach der 174-OP-Migration (#477) densync-ops-Lauf per Dispatch nachgefahren (Fix #512) → Board vollständig (~142 offene OPs gespiegelt). PO-Entscheide (3 Fragen) verankert inagents.md§6.2a: (1) Priorität/Reihenfolge im Repo entscheiden (prio:/status:inops/<ID>.md, kein Board→Repo-Backflow — Everything-as-Code, eine Quelle). (2) OP-Diskussion zusammenfassen = stehender, agentgetriebener Task auf Zuruf (liest die op-sync-Issue-Kommentare via GitHub-MCP →## Diskussion-Block in der ops-Datei → PR; keine Pipeline). (3) OP-Grooming on-demand je genanntem OP (## Grooming-Block: Akzeptanzkriterien · Aufwand · Abhängigkeiten · offene DSGVO-Fragen · prio-Vorschlag → PR)._Vorlage.mdum beide optionalen Blöcke ergänzt. Reine Doku, kein Bump. - Branch
claude/docs-review-process-automation-soolri(PR folgt) — Fix:sync-ops-issues.mjsskaliert auf den vollen OP-Bestand (Big-Bang-Folge) (#512) (Tooling,APP_VERSIONunverändert 0.79.0). Befund: Der erstesync-ops-Lauf nach der 174-OP-Migration (#477) brach mit GitHub-Search-API-403 (Secondary-Rate-Limit) ab — das Skript machte eine Such-Anfrage je OP (~140), was den strengen Search-Burst-Limit sprengt; das Board war nur bis ~OP-DOCS-4 befüllt. Fix: (1) Issue-Lookup auf einen paginierten Core-List-Aufruf umgestellt (/issues?labels=op-sync&state=all→ In-Memory-Index statt N×/search/issues); (2)gh()-Wrapper mit Backoff bei 403/429-Secondary-Limits (retry-after/exponentiell, 5 Versuche) + Drosselung bei fast leerem Primär-Limit; (3) 300 ms Pause zwischen Schreib-Calls. Idempotent — der Nachlauf vervollständigt den Rest. Verifikation:node --check+ Dormant-Skip grün. - Branch
claude/docs-review-process-automation-soolri(#477) — OP-DOCS-11 v3: OP-Archiv vollständig ins ops/-Modell migriert (Big-Bang, PO-Auftrag „überführe das OP-Archiv … dann haben wir das sauber") (Doku/Tooling,APP_VERSIONunverändert 0.79.0). Gebaut: (1) ~166 Alt-OPs aus HANDOFF §4 + Lastenheft §11 in je eineops/<ID>.mdüberführt (4 parallele Agenten, §4-Texte wortgetreu als Audit-Trail übernommen + programmatisch als byte-identisch verifiziert; Status/audience je Quelltext beurteilt, Grenzfälle dokumentiert). ops/-Bestand jetzt 174 OPs — 100 offen · 42 in Arbeit · 32 erledigt · 0 verworfen. (2) HANDOFF §4 → Pointer (184→23 Zeilen; verbindliche Liste = generierteOffene-Punkte.md, Lastenheft §11 bleibt fachlichesdetail:-Ziel, Stand-Schnappschuss 06-23 als Historie erhalten). (3)gen-ops.mjsohne Archiv-Heuristik — die 📊-Statistik zählt seither exakt (kein §4-Schätz-Pie mehr). (4) 3 Sammel-Rollups (OP-R7/R8/R9 „1..9"-Zeilen) entfernt — die Einzel-OPs existieren separat. (5) Querverweise nachgezogen: CLAUDE.md · agents.md (§2.1/§3/§6.2) · IDs.md (Reverse-Lookup auf ops/) · Lastenheft-§11-Banner · Gold-Standard · ops/README · Compliance/Risikoregister/Roadmap/Funktionsumfang. Entscheidung: Big-Bang statt „wandert bei Berührung" (PO-Auftrag); §4-Texte bleiben unverändert erhalten (Wortlaut = Audit-Trail). Hinweis: der Merge löst densync-ops-Spiegel aus → ~142 offene OPs werden als GitHub-Issues gespiegelt (op-sync-Board). Verifikation:gen-ops(174) ·check-doc-consistency --strictgrün ·smooth-logssauber. - Branch
claude/docs-review-process-automation-soolri(#476) — OP-ORG-1 ✅ abgeschlossen (Board live · Kadenz wöchentlich) + CodeRabbit auf einmaligen Ready-PR-Review (Doku/Config,APP_VERSIONunverändert 0.79.0). (1) OP-ORG-1 ✅: PO hat das GitHub-Projects-Board über dieop-sync-Issues angelegt und die Kadenz auf wöchentlich entschieden (PO-Wochenblick aufs Board; Agenten-📊-Blick je Session-Beginn) — verankert inagents.md§6.2,ops/OP-ORG-1.md→ erledigt (Rest-Ideen als YAGNI-Later notiert). (2) CodeRabbit-Umstellung (PO-Entscheid):reviews.auto_review.auto_incremental_review: falsein.coderabbit.yaml(gegen das Schema verifiziert) — ein automatischer Review je Ready-PR, keine inkrementellen Re-Reviews bei Pushes; manuell weiter via@coderabbitai review. Motiv: Fair-Usage-Limit heute erreicht + „head commit changed"-Neustarts nach Marker-Amends entfallen. Verifikation:gen-ops(11: 4 offen · 0 in Arbeit · 7 erledigt) ·--strictgrün ·smooth-logssauber. - Branch
claude/docs-review-process-automation-soolri(#474) — CodeRabbit-#473-Nachzug: Statistik-Quellen schlagen hart fehl + Board-Wording korrigiert (beide Findings valide) (Doku/Tooling,APP_VERSIONunverändert 0.79.0). (1)risiken()/entscheidungen()ingen-ops.mjsschlagen bei Lesefehlern HART fehl statt still 0/Teilstatistik zu rendern (Haus-Stil; +Guard „keine RISK-Zeilen gefunden"). (2) Board-Wording: die Spiegel-Labelsstatus:*/prio:*sind Filter/Slice — Board-Spalten kommen bei GitHub Projects aus dem Projects-eigenen Status-Feld, nicht aus Labels (gegen GH-Doku verifiziert; korrigiert inops/OP-ORG-1.md+agents.md§6.2, Feld-Sync aus ops/ als optionale spätere Automation notiert — der „(Board-Spalten/Filter)"-Wortlaut im #473-Eintrag unten bleibt als Historie stehen, dieser Eintrag ist die Korrektur). Verifikation:gen-opsgrün (Zahlen unverändert) ·--strictgrün ·smooth-logssauber. - Branch
claude/docs-review-process-automation-soolri(#473) — OP-ORG-1 v2: Tasktracking auf GitHub-Projects-Basis + Statistik-Ausbau auf Entscheidungen & Risiken (Doku/Tooling,APP_VERSIONunverändert 0.79.0). Entscheidung: GitHub Projects statt neuem Tool — Board als reiner Konsument über den vorhandenenop-sync-Issue-Spiegel (0 neue Systeme, Repo bleibt Quelle der Wahrheit, Einfachheit). Gebaut: (1)gen-ops.mjs-📊-Statistik zählt jetzt zusätzlich Entscheidungen (E-IDs aus den Sign-offs indocs/, ✅-Heuristik: 12 entschieden / 2 offen) und Risiken (Status-Spalte Risikoregister, fett-tolerant geparst: 13 offen/in Arbeit / 6 gemindert) — als Bestandstabelle neben den beiden Mermaid-Pies. (2)sync-ops-issues.mjsspiegeltstatus:*-Labels (Board-Spalten/Filter). (3) Sichten-&-Steuern-Ritual inagents.md§6.2 verankert (📊-Blick je Session-Beginn; Board = Stakeholder-Sicht). Offener Rest (dokumentiert inops/OP-ORG-1.md): Board-Anlage durch PO (~5 Min, braucht Org-Projects-Rechte — per API/MCP hier nicht möglich; Anleitung im OP) + Kadenz-Entscheid. Verifikation:gen-ops(11) ·check-doc-consistency --strictgrün ·node --check sync-ops-issues·smooth-logssauber. - Branch
claude/docs-review-process-automation-soolri(#469) — OP-DOCS-13 ✅ abgeschlossen: HANDOFF-§4-Archiv-Glättung + #405-Abschluss (reine Doku,APP_VERSIONunverändert 0.79.0). (1) §4-Glättung (Schluss-Runde der 5-Phasen-Roadmap): 117 near-identische/überholte Zeilen entfernt — 96 Dekorations-Duplikate (Anker/Link- vs. blanke Variante, Inhalt byte-identisch; Union-Merge-Bestand) + 21 überholte Generationen desselben Eintrags (jeweils die neueste, entschiedene Fassung bleibt: z. B. OP-OPT-1 ×3→1, OP-TENANT ×7, OP-BACKUP-1 ×7, OP-SEED-1/OP-COST-*/OP-AUDIT-1-Generationen); HANDOFF 587→470 Zeilen, Mega-Zeilen (>2000) 90→52; alle 143 distinkten Alt-IDs erhalten (gen-ops-Zähler unverändert). Entscheidungen: inhaltlich verschiedene Mehrfach-Einträge (z. B. OP-AI-4 Slice 14/15, OP-PM-3 Plan vs. Umsetzung) bleiben; der verbliebene OP-BACKUP-1-Eintrag erhält eine PITR-Korrektur-Notiz (#467: nicht tabellen-selektiv, zweistufig Export→Whole-DO-PITR→Re-Append) statt stehenbleibendem Widerspruch (OP-DOCS-9); restliche Lang-Zeilen = akzeptierte Einzel-Historie, Warn-Gate adressiert nur Neues. (2) #405 abgeschlossen (cross-repo Repo-Keys TKT/MED/GRM): Branch war 1 Woche hintermainmit Server-seitigem Merge-Konflikt (GitHub wendetmerge=unionnicht an) — lokal union-gemergt, dabei 2 überholte „(PR folgt)"-CHANGELOG-Dubletten vonmaingeglättet, Auto-Merge → gemergt; CodeRabbit-Nachzug-Finding umgesetzt:IDs.md„bare" → „repo-lokal, also ohne Repo-Key" (Selbsterklärbarkeit). (3) Zwei neue OPs (PO, 07-12):ops/OP-PILOT-1.md(Konzept Pilot-Phasen — Phasenmodell/Erfolgskriterien/Rollen/Abbruchkriterien für den Vest-POC, 🔴 jetzt; Abgrenzung: OP-VERTRIEB-3 = Zeitachse, OP-PILOT-1 = Inhalt) +ops/OP-ORG-1.md(Tasktracking; Empfehlung: GitHub Projects über den op-sync-Spiegel ausreizen statt neuem Tool). (4) Statistik-Vorgabe (PO, verbindlich): die Doku führt immer eine Statistik + Grafik offen vs. abgeschlossen — umgesetzt generiert (nie stale):gen-ops.mjserzeugt inOffene-Punkte.mdeine 📊-Sektion mit Zahlen + 2 Mermaid-Pies (ops/-Bestand nach Status · §4-Archiv per ✅-Heuristik); Regel inCLAUDE.mdverankert, Ausbau (Entscheidungen/Risiken, Projects-Board) → OP-ORG-1. Verifikation:gen-ops(11) ·check-doc-consistency --strictgrün ·smooth-logssauber. Folge-Runde (#469-Review, 2 von 6 Findings valide): §4-Eintrag OP-DOCS-13 entfernt (lebt alsops/OP-DOCS-13.md✅ — der Archiv-Eintrag widersprach dem Erledigt-Stand) · §4-Intro-Block ehrlich als „Stand-Schnappschuss 2026-06-23 (Historie)" betitelt (stand als „Aktueller Stand" neben Footer 12.07.). Abgelehnt: „Rest-Duplikate OP-R8-11/OPT-6/R9-12/R8-15/R4-3" (verifiziert: je genau 1×) · True-North-Kopf für die generierte Offene-Punkte-Übersicht (Kopf-Standard bewusst aufarchitektur/gescoped, #467; erfundene Betriebsmetrik wäre selbst Feigenblatt) · OP-ORG-1-Titel (PO-Wortwahl, Zielgruppe Stakeholder/Technik, kein Werkstatt-UI) · gen-ops-Zeilen-Parsing (§4-Bullets sind konstruktionsbedingt einzeilig; Heuristik dokumentiert). - Branch
claude/app-ux-process-review-i4b52d(#468) — OP-QS-6: Vier-Augen-Prinzip beim Quality-Check hart durchgesetzt — Abweichung nur durch den Chef (APP_VERSION0.78.0 → 0.79.0, MINOR; setzt die G-4-Ausnahme um, PO-Zusatz 07-12: „von dieser Regel darf nur der Chef abweichen"). Begriffsschärfung: Prüfschritt = PhaseqsOHNE Nacharbeit-/Klärungs-Marker (Nacharbeit + Klärung sind Ausführung in der QS-Phase). Pure DomäneistPruefschritt/qsAusfuehrende/vierAugenVerletzung(Helfer zählen nicht — der Produktive verantwortet). Durchsetzung an 4 Punkten: (1) TS-Scheduler schließt für Prüfschritte die Crews der Nicht-Prüfschritte desselben Auftrags aus (prospektiv im Lauf, plus Ist-Ausführende viaAuftragInput.vierAugenAusgeschlossen); neue G-4-Heuristik „zwingende Ausführende zuerst" (der einzige Könner eines Schritts übernimmt bevorzugt auch andere Schritte — minimiert Kontextwechsel UND hält die übrigen QM-Träger als Prüfer frei, sonst „verbrennt" der Greedy den letzten Prüfer); Infeasible-Grund nennt Vier-Augen. (2) CP-SAT-Payload entfernt Ist-Ausführende aus der Prüfschritt-Eligibility (⚠ dokumentierte Lücke: prospektive Co-Zuweisung im selben CP-SAT-Lauf — echte Cross-Task-Constraint inmodel.py= Folge; gedeckt durch (3)). (3) Harter Ausführungs-Guard: Start/Fortsetzen eines Prüfschritts mit Ausführenden in der Crew wird serverseitig abgelehnt — UI zeigt „⚠ Vier-Augen" (Detail-Panel-Badge + Meine-Arbeit-Hinweis). (4) Hand-Zuweisungs-Gate (teilschritt.zuweisen): Ablehnung sichtbar in der Chronik. Chef-Abweichung (Entscheidung PO): je Prüfschrittqs.vierAugenFreigabemit Pflicht-Begründung — Chef-gegated (interim = Werkstattleitungs-Allowlist wie Kosten-Admin,chef-Flag im State, bis OP-AUTH-1 Rollen liefert), Chronik + D1-Auditqs.vieraugen.freigabe; Freigabe wirkt für genau eine Instanz; UI: „🔓 Als Chef freigeben …" im Detail-Panel (nur für Chef sichtbar). Seed-Folge (Staffing-Erkenntnis): Marco erhieltskill-qm★2 — im Premium-Prozess führen Julian (Folie ★3) und Sina (Keramik) selbst aus, ohne dritten QM-Träger wäre die Endkontrolle unplanbar → realer Punkt für den Vest-Stammdaten-Abgleich (wer prüft Güteklasse-3-Aufträge?). Tests:operativ+8 Vier-Augen-Asserts (Prüfschritt-Erkennung QS≠Nacharbeit/Klärung · Ausführenden-Set · Verletzung · Chef-Freigabe · Re-Plan respektiert die Freigabe —toAuftragInputlässt den Ausschluss bei freigegebener Prüfschritt-Instanz fallen, sonst blockierte der Re-Plan die vom Chef sanktionierte Prüfung);test:eligibilityauf Zwei-Personen-Setup umgebaut + dokumentiert den Ein-Personen-Engpass (Werkstatt mit einer Person kann die eigene Arbeit nicht prüfen → Endkontrolle korrekt unplanbar, Grund nennt Vier-Augen); komplette Suite (38 Skripte) grün. Doku: CLAUDE.md + Lastenheft §3 (G-4 + Chef-Satz) + §11.1 OP-QS-6 ✅, HANDOFF §4, Funktionsumfang, Roadmap, Tests.md. - Branch
claude/app-ux-process-review-i4b52d(#449) — OP-UMPARK-1: Umparken als zuweisbare Aufgabe, G-4-platziert (APP_VERSION0.77.1 → 0.78.0, MINOR). Setzt die Befunde des Umparken-Checks um: (1) Geteilter Fakt statt Client-Optik — Umpark-Aufträge leben im DO-State (umparkAuftraege, persistiert + Broadcast): alle Terminals sehen den „unterwegs"-Puls, Reload vergisst nichts, „✓ Angekommen" von jedem Terminal (Chronik + D1-Audit je Beauftragung/Ankunft). (2) Ehrliche Quittung — Beauftragung ist EINE Messageauftrag.umparken(Server führt parken/starten/buchtwechsel-Dispatch aus, gemeinsame Logik extrahiert), Erfolgs-Toast erst mitumpark.resultinkl. Zuweisung; stille Ablehnungen (z. B. Bucht-Start ohne Zuweisung) kommen jetzt mit Grund zurück — Phantom-Transit behoben. (3) G-4-Platzierung — pure FunktionwaehleUmparkMitarbeiter: bevorzugt der Umpark-fähige Mitarbeiter, der als Nächstes an diesem Fahrzeug arbeitet (frühester offener Schritt), sonst ein gerade freier Umpark-fähiger (stört keinen laufenden Schritt, am wenigsten belastet), sonst „offen". (4) Skill-Gate — neuer Stammdaten-Skillskill-umparken(„Umparken"): Seed Julian+Marco, Migration v20 (SCHEMA_VERSION 19→20, Katalog-Backfill, idempotent; Zuweisungen = Mitarbeiter-Workspace-Pflege); die bisher tote „Umparken"-Chip-Hervorhebung im Mitarbeiter-Workspace ist damit live. (5) „Meine Arbeit" — zugewiesene + offene Umpark-Aufgaben als Karte über der Queue („AU-nnn nach ‚Stellplatz 2' bringen … ✓ Angekommen"). Entscheidungen: Belegungs-Drag&Drop bleibt direkte Inventur-Korrektur (dokumentiert Ist, beauftragt nicht); Umparken bleibt bewusst ohne Solver-Kapazität (Minutensache, kein Teilschritt); Rollen-Gate fürs Bestätigen folgt mit OP-AUTH-1. Tests:operativ+4 Platzierungs-Asserts (nächster-am-Fahrzeug · Skill-Gate · stört-keinen-laufenden-Schritt · offen),test:do-migrationsv20. Doku: Lastenheft §11.1 ✅, HANDOFF §4, Funktionsumfang, Roadmap, Tests.md, COMPONENTS.md/WORKSPACES.md (Re-park-Vertrag). - Branch
claude/app-ux-process-review-i4b52d(#446, gemergt) — Umparken-Check ✅ + neue Regel G-4 (Kontextwechsel-Minimierung, Vier-Augen-QS) + Chronik-Fix (APP_VERSION0.77.0 → 0.77.1, PATCH). Check (TODO 06-28, alle Pfade per Code-Review): Belegung-Drag&Drop · Repark-Modal (Detail-Panel/Belegung) · Konflikt-Preemption laufen auf konsistente Server-Pfade; Interrupt-Pflicht-Kommentar, Bucht-Typ-Bindung, Doppelbelegungs-Markierung, Guards intakt. Befunde: (1) Der Umpark-Auftrag wird niemandem zugewiesen — kein Skill/Schritt/Queue-Eintrag; „unterwegs" lebt nur client-lokal (kein DO-State/Broadcast, Reload vergisst, nur der Beauftragende kann „Angekommen" bestätigen) → OP-UMPARK-1 (echte zuweisbare Aufgabe, G-4-Platzierung); (2) Erfolgs-Toast vor Server-Antwort → Phantom-Transit bei stillen Ablehnungen (in OP-UMPARK-1); (3) gefixt: Chronik log beiauftrag.parken„Prozess beendet/pausiert", auch wenn die Transition scheiterte (z. B. beenden auspausiert) — schreibt jetzt nur, was wirklich geschah; (4) tote „Umparken"-Skill-Hervorhebung (v3-Rest, in OP-UMPARK-1). Entscheidungen (PO, 07-12): G-4 neu (CLAUDE.md + Lastenheft §3): Aufgaben-Platzierung minimiert Kontextwechsel — wer als Nächstes am Fahrzeug arbeitet, übernimmt bevorzugt dessen Neben-/Logistikaufgaben (z. B. Umparken vor der eigenen Folierung); harte Ausnahme QS (Vier-Augen): Ausführende verifizieren nie die eigene Arbeit → OP-QS-6 (Scheduler kennt die Constraint heute nicht — QS rein skill-basiert vergeben). Doku: Lastenheft §3 G-4 + §11.1 OP-UMPARK-1/OP-QS-6, HANDOFF §4 (TODO ✅ + 2 OPs), IDs.md, Roadmap. - Branch
claude/docs-review-process-automation-soolri(#467) — CodeRabbit-#462-Review: 9 Findings behoben, 8 begründet abgelehnt (E6-Folge) (reine Doku/Tooling,APP_VERSIONunverändert 0.77.1). Behoben: (1) Backup-Restore-Kernaussage korrigiert — der native DO-SQLite-PITR ist nicht tabellen-selektiv (CodeRabbit gegen CF-Doku verifiziert); Kernaussage + neue §5-Randbedingung: Audit-Delta vor Rollback exportieren/re-appenden oder eigene Storage-Grenze (Festlegung im Restore-Slice). (2) Mandantenfähigkeit-Kernaussage: zwei zentrale Ausnahmen (Registry und Hash-Anker) + R2-Prefix-Isolation als logisch abgegrenzt. (3) Bildbewertung: dormant eindeutig an Phase 1b (1a ist gebaut). (4) Audit-Log-Slice-Bullet: „dormant … inzwischen aktiv" → ✅ aktiv mit datierter Historie-Klammer. (5) agents.md §2.1 Kopf-Standard explizit aufdocs/architektur/*.mdgescoped (sonst hätte jede docs/-Datei sofort verletzt; für andere schwere Docs „empfohlen") + MD031-Leerzeilen. (6) Gate §10 gehärtet: prüft nur den Block direkt nach der H1 und verlangt alle vier Felder (Status/Bezug/Zielgruppe/True North) + genau eine Kernaussage — Negativ-Test verifiziert; Tests.md-Beschreibung nachgezogen. (7) OP-VERTRIEB-4 +Negativ-Security-Check als Abnahme-Kriterium (nur/vorteilsrechneröffentlich). (8) CHANGELOG-Migrations-Zähler präzisiert (143 Alt-IDs / 7 migriert / 9 ops-Dateien). Abgelehnt mit Begründung: die 8 MD028-Findings („blank line in blockquote" in den neuen Köpfen) — das Zwei-Block-Design (Metadaten-Box + Kernaussage-Box) ist gewollt (Vorbild Doku-UX-Konzept, Template agents.md §2.1); als Design-Entscheid jetzt explizit in §2.1 dokumentiert. Verifikation: Gate-Negativ-Test (kaputter Kopf → 2 Warnungen, restauriert → 0) ·check-doc-consistency --strictgrün ·smooth-logssauber. Folge-Runde (#467-Review, 2 Findings): PITR-Vertrag jetzt in §§5/7/8 konsistent (E-BACKUP-1/B5-5: zweistufig Audit-Export → Whole-DO-PITR → Re-Append; keine native Selektivitäts-Behauptung mehr) · Gate §10 auf Blockquote-Zeilen geankert (Prosa-/Code-Treffer zählen nicht). - Branch
claude/docs-review-process-automation-soolri(#462) — Doku-Review E6: architektur/-Kopf-Standard + Glossar-Alltagsbegriffe · CodeRabbit-Tuning · OP-VERTRIEB-4 (reine Doku/Tooling,APP_VERSIONunverändert 0.77.1). (1) E6-Format (Befund D6): kanonischer Kopf (Status · Bezug · Zielgruppe · True-North + genau eine> **Kernaussage.**) in allen 16architektur/-Docs durchgezogen (vorher 0/16) — inkl. Auflösung der belegten Selbstwidersprüche (In-App-Assistent „kein Code" vs. „Slices umgesetzt"; Audit-Log §2.1 „Heute alles DO-Blob" vs. „D1 ✅ aktiv" → historisch eingeordnet) und der Doppel-Kernaussagen (Offline-PWA mit erhaltener Foto-Queue-Einschränkung · Fahrzeug-3D); Standard als Regel inagents.md§2.1 verankert + Warn-Gatecheck-doc-consistency.sh§10 (Status/Zielgruppe/genau-eine-Kernaussage je architektur/-Doc). (2) Glossar (Befund D7, OP-DOCS-10): 11 Alltagsbegriffe ergänzt (Klärfall · Phase · Leistung · Terminklasse · Angebotsmodus · Auslastung · Endkontrolle · Nachkontrolle · Helfer · Wunschfrei · Crystal-Bar) → 68 Begriffe; ART-Label ehrlich „Fachlich (Werkstatt/Geschäft)"; Lastenheft-§13-Doppel-Glossar auf Verweis eingedampft (die dortigen Falsch-Definitionen Helfer/Standort dokumentiert entfernt; Crystal-Bar zentral gerettet); RAG-Doku-Index regeneriert (581 Chunks/51 Dateien). (3) CodeRabbit-Tuning (Nutzer-Auftrag):.coderabbit.yaml— True-North-Regel explizit auf Liefergegenstände als Ganzes gescoped (nicht je Zeile/Checkbox, Doku-Review-D6-Feigenblatt-Verbot); neue Pfad-Instruktionen für Timesheet/CHANGELOG (append-only Logs: keine True-North-/Lint-Forderungen, historische Marker nicht anmahnen) +.github/**(Template = Body-Prefill, kein MD041); nebenbei „Angular 20"→„Angular 22" gefixt. (4) Neuer OPops/OP-VERTRIEB-4.md(PO-Wunsch): Vorteilsrechner als öffentlicher Direktlink (z. B. taktano.com/vorteilsrechner) — Klärpunkte Access-Bypass vs. separates Public-Deployment, taktano.com-Zone (OP-BRAND-1), Lead-Erfassung bleibt OP-VERTRIEB-2. (5) ops/-first gelebt: OP-DOCS-13 bei Berührung ins ops/-Format migriert (ops/OP-DOCS-13.md, in-arbeit — Migrations-Zähler jetzt 143 Alt-IDs / 7 davon migriert, 9 ops-Dateien gesamt). Verifikation:gen-ops(9 OPs) +gen-glossar(68) +doku-index+check-doc-consistency --strict(0 architektur-Kopf-Warnungen) +smooth-logsgrün. - Branch
claude/docs-review-process-automation-soolri(#459) — Template-Präzisierung: Branch-Löschung konditional (CodeRabbit-#458-Finding) (reine Doku,APP_VERSIONunverändert 0.77.1). Ein-Zeilen-Fix im PR-Template: „(Branch wird nach Merge automatisch gelöscht)" → „(Branch nach Merge löschen — automatisch via Repo-Setting, sonst manuell)" — deckungsgleich mit agents.md §7 statt unbedingtem Versprechen. War als Fix in #458 gedacht, der Auto-Merge gewann den Wettlauf. - Branch
claude/docs-review-process-automation-soolri(#458) — CodeRabbit-#457-Review: 3 Findings behoben, 2 begründet abgelehnt (OP-DOCS-15-Folge) (reine Doku/Prozess,APP_VERSIONunverändert 0.77.1). Behoben: (1) Prozess-Checkliste im PR-Template vervollständigt (+Branch-first, +Remote-Writes via GitHub-API/MCP — die Vollständigkeits-Behauptung stimmt jetzt); (2) Session-Hook auf reinen Pointer reduziert (duplizierter „Kern"-Satz raus — eigene Sicht-Doktrin); (3) True-North-Bezug inops/OP-DOCS-15.mdergänzt („schneller"-Klausel, ehrlich abgegrenzt). Abgelehnt mit Begründung: (a) H1 im PR-Template (MD041) — das Template ist Body-Prefill, kein Standalone-Doc; eine Überschrift würde jeden PR-Body verschmutzen; (b) relative Links statt blob/main auf.github/-Dateien — Repo-Datei-Links außerhalbdocs/brechen auf der Docusaurus-Site, blob-URLs sind die dokumentierte Konvention (#419, OP-DOCS-9). Verifikation:gen-ops+check-doc-consistency --strict+smooth-logsgrün. - Branch
claude/docs-review-process-automation-soolri(#457) — OP-DOCS-15: Kanonische PR-Checkliste (neu:.github/PULL_REQUEST_TEMPLATE.md) (reine Doku/Prozess,APP_VERSIONunverändert 0.77.1). Schließt Empfehlung E5 des Doku-Reviews (#447, Befund D5/D10): ~20 Je-PR-Pflichten waren über ≥5 Orte verstreut, ohne PR-Template und ohne eine vollständige Checkliste. Gebaut: PR-Template als Checkbox-Liste — Pflicht jeder PR (8: CHANGELOG · HANDOFF · Timesheet · APP_VERSION · Konsistenz-Check · Log-Glätten · Branch-Sync · Verifikation) · falls zutreffend (6: Funktionsumfang · Tests.md · ops/-first · Glossar/Landkarte/IDs · Roadmap/Sanity · Compliance/Risiko) · Prozess („go"-Gate · Chat-Zusammenfassung); GitHub legt sie jedem neuen PR automatisch in den Body. Entscheidungen: (1) Checkliste = Sicht, kein neuer Regel-Owner — jede Pflicht zitiert ihre Owner-Regel (Lehre aus D4); (2) Pflege-Regel als neuesagents.md§6.9: neue/geänderte Je-PR-Pflicht ⇒ Template im selben PR nachziehen; (3) kein Generator (Einfachheit — ein Artefakt, Hook/CLAUDE.md verweisen statt duplizieren). Session-Hook Punkt 4 + CLAUDE.md §Repo auf die Checkliste umgestellt; neuerops/OP-DOCS-15.md(erledigt, ops/-first) + IDs.md/Register.md-Zeilen + Offene-Punkte regeneriert. Verifikation:gen-ops+check-doc-consistency --strict+smooth-logsgrün. - Branch
claude/docs-review-process-automation-soolri(#454) — Wrap: CodeRabbit-#453-Review adressiert (6 Findings) + Log-Finalisierung (reine Doku/Tooling,APP_VERSIONunverändert 0.77.1). (1)gen-ops.mjsaltBestand(): 160-Zeichen-Deckel im Zeilen-Scan entfernt (OP-IDs jenseits der ersten 160 Zeichen einer Mega-Zeile wurden übersehen; Zähler bleibt real bei 143/6 — Set-Dedup fing den Fall ab, Fix ist defensiv korrekt). (2) Rest-Widersprüche zur ops/-first-Regel getilgt: Register.md Änderungs-Reihenfolge-Regel · IDs.md Status-Zeile + Fußnote · HANDOFF §7-„Abarbeiten"/§8-Baum/§9-Reminder + Footer-Detailzeile. (3) Harte OP-Zahlen aus Hand-Docs entfernt (agents.md/Register.md verweisen auf die generierte Zählzeile — keine Zahlen-Drift). (4) Frische „(PR folgt)"-Marker finalisiert (#446 · #450 · #451 · #452 · #453 in CHANGELOG + Timesheet; historisch-mehrdeutige bewusst belassen, Präzedenz 07-11) + fehlender Teil-2-Timesheet-Eintrag nachgetragen. Verifikation:gen-ops+check-doc-consistency --strict+smooth-logsgrün. - Branch
claude/docs-review-process-automation-soolri(#453) — ops/-first verbindlich: OP-Doppel-Wahrheit aufgelöst (OP-DOCS-11 v2, Doku-Review E3/D4) (reine Doku/Tooling,APP_VERSIONunverändert 0.77.1). Das Review #447 belegte: HANDOFF §4 undops/*.mdbeanspruchten beide die Quelle der Wahrheit,agents.md§6.2 kannte das ops/-Format nicht (Ergebnis: Dreifach-Buchführung), und Doku-UX-Konzept Phase 5 skizzierte eine konkurrierende Zielarchitektur unter derselben OP-ID. Entschieden + umgesetzt: (1)agents.md§6.2 auf ops/-first umgeschrieben — neuer OP =ops/<ID>.md(Frontmatter, audience-Pflicht) +gen-ops; keine neuen Einträge mehr in HANDOFF §4 / Lastenheft §11 (Status-Updates am Bestand bleiben zulässig, Alt-OPs wandern bei Berührung). (2) HANDOFF §4 als Archiv gelabelt (Überschrift + Banner). (3) Migrations-Zähler ingen-ops.mjs: die generierteOffene-Punkte.mdzeigt jetzt „143 distinkte Alt-OP-IDs im §4-Archiv, 6 migriert" — Fortschritt sichtbar statt behauptet. (4) Doku-UX-Konzept Phase 5 als „anders gelöst" markiert (diesrc/op/op.mjs-Generierung von Register/IDs/§4 ist verworfen — §4 stirbt als Archiv aus, Register/IDs bleiben kuratierte Indizes). (5) Zuständigkeits-Kopien nachgezogen: Register.md (Quelle-Tabelle zweizeilig neu/Bestand) · IDs.md (Intro + OP-Legende) · CLAUDE.md (Audit-Trail-Regel) · ops/README.md · Gold-Standard (+Archiv-Label-Lehre für drkv-Rollouts). (6)ops/OP-DOCS-11.mdv2-Block. Walk-the-talk: dieser PR legt selbst KEINEN neuen HANDOFF-§4-Eintrag an — der OP-Lebenszyklus steht inops/OP-DOCS-11.md. Verifikation:gen-opsgrün (Zähler korrekt) ·check-doc-consistency --strictgrün ·smooth-logssauber. Doku: agents.md §6.2, HANDOFF §4-Banner+Footer, gen-ops.mjs, Offene-Punkte.md (generiert), Register.md, IDs.md, CLAUDE.md, ops/README.md, OP-Management-Gold-Standard.md, Doku-UX-Konzept.md, ops/OP-DOCS-11.md, CHANGELOG, Timesheet. - Branch
claude/docs-review-process-automation-soolri(#452) — OP-DOCS-14 Teil 3: Doku-Gates scharf schalten — OP geschlossen (Tooling/CI/Doku,APP_VERSIONunverändert 0.77.1). Schließt Befund D5 des Doku-Reviews (#447: „kein einziges Doku-Gate blockiert; Erfolgs-Behauptungen übertreiben") und damit den letzten OP-DOCS-14-Teil. (1)scripts/check-doc-consistency.shzweistufig: harte, False-Positive-arme Teilmenge (tote Links/Bilder · Version/Build-Single-Source) blockt mit--strict(Exit 1 +::error), alle übrigen Checks warnen weiter; drei neue Warn-Checks — Log-Zeilenlängen > 2000 Zeichen (HANDOFF/CHANGELOG, aggregiert je Datei, OP-DOCS-13) · Footer-Staleness (README/HANDOFF „Letztes Update" > 7 Tage hinter letztem Commit, Review-D3) · Landkarte-Rücklink je Leaf-Doc. Negativ-Test verifiziert (injizierter toter Link → strict Exit 1, sauber → Exit 0). (2) CI (ci.yml):doc-consistencyläuft--strictund hängt jetzt amci-gate(war bewusst draußen); derOffene-Punkte.md-Staleness-Diff nachgen-opsblockt (::error/Exit 1) statt warn-only. (3) Doku-Site:onBrokenLinks: 'warn'→'throw'— Build vorher und nachher komplett grün verifiziert (npm ci + build, 0 Broken-Link-Warnungen); diethrow-Behauptung im Doku-UX-Konzept stimmt damit erstmals. (4) Neuer Generatorscripts/gen-doc-footer.mjs(idempotent,--check): schreibt den „↩ Zurück zur Doku-Landkarte · Lesepfade · Register"-Footer statisch in die Markdown-Quellen (39 Leaf-Docs) — die Rück-Navigation existiert jetzt auch auf GitHub, nicht nur auf der gerenderten Site (Review-Kennzahl „0/16 Rücklinks im MD" behoben); der Site-Remark-Footer (docNavFooter.mjs) erkennt den relativen README-Link und doppelt nicht. Entscheidungen: (a)Timesheet.mdbewusst ohne statischen Footer (append-only union-merge-Log — neue Sessions landen am Dateiende, ein End-Footer würde in die Mitte rutschen); (b) blockierende Teilmenge bewusst minimal (nur deterministische Checks) — Navigation/Hygiene/Staleness bleiben Warnungen, damit kein False-Positive einen Merge stoppt; (c) Regel-Kopien nachgezogen statt driften lassen (CLAUDE.md · agents.md §2.1/§5.1/§6.6 · session-start-hook · Tests.md · Doku-UX-Konzept §3 inkl. Korrektur der beiden übertreibenden Behauptungen). Verifikation:bash -n+ beide Modi + Negativ-Test ·gen-doc-footer --checkgrün · Docusaurus-Build grün (throw) ·check-no-hexgrün ·gen-opsgrün. Doku: check-doc-consistency.sh, gen-doc-footer.mjs (neu), ci.yml, docusaurus.config.js, 39× docs/-Footer, agents.md, CLAUDE.md, session-start-hook.sh, Tests.md, Doku-UX-Konzept.md, ops/OP-DOCS-14.md (erledigt), Offene-Punkte.md (generiert), HANDOFF §4, CHANGELOG, Timesheet. - Branch
claude/docs-review-process-automation-soolri(#451) — OP-DOCS-14 Teil 2: Drift-Fix-Runde verbindliche Stellen (reine Doku,APP_VERSIONunverändert 0.77.1). Schließt die Befunde D2 (Doku widerspricht Code/sich selbst) und D3-Vordertüren des Doku-Reviews (#447) an sechs verbindlichen Stellen: (1)docs/fachlich/operativmodell.md— der abgelöste Lifecycle (unbestaetigt→aktiv→…) und das alte Nummernformat#JJJJ-NNNdurch das reale Modell ersetzt (9 Status inkl.abgebrochen,nacharbeiten-Rückkante,#000.KW00.JJJJ, sprechende UI-Labels auslabels.ts); anschließend RAG-Doku-Index regeneriert (npm run doku-index) — der In-App-Assistent antwortet nicht länger mit dem wegmigrierten Statusmodell. (2) Lastenheft §5.1 —abgebrochen(terminal, aus allen aktiven Status) +nacharbeiten(Fertiggestellt→Angeliefert) in State-Diagramm, Status-Tabelle und F02 ergänzt; das Master-Spec-Diagramm widerspricht dem Code nicht mehr. (3)design/CLAUDE.md(Detailvertrag) — Alt-Client-Beschreibung (Tailwind-CDN,STATUS_HEX, Montserrat, „Monolith zerlegen",design-system/-Pfade) durch den Ist-Stand ersetzt (Tailwind v4 auf--tk-*-Tokens via PostCSS, Shell + 15 Workspace-Pages, Token-Pipeline +design-gate, Brand-Hex im Fließtext durch Token-Namen); alle weiterhin gültigen Non-Negotiables behalten. (4) Root-README.md— Angular 17→22, Node ≥18/wrangler@3-Begründung → Node 22/Wrangler 4, Test-Abschnitt auf 4 Kern-Befehle + Link auf die lebende Listedocs/betrieb/Tests.mdeingedampft, Anwender-Handbuch + Landkarte als Einstiege, Footer-Datum. (5)HANDOFF.md— Footer (16.06./„Angular 20" → 12.07./v0.77.1 mit aktuellem Fokus POC Vest + OP-DOCS-14) + §8-Dateibaum (flacher Alt-Baumdocs/Lastenheft.md→ reale Ordnerstruktur inkl. ops/, docs-site/, anwender/) + §6.1 „Tailwind via CDN" → Tailwind v4/Tokens. (6)docs/architektur/Persistenz.md— E-TENANT-1 von „voller D1-Sink empfohlen — offen" auf den Entscheid „✅ Variante C: D1 nur Tamper-Anker, keine PII zentral" nachgezogen (Widerspruch zuMandantenfaehigkeit.md§4 beseitigt); Root-CLAUDE.mdObservability/OP-LOG-1 von „heute noch console-basiert → migrieren" auf den Ist-Stand (OTLP → Grafana Cloud EU live,check-no-console.sh-Gate) + Owner-Pointer gekürzt. Entscheidung: Rewrites strikt gegen Code/Konfig verifiziert (auftrag.ts/labels.ts · client/package.json · .nvmrc · tokens-Pipeline) — keine Aussage ohne Beleg;check-doc-consistency+check-no-hexgrün. Doku: operativmodell.md, Lastenheft §4.9/§5.1, design/CLAUDE.md, README.md, HANDOFF (Footer/§8/§6.1/§4), Persistenz.md, CLAUDE.md,server/src/assistant/doku-index.generated.ts(regeneriert), ops/OP-DOCS-14.md (Teil 2 ✅), CHANGELOG, Timesheet. - Branch
claude/docs-review-process-automation-soolri(#450) — OP-DOCS-14 Teil 1: Anwender-Handbuch (neu:docs/anwender/, 4 Seiten) (reine Doku,APP_VERSIONunverändert 0.77.1). Schließt Befund D1 des Doku-Reviews (#447): die am stärksten geführte Zielgruppe — das Werkstatt-Team — hatte kein einziges Dokument in ihrer Sprache. Gebaut:Handbuch.md(erste Schritte: Bereiche der linken Leiste mit App-Untertiteln, Werker-Modus, „?"-Hilfe, Status-Wörter, die drei Leitfragen als „Wo sehe ich das?"-Tabelle) ·Mein-Arbeitstag.md(Queue mit Positionsnummern, ⏸ Pause/▶ Weiter/✓ Fertig, Doku-Fenster mit den fünf Textbaustein-Chips, Pflicht-Fotos je Perspektive, Offline-Foto-Warteschlange) ·Klaerfall-melden.md(melden in 3 Schritten mit den vier Grund-Presets, die vier Lösungs-Wege als Tabelle, „⏱ Klärung einplanen" 15/30/60 min) ·Fahrzeug-annehmen.md(Ein-Satz-Annahme mit den fünf Bausteinen + Termin-Härte, Check-in „🚗 Fahrzeug da" mit Car-Check-Pflicht + FIN-Pflichtfeld). Entscheidungen: (1) alle UI-Strings wörtlich aus dem Client extrahiert (Explore-Lauf übershell/meine-arbeit/annahme/quality/klaerfall-loesen/labels.ts) statt aus dem Gedächtnis — Doku↔Code-Treue ab Tag 1 (OP-DOCS-9); (2) Vier-Augen-Regel bewusst nicht beschrieben (im Client nicht umgesetzt — das Handbuch beschreibt nur Gebautes); (3) du-Form wie die App selbst, keine OP-IDs/Code-Symbole im Text; (4) Sidebar-Position 0.5 (direkt nach Lesepfaden, nicht-invasiv ohne Umnummerieren der 6 Bestands-Ordner). Anwender- + Customer-Service-Lesepfad führen jetzt zuerst ins Handbuch (statt aufs veralteteoperativmodell.md); Aufgaben-Tabelle +„die App im Alltag bedienen". Doku: docs/anwender/* (neu, inkl._category_.json), Lesepfade.md, docs/README.md, ops/OP-DOCS-14.md (Teil 1 ✅), Offene-Punkte.md (generiert), HANDOFF §4, CHANGELOG, Timesheet. - Branch
claude/docs-review-process-automation-soolri(#447) — Doku-Review 2026-07: „Ist die Dokumentation ein Meisterwerk?" (neu:docs/betrieb/Doku-Review-2026-07.md+ OP-DOCS-14) (reine Doku,APP_VERSIONunverändert 0.77.0). Nutzer-Auftrag: Experten-Review der Dokumentation (inhaltlich · strukturell · Doku-Vorgaben) aus Sicht UX + Prozess-Automatisierung für stark geführte Akteure — Schwester-Review zum App-UX-Review #434. Methode: 4 parallele Tiefen-Reviews über alle ~55 Docs (fachlich+Glossar · architektur/ · betrieb/produkt/Logs · Konventionen/Governance) mit Code-Stichproben + mechanischen Messungen. Urteil: starkes Gesellenstück mit Meister-Inseln — generierte/kuratierte Sichten (Glossar, ops/, Funktionsumfang, Tests.md) nahe am Anspruch; verhindert wird das Prädikat durch D1 keine Anwender-Doku (Lesepfad führt aufs veralteteoperativmodell.md) · D2 Drift an verbindlichen Stellen (operativmodell-Lifecycle abgelöst + im RAG-Index, Lastenheft §5.1 ohneabgebrochen/nacharbeiten,design/CLAUDE.mdbeschreibt Alt-Client, Persistenz↔Mandantenfähigkeit widersprechen sich bei E-TENANT-1) · D3 stale Vordertüren + Mega-Zeilen (README „Angular 17", HANDOFF-Footer 16.06., Roadmap 06-28, Timesheet 3 Σ-Zeilen, HANDOFF-Max 15.284 Z., CHANGELOG 70× „PR folgt") · D4 OP-Doppel-Wahrheit (HANDOFF §4 vs.ops/*.md, 5/~210 migriert, agents.md §6.2 kennt ops/ nicht) · D5 ~20 Je-PR-Pflichten ohne ein blockierendes Gate (doc-consistencynicht im ci-gate,onBrokenLinksrealwarn) · D6–D10 Format/Glossar/Gelebte-Prozesse/Politur/Onboarding-Last. Entscheidungen: Empfehlungen E1–E6 nach Wirkung÷Aufwand; Top-3 (Anwender-Handbuch · Drift-Fix-Runde · Gates scharf) als neuerops/OP-DOCS-14.md(audience technik+produkt) gebündelt — E3 bleibt bei OP-DOCS-11, E6 bei OP-DOCS-13/-10; neuer OP bewusst ops/-first angelegt (ohne Lastenheft-§11-Doppelung — die Doppel-Buchführung ist selbst Befund D4). Doku: Doku-Review-2026-07.md (neu), ops/OP-DOCS-14.md (neu), Offene-Punkte.md (generiert), docs/README.md, IDs.md, Register.md, HANDOFF §4, CHANGELOG, Timesheet. - Branch
claude/app-ux-process-review-i4b52d(#446) — Umparken-Check ✅ + neue Regel G-4 (Kontextwechsel-Minimierung, Vier-Augen-QS) + Chronik-Fix (APP_VERSION0.77.0 → 0.77.1, PATCH). Check (TODO 06-28, alle Pfade per Code-Review): Belegung-Drag&Drop · Repark-Modal (Detail-Panel/Belegung) · Konflikt-Preemption laufen auf konsistente Server-Pfade; Interrupt-Pflicht-Kommentar, Bucht-Typ-Bindung, Doppelbelegungs-Markierung, Guards intakt. Befunde: (1) Der Umpark-Auftrag wird niemandem zugewiesen — kein Skill/Schritt/Queue-Eintrag; „unterwegs" lebt nur client-lokal (kein DO-State/Broadcast, Reload vergisst, nur der Beauftragende kann „Angekommen" bestätigen) → OP-UMPARK-1 (echte zuweisbare Aufgabe, G-4-Platzierung); (2) Erfolgs-Toast vor Server-Antwort → Phantom-Transit bei stillen Ablehnungen (in OP-UMPARK-1); (3) gefixt: Chronik log beiauftrag.parken„Prozess beendet/pausiert", auch wenn die Transition scheiterte (z. B. beenden auspausiert) — schreibt jetzt nur, was wirklich geschah; (4) tote „Umparken"-Skill-Hervorhebung (v3-Rest, in OP-UMPARK-1). Entscheidungen (PO, 07-12): G-4 neu (CLAUDE.md + Lastenheft §3): Aufgaben-Platzierung minimiert Kontextwechsel — wer als Nächstes am Fahrzeug arbeitet, übernimmt bevorzugt dessen Neben-/Logistikaufgaben (z. B. Umparken vor der eigenen Folierung); harte Ausnahme QS (Vier-Augen): Ausführende verifizieren nie die eigene Arbeit → OP-QS-6 (Scheduler kennt die Constraint heute nicht — QS rein skill-basiert vergeben). Doku: Lastenheft §3 G-4 + §11.1 OP-UMPARK-1/OP-QS-6, HANDOFF §4 (TODO ✅ + 2 OPs), IDs.md, Roadmap. - Branch
claude/app-ux-process-review-i4b52d(#445, gemergt) — OP-R7-16 v1: Fahrzeug-Angaben am Auftrag (FIN/Kennzeichen/Beschreibung) (APP_VERSION0.76.0 → 0.77.0, MINOR). Domäne:Auftrag.fahrzeug = { fin?, kennzeichen?, beschreibung? }(§4.9-konform: Attribute am Auftrag, kein Fahrzeug-Objekt) +finPlausibel()(ISO 3779: 17 Zeichen ohne I/O/Q);fahrzeugAnnahmeverlangt die FIN hart (Guard). Handler:auftrag.create/auftrag.checkin/auftrag.updatenehmenfahrzeugan (bereinigeFahrzeugtrimmt/verwirft Leerstrings; checkin patcht vor der Annahme, update merged Felder + Chronik „Nachgetragen" + D1-Audit); DTO-Passthrough. Client: Annahme-Buchung mit optionaler Fahrzeug-Zeile (Kennzeichen/FIN/Beschreibung); Check-in „Fahrzeug da" mit FIN-Pflichtfeld (vorbefüllt aus der Buchung) + Kennzeichen; Auftrag-Detail zeigt Fahrzeug-Karte + „✎ nachtragen" (Muster Kunde/CRM); Tafel zeigt Kennzeichen-Chip. Entscheidungen: (1) FIN Pflicht spätestens beim Check-in, optional bei Buchung (Fahrzeug oft noch nicht da); generischerliefern-Altpfad bleibt ohne Guard (Edge/Legacy). (2) FIN-Plausibilität warn-only (Sonder-/Altfahrzeuge blockieren nie). (3) Fotos über den bestehenden Annahme-Schritt mit Foto-Pflichtperspektiven (OP-R4-3) — kein zweiter Foto-Pfad. (4) ⚠ DSGVO: FIN/Kennzeichen personenbezogen → Löschkonzept-Detail bleibt bei OP-CRUD-1/E-CRUD-4. Selbsttestnpm run operativum FIN-Pflicht/-Plausibilität erweitert; Doku: Lastenheft §4.9+§11.1, HANDOFF §4, Funktionsumfang, Roadmap (🔴-W1 erledigt). - Branch
claude/app-ux-process-review-i4b52d(#444, gemergt) — Korrektur: Pilotkunde = Vest Automotive (OP-VERTRIEB-3) (reine Doku,APP_VERSIONunverändert 0.76.0). Nutzer-Korrektur (07-12): Der Probebetrieb-Pilotkunde ist Vest Automotive — die Gründer-Call-Notiz (07-08) nannte zunächst „Festler Automotive". Inops/OP-VERTRIEB-3.md, HANDOFF §4 und Lastenheft §11.6 korrigiert, jeweils mit selbst-dokumentierender Korrektur-Notiz (kein stilles Umschreiben der Call-Notiz);Offene-Punkte.mdregeneriert. Erfreuliche Folge für die POC-Vorbereitung: die Tenant-Vorlageserver/src/tenants/vest-automotive.tsträgt bereits den Pilotkunden — der Blocker „Tenant-Setup" schrumpft auf Stammdaten-Abgleich (echte Leistungen/Teilschritte/Skills/Schichten/Buchten von Vest gegen die Vorlage prüfen/vervollständigen) statt Neuaufbau. - Branch
claude/app-ux-process-review-i4b52d(PR folgt) — UX-Review B6: Bedien-Politur — Gantt-Tastatur-Pfad · Hof-Radar responsiv · Textbausteine (OP-TEXTBLOCK-1 v1) (APP_VERSION0.75.0 → 0.76.0, MINOR, rein client-seitig). Schließt die letzten B6-Randthemen weitgehend: (1) Gantt-Entwurf per Tastatur — verschiebbare Blöcke sind im Entwurfs-Modus fokussierbar (role=button/tabindex, aria-Hinweis); Enter öffnet einen Verschiebe-Dialog (Bucht-Select +datetime-local, auf dasselbe 15-min-Raster gerastert wie der Drag), der das gleichepinned-Event emittiert — ein Pin-Pfad, keine Parallel-Logik; außerhalb des Entwurfs bleibt Enter der Detail-Klick. (2) Hof-Radar responsiv — das 760px-Design skaliert pertransform: scale()(ResizeObserverauf der Board-Spalte, Wrapper trägt Breite/Höhe × Skala, nie >1) auf schmale Container/Tablets; Pixel-Koordinaten der Kacheln bleiben unverändert gültig. (3) Textbausteine am Doku-Gate (OP-TEXTBLOCK-1 v1) — fünf feste Werkstatt-Phrasen als Antipp-Chips über dem Pflicht-Kommentar im Detail-Panel („ohne Befund" · „wie geplant ausgeführt" · „siehe Fotos" · „Kunde informiert" · „Restarbeit notiert"), Antippen hängt mit·-Trenner an, Tippen bleibt frei — Touch-Terminal-Ergonomie; admin-editierbare Bausteine je Schritt/Aspekt bleiben offener Rest (G-1). Bewusst verbleibend aus B6: Umparken in Belegung/Hof-Radar bleibt Drag-only (Tastatur-Weg existiert über das Umpark-Modal im Detail-Panel) · Diktat = OP-DIKTAT-1. Doku: UX-Review (B6 ✅ weitgehend), HANDOFF §4 (OP-TEXTBLOCK-1 v1),Funktionsumfang.md,design/COMPONENTS.md(B6-Patterns), CHANGELOG, Timesheet. Verifikation:ng buildgrün · No-Hex grün ·check-doc-consistencygrün. - Branch
claude/app-ux-process-review-i4b52d(PR folgt) — Kapazitätstragender Klärungs-Arbeitsschritt (OP-R3-1-Folge) (APP_VERSION0.74.0 → 0.75.0, MINOR). Die im Engine-PR (#440) bewusst offen gelassene Folge: die Klärungsarbeit selbst (Kunde anrufen, begutachten, abstimmen) ist jetzt opt-in als geplanter Schritt einplanbar — sie kostet damit sichtbar Kapazität (True-North-Frage 1), der Klärende ist nicht doppelt verplanbar, und die Verantwortung steht im Plan. Gebaut: (1) Katalog-Templatets-klaerung(Skillskill-klaerung— der seit OP-R3-1 reservierte Skill hat seinen ersten Verwender; keine Bucht-Bindung, Doku-Aspekte als Klärungs-Leitfaden, Doku-Pflicht beim Erledigen = Klärungs-Doku) in der Tenant-Vorlage + Migration v19 (SCHEMA_VERSION18→19, zieht das Template idempotent in Bestands-Tenants nach; Mitarbeiter-Skills bewusst NICHT migriert — wer klären darf, ist Stammdaten-Pflege). Seed: Julian trägtskill-klaerung(Niveau 2), damit frische Tenants sofort planbar sind. (2) Domäne:klaerungsArbeitsInstanz()(pure, Guards: offener Klärfall · max. eine offene Klärung · Dauer 5–480 min) +offeneKlaerungsInstanz()— Instanz in der aktuellen Auftrags-Phase, Dauer über das bewährtenacharbeitMin/zusatzSchritte-Muster (TS-Scheduler + CP-SAT, kein Solver-Redeploy). (3) Handlerauftrag.klaerungEinplanen(+ REOPT_EVENT + D1-Auditklaerung.eingeplant): Einzelplan sofort; ist er nicht machbar, bleibt der Schritt vorgemerkt und die Chronik nennt die wahrscheinliche Ursache („Hat ein Mitarbeiter den Skill Klärung?"). (4) Client: geteilteklaerung-einplanen.component.ts— „⏱ Klärung einplanen …" mit Presets 15/30/60 min (bewusst grob: Schätzung statt Scheingenauigkeit) in Konflikte & Klärfälle + Detail-Panel; eingeplante Klärung zeigt sich als Badge (und ganz normal in Planung/Gantt/„Meine Arbeit"). Entscheidungen: Opt-in statt Automatik (Minutensachen bleiben formlos) · Migration nur Katalog, nicht MA-Skills · Warten-auf-Kunde (verstrichene Zeit ≠ Arbeitszeit) bewusst nicht modelliert — bei Bedarf eigene Folge. Verifikation:test:do-migrations(v19 ergänzt genau einmal + idempotent) grün ·npm run operativum Klärungs-Arbeitsschritt-Asserts erweitert (planbar · Template geseedet · Seed-MA mit Skill · Doppel-Guard · ohne-Klärfall-Guard) grün · Server-tscgrün ·ng build+ No-Hex +check-doc-consistencygrün. Doku: Lastenheft §5.1 (Folge ✅),Operative-Durchgaengigkeit.md,Funktionsumfang.md,Tests.md, CHANGELOG, Timesheet.
2026-07-11
- Branch
claude/app-ux-process-review-i4b52d(PR folgt) — Session-Wrap-up: Log-Hygiene + Stand nachgezogen (reine Doku,APP_VERSIONunverändert 0.74.0, OP-PM-2). Nach den sechs Merges des UX-Review-Zyklus (#434, #436–#440): (1)CHANGELOG.md: 16 veraltete „(PR folgt)"-Marker durch echte PR-Links ersetzt — die beiden Session-Einträge (#439/#440, inhaltlich zugeordnet) plus 14 eindeutige Ein-PR-Branches älterer Sessions (Mapping über die GitHub-API, Branch→gemergter PR); bewusst belassen: ~42 Marker von Mehrfach-PR-Branches/älteren Sessions, deren Zeile→PR-Zuordnung nicht mechanisch eindeutig ist (kein Rate-Raten im Audit-Trail). (2)HANDOFF.md§2: neue Kompakt-Zeile „UX-Review-Zyklus 07-11 + Klärungs-Engine" (v0.70.0→0.74.0, alle 6 Empfehlungen + OP-R3-1-Abschluss, größter offener Hebel OP-AUTH-1); Auslastungs-Quote-Zeile von „auf Branch" auf „auf main (#433)" korrigiert. (3)Roadmap.md: OP-ONBOARD-1 → Slice 1 ✅. (4)npm run smooth-logssauber (keine Dubletten/Konflikt-Marker). Verifikation:check-doc-consistencygrün. - Branch
claude/app-ux-process-review-i4b52d(#440) — Klärungs-Workflow-Engine: geroutetes Klärfall-Lösen (OP-R3-1-Folge, Lastenheft §5.1) (APP_VERSION0.73.0 → 0.74.0, MINOR). Schließt den letzten benannten OP-R3-1-Rest („volle Klärungs-Engine") und Review-Befund B2 vollständig. Gebaut (Server,operativ/auftrag.ts+party/leitstand.ts): (1) Melden = echte Unterbrechung — neue purepausiereLaufendeSchritte()pausiert alle laufenden Schritte (mit Namen für die Chronik),KlaerfallKontexterfasst den auslösenden Schritt (teilschrittInstanzId, aus „Meine Arbeit" mitgesendet). (2) Geroutetes Lösen — neue pure, testbareloeseKlaerfallMitRoute()mitKlaerfallRoute = zurueck | qs | schritt | abbruch:zurueck(Kontext weg, Schritte bleiben pausiert → Weiterarbeit über ▶ mit allen Guards) ·qs(offene Nicht-QS-Phase-Schritte werden Klärungs-übersprungen — neueueberspringeFuerKlaerung(), die als sanktionierte OP-R3-5-Ausnahme auch Pflicht- und pausierte Schritte überspringen darf; bleibt nichts offen →fertigstellen, Auftrag landet in der Endkontroll-Queue) ·schritt(doppelt interpretiert: offenes Ziel = „ab hier weiter" mit Klärungs-Skip des Offenen davor; Katalog-Ziel = Einschub-Wiederholung als neue-KL-Instanz über das bewährte nacharbeit-/zusatzSchritte-Muster +einzelplan, kein Solver-Redeploy) ·abbruch(delegiert anstornieren). Lösungs-Kommentar ist Pflicht (§5.1 „Dokumentieren & Kommentieren"). (3)auftrag.klaerfallist jetzt REOPT_EVENT und schreibt D1-Audit (klaerfall.gemeldet/klaerfall.geloestmit Route/Ziel) — beides fehlte. Abwärtskompatibel:loesenohneroute=zurueck. Client: neue geteilteklaerfall-loesen.component.ts(Routen-Chips mit Hinweis je Weg + Ziel-Picker „ab hier weiter"/„einschieben/wiederholen" + Pflicht-Kommentar) ersetzt den nackten „✓ Klärfall lösen"-Button in Konflikte & Klärfälle und im Detail-Panel (ein Server-Pfad, nichts dupliziert); „Meine Arbeit" sendet die Schritt-Instanz beim Melden mit. Entscheidungen: Klärfall-Bearbeitung bleibt ohne eigenen kapazitäts-tragenden Arbeitsschritt (Skill „Klärung" weiter reserviert — bewusste Folge); Melden pausiert alle laufenden Schritte des Auftrags (Unterbrechung gilt dem Auftrag). Verifikation:npm run operativum den Klärungs-Engine-Selbsttest erweitert (melden-pausiert · Kommentar-Pflicht · zurück · QS-Sprung · ab-hier-weiter · Einschub planbar · Abbruch terminal) grün ·test:nacharbeitgrün (zusatzSchritte-Regression) · Server-tscgrün ·ng build+ No-Hex +check-doc-consistencygrün. Doku: Lastenheft §5.1 (Umgesetzt-Block) + §11 OP-R3-1 (Engine ✅),Operative-Durchgaengigkeit.md(neuer Lösen-Vertrag),design/WORKSPACES.md, UX-Review (B2 ✅ vollständig),Funktionsumfang.md,Tests.md, HANDOFF §4 (Folge-OP ✅), CHANGELOG, Timesheet. - Branch
claude/app-ux-process-review-i4b52d(#439) — UX-Review E4: True-North-Kacheln komplett — „Nächste freie Kapazität" je Leistung + „Standorte" im Überblick (APP_VERSION0.72.0 → 0.73.0, MINOR). Schließt die letzte offene Review-Empfehlung: die Top-3-Antworten stehen jetzt gebündelt in der Überblick-Sidebar (Frage 1 Auslastungs-Quote #433 · Frage 3 Kapazitäts-Kachel neu · Frage 2 Standorte-Kachel neu). Gebaut: (1) Server — neue reine FunktionnaechsteKapazitaeten()(server/src/insights/insights.ts): je aktiver Leistung EIN ASAP-Dry-Run des TS-Schedulers (scheduleLeistung, kein Angebots-Scan) → frühestmögliche Anlieferung („ab wann wieder Platz?") + früheste Abholbereitschaft; defensiv (kaputte Leistung reißt nie den Broadcast,grundstatt Throw); Entscheidung Performance: im DO über Plan-Stempel + Stunden-Raster gecacht (kapazitaetCache) — nicht jeder Broadcast rechnet neu, „ab wann" wandert trotzdem mit der Zeit; nichts persistiert (D-2). DTOinsights.kapazitaet. (2) Client — Überblick-Sidebar: Kachel „Nächste freie Kapazität" (je Leistung „ab morgen 08:00" viafmtRelative, Tooltip mit Abholbereitschaft; „kein Fenster" amber mit Grund) + Kachel „Standorte" (grün „✓ alle verortet" bzw. amber „⚠ N ohne Standort →" als Link in die Konflikte — Rot bleibt Warnungen). (3) Selbsttesttest:insightserweitert (Kachel: Anlieferung ≥ ab-Zeitpunkt · abholbereit ≥ Anlieferung · unbekannte Leistung → Grund). Sanity-Checkliste Frage 3 → ✅ (erste der drei Leitfragen auf Grün; Ausbau: proaktive Kunden-Angebote OP-R9-6, Kachel-Klick → vorbefüllte Annahme). Doku: UX-Review §4 (E4 ✅ — alle sechs Empfehlungen umgesetzt), Sanity-Checkliste (F3 ✅),Funktionsumfang.md, CHANGELOG, Timesheet. Verifikation: Server-tsc+test:insights+npm run operativgrün ·ng buildgrün · No-Hex grün ·check-doc-consistencygrün. - Branch
claude/app-ux-process-review-i4b52d(#438) — UX-Review E6 / OP-ONBOARD-1 Slice 1: Onboarding „Kurz erklärt" je Workspace (APP_VERSION0.71.1 → 0.72.0, MINOR — neues Feature, rein client-seitig). Gebaut: (1)onboarding-hinweis.component.ts— „Kurz erklärt:"-Karte beim Erstbesuch jedes Workspace, über dem Inhalt gerendert (eine Einbaustelle in der Shell, kein Change je Page): ein Satz „was ist hier?" + 2–3 konkrete erste Schritte in Werkstattsprache (gespeist aus den Rail-Untertiteln + Kern-Aktionen, 14 Workspaces abgedeckt), Workspace-Signaturfarbe als Akzent, „✓ Verstanden" blendet aus. (2) onboarding.service.ts— Gesehen-Status pro Gerät (localStoragetk-onboarding-gesehen, Signals; Privatmodus-fail-open: Hinweise erscheinen dann je Session). (3) „?"-Button im Header holt die Karte für den aktiven Workspace jederzeit zurück (aria-Label, gleiche Bedien-Sprache wie Theme-Toggle). Entscheidungen: bewusst Text-Karten statt verankerter Coachmark-Pfeile (Element-Anker brechen bei jedem Layout-Umbau; Karte bleibt wartungsarm) — Vertiefung/Fragen übernimmt der In-App-Assistent (OP-AI-4); Progressive Feature-Freischaltung + geführte Kern-Flow-Tour bleiben offen (OP-ONBOARD-1 Rest; der Werker-Terminal-Modus aus OP-UX-7 ist bereits eine manuelle Vorstufe der Staffelung). Damit sind alle sechs UX-Review-Empfehlungen adressiert (E1–E3 #436 · E5 #437 · E6 hier · E4 🟡 Rest = Kapazitäts-Kachel OP-R9-10/-6). Doku: UX-Review §4 (E6 ✅ v1), HANDOFF §4 (OP-ONBOARD-1 Slice 1 ✅),Funktionsumfang.md,design/COMPONENTS.md(Pattern „Onboarding Kurz erklärt"), CHANGELOG, Timesheet. Verifikation:ng buildgrün · No-Hex grün ·check-doc-consistencygrün. (Stolperstein erneut: deutsches Schließ-Anführungszeichen in Attribut-Bindings → aus dem aria-Label entfernt.) - Branch
claude/app-ux-process-review-i4b52d(#437) — UX-Review E5 „Politur": token-gestylte Dialoge statt nativer Browser-Dialoge + tote Komponenten entfernt (APP_VERSION0.71.0 → 0.71.1, PATCH — Tweaks, keine neue Funktion). (1) Native Dialoge ersetzt (Befund B6): neue geteilte Komponenteclient/src/app/leitstand/modal-dialog.component.ts(app-modal-dialog, Muster verallgemeinert aus Planung „Entwurf verwerfen?" OP-R8-15: Fog-Scrim + zentriertes Panel, Esc/Scrim bricht ab, optionales Pflicht-Eingabefeld mit Auto-Fokus + Enter,gefahr= rot umrandeter Bestätigen-Button) — ersetztconfirm()(Mitarbeiter-/Teilschritt-Archivieren),prompt()(neue Teilschritt-Vorlage/Leistung, Skill umbenennen); diealert()-Duplikat-Warnungen (Skill-Name vergeben) sind jetzt Warn-Toasts (nicht-blockierend, bestehender ToastService). Entscheidung/Anti-Pattern indesign/COMPONENTS.mdverankert: keine neuenconfirm()/prompt()/alert(). (2) Tote Komponenten gelöscht (Befund B7):FlowBandComponent(v2-Pipeline-Band, durch Hof-Radar + Aufträge-Fluss überholt) undInsightsPanelComponent(„Lage auf einen Blick", durch Überblick-KPI-Kacheln inkl. Auslastungs-Quote #433 überholt) — beide nirgends referenziert (Grep-verifiziert), per Git-Historie wiederherstellbar; COMPONENTS.md-Abschnitt entsprechend umgeschrieben. (3)/bild-schutz-Entscheidung: bleibt bewusst Deep-Link-Demo ohne Rail-Eintrag (OP-QS-2 Phase 1, dockt später an das R4-Foto-Upload-Feld — im Komponenten-Kommentar dokumentiert). Bewusst offen aus B6 (nicht Teil dieser Politur): Tastatur-Alternative für Drag&Drop, Hof-Radar-Responsivität, Touch-Kommentar-Ergonomie (OP-TEXTBLOCK-1/OP-DIKTAT-1). Doku: UX-Review §4 (E5 ✅),design/COMPONENTS.md(Modal-Dialog-Pattern neu, Flow-Band als entfernt markiert), CHANGELOG, Timesheet. Verifikation:ng buildgrün · No-Hex grün ·check-doc-consistencygrün · Grep: 0 native Dialoge im Client (einzigeconfirm-Treffer sind Methodennamen des Repark-Flows). - Branch
claude/app-ux-process-review-i4b52d(#436) — OP-UX-7 umgesetzt: Werker-Terminal-Modus · Klärfall am Schritt · zentrale Label-Sprache (APP_VERSION0.70.0 → 0.71.0, MINOR). Die drei Top-Empfehlungen aus dem UX-Review (#434) gebaut, rein client-seitig (kein Server-/Solver-/Schema-Change): (E1) Werker-Terminal-Modus — Rail-Footer-Toggle „⬣ Werker-Modus" (localStoragetk-werker-modus, Muster Theme-/Feedback-Toggle) reduziert die Navigation auf Meine Arbeit · Tafel · Qualität und springt beim Aktivieren nach/meine-arbeit; Entscheidung: bewusst Geräte-Einstellung ohne Security-Gate (Deep-Links bleiben erreichbar) — echte Rollen/Login bleiben OP-AUTH-1, dies ist die Vorstufe zur Mitarbeiter-Ansicht (OP-R9-4). (E2) „⚠ Klärfall" je Schritt-Karte in „Meine Arbeit" (nur produktiv Zugeteilte, kein offener Klärfall): Inline-Form mit Grund-Presets (Material fehlt · Schaden entdeckt · Rückfrage Kunde/Leitung · Maschine/Werkzeug defekt) + Pflicht-Freitext + eskalieren → bestehender Server-Pfadauftrag.klaerfall, Schrittname als Grund-Präfix (Klärfall bleibt Auftrags-Kontext, kein Modell-Change); aktiver Klärfall = rote Badge, Lösen bleibt im Panel/Konflikte. (E3) Neues zentrales Label-Modulclient/src/app/leitstand/labels.ts(Musterphase.ts): Auftrag-Status (kanonisch „Fahrzeug angeliefert") + Badge-Farben, Teilschritt-Status („wartet/läuft/pausiert"), Terminklasse (Title-Case „Garantiert/Zieltermin/Best-Effort"), Aktions-Labels — ersetzt die Inline-Maps in Tafel/Detail-Panel/Gantt/Aufträge/Annahme/Meine Arbeit; Entscheidungen: Tafel-archiviertrot → neutral (Rot nur für Warnungen), Mitarbeiter-Verfügbarkeit „Verfügbar" → „Frei" (deckungsgleich mit „○ Frei melden"), Gantt-Block-Farben (--tk-gantt-*) bleiben bewusst kontext-lokal. Doku: UX-Review §4 (E1–E3 ✅, E4 🟡 — Auslastungs-Quote kam parallel via #433),ops/OP-UX-7.mderledigt +Offene-Punkte.mdgeneriert,Funktionsumfang.md(3 Zeilen),design/COMPONENTS.md(3 neue Patterns), HANDOFF §4, Timesheet. Verifikation:ng buildgrün (Node 22.23; Budget-Warnung Bestand) · No-Hex-Gate grün ·check-doc-consistencygrün · Grep bestätigt 0 verbliebene Alt-Label-Maps. - Branch
claude/app-ux-process-review-i4b52d(#434) — UX- & Prozess-Review der Gesamt-App (neu:docs/betrieb/UX-Review-2026-07.md+ OP-UX-7) (reine Doku,APP_VERSIONunverändert). Nutzer-Auftrag: Experten-Review „verständlich, konsistent, leicht bedienbar, intuitiv — ist das ein richtig cooles Meisterwerk?" aus Sicht UX + Prozess-Automatisierung für stark anzuleitende Akteure. Urteil: außergewöhnlich reifes Werkstück, noch kein Meisterwerk — Fundament auf Meisterwerk-Niveau (harte Zustandsmaschine + QS-Gate, Next-Task-Push „Meine Arbeit", „Vorschlag statt Zwang"-Automatisierung, Ehrlichkeit als UX-Prinzip, Design-Disziplin ohne Hex-Verstöße; Stärken S1–S6), aber sieben Befunde B1–B7: B1 keine Identität/Rollen (jeder agiert als jeder, alles für alle sichtbar; OP-AUTH-1) · B2 Klärfall nicht im Werker-Flow („Meine Arbeit" ohne Klärfall-Button; dokumentierter Klärungs-Workflow §5.1 ungebaut) · B3 True North 3×🟡/0×✅ (Antworten verstreut) · B4 vier belegte Label-Inkonsistenzen („angeliefert"/„Fahrzeug angeliefert" · „ziel"/„Zieltermin" · „wartet"/„geplant" · „Frei"/„Verfügbar") · B5 kein Onboarding (OP-ONBOARD-1) · B6 Bedienränder (Drag&Drop ohne Tastatur, Hof-Radar fix 760px, nativeconfirm()/alert()) · B7 verwaiste Komponenten (FlowBandComponent/InsightsPanelComponentungenutzt),kontrolliert-Status faktisch übersprungen. Entscheidungen: Empfehlungen E1–E6 nach Wirkung÷Aufwand priorisiert; die Top-3 (Werker-Terminal-Modus · Klärfall-Button in „Meine Arbeit" · Label-Konsolidierung nachphase.ts-Muster) als neuerops/OP-UX-7.md(audience produkt+technik) gebündelt — E4 bleibt bei OP-R9-10, E6 bei OP-ONBOARD-1. Sanity-Checkliste um externe Bestätigung der 🟡-Bewertungen ergänzt; Landkarte +Offene-Punkte.md(generiert) nachgezogen. - Branch
claude/next-steps-pot5hb(#433) — Zeitbasierte Auslastungs-Quote als KPI-Kachel (Sanity-Checkliste Frage 1,APP_VERSION0.69.0 → 0.70.0 MINOR). Nutzer-Auftrag: „Was steht als nächstes an?" → aus den offenen Punkten die Spur Auslastungs-Quote KPI gewählt (Sanity-Checkliste North-Star-Frage 1 stand auf 🟡: „explizite % belegte vs. verfügbare Bucht-/MA-Zeit über Zeitraum als KPI/Dashboard-Kachel" fehlte). Gebaut: (1) reine, testbare FunktionauslastungsQuote()inserver/src/insights/insights.ts— je Ressourcengruppe (Mitarbeiter · Buchten) der Anteil verplanter an verfügbarer Zeit über ein Fenster; kappt belegt ∩ verfügbar (kein Über-100-%-Artefakt), summiert überlappungsfrei (merge/subtractaustime.ts). Ergänzt den bestehenden Snapshotauslastung()(belegte Buchten jetzt) um die Zeit-Achse. (2) DO-Verdrahtung (server/party/leitstand.ts): Fenster = Planungszeitraum (dieselbe Logik wie die Gantt-Ausfallbänder); MA-Verfügbarkeit viamitarbeiterAvailability(Schicht − harte Abwesenheit), MA-Belegung aus verplanten Schritt-Intervallen; Bucht-Verfügbarkeit = offene Werkstattzeit (Envelope aller MA-Schichten) − Sperre/Wartung (bayAusfall) — bewusste Entscheidung: Buchten sind sonst 24/7, das wäre als Nenner irreführend; Bucht-Belegung aus Schritt-Bucht-Intervallen. Nichts gespeichert (D-2, rein abgeleitet). (3) Client:insights.auslastungsQuoteim State-Typ + KPI-Kachel oben in der Überblick-Sidebar (overview.component.ts) mit Mini-Balken je Gruppe (Prozent · belegt/verfügbar h · Ressourcenzahl · Fenster in Tagen); Ampel-Farbe ohne Rot (dim < 60 % · Brand-Cyan 60–90 % · Amber > 90 %, Rot bleibt Warnungen — Design-Prinzip). Verifikation:test:insightsum Quote-Assertions erweitert (Kappen belegt→verfügbar: 540/960 = 56 %, Bucht 300/480 = 63 %) grün; alle Server-Selbsttests (spike/operativ/replan/solve/test:teilplan/test:ausfall/test:kosten) grün; Server- + Client-tscsauber (ng buildnur wegen Node 22.22.2 < 22.22.3 lokal nicht ausführbar — CI baut). Offen (nachgezogen in Sanity-Checkliste): wählbarer Zeitraum (heute/Woche) statt fixem Planungsfenster, Historien-/Trend-Sicht. Doku:server/src/insights/insights.ts+insights-demo.ts,server/party/leitstand.ts,client/.../services/leitstand.service.ts+pages/overview.component.ts,server/src/version.ts,docs/betrieb/Sanity-Checkliste.md+Tests.md, HANDOFF §2, CHANGELOG, Timesheet. - Branch
claude/op-audience-field(#432) —audience-Pflichtfeld fürops/*.md(OP-DOCS-11-Nachtrag) (Tooling/Doku,APP_VERSIONunverändert). Nutzer-Auftrag: „Bei den OP-/Diskussionspunkten sollen wir immer entscheiden, wer die Audience ist — Technik, Produkt, Stakeholder, Legal." Gebaut: neues Pflichtfeldaudienceimops/*.md-Frontmatter (Array, Wertetechnik/produkt/stakeholder/legal, mehrere möglich) — Standard-Entscheidung: multi-select statt single-value, da reale OPs oft mehrere Zielgruppen betreffen (z. B. Produkt und Legal).scripts/gen-ops.mjsvalidiert hart (fehlt/unbekannter Wert → Build bricht, wie beistatus/prio), zeigt eine neue Audience-Spalte + Audience-Summenzeile indocs/betrieb/Offene-Punkte.md.scripts/sync-ops-issues.mjssetzt passendeaudience:*-Issue-Labels + Body-Zeile. Vier Pilot-OPs nachgezogen:OP-DOCS-11[technik],OP-VERTRIEB-1[produkt, stakeholder],OP-VERTRIEB-2[produkt, stakeholder, legal],OP-VERTRIEB-3[produkt, stakeholder]. Proaktives Flagging (CLAUDE.md §Compliance):OP-VERTRIEB-2s Legal-Bezug (externes Akquise-Tool mit Lead-Kontaktdaten Dritter, DSGVO DE/AT/CH) war im Risikoregister noch nicht erfasst — als neue Zeile RISK-19 ergänzt (offen, Score 4, verweist zurück auf OP-VERTRIEB-2 als Klärungsort).ops/README.mddokumentiert die vier Werte + Begründung (Legal-OPs verlangen Blick ins Risikoregister). Nebenbei behoben: toter Link inOP-Management-Gold-Standard.md(Offene-Punkteohne.md-Endung —check-doc-consistency.shflaggte ihn beim Gegenprüfen). Verifikation:gen-ops.mjs+check-doc-consistency.shgrün,docs-siteBuild warnungsfrei. Kein Code-/Solver-Change, kein App-Bump. Doku:ops/README.md+_Vorlage.md+4 Piloten,scripts/gen-ops.mjs+sync-ops-issues.mjs,docs/konventionen/OP-Management-Gold-Standard.md,docs/betrieb/Offene-Punkte.md(generiert),docs/betrieb/Risikoregister.md(RISK-19, neu), HANDOFF §4, CHANGELOG, Timesheet. - Branch
claude/op-management-gold-standard(#430) — OP-Management-Gold-Standard:ops/*.md+ GitHub-Issues-Spiegel (OP-DOCS-11) (Tooling/Doku,APP_VERSIONunverändert). Nutzer-Auftrag: Diskussion zu offenen Punkten — GitHub Issues wären fachlich passend, aber für Nicht-Techniker nicht intuitiv, Eigenbau unerwünscht; Frage nach Gitbook oder Alternative; harte Anforderung: Claude Code und Codex sollen sauber damit arbeiten (umsetzen, abhaken). Empfehlung gegeben + umgesetzt: GitHub Issues + optionales Projects-Board (vorhandener Baustein, beide Agenten haben native GitHub-Tool-Unterstützung) statt Gitbook (reines Doku-Rendering-Tool, kein Status/Board/Diskussions-Modell — wäre dritte Quelle) oder Linear/separates SaaS (neuer Vendor/Kosten). Löst damit den seit 06-28 offenen OP-DOCS-11 (Optionsanalyse A/B/C/D, Empfehlung C Hybrid war schon dokumentiert, jetzt entschieden + gebaut). Gebaut: (1)ops/<ID>.md— ein Markdown-File je offener Punkt (Frontmatterid/title/status/prio/bereich/bezug/detail), git-nativ konfliktfrei bei den vielen parallelen Claude-/Codex-Branches dieses Repos; Format-Dokuops/README.md+ Vorlageops/_Vorlage.md. (2)scripts/gen-ops.mjs— generiertdocs/betrieb/Offene-Punkte.md(nach Status gruppierte Tabellen, sortiert nach Priorität), hart fehlschlagend bei kaputtem Frontmatter (Muster wiegen-glossar.mjs);npm run gen-opsinserver/. (3)scripts/sync-ops-issues.mjs+.github/workflows/sync-ops.yml— spiegeltops/*.mdeinseitig (Repo → GitHub) nach Issues (Labelop-sync), idempotent über Titel-Suche, kein Zurückschreiben in die Dateien; läuft mit dem Standard-GITHUB_TOKENder Action bei jedem Push aufops/**. (4) Pilot: vier OPs migriert (OP-DOCS-11selbst,OP-VERTRIEB-1/-2/-3aus #426/#427) — zwei davon (OP-VERTRIEB-2/-3, Status offen) live als GitHub Issues erstellt (#428, #429, lokal getestet über die MCP-GitHub-Tools, da der Sandbox-GITHUB_TOKENkein direktes REST-PAT ist — die Action bekommt ein echtes). (5)docs/konventionen/OP-Management-Gold-Standard.md(neu) — das Muster generisch für alle drkv-Projekte dokumentiert (Problem/Alternativen-Analyse, 3-Schichten-Architektur inkl. Mermaid, Rollout-Checkliste). CI:doc-consistency-Job bekommtactions/setup-node+ zwei neue, nicht-blockierende Schritte (node scripts/gen-ops.mjshart, Diff-Check warnt bei Staleness — Job war schon vorher nicht inci-gate.needs). Entscheidungen: (a) Migration der ~150 Bestands-OPs (HANDOFF §4/Lastenheft §11) bewusst nicht Teil dieses Schritts — neue OPs entstehen ab sofort im neuen Format, Bestand wandert schrittweise bei Berührung (Risiko/Aufwand einer Big-Bang-Migration vermieden, Präzedenz OP-DOCS-13 nicht-invasiver Rollout); (b) zwei near-identische OP-DOCS-11-Dubletten inHANDOFF.md§4 (Union-Merge-Artefakt) beim Aktualisieren konsolidiert. Verifikation:gen-ops.mjs+check-doc-consistency.shgrün,docs-siteBuild warnungsfrei, Mermaid-Diagramm via MCPvalid:true. Doku:ops/README.md+_Vorlage.md+4 Piloten (neu),scripts/gen-ops.mjs+sync-ops-issues.mjs(neu),.github/workflows/sync-ops.yml(neu),docs/konventionen/OP-Management-Gold-Standard.md(neu),docs/betrieb/Offene-Punkte.md(generiert, neu),docs/fachlich/Lastenheft.md§11.10,docs/konventionen/IDs.md+Register.md+docs/README.md,server/package.json,.github/workflows/ci.yml, HANDOFF §2+§4, CHANGELOG, Timesheet.
2026-07-08
- Branch
claude/vorteilsrechner-prospects-0hm08a(#427) — Vorteilsrechner als Landingpage für Interessenten (OP-MARKET-2) (Doku-Site,APP_VERSIONunverändert 0.69.0). Nutzer-Auftrag: „Vorteilsrechner für Interessenten einbauen — Akquise-wie? Hubspot?". Befund:docs/produkt/Produkt-und-Marketing.md§3 hatte bereits eine ausformulierte Rechen-Logik-Skizze („für ein späteres Tool") inkl. Eingangsdaten und Payback-Formel — aber kein Tool. Gebaut: neue Docusaurus-Seitedocs-site/src/pages/vorteilsrechner.js(rein client-seitig, React, self-contained wieindex.js— Theme-CSS-Variablen, kein Hex): 4 Eingaben (Fahrzeuge/Woche, Ø Auftragswert, Marge, Lösungskosten/Monat) → Δ Fahrzeuge/Woche, Δ Umsatz/Monat, Δ Deckungsbeitrag/Monat, Payback in Monaten, jeweils mit konservativer Bandbreite (Verbesserungsfaktor 8–22 %, erwartet 15 %) statt Scheingenauigkeit; Link von der Startseite (index.js). Entscheidung (Nutzer, per Rückfrage): Scope = Quick-Rechner (nicht der vollständige Rechner aus §3.1 mit allen Eingangsdaten); Akquise-Anbindung (Hubspot) bewusst noch offen gelassen — Nutzer hat sich noch nicht zwischen Hubspot-Formular-Embed / Hubspot-Forms-API / eigenem Kontaktformular entschieden. Seite geht deshalb v1 ohne Lead-Erfassungs-Backend live (nurmailto:-Kontaktlink als Platzhalter) — neuer offener Punkt OP-MARKET-2, damit die Anbindung nicht verloren geht. Verifikation:npm run build(Docusaurus, docs-site) grün, neue Seite kompiliert fehlerfrei. Kein Code-/Solver-/Token-Change, kein App-Version-Bump (Doku-Site-only, Präzedenz #205/#206 u. a.). Registriert indocs/produkt/Produkt-und-Marketing.md§3,docs/konventionen/IDs.md,docs/konventionen/Register.md, HANDOFF §2+§4, CHANGELOG, Timesheet. - Branch
claude/vorteilsrechner-prospects-0hm08a(Nachtrag, PR #427) — OP-ID-Reconciliation mit #426. Beim Aktuellhalten des Branches gegenmainzeigte sich: #426 (parallel gemergt, „Vertriebsthemen aus Meeting als OP-VERTRIEB-1..3") hatte inzwischen genau denselben Rechner bereits als OP-VERTRIEB-1 dokumentiert (Anlass: Gründer-Call vom selben Tag) — der oben neu erfundene OP-MARKET-2 war damit redundant. Aufgelöst zugunsten der autoritativen Gründer-Call-IDs: OP-VERTRIEB-1 in HANDOFF §4 + Lastenheft §11.6 auf ✅ v1 umgesetzt gesetzt (Entscheidung „Web-Tool vs. Sales-Deck/Excel" → Web-Tool); die Akquise-/Lead-Erfassungs-Frage verweist jetzt auf das bereits existierende OP-VERTRIEB-2 („Akquise-/Orga-Tool — Build vs. Buy, z. B. Hubspot", kein Code bis (a)–(c) entschieden — betrifft den separaten Lead-Tracker für 50–100 Anbahnungen, nicht das Rechner-Formular selbst). OP-MARKET-2 zurückgezogen; OP-VERTRIEB-1/-2/-3 zusätzlich inIDs.md/Register.mdregistriert (fehlten dort nach #426 noch — Lücke mitgeschlossen). Code-Kommentar invorteilsrechner.js+ Callout in Produkt-und-Marketing.md §3 entsprechend angepasst.check-doc-consistency.shgrün. Kein App-Bump.
2026-07-07
- Branch
claude/documentation-structure-ux-qzof50(Folge nach #421, PR folgt) — Kernaussage-Korrekturen (CodeRabbit-#421-Review) — OP-DOCS-9/-13 (Doku,APP_VERSIONunverändert 0.69.0). Zwei in Phase 4 (#421) neu eingeführte Kernaussage-Blöcke waren inhaltlich zu stark/veraltet (CodeRabbit, je Major): (1)Audit-Log.md— sagte „in separater D1 (EU)", der finale Zuschnitt (E-TENANT-1 = C) ist aber DO-SQLite je Tenant + D1 nur als Tamper-Anker (Chain-Kopf); korrigiert → jetzt deckungsgleich mit §2 des Docs. (2)Offline-PWA.md— „Fotos nie verloren" überzeichnet (die Garantie hängt an funktionierender IndexedDB-Queue;uploadFoto()meldet sonst statt still zu verlieren) → auf konditional abgeschwächt. Nachzug: #421-Referenzen im Phase-4-CHANGELOG/Timesheet-Eintrag finalisiert. Verifikation:check-doc-consistency.shgrün. Lehre: pyramidale TL;DR-Blöcke gegen die Doc-eigene Detailsektion gegenprüfen (OP-DOCS-9). - Branch
claude/documentation-structure-ux-qzof50(Folge nach #420, #421) — OP-DOCS-13 Phase 4: Lesbarkeit — Kernaussage-Blöcke + HANDOFF-§4-Entdichtung (Worst-Offender) (Doku,APP_VERSIONunverändert 0.69.0). Nutzer-Wahl „Worst-Offender + Kernaussage". (1) Pyramidale Kernaussage-Blöcke (> **Kernaussage.**) oben in 7 schweren Docs:Lastenheft.md,HANDOFF.md+ die 5 architektur/-Docs ohne TL;DR (Akademie, Audit-Log, Fahrzeug-3D, Kosten, Offline-PWA) — wer nach dem ersten Absatz aufhört, hat das Wesentliche (Minto). (2) HANDOFF §4 entdichtet: Befund — §4 war eine union-Merge-Dublettenhalde (226 OP-Bullets, nur ~116 distinkte OPs;OP-AUDIT-1×9,OP-TENANT/OP-BACKUP-1×7 …). 19 byte-identische Dubletten-Zeilen entfernt (226 → 207) — sicher & verifiziert (jede entfernte Zeile existiert weiter, kein Info-Verlust; OP-PM-2-Glätten). (3) Format-Konvention inagents.md§6.2: neue §4-Einträge kurz + strukturiert (Titel + Status), keine Mega-Zeilen (Tiefe ins Owning-Doc). Verifikation:check-doc-consistency.shgrün (keine toten Links durch die Dedup). Bewusst offen: die near-identischen Mega-Zeilen (z. B. die zwei ~15k-Zeichen-OP-OPT-1-Kopien, 15250 vs 15284) sind nicht byte-identisch → brauchen eine gezielte, per-OP verifizierte Glätt-Runde (eigener PR, um den append-only Audit-Trail nicht zu riskieren). Nachzug: #420-Ref im Vor-Eintrag finalisiert. Offen: §4-Vollglättung · Phase 5 (OP-Register, OP-DOCS-11). - Branch
claude/documentation-structure-ux-qzof50(Folge nach #419, #420) — OP-DOCS-13 Phase 3b Teil B: Konsistenz-Gate gehärtet (statt README-Generierung) (Tooling/Doku,APP_VERSIONunverändert 0.69.0). Entscheidung (Nutzer „Check härten"): Beim Grounding zeigte sich, dasscheck-doc-consistency.sh§4 bereits prüft, dass jededocs/**-Datei in der README-Landkarte verlinkt ist — die Haupt-Drift war abgesichert. Volle Generierung (~38-Doc-kurz:-Migration + kuratierte README-Tabellen durch generierte ersetzen) hätte nur marginalen Zusatznutzen; daher Gate härten statt generieren (Einfachheit, die kuratierte Landkarte bleibt). Gebaut (scripts/check-doc-consistency.sh): (a) 3-Ebenen-Glob — verschachtelte Docs (betrieb/meetings/, künftige Unterordner) werden jetzt geprüft,_-Partials ausgenommen; (b)_category_.json-Check für jeden md-Ordner (bis 3 Ebenen); (c)sidebar_position-Eindeutigkeit je Ordner (hätte den Tests/Timesheet-40/40-Clash gefangen); (d) Zielgruppen-Paritätglossar.mjsZIELGRUPPEN ==Lesepfade.md-Rollen-Anker (hätte den 4-vs-7-Drift gefangen;gen-glossarhard-failt sonst).docs/betrieb/Tests.mdnachgezogen. Verifikation:bash -n+ Lauf grün (0 Findings); Negativ-Tests bestätigt (Positions-Clash und Taxonomie-Divergenz werden korrekt geflaggt, danach sauber revertiert). Damit Phase 3b vollständig (Bänder + Anti-Drift). Offen: Phase 4 (Mega-Zeilen in HANDOFF §4/CHANGELOG brechen) · Phase 5 (OP-Register generiert, OP-DOCS-11). - Branch
claude/documentation-structure-ux-qzof50(Folge nach #418, #419) — Broken Links & Anchors der Doku-Site bereinigt (OP-DOCS-9/-13) (Doku,APP_VERSIONunverändert 0.69.0). Anlass (Nutzer): diedocs-deploy-Build-Warnungen „Docusaurus found broken links/anchors" (Rauschen im Deploy-Log). Behoben (Build jetzt warnungsfrei — vorher 6 Links + 2 Anchors): (1) Repo-Datei-Links außerhalbdocs/—.github/workflows/ci.yml(IDs.md×4,HANDOFF.md) +design/WORKSPACES.md(IDs.md×2) — auf absolute GitHub-Blob-URLs umgestellt (funktionieren auf Site und GitHub; die relativen Pfade brachen auf der Site, weil sie aus dem Docs-Baum herauszeigen); (2) Links aufbetrieb/meetings/_Vorlage.md(README-Landkarte + meetings-Index) auf GitHub-URL — Docusaurus schließt_-präfixierte Dateien vom Routing aus (Partial-Konvention) → keine Site-Route; (3) blanker../-Parent-Link im meetings-Index entfernt (der Landkarte-Link daneben bleibt); (4) Anchor#2-marktabschatzung-tamsamsom(Umlaut-Slug) via explizite{#…}-Heading-ID inMarkt-und-Markteintritt.mdfixiert → die Verweise ausWettbewerbsanalyse.md/Marktlösen wieder auf. Verifikation:npm run buildgrün, 0 Broken-Link-/Anchor-Warnungen;check-doc-consistency.shgrün. Kontext:docs-deploynach #418 wieder grün (Run #211, success) — der React-19-Peer-Fix (.npmrc) wirkt. - Branch
claude/documentation-structure-ux-qzof50(Folge nach #417, #418) — docs-deploy-Fix (React-19-Peer) + OP-DOCS-13 Phase 3b Teil A (architektur/-Bänder) + CodeRabbit-#417-Finalisierung (Doku/Doku-Tooling,APP_VERSIONunverändert 0.69.0). docs-deploy repariert (Priorität — Nutzer-Screenshot): derdocs-deploy.yml-Job scheiterte aufmainannpm ci(ERESOLVE) —@easyops-cn/docusaurus-search-local@0.45deklariert einen React-Peer<20, inkompatibel mit dem React-19-Stand (Framework-Bump 2026-07-06); durch #417 (erster docs-site-Push seither) sichtbar geworden. Fix: neuesdocs-site/.npmrcmitlegacy-peer-deps=true→npm ciüberspringt den überstrengen Peer (das Plugin läuft mit React 19, Build grün). Verifiziert:npm ciundnpm run buildlokal grün,package-lock.jsonunverändert. Rückbau, sobald search-local einen React-19-Peer deklariert. Phase 3b Teil A: die 16 flachenarchitektur/-Docs in 5 thematische Sidebar-Bänder gruppiert (Betrieb · Daten · Produkt/Flow · KI/QS · Zugang/Team) viasidebar_label-Präfix + zusammenhängendesidebar_position(10–160). CodeRabbit-Review #417 (4 Findings, alle adressiert): „PR folgt"→#417 in CHANGELOG/Timesheet finalisiert; True-North-Frage 3 inLesepfade.mdauf die kanonische Plural-Form angeglichen; True-North-Bezug imDoku-UX-Konzept-Status als „schneller"-Klausel präzisiert (MD022-Leerzeile bewusst übersprungen — entspricht dem Stil aller Datums-Überschriften der Datei, kein CI-Gate). Verifikation:npm run buildgrün (Bänder korrekt sortiert),check-doc-consistency.shgrün. Offen: Phase 3b Teil B (generierte Landkartegen-doku-landkarte.mjs+kurz:-Frontmatter-Migration ~37 Docs) · Phase 4/5. - Branch
claude/documentation-structure-ux-qzof50(#417) — Doku entwirren: Konzept (OP-DOCS-13) + Phase-1-Drift-Fixes (Doku/Doku-Tooling,APP_VERSIONunverändert 0.69.0). Anlass (Nutzer): „Die Dokumentation wirkt verworren — wie kann das verbessert werden bzgl. Struktur, Lesbarkeit, Navigation und UX?". Diagnose (3 Explore-Analysen): kein Inhalts-, sondern Struktur-/Redundanz-/Dichte-Problem — Mensch-/Maschinen-Doku im selben Prosastrom · ~155 OP-IDs als Kurzschrift-Prosa · Leitplanken mehrfach statt einmal besessen · vier überlappende OP-Indizes · Mega-Zeilen 5k–15k Z. in HANDOFF §4/CHANGELOG · 20/41 Leaf-Docs = Navigations-Sackgassen (alle 16 architektur/). Entscheidung: nicht-invasiv (keine Datei-Verschiebungen), fünf einzeln lieferbare Phasen nach dem Glossar-Generator-Muster; neues Owning-Docdocs/betrieb/Doku-UX-Konzept.md(pyramidal, Mermaid, messbare Kriterien) + OP-DOCS-13. Phase 1 (Drift-Fixes): Zielgruppen-Taxonomie 4→7 inglossar.mjs(deckungsgleich mitLesepfade.md; entsperrtgen-glossar.mjsfürdevops/security/support, das sonst hart fehlschlägt) ·sidebar_position-ClashTests.md/Timesheet.md(40/40 → 40/50) · stale_category_.json-Aufzählungen (architektur 7/16 · konventionen) → generisch · stale Pfadedocs/Timesheet.md→docs/betrieb/Timesheet.md(agents.md 3×) +docs/agents.md→docs/konventionen/agents.md(CHANGELOG-Intro) · Topic-Split-Querlinks Mandantenfähigkeit↔Seed-Ablöse-Plan + Flow-Analyse-Status „größtenteils umgesetzt (Historie)" (behebt Widerspruch zu Flow-Refactor-Plan). Registriert in HANDOFF §4 · Roadmap · IDs.md · README-Landkarte · CLAUDE.md-Tiefenquellen. Phase 2 (Leitplanken-Single-Source, ebenfalls dieser PR): die zwei verbose-duplizierten Blöcke OP-DOCS-9 + OP-PM-2 in der immer-geladenenCLAUDE.mdauf Essenz + Owner-Pointer (agents.md§5.1/§6.5/§6.6) gekürzt (~12 Zeilen Duplikat weniger, jede Regel erhalten); True-North-Owner-Link inLesepfade.md(SemVer & ID-Legende sind bereits single-source). Phase 3 (Navigation, ebenfalls dieser PR): Aufgaben-Lesepfade ausREADMEinzielgruppen/Lesepfade.mdkonsolidiert (eine menschliche Vordertür statt zwei überlappender Lesepfad-Systeme); neues Remark-Plugindocs-site/src/remark/docNavFooter.mjshängt einen einheitlichen „↩ Landkarte · Lesepfade · Register"-Footer an jedes Leaf-Doc der Haupt-Instanz → schließt alle 20 Navigations-Sackgassen driftfrei (idempotent: überspringt Hubs, Projekt-Instanz und Docs mit vorhandenem Rücklink); Sidebar-Brücke/docs↔/projekt(sidebars.js/sidebars-projekt.js, die zwei Instanzen waren unverbunden);konventionenals Prozess-/Agenten-Tier gelabelt (Mensch/Maschine-Split sichtbar). Verifikation:npm run buildgrün (Plugin läuft, Sidebars kompilieren; nur vorbestehende Broken-Link-Warnungen), Footer-Injektion + Idempotenz + Skip-Regeln am Build-Output geprüft;check-doc-consistency.shgrün. Offen (Folge-PRs): Phase 3b (generierte Landkarte +architektur/-Bänder) · Phase 4 (Mega-Zeilen in HANDOFF §4/CHANGELOG brechen, pyramidale Kernaussage) · Phase 5 (OP-Register generiert, OP-DOCS-11). - Branch
claude/docs-guidelines-tech-standards-zhu4a5(#416) — Entwicklungsansatz-Übersichtsseite + drkv-Standard-Bausteine referenziert (Doku-only,APP_VERSIONunverändert). Neue Seitedocs/konventionen/Entwicklungsansatz.md— True North · Leitprinzipien (Einfachheit · Selbsterklärbarkeit · Dokumentation-als-Meisterwerk · Everything-as-Code) · Way-of-Working · Standard-Bausteine, mit Mermaid und Hinweis „TaktanosG-1…G-3sind Scheduler-Constraints, nicht die drkv-Leitprinzipien".CLAUDE.md: neuer Abschnitt Standard-Bausteine (drkv) — Taktano ist Referenz-Implementierung (Echtzeit · moderne Frameworks · In-App-Chatbot · Feedback, kanonisch im Templateeverything-as-code-template/docs/Standard-Tech-Stack.md) + Regel „Way-of-Working sichtbar (Entwicklungsansatz.md)" + Tiefenquellen (Entwicklungsansatz, In-App-Assistent).docs/README.md-Landkarte ergänzt. Anlass (Nutzer): Guideline „Way-of-Working sichtbar in der Doku" + drkv-weite Governance/Standard-Tech-Stacks; Taktanos bewährte Bausteine (In-App-Assistent OP-AI-4, Feedback, Echtzeit) sind die Referenz. Konsistent in allen drei Schwester-Repos (Template kanonisch, medidentas gespiegelt). - Branch
claude/confirmation-dialog-scope-7627x6(#415) — Konvention: Chat-Zusammenfassung bei wichtigen Entscheidungen + sparsame Rückfragen (Doku-only,APP_VERSIONunverändert).CLAUDE.md(Repo/Audit-Trail) um eine Regel ergänzt: bei wichtigen Entscheidungen und vor jedem Push/PR eine kurze Chat-Zusammenfassung (Was gebaut · Warum/Entscheidung · Offen) als Chat-Sicht fürs Arbeiten über mehrere Projekte/Chats — zusätzlich zu CHANGELOG/HANDOFF, nur an relevanten Punkten (kein Rauschen); Rückfragen nur an echten Weggabelungen. Anlass (Nutzer): besserer Durchlauf der Coding-Chats + Wiedereinstieg beim Multi-Projekt-Arbeiten. Konsistent in allen drei Schwester-Repos ergänzt.
2026-07-06
- Branch
claude/angular-react-version-bump-rq4eis(#414) — Framework-Bump: Angular 20 → 22 (Client) + React 18 → 19 / Docusaurus 3.6 → 3.10.1 (Doku-Site) (Version 0.68.0 → 0.69.0, MINOR — Toolchain-Optimierung, rückwärtskompatibel). Auslöser (Nutzer): „Bump angular and react to recent version" — beide Frameworks lagen hinter den aktuellen Stable-Releases (Angular 22 = Juni 2026; React 19). Entscheidungen: (1) Angular auf die aktuelle Stable 22 (nicht nur LTS 21) viang update @angular/core@21 → @22(Angular erlaubt nur je eine Major-Stufe; Zwischenschritt 21 committet) — alle@angular/*auf 22.0.5, TypeScript ~6.0.3, zone.js unverändert 0.15.1. Automatische, verhaltensbewahrende Migrationen: Block-Control-Flow-Syntax, expliziteChangeDetectionStrategy.Eager,extendedDiagnostics-Suppress (nullishCoalescingNotNullable/optionalChainNotNullable), Safe-Navigation. (2) React nur in der Docusaurus-Doku-Site (docs-site/, zwei Landingpagesindex.js/team.js) →react/react-dom19.2.7; React 19 verlangt Docusaurus ≥ 3.7, daher@docusaurus/*auf die aktuelle 3.x 3.10.1 gehoben;@types/react(transitiv) stimmig 19.2.17. Keine Peer-Konflikte, keine React-Code-Änderung nötig. Manuelle Anpassungen (durch TS-6-/v22-Diagnostik erzwungen, kleinstmöglich):bild-upload-gate.component.ts—ImageDataaus frischerUint8ClampedArray-Kopie (TS-6-lib.dom:ArrayBufferLike≠ArrayBuffer; gleiches Muster wie die vorhandenen pii-/nsfw-Adapter); ungenutztenEmptyStateComponent-Import inquality/staff-Page entfernt (NG8113). Node: lokal 22.23.1 nötig (Angular-CLI 22 verlangt ≥ 22.22.3; CInode-version: 22löst ohnehin die neueste 22.x auf) —.nvmrc/CI unverändert 22. Verifikation:clientng buildgrün (nur vorbestehende Bundle-Budget-Warnung), Selbstteststest:bildgate/test:fotoqueue/test:queuebestanden;docs-sitenpm run buildgrün ([SUCCESS]; die Broken-Link/Anchor-Warnungen sind vorbestehende Inhalts-Links, unabhängig vom Bump). Doku: Stack-Verweise „Angular 20 → 22" inCLAUDE.md·HANDOFF.md(Diagramm/Client/Baum) ·design/INTEGRATION_PLAN.md·docs/architektur/Fahrzeug-3D.md(dated/historische Log-Einträge bewusst unverändert; kein neuer OP, da abgeschlossene Wartung), CHANGELOG, Timesheet.
2026-07-05
- Branch
claude/fix-no-hex-pr-ref(#413) — No-Hex-Gate: PR-/Issue-Referenzen (#409) nicht mehr als Hex-Farbe fehlgemeldet (Tooling/scripts/check-no-hex.sh+ Doku, kein App-Bump —APP_VERSIONunverändert 0.68.0). Auslöser:main-CI (Design-Job) rot, weilcheck-no-hex.shinconflicts.component.ts:402den Kommentar „…Review #409)" als 3-stelligen Hex-Code (#rgb) matchte — jede 3-/6-stellige PR-Nummer (#100–#999,#100000+) ist syntaktisch gültiges Hex, ein reiner False-Positive (keine Farbe). Fix: Das Gate ignoriert jetzt Kommentar-Anteile (// …·/* … */·<!-- … -->) je Zeile — ein Hex in einem Kommentar rendert nichts, ist also kein Token-Verstoß, und PR-Referenzen leben dort. Umsetzung: Kandidaten-Treffer werden vor der Bewertung um ihren Kommentar-Anteil bereinigt (sed) und nur gemeldet, wenn das Hex außerhalb des Kommentars steht;tk-allow-hex-Marker unverändert. Der Original-Kommentar (#409) bleibt erhalten (GitHub-Ref) und dient als Regressionsfall. Rest-Risiko: seltene mehrzeilige Block-Kommentare (per-Zeile-Neutralisierung greift dort nur teilweise) — im Header dokumentiert. Verifikation: lokale Fälle grün — (1)#409-Kommentar passiert, (2) echter Hex im Code blockt weiter (auch mit Trailing-Kommentar), (3) reiner Kommentar-Hex passiert, (4) echter Hex nach einerhttps://-URL auf derselben Zeile blockt weiter;check-doc-consistency.shohne neue Warnung. Review (CodeRabbit, 2 Findings gefixt): (a) Major —//-Stripping URL-sicher gemacht (s#([^:])//.*$#\1#; s#^//.*$##→://gilt nicht als Kommentar-Start, sonst hätte ein Hex nachhttps://als „im Kommentar" fälschlich durchgerutscht = False-Negative); (b) Minor — Timesheet MD037 (Kommentar-Syntax-Liste in Backticks, damit/* */nicht als Emphasis geparst wird); (c) Major —/* *//<!-- -->-Stripping von greedy (.*) auf non-greedy (negierte Klasse[^*]/[^>], stoppt am nächsten Closer) umgestellt, sonst hätte/* a */ #fff /* b */als ein Block den echten Hex verdeckt; Fehlrichtung nun „meldet zu viel" statt „verdeckt echten Hex". Doku:scripts/check-no-hex.sh(Header),docs/betrieb/Tests.md, CHANGELOG, Timesheet. - #411 2026-07-05 — Auto-Rerun bei flakigem Runner (
auto-rerun.yml, §6.8) (Tooling/Workflow, kein App-Bump). Neuerworkflow_run-getriggerter Job: schlägt ein CI-Lauf fehl, werden die fehlgeschlagenen Jobs einmalig neu angestoßen (run_attempt < 2→ genau 1 Retry, kein Loop). Heilt die typische self-hosted-Flakiness (github.com:443-Timeout, Runner mitten im Job gestorben). Nicht neugestartet: abgebrochene Läufe (Concurrency-Cancel =cancelled≠failure) und Fork-PRs. Idempotenz:concurrency: auto-rerun-<run_id>(serialize-not-cancel) gegen doppelte/redeliveredworkflow_run-Events; Timeoutscurl --connect-timeout 10 --max-time 30+ Jobtimeout-minutes: 5, damit ein hängender API-Call keinenhot-Runner-Slot blockiert (CodeRabbit-Review #411). Dependency-frei viacurl(keingh/Node-Action → keine node20-Warnung). Deploys bewusst ausgenommen. Doku:agents.md§6.8,.github/workflows/auto-rerun.yml, CHANGELOG. - Branch
claude/missing-vehicles-clarification-n3eqe8(#412) — OP-UX-6-Nachschärfung: freie Notiz am Auftrag + Verlauf im Detail-Panel (Version 0.67.0 → 0.68.0, MINOR). Nutzer-Befund zum „Fahrzeug da"/Klärfälle-Screenshot: (a) man möchte „auch einen allgemeinen Kommentar (z. B. nochmal angerufen und gefragt) ergänzen können", und (b) die seit Wochen überfälligen Fahrzeuge sollten in der Klärfälle-Liste erscheinen. Klärung zu (b): die überfälligen Anlieferungen erscheinen bereits — Sektion „⏱ Überfällige Anlieferungen" im Klärfälle-Tab (OP-UX-6/#409,ueberfaelligeAnlieferung=status geplant+bringtermin < jetzt, identisch zum „erwartet seit"-Badge im Annahme-Screen); eine leere Liste bei sichtbar überfälligen Fahrzeugen bedeutet nur, dass der laufende Build vor #409 liegt (Deploy-Nachzug), kein Logikfehler. Entscheidung (Nutzer): freie Notiz „überall am Auftrag" — kein Statuswechsel, kein Klärfall-Zwang, keine Re-Optimierung. Gebaut: neue Client-Messageauftrag.notiz(Handler hängt einenNotiz: …-Protokoll-Eintrag an, leere Notizen verworfen, nicht inREOPT_EVENTS) + ServiceauftragNotiz+ UI an zwei Stellen: (1) „📝 Notiz"-Aktion + Mini-Formular im geteiltenauftrag-detail-panelplus neuer „Verlauf"-Block (Protokoll, neueste zuerst — war bislang im DTO vorhanden, aber nirgends angezeigt), (2) „📝 Notiz"-Button + Inline-Feld direkt an der Überfällig-Zeile im Klärfälle-Workspace (Anruf dokumentieren ohne Umweg über Storno/Klärfall). Verifikation:tsc+operativ+ng buildgrün. Doku: HANDOFF §4 (OP-UX-6), CHANGELOG, Timesheet. - Branch
claude/cleanup-logs-frontmatter-ae43ki(#410) — Log-Hygiene: Timesheet-ID-Kollision geglättet + fehlendes Doku-Frontmatter (OP-PM-2/OP-DOCS-9, Doku/Tooling-only, kein App-Bump —APP_VERSIONunverändert 0.67.0).scripts/check-doc-consistency.shflaggte zwei Punkte aufmain. (1) Timesheet-ID-Kollision: die Sessions 37–47 existierten doppelt — ein zweiter, inhaltlich eigenständiger Block aus dem parallelen Branchclaude/seed-usage-audit-frsx52(OP-SEED-1 · S-SEED-1…5 · E-TENANT/E-BACKUP-Entscheidungen) hatte dieselben laufenden Nummern gegriffen (die Vor-OP-PM-3-Zahl-Kollision paralleler Branches; union-Merge konkatenierte statt zu überschreiben). Kein byte-identisches Duplikat →smooth-logslöst das bewusst nicht automatisch. Auflösung: der Seed-Audit-Block auf eindeutige IDs 53–63 umnummeriert (nach dem bisherigen Max 52), inkl. der zeileninternen „(Session NN)"-Selbstverweise; die Start-Spalte trägt ohnehin die echte Chronologie. (2) Frontmatter:docs/architektur/Fahrzeug-3D.mdbegann ohne----Block →sidebar_position: 75(zwischen Bildbewertung 70 und Persistenz 80) +sidebar_label: Fahrzeug-3D (OP-R6-2)ergänzt, konsistent mit den übrigenarchitektur/-Docs. Verifikation:check-doc-consistency.shmeldet keine Session-ID-/Frontmatter-Warnung mehr; keine doppelten numerischen IDs. Doku:docs/betrieb/Timesheet.md,docs/architektur/Fahrzeug-3D.md, CHANGELOG, Timesheet. - Branch
claude/ci-cache(#408) — Persistenter Angular-Build-Cache +hot-Runner-Pinning (§6.8) (Tooling/ci.yml+ Angular-Config + Doku, kein App-Bump —APP_VERSIONunverändert). (1) Build-Cache:client/angular.json→cli.cache.environment: "all"(Angular deaktiviert den Disk-Cache in CI sonst) +actions/checkoutclean: falseim Client-Job →.angular/cacheüberlebt dengit cleanzwischen Läufen = inkrementeller Angular-Build (content-adressiert, selbst-invalidierend → unbedenklich). (2)hot-Pinning: alle 11 CI-Jobsruns-on: … || 'hot'statt generischself-hosted— die Cache-/Offline-Hebel (warmes~/.npm, entfernter npm-Cache,.angular/cache) greifen nur auf persistentenhot-Runnern; ephemere tragenephemeral. Fork-Gate (ubuntu-latest) +CI_RUNNER-Override unverändert. Kapazität:hot-Runner-Zahl = Parallelitäts-Obergrenze. Verifikation:ci.yml+angular.jsonvalide, keinself-hosted-Default mehr. Doku:agents.md§6.8,ci.yml,client/angular.json, CHANGELOG. - Branch
claude/ci-speedup(#407) — CI-Installs beschleunigt (§6.8) (Tooling/ci.yml+ Doku, kein App-Bump —APP_VERSIONunverändert). Allenpm ci-Aufrufe inci.yml(server · persistence-gate · client · sbom · deploy) laufen jetzt mit--prefer-offline --no-audit --fund=false→ nutzt das warme lokale~/.npmohne Audit-/Funding-Netz-Calls (spart Zeit, robuster bei flakiger github.com-Anbindung). Der Pfad-Filter (changes-Job) war bereits vorhanden → taktano-PRs sind schon bereichs-schlank; die Konvention §6.8 hält beides fest. Keinfetch-depth-Change nötig (Server-Job ist bereits shallow; nur der Deploy-Job braucht volle History, läuft aber ohnehin nur aufmain). Gegenstück in medidentas (#…: Pfad-Filter + Installs + shallow Checkout, D-37). Verifikation:ci.ymlYAML-Parse grün, keine barenpm cimehr. Doku:agents.md§6.8,ci.yml, CHANGELOG. - Branch
claude/ci-concurrency-guideline(#406) — CI-Concurrency-Konvention (§6.8) + npm-Cache-Fix (Doku/Konvention +ci.yml, kein App-Bump —APP_VERSIONunverändert). Neue Way-of-Working-Regeldocs/konventionen/agents.md§6.8: jede Workflow-Pipeline nutzt einenconcurrency-Block, wo er Nutzen bringt — CI/PR-Läufe gruppieren nachci-${{ github.workflow }}-${{ github.ref }}und canceln überholte Läufe außer aufmain(cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}); Deploy-Pipelines nach fixem Ziel +cancel-in-progress: true; serielle Jobs (Log-Sync)cancel-in-progress: false. Faustregel + Zusammenspiel mit der Trigger-Hygiene (OP-CI-1). Concurrency-Block war bereits da (ci.yml/sync-pr-logs.yml) → die Konvention hält den Ist-Zustand fest (Doku↔Code). Zusätzlich (Umsetzung derselben Regel):cache: npmaus allensetup-node-Steps inci.ymlentfernt — auf dem persistenten self-hosted Runner ist~/.npmwarm;cache: npm(für ephemere Runner gedacht) lud nur ein großes Archiv langsam durch den Actions-Cache-Service (Timeout-Risiko auf flakiger Anbindung). Fork-PRs (ubuntu-latest) laden dann frisch aus der Registry. Gegenstück in medidentas §6.6 +ci.yml(dort zusätzlich Triggerpush→[main]+ neuer Concurrency-Block). Verifikation: YAML-Parseci.ymlgrün, keine aktivecache:-Direktive mehr. Doku:agents.md§6.8,ci.yml, CHANGELOG.
2026-07-04
- Branch
claude/cross-repo-id-scheme(#405) — Repo-übergreifendes ID-Schema (Repo-KeyTKT/MED/GRM) (Doku/Konvention, kein App-Bump —APP_VERSIONunverändert). Auslöser (Nutzer):OP-*-IDs kollidieren repo-übergreifend (taktano/medidentas/gh-runner-manager führen je eigeneOP-n). Entscheidung: IDs bleiben repo-lokal bare; cross-repo mit Repo-Key qualifizieren (TKT-OP-CI-2,MED-OP-SIGN-1,GRM-OP-2) — analog GitHubsowner/repo#123; keine Massen-Umbenennung bestehender IDs (Einfachheit/YAGNI). Doku:docs/konventionen/IDs.md(neue Sektion „Repo-übergreifende IDs"). Parallel in medidentas (agents.md§3) + gh-runner-manager (open-points.md) verankert. - Branch
claude/design-input-integration-ae43ki(#409, Folge-PR zu #402, Branch von main neu aufgesetzt) — OP-UX-6: Überfällige Anlieferung = Klärfall + Auftragsstorno (Version 0.66.0 → 0.67.0, MINOR). Nutzer-Befund („Fahrzeug da"-Screenshot: alle 15 erwarteten Anlieferungen überfällig, aber niemand zuständig; kein Weg, ein Fahrzeug rauszunehmen). Entscheidungen (Nutzer): überfällige Anlieferungen automatisch abgeleitet in die Klärfälle (kein persistierter State, D-2:status geplant+bringtermin < jetzt); Auftragsstorno aus dem Klärfall-Kontext mit Pflicht-Grund. Gebaut: Domänen-Helferstornieren(Grund-Pflicht ·abbrechen→abgebrochenterminal · Grund in Chronik) + Handlerauftrag.stornieren(Quittung, Auditauftrag.storniert, REOPT-Event) + ClientueberfaelligeAnlieferung-Kategorie/stornoAuftrag+ Klärfälle-Workspace: Sektion „⏱ Überfällige Anlieferungen" (Storno mit Pflicht-Grund-Textarea) und „✕ Auftrag stornieren" im Klärfall-Detail; Nav-/Tab-Badge zählt jetzt Klärfälle + überfällige. Selbsttest imoperativ-Durchlauf (Grund-Pflicht · abbrechen · Chronik · Doppel-Storno abgelehnt). Verifikation:tsc+operativ+ng buildgrün. Doku: HANDOFF §2/§4 (OP-UX-6 neu), IDs.md, CHANGELOG, Timesheet. - Branch
claude/runner-env-variables-v5tc5h(#404) — Runner-Tool-Cache: Provisionierung auf Runner-Ebene statt Workflow-env (self-hosted, OP-CI-2-Nachzug) (Tooling/Workflows, kein App-Bump —APP_VERSIONunverändert 0.65.0). Auslöser (Nutzer): Ergänzung zur self-hosted-Umstellung — auf dem lokalen Org-Runner ist der geteilte Host-Tool-Cache (/opt/hostedtoolcache) nicht je Lauf isoliert/beschreibbar →setup-node/setup-pythonkönnen bei parallelen Jobs kollidieren oder an Schreibrechten scheitern. Ergebnis (nach Iteration): Der Workflow-Weg (Step-envRUNNER_TOOL_CACHE/AGENT_TOOLSDIRECTORY=${{ runner.temp }}/_tool) fixte zwarsetup-node, abersetup-pythonignoriert die Umleitung auf macOS — dasactions/python-versions-Install-Skript legt den Toolcache hart unter/Users/runner/hostedtoolcachean →mkdir: /Users/runner: Permission denied(Runner-User darf unter/Users/nichts anlegen). Entscheidung (mit Nutzer): Toolcache/Toolchain auf Runner-Ebene provisionieren (beschreibbares/Users/runner/hostedtoolcachebzw.RUNNER_TOOL_CACHEin der Runner-.env+ vorinstallierte Node/Python-Toolchain) statt im Workflow — die Cache-env:-Blöcke wurden daher wieder aus allen Workflows entfernt (ci/docs-deploy/fly-deploy/weekly-audit;sync-pr-logshatte keine). Nebeneffekt-Fix: ein parallel aufmaingelandeter invalider job-levelenv:mitrunner.temp(→ „Unrecognized named-value: 'runner'", brachmain-CI/Deploys) wird damit ebenfalls beseitigt. Verifikation: YAML-Parse aller Workflows grün, keinrunner.temp/RUNNER_TOOL_CACHEmehr unter.github/workflows/; CI auf den provisionierten Runnern. Doku:.github/workflows/*.yml, CHANGELOG, HANDOFF §4 (OP-CI-2), Timesheet. - Branch
claude/design-input-integration-ae43ki(#402, Folge-PR zu #400, Branch von main neu aufgesetzt) — OP-UX-5: Trennung Auftragsannahme (Buchung) / Fahrzeugannahme (Check-in) (Version 0.65.0 → 0.66.0, MINOR). Das Datenmodell trennte die Ereignisse längst (geplant→liefern→angeliefertmit Ist-Stempel + harter Reservierung), die UX nicht: „Fahrzeug angeliefert" war ein nackter Status-Button ohne Check-in. Entscheidungen (Nutzer): Fahrzeugannahme als Tab im Annahme-Workspace · Doku-Pflicht (Check-in erledigt den Standard-Annahme-Schritt OP-R3-1 mit Pflicht-Zustandskommentar/Car-Check). Gebaut: reiner, getesteter Domänen-HelferfahrzeugAnnahme(Kommentar-Pflicht · nur ausgeplant· erledigt Annahme-Schritt ·liefernatomar — Doppel-Check-in = sauberer Fehler statt Duplikat) + Handlerauftrag.checkin(Quittung, Protokoll, Auditauftrag.angeliefert, REOPT-Event) + UI-Tabs „⌨ Auftrag anlegen" / „🚗 Fahrzeug da" (Badge = erwartete Anlieferungen; Liste nach Bringtermin, überfällige amber „erwartet seit …"; aufklappbarer Check-in). DTO additiv+bringtermin. Selbsttest imoperativ-Durchlauf (+Tests.md), OP-UX-5 in IDs.md, WORKSPACES §0. Verifikation:tsc+operativ+ng buildgrün. Doku: HANDOFF §2/§4 (OP-UX-5 neu), CHANGELOG, Timesheet. Nachtrag (gleicher PR, Nutzer-Anweisung): alle 5 GitHub-Workflows (ci·docs-deploy·fly-deploy·sync-pr-logs·weekly-audit) zwischenzeitlich vonubuntu-latestauf self-hosted Runner umgestellt (GitHub-gehostete Runner nahmen ab ~15:55 UTC keine Jobs mehr an). Beim Merge vonmaindurch die kanonische Lösung aus #403 (OP-CI-2, „runner-unabhängig — self-hosted Default + Fork-Gate, aus medidentas D-29") ersetzt:runs-on: ${{ …fork && ubuntu-latest || vars.CI_RUNNER || self-hosted }}— Fork-PRs laufen sicher auf GitHub-hosted, sonst konfigurierbar via Repo-VariableCI_RUNNER, Default self-hosted. Meine[self-hosted]-Zwischenlösung ist damit obsolet (Konflikt zugunsten #403 gelöst). Zusätzlich Tool-Cache-env(RUNNER_TOOL_CACHE/AGENT_TOOLSDIRECTORY=${{ runner.temp }}/_tool) je Setup-Job ergänzt, damitsetup-node/setup-pythonauf den (nicht-ephemeren, macOS-ARM64) self-hosted Runnern den Tool-Cache finden. Nachtrag 2 (gleicher PR, Nutzer-Wunsch): OP-ORTUNG-2 neu — „Standort unbekannt" (DTOstandort: null) soll Klärfall werden statt stilles „—", plus Skill „Fahrzeug finden" analog zum Umparken-Flow (Suchauftrag → Fund → Belegung setzen → Klärfall gelöst); Hardware-loser Fallback/Prozess-Vorlage zu OP-ORTUNG-1 — HANDOFF §4 + IDs.md. Nachtrag 3 (gleicher PR, Nutzer-Wunsch): OP-KOMM-1 neu — Broadcast-Nachrichten ans Team (Durchsagen + Rückfragen mit Kurz-Antwort) über die vorhandene Broadcast-Infrastruktur (Musterplan.autoAngewendet); bewusst kein Chat; Klärfall-anbindbar (z. B. Standort-Suche OP-ORTUNG-2) — HANDOFF §4 + IDs.md. Review (CodeRabbit, 3 Runden/10 Findings) im selben PR gefixt: Car-Check-Doku-Garantie für Alt-Aufträge (Chronik-Eintrag im Domänen-Helfer, eine Quelle), Panel-Race der Check-in-Quittung, Offline-/Disconnect-Guards, Textarea-Sperre während des Sendens, Minuten-genauer Überfällig-Vergleich. - Branch
claude/nifty-euler-esi8p6(#403) — OP-CI-2: CI/Deploy runner-unabhängig — self-hosted Default + Fork-Gate (aus medidentas D-29 übernommen) (Tooling/Workflows/Doku, kein App-Bump —APP_VERSIONunverändert 0.65.0). Auslöser (Nutzer, „vergleiche die runner config"): Der Vergleich der GitHub-Actions-runs-on-Konfiguration beider Repos zeigte: medidentas war bereits auf einen self-hosted Runner umgestellt (Entscheidung D-29, Header-Kommentar: „2026-07-04 startete GitHub Actions für die Org keine gehosteten Jobs mehr — Billing/Limit"), taktano stand noch überall auf hartkodiertemubuntu-latest. Da beide Repos in derselben Orgdrkv-comliegen, trifft das Hosted-Minuten-Limit taktano genauso → CI + alle Deploys (fly/docs/app) stünden still. Entscheidung (Nutzer „ja"): D-29-Strategie 1:1 auf taktano portiert. Gebaut (nur Workflows + Doku, kein Code/Schema): alle 5 Workflows nutzen jetztruns-on: ${{ vars.CI_RUNNER || 'self-hosted' }}→ Default = lokaler Org-Runner, ohne Commit auf GitHub-Runner umschaltbar über die Repo-/Org-VariableCI_RUNNER(z. B.CI_RUNNER=ubuntu-latest). Sicherheits-Gate (RISK-18, neu): inci.yml(läuft aufpull_request, auch aus Forks) trägt jeder der 11 Jobs den erweiterten Ausdruck${{ github.event.pull_request.head.repo.fork && 'ubuntu-latest' || vars.CI_RUNNER || 'self-hosted' }}→ Fork-PRs (fremder Code) laufen nie auf dem self-hosted Runner, immer auf GitHub-Wegwerf-Runnern.sync-pr-logs.ymlbekommt die einfache Form (Fork-PRs werden dort ohnehin per Guard 2 vor dem Checkout abgewiesen, fremder Code läuft nie);fly-deploy/docs-deploy/weekly-auditlaufen nur aufmain-Push/Dispatch/Cron im eigenen Repo (kein Fremd-PR) → einfache Form. Jeder Workflow-Kopf erklärt Runner-Wahl + Hintergrund + Fork-Gate. Rest-Offen: Runner-Host härten (ephemer/isoliert, least-privilege im Org-Netz), sobald der lokale Runner produktiv trägt (RISK-18). Verifikation: YAML-Parse aller 5 Workflows grün;grep runs-onbestätigt kein hartesubuntu-latestmehr (nur im Fork-Zweig). Doku:.github/workflows/*.yml(Kopf-Kommentare), Risikoregister RISK-18, HANDOFF §4 (OP-CI-2),konventionen/IDs.md, CHANGELOG, Timesheet. - Branch
claude/design-input-integration-ae43ki(#400, Folge-PR zu #399, Branch von main neu aufgesetzt) — OP-UX-4-Nachschärfung 2: Alternativen statt Sackgasse + Trotzdem-Annehmen + Leistungs-Schnellauswahl + Kunden-Lookup (Version 0.64.0 → 0.65.0, MINOR). Nutzer-Befund (Screenshot): „✗ Kein machbarer Plan: kein verfügbares Ressourcen-Set …" war eine Sackgasse — keine Option, den Auftrag dennoch anzunehmen oder auf einen machbaren Termin auszuweichen. (1) Alternativen:auftrag.pruefenprobt bei Infeasibility spätere Anlieferungen (gleiche Uhrzeit, +1…+14 Tage) und liefert die erste machbare alsalternativeAnlieferung/alternativeFertig; das Panel bietet sie als Ein-Klick-Übernahme („→ Anlieferung Mo 06.07. 08:00 übernehmen (fertig …)"). Bei geplatztem Wunschtermin (Warnung) analogfruehesteAbholung→ „→ Abholung auf … setzen". Entscheidung: Termin-Übernahmen alsoverrides-Signal, das das Parsing übersteuert (Termine lassen sich nicht sinnvoll in den Satz zurück-patchen); manuelles Weitertippen setzt sie zurück — der Satz bleibt die eine Quelle. (2) Trotzdem annehmen:auftrag.createmittrotzdem-Flag legt den Auftrag auch ohne machbaren Plan an — Prozess-Schritte als ungeplante Platzhalter-Instanzen (bayId leer, 0-Dauer, Statusgeplant→ der Auftrag bleibt für die Re-Optimierung wählbar und wird eingeplant, sobald Ressourcen da sind; CodeRabbit-Befund), als Klärfall markiert (Grund = Scheduler-Befund) → sichtbar im Klärfälle-Workspace statt still verloren; amber Button „⚠ Trotzdem annehmen (wird Klärfall)". (3) Leistungs-Schnellauswahl: Chip-Zeile aller aktiven Leistungen unter der Kommandozeile — Klick ergänzt den Satz (Nutzer-Vorgabe; ersetzt die bisher erkannte Nennung per Stamm-Suche, sonst angehängt), erkannte Leistung ist markiert. (4) Kunden-Lookup: „Meintest du: ☺ …"-Vorschläge aus den Kunden bisheriger Aufträge (Substring-Match ab 2 Zeichen, max. 3, inkl. CRM-Hinweis); Übernahme ersetzt die Kurzform im Satz durch den vollen Namen, und beim Annehmen wird der CRM-Link des bekannten Kunden automatisch mit verknüpft. Verifikation:tsc+ng build+operativ+test:annahme-parsegrün. Doku: CHANGELOG, HANDOFF §4 (OP-UX-4), Timesheet. - Branch
claude/design-input-integration-ae43ki(#399, Folge-PR zu #398, Branch von main neu aufgesetzt) — OP-UX-4-Rest: Kunde/CRM-Nachtrag im geteilten Detail-Panel (Version 0.63.0 → 0.64.0, MINOR). Die frühere U5-Funktion (Kunde-Name korrigieren + CRM-Link nachtragen an bereits angelegten Aufträgen) hatte seit dem v3-Redesign keine UI mehr (das „Zuletzt angenommen"-Panel wich dem Erfolgs-Screen). Jetzt als Kunde-Karte im Fakten-Grid des geteiltenauftrag-detail-panel: Name + klickbarer CRM-Link, „✎ nachtragen" öffnet den Inline-Edit (Name Pflicht, CRM optional) → bestehenderauftrag.update-Handler (Audit/Chronik unverändert). Damit von überall erreichbar, wo das Panel öffnet (Aufträge · Tafel · Radar · Planung-Gantt · Klärfälle · Meine Arbeit) — besser als das alte Annahme-only-Panel. Reiner Client-Pfad, kein Server-Change. Verifikation:ng buildgrün. Doku: HANDOFF §4 (OP-UX-4-Offen-Liste), CHANGELOG, Timesheet. - Branch
claude/design-input-integration-ae43ki(Folge-PR zu #397, Branch von main neu aufgesetzt) — OP-UX-4-Nachschärfung: Dauer-Angaben + Quellen-Anzeige im Takt-Kommando (Version 0.62.0 → 0.63.0, MINOR). Nutzer-Befund (Screenshot): „…kommt mo, 14 Tage Zeit" ließ die Abholung leer — die Heuristik kannte nur „bis ‹X›", und ob das LLM überhaupt geantwortet hatte, war unsichtbar. (1) Dauer-Parsing: Heuristik versteht jetzt Dauer-Angaben („14 Tage Zeit", „in 3 Tagen", „2 Wochen") → Abholung = Anlieferung (sonst heute) + Dauer, 17:00; derselbe Fall steht explizit im LLM-System-Prompt. (2) Robustere LLM-Validierung: Voll-ISO-Zeiten mit Sekunden/Zeitzone (LLM-typisch) werden auf die Minute gekürzt statt verworfen (ISO_MINUTE_PREFIX). (3) Dezente Quellen-Anzeige unter den Baustein-Chips: „Analyse: KI (LLM) + Heuristik" (magenta Punkt) · „Analyse: Heuristik" · „… (KI nicht konfiguriert)" bei dormant · „… (KI nicht erreichbar)" (amber) bei Fehler — der LLM-Status ist damit erstmals sichtbar (llmStatus-Signal statt stummem Catch). Fehlen-Hinweis nennt jetzt auch das Dauer-Beispiel. Selbsttesttest:annahme-parse+2 Asserts (ISO-Kürzung, Dauer-Regel im Prompt). Verifikation:tsc+test:annahme-parse+ng buildgrün; Nutzer-Satz parst komplett per Heuristik (Mo 06.07. 08:00 → Mo 20.07. 17:00). Doku: CHANGELOG, HANDOFF §4 (OP-UX-4), Timesheet. - Branch
claude/design-input-integration-ae43ki(#397, gemergt) — OP-UX-4: v3-Kern-Loop-Redesign aus Claude Design umgesetzt (Version 0.61.0 → 0.62.0, MINOR). Design-Handoff „Car intake UI redesign" als neue lebende Design-Quelle abgelegt (design/prototype/Taktano Werkstatt-OS v3.dc.htmlersetzt v2 · Handoff-Specdesign/prototype/HANDOFF-Kernloop-Slice1.md· 10 Referenz-Screenshots; Bundle-Tokens byte-identisch mitdesign/tokens/) und exakt umgesetzt — alle 8 Kern-Workspaces, mit echten Daten statt Prototyp-Fixtures. Entscheidungen (Nutzer, 07-04): (a) alle 8 Workspaces in dieser Session; (b) Ein-Satz-Parsing direkt mit LLM (Assistent-Infrastruktur) + Heuristik als Fallback; (c) Crystal-Bar = 8 Prototyp-Workspaces oben + übrige („Weitere") darunter; (d) Konflikte & Klärfälle zusammengelegt (ein Workspace, zwei Tabs;/klaerfaelle→ Redirect). Gebaut: Shell (Nav-Reihenfolge/Glyphen/Badge-Farben je Kontext, Logo-Gradient, Backdrop-Grid, Header 17 px + Glow-Dot + JETZT-Uhr) · Annahme „Takt-Kommando" (Ein-Satz-Intake: 5 Baustein-Chips live via Client-Heuristikutil/annahme-parse.ts+ LLM-EndpointPOST /annahme/parse— enum-gebundenes Function-Calling gegen den echten Leistungs-Katalog, dormant ohneASSISTENT_LLM_KEY; Machbarkeits-Panel = echter Dry-Runauftrag.pruefen[erweitert umstartMin/slotNamedes ersten Schritts] mit Reserve-Pille/Preis/„✓ Annehmen" in einem Schritt [Panel = U4-Bestätigung]; Erfolgs-Screen „AU-nnn ist im Takt." + Radar-Fokus; Selbsttesttest:annahme-parse+ CI) · Überblick = Hof-Radar (Buchten-/Hof-Kacheln aus der Ist-Belegung, Radar-Sweep, Mitarbeiter-Avatare aus dem Plan — ehrlich beschriftet („Ortung abgeleitet aus Plan & Belegung", keine BLE/RFID-Behauptung), „Als Nächstes"-Takt-Vorschau, Live-Ortung-Panel mit echtem Sync-Zähler; Cross-Links?fokus=AU-…/?mitarbeiter=…) · Aufträge (Fluss = 5 Prozess-Stationen mit WIP-Limit 4 · Risiko = Dringlichkeits-Timeline · Vollbreiten-Detail-Panel mit Terminklassen-/Reserve-Pille, Faktenzeile [neuAuftragDTO.leistungIds], 5-Stufen-Strip, Kontext-Aktionen ⚡/✦/📍; Lifecycle-Aktionen/Helfer/Fly-in erhalten) · Konflikte & Klärfälle (Tabs mit Kontext-Badges, Hebel-Zeilen mit „✓ Termin hält"/„✗ hält nicht" + ↷ Knock-on, Engpass-Box ◎, Lösen mit Crumple + 26-Pixel-Dissolve; Klärfall-Detail mit „✓ lösen"/„📍 Hofplan") · Vorschläge (Karten-Gridminmax(420px,1fr), Badges inkl. „☺ von dir", Impact-Rows in festen Spalten, Quelle mono) · Mitarbeiter (Karten mit Plan-Ortung, ✦-Empfehlungs-Box magenta, „Umparken"-Chip cyan, Status-Aktionen ✓/▶/○/⏸/✕ + 📍 Radar; CRUD/XP/Statistik erhalten) · Qualität (KPI-Zeile real abgeleitet, 3 Spalten, ✓/✕-Checkliste + Release-Gate „✓ Freigeben — in den Ausgang", Zwei-Wege-Nacharbeit: „🛠 In QS behoben" [neuessofortBehoben-Flag anqs.mangelErfassen→ Mangel entsteht als behoben, Aufwands-Log „QS-Aufwand auf Auftrag erfasst" mit Σ = Ist-Aufwand-Hook] / „↩ Nacharbeit → Produktion" [bestehender OP-QS-4-Pfad, vorbefüllt]; Ausgang-Feed mit NEU-Pille + Nachkontrolle). Planung: bereits v3-konform (Konflikt-Chip „⚡ n → nächster", JETZT-Linie, ⚑-Flags, Heatrow gebaut); der Prototyp-Detail-Strip ist bewusst durch das reichere geteilte Detail-Fly-in (OP-R8-16) abgedeckt. Bewusste Abweichungen: Ortung ehrlich als abgeleitet beschriftet; „Zuletzt angenommen"-Panel (U5) weicht dem Erfolgs-Screen — Kunde-Nachtrag als OP-UX-4-Rest notiert. Verifikation:tsc+ng build+test:annahme-parse+test:qs-nacharbeit+operativ+ No-Hex grün. Doku:design/WORKSPACES.md(v3-Abschnitte inkl. neuem §0 Annahme), HANDOFF §2/§4, Tests.md, CHANGELOG, Timesheet. Nachtrag (gleicher PR, Nutzer-Wunsch): OP-ORTUNG-1 neu — echte Live-Ortung für Mitarbeiter (Handy/BLE) + Fahrzeuge (BLE/RFID/UWB) fürs Hof-Radar (heute Plan-/Belegungs-Ableitung als ehrlicher Stand); inkl. Radar-Fusion mit Abweichungs-Signal, D-2-Datenmodell (rohe Sichtungen ≠ Abgeleitetes) und Datenschutz/Mitbestimmung DE/AT/CH (BetrVG §87/DSGVO, Zonen- statt Bewegungsprofil, Pilot mit Fahrzeug-Tags zuerst) — HANDOFF §4 + IDs.md. - Branch
claude/3d-vehicle-models-sfljc1(#396) — OP-R6-2 Recherche: Fahrzeug-3D — Modell-Quellen, Rendering & Markierungen (reine Doku,APP_VERSIONunverändert). Nutzer-Frage „Quelle für 3D-Fahrzeugmodelle, easy einbettbar/drehbar (Web + später iOS), mit nummerierten Markierungen + Kommentar/Foto?" recherchiert und als neues Architektur-Docdocs/architektur/Fahrzeug-3D.mdfestgehalten. Ergebnis/Empfehlung (Entscheidung offen): (1) generisches Karosserietyp-Set statt fahrzeuggenauer Modelle — CC0-GLBs (Quaternius/Poly Pizza/Kenney), Ablage im bereits vorgesehenen R2-Buckettaktano-models(dormantes Binding) mit Lizenz-Nachweis; keine Marken-Modelle (Editorial-Lizenz/Markenrecht, Redistributions-Verbot offener Formate). (2)<model-viewer>(v4.3.1, aktiv) als einfachste tragfähige Web-Einbettung — Drehen/Zoomen + nummerierte Hotspot-Markierungen out of the box, Setzen per Klick (positionAndNormalFromPoint), als erste Lazy-Route. (3) Markierungs-Datenmodell renderer-neutral (FahrzeugMarkierungam Auftrag: Position+Normale,kommentar,mangelId?,fotoIds[]→ knüpft anFotoAttachment/Mangel/OP-R7-16 an). (4) iOS-nativ später über dieselben Assets (GLB→USDZ einmalig, RealityKit/Quick Look); model-viewer-AR-Modus deckt „AR vorbereiten" strukturell ab. Konsequenz: das ⚠-Aufwand-Flag in OP-R6-2 relativiert — Stufe 1 kann direkt generisches 3D sein (statt 2D-Silhouette-Umweg); Slices V-1…V-4 skizziert. Doku: Lastenheft §11.1 OP-R6-2 + HANDOFF §4 (Recherche-Verweis), Doku-Landkarte + CLAUDE.md-Tiefenquellen (neue Datei), Timesheet. - Branch
claude/planning-queue-optimization-iniw7z(#395, Branch von main neu aufgesetzt — #394 gemergt) — OP-OPT-9 Slice 5: Queue-Hinweis in der Tafel (Version 0.60.0 → 0.61.0, MINOR). Der letzte OP-OPT-9-Folgepunkt ohne Login-Abhängigkeit (Nutzer-Wahl „Tafel-Queue-Hinweis"): Jede Tafel-Auftragszeile zeigt unter dem aktuellen Schritt jetzt „→ als Nächstes:· ab — den nach dem aktuellen Schritt nächsten wartenden Schritt in Queue-Reihenfolge (" queueVergleichausqueue-reihenfolge.ts, Startzeit statt Template-Reihenfolge — dieselbe Semantik wie die Planung-Queues und „Meine Arbeit"; die Wiederverwendung des geteilten Helfers ist der Punkt, keine dritte Kopie). Reine Projektion (S-2), kein Server-Change; rückt durch die Auto-Nachführung automatisch mit. Damit beantwortet die Tafel True-North-Frage 2 einen Tick voraus: nicht nur wo steht der Auftrag jetzt, sondern was passiert als Nächstes. Verbleibende OP-OPT-9-Punkte (personalisierte Push-Zustellung, Rollen-Gate für den Auto-Schalter) hängen an OP-AUTH-1 und bleiben dort notiert. Verifikation:ng build+ No-Hex grün (client-only). Doku: Lastenheft OP-OPT-9 (Slice 5, Offen-Liste) · HANDOFF §2/§4 · Funktionsumfang · CHANGELOG · Timesheet.
2026-07-03
- Branch
claude/planning-queue-optimization-iniw7z(#394, Branch von main neu aufgesetzt — #393 gemergt) — OP-OPT-9 Slice 4: Auto-Nachführung an-/abschaltbar + In-App-Benachrichtigung bei Auto-Anwendung (Version 0.59.0 → 0.60.0, MINOR). Setzt zwei der offenen OP-OPT-9-Folgepunkte um. (1) Schalter: neues persistiertes FeldautoOptAktiv(PersistedState, Default an, onStart-Backfill?? true— Persistenz-Gate D5-4 gedeckt) + ClientMsgautoopt.setzen; die Event-Re-Opt wendet nur bei aktivem Schalter automatisch an, sonst bleibt alles bestätigungspflichtiger Vorschlag (Verhalten wie vor v0.59.0). Toggle-Button „⟲ Auto-Nachführung an/aus" in der Planung-Toolbar (grün = an, Tooltip erklärt das Kriterium); jeder Schaltvorgang wird auditiert (plan.autoopt.konfiguriert, D1). Entscheidung: Schalter global je Werkstatt-DO (= je Tenant, da ein DO pro Tenant — OP-TENANT), nicht je Nutzer — die Planungs-Policy ist eine Betriebs-, keine Personen-Einstellung; Rollen-Gate folgt mit OP-AUTH-1. (2) Benachrichtigung: beim Auto-Anwenden broadcastet der DOplan.autoAngewendet(Grund + betroffene Auftragsnummern/Δ) an alle Verbindungen → Toast „⟲ Plan automatisch nachgeführt · …" (Leitstand und Werker-Terminals in „Meine Arbeit" — die nachgerückte Queue springt nicht mehr kommentarlos). Entscheidung: In-App-Broadcast statt Push/E-Mail — es gibt noch keinen Mitarbeiter-Login/Push-Kanal (OP-AUTH-1/OP-R1-2); der Toast an alle ist die ehrliche v1, personalisierte Zustellung folgt mit dem Login. Verifikation: Servertsc+ Persistenz-Gate (check-persistence.sh, 20/20 Felder gedeckt) · Clientng build+ No-Hex grün. Doku: Lastenheft OP-OPT-9 (Slice 4, Offen-Liste) · HANDOFF §2/§4 · Funktionsumfang · CHANGELOG · Timesheet. - Branch
claude/planning-queue-optimization-iniw7z(#393) — OP-OPT-9: „Nächste Aufgaben"-Queues je Mitarbeiter/Arbeitsplatz + Auto-Anwenden terminneutraler Re-Opt-Verbesserungen (Version 0.58.0 → 0.59.0, MINOR). Nutzer-Impuls (07-03): „Hat jeder Platz/Mitarbeiter eine priorisierte Queue geeigneter nächster Aufträge? Wird bei jeder Veränderung neu das nächste Optimum vorgeschlagen? Das würde das Ganze dynamischer machen, anstatt einen pseudo-korrekten Plan zu huldigen." Befund: die Dynamik existierte bereits (event-getriggerte Re-Opt rechnet nach jedem materiellen Event neu), aber (a) ohne Ressourcen-Queue-Sicht und (b) jede Verbesserung blieb bestätigungspflichtig. (1) „Nächste Aufgaben" je Mitarbeiter/Arbeitsplatz (neuclient/src/app/leitstand/naechste-aufgaben.component.ts, in der Planung unter dem Gantt): die priorisierte Queue jeder Ressource als reine Projektion des aktuellen Plans (Derived State S-2 — kein neues Schema, kein Server-Change): läuft jetzt (▸) · pausiert (⏸) · kommt als Nächstes (1…n in Plan-Reihenfolge); je Eintrag Start · Auftrags-Nr. · Schritt · 🎓-Helfer-Kennung · ⚡ bei Termin-Konflikt; Karten-Kopf zeigt je Ressource „frei ab …" bzw. „jetzt frei" (True-North-Frage 3 — nächste freie Kapazität); Tabs Mitarbeiter/Arbeitsplätze (Bucht-Freigabe inkl. Cool-down viabayEnd); Klick öffnet das geteilte Detail-Panel (fokussierter Schritt). Entscheidung — Architektur bleibt globaler Plan: echte lokale Dispatch-Queues (greedy „nimm den nächsten geeigneten Auftrag") verworfen — sie verlieren gegen CP-SAT Abhängigkeiten, Termingarantien, Park-/Buchtkonflikte, G-2/G-3; die Queue ist die Ressourcen-Projektion des globalen Optimums, nicht sein Ersatz. (2) Auto-Anwenden (Server): die event-getriggerte Re-Opt (aktualisiereVorschlaegeAuto) wendet terminneutrale Pareto-Verbesserungen jetzt direkt an statt nur vorzuschlagen. Kriterium pure + getestet in neuserver/src/operativ/autoopt.ts(autoAnwendbar): ≥1 Auftrag echt früher fertig UND keiner später — „keiner später" garantiert zugleich, dass kein Wunsch-Abholtermin neu reißt; reine Umsortierungen ohne Zeitgewinn werden bewusst NICHT angewendet (Plan-Stabilität — kein Zappeln durch gleichwertige CP-SAT-Alternativlösungen, keine Endlos-Nachführung). Beim Anwenden: Chronik-Eintrag je geändertem Auftrag („Plan automatisch nachgeführt: X früher fertig"), Audit-Eventplan.auto(wie indocs/architektur/Audit-Log.mdvorgesehen), solverInfo „Auto-Optimierung angewendet: …", Persist + Broadcast; Trade-offs (jemand würde später fertig) bleiben unverändert bestätigungspflichtiger Vorschlag im Feed — „Vorschlag statt Zwang" gilt weiter für alles Nicht-Risikofreie. Neuer Selbsttesttest:autoopt(+ CI) fixiert genau diese Grenze. (3) Persönliche Queue in „Meine Arbeit" (Folge-Slice im selben PR): die Werker-Sicht sortiert die eigenen Schritte jetzt in Plan-Reihenfolge (laufend → pausiert → geplant nach Optimierer-Startzeit, vorher Auftragsnummer), nummeriert die wartenden Schritte (1 = als Nächstes dran), zeigt je geplantem Schritt „ab" und im Kopf „laut Plan frei" — dieselbe Projektion wie die Planung-Queues, für den einzelnen Werker. Review-Härtung (CodeRabbit): Queue-Reihung/Positions-Nummern/„frei ab" als pure Helfer extrahiert (client/src/app/leitstand/queue-reihenfolge.ts, von Planung-Queues und „Meine Arbeit" geteilt) + neuer Selbsttesttest:queue(+ CI, Tests.md); „laut Plan frei"-Badge prüft nicht mehr falsy (formatierter String statt Zahl — Zeitwert 0 bliebe sichtbar, Sentinel ist null); OP-ID-Kommentar-Korrekturen (OP-OPT-8→9 inci.yml/leitstand.ts), unnötigerCommonModule-Import entfernt; Fog-Finding (Queue im Entwurfs-Modus gemutet) als gewolltes OP-R8-15-Verhalten begründet abgelehnt, von CodeRabbit zurückgezogen. Verifikation: Servertsc+test:autoopt· Clientng build+test:queuegrün. Doku: Lastenheft §11.2 OP-OPT-9 · HANDOFF §2/§4 · Funktionsumfang · Tests.md · Sanity-Checkliste (F3) · Timesheet. - Branch
claude/pickup-date-special-requests-6hrlnc(#391) — OP-UX-1/U9 + R7-F10: Frühestmöglicher Abholtermin direkt in der Annahme angeboten + Sonderwünsche erfassen (Version 0.57.0 → 0.58.0, MINOR). Nutzer-Wunsch (07-03, Screenshot): „In der Annahme soll direkt der frühestmögliche Abholtermin basierend auf dem gewählten Service angeboten werden. Sonderwünsche müssen auch erfasst werden können." (1) Termin-Vorschlag: neuer Dry-Runauftrag.terminvorschlag({leistungId, anlieferung, gueteklasse}→auftrag.terminvorschlag.resultmitfruehesteAbholung=scheduleLeistung(...).abholbereitinkl. Standzeit — dieselbe Größe, an derauftrag.create/pruefendie Wunschtermin-Warnung messen; kein State-Change/Broadcast/Reopt, wieauftrag.pruefen). Das Annahme-Formular fragt ihn entprellt (300 ms) bei Leistung-/Anlieferung-/Güteklasse-Änderung an (ohne Anlieferung ab „jetzt"). Entscheidung Vorbefüll-Regel: ein leeres oder zuvor automatisch befülltes Wunsch-Abholung-Feld wird sofort vorbefüllt; ein Hand-Wert bleibt unangetastet (Zeile „Frühestmöglich: … · Übernehmen" darunter); nicht machbar ⇒ dezenter Amber-Hinweis mit konkretem Grund (hartes Gate bleibt der Prüfen-Schritt). Neue Zeit-HelferminToInput/nowInput(client/src/app/util/time.ts, UTC-Wanduhr-Konvention wie Server-parseIso). (2) Sonderwünsche (R7-F10 — war spezifiziert, nicht gebaut): optionales Freitext-Feld in der Annahme →auftrag.create.sonderwuensche→Auftrag.sonderwuensche(additiv/optional, keine Migration) → sichtbar im Bestätigungs-Dialog + im Aufträge-Detail (Fakten-Grid, volle Breite). Abgrenzungen (Entscheidungen): Freitext am Auftrag genügt v1 — Struktur/Häufigkeits-Auswertung bleibt OP-FIND-1, Sonderwünsche als geprüfter QS-Punkt bleibt der vertagteistAbnahmebereit-Erweiterungspunkt (OP-QS-GATE), Kommentar-Verlauf mit Foto/Voice bleibt OP-R7-12; kein neuer Self-Test (Handler = dünner Wrapper über den getesteten TS-Scheduler, Feld = Pass-through). Verifikation: Servertsc+ Smokes (spike/operativ/test:teilplan/test:abnahme/test:preis) · Clientng buildgrün. Doku:Operative-Durchgaengigkeit.md§U9 · Lastenheft §5.1 F10 + §5.2.2 ·Funktionsumfang.md· HANDOFF §2 · Timesheet. - Branch
claude/dependabot-vulnerabilities-0wzu6o(#389) — RISK-4/OP-SBOM-1/OP-SEC-1: Dependabot-/Vuln-Assessment + Safe-Fixes (Version 0.57.0 → 0.57.1, PATCH — Security-Tweaks, keine neue Funktion). Befund: 0 Prod-Runtime-Vulns (Server/Clientnpm audit --omit=dev= 0,pip-auditSolver grün; auch die neuen Client-Runtime-Depshtml2canvas-pro/@angular/service-workeradvisory-frei) — alle 57 Voll-Audit-Findings (Server 8 · Client 12 · docs-site 37) lagen ausschließlich in Dev-/Build-Toolchains. Entscheidung (Nutzer-Wahl): „Assess + Safe-Fixes" — nur nicht-brechende Bumps, keine Major-/Force-Upgrades. Fixes: (1)wrangler ^4.100 → ^4.105(Server + docs-site) → undici-TLS-Bypass-/ws-DoS-/miniflare-Highs beseitigt; (2) Clientnpm audit fix(Angular-Build 20.3.28→20.3.31, vite 7.3.2→7.3.5 — Highs weg) + Patch-Overridehttp-proxy-middleware 3.0.7(Angular pinnt exakt die verwundbare 3.0.5; Override = kleinste nicht-brechende Lösung, wieder entfernbar sobald Angular selbst bumpt); (3) flyctl-Action SHA-gepinnt (ed8efb3…= v1.6; war die letzte@master-Referenz → Supply-Chain-Lücke zu, Dependabot github-actions trackt den Pin). Akzeptierte Dev-only-Residuen (begründet, kein nicht-brechender Fix): drizzle-kit→@esbuild-kit/esbuild (moderate; npm-„Fix" wäre Downgrade auf drizzle-kit 0.18 — abgelehnt), Client babel-/uuid-Ketten (low/moderate, Angular-Exakt-Pins), docs-siteserialize-javascript(high, aber nur Build-Cache der statisch generierten Doku mit vertrauenswürdigen Inputs; npm-„Fix" wäre Docusaurus-Downgrade — abgelehnt; löst sich mit Docusaurus-Bump). Verifiziert: Prod-Gates grün,ng build+ docs-site-Build grün. Doku: Risikoregister RISK-4 (Prüfdatum 07-03) + Compliance C-05 + HANDOFF OP-SBOM-1 (flyctl-Pin aus „Offen" erledigt; 1 Union-Merge-Duplikat entfernt — ältere §4-Generationen-Dubletten verbleiben für eine eigene Glättungs-Session), CHANGELOG, Timesheet. - Branch
claude/markup-rendering-issue-tooltips-8i90j3(#388) — OP-DOCS-2/-7: Markdown-Rendering im Doku-Widget + Issue-Details-Tooltip mit Screenshot-/Bild-Vorschau (Version 0.56.0 → 0.57.0, MINOR — 0.55/0.56 parallel von #379/#384 vergeben, OP-PM-2-Muster). Befund (Nutzer-Screenshot): Assistent-Antworten im Doku-Widget erschienen als roher Markdown-Text (###,**fett**,[Link](…)unformatiert); Wunsch: die Issue-Liste soll Details im Tooltip inkl. verlinkter Screenshots/Bilder zeigen. (1) Markdown-Rendering: widget-eigener minimaler RenderermdHtml(Entscheidung: keine Markdown-Lib — Leitprinzip Einfachheit, kein neues Bundle-Gewicht): erst wird alles escaped, dann zeilenbasiert Überschriften/Listen/Trennlinien/```-Code-Blöcke + Inline**fett**/*kursiv*/`Code`/[Links](…)mit Schema-Allowlist (nur http(s)/relativ;javascript:/data:bleiben Text) umgesetzt;escapeHtmlescapet jetzt auch"(Attribut-sicher); Nutzer-Blasen bleiben Klartext. (2) Issue-Details-Tooltip:FeedbackIssueumdetails(Issue-Body ohne<sub>-Meta-Fußzeile/Bild-Markup, 600 Zeichen gekappt) +bilder(extrahierte Bild-Links: Markdown-Bilder,<img src>, Bild-URLs inkl. GitHub-Attachments + Access-gated Screenshot-Link ausfeedbackZuIssue) erweitert — reine HelferdetailsAusIssueBody/bilderAusIssueBody(github-issues.ts), DTO-Symmetrie beidseitig. Doku-Widget: Hover-/Fokus-Tooltip je Issue-Zeile (position:fixedgegen Panel-Overflow-Clipping; bleibt beim Überfahren offen → Bild-Links klickbar; 📷-Marker bei angehängten Bildern); App-Formular „Bisheriges Feedback“: derselbe Tooltip (verzögertes Ausblenden; Entscheidung: Details dort als Klartext, kein eigener Markdown-Renderer im Angular-Client — Einfachheit). Nachschärfung (Nutzer „Ich sehe die Issues nur im Chat-Dialog — wo ist das in der App?“): die Übersicht war in der App nur im Feedback-Formular versteckt → neuer „🗂 Issues“-Umschalter im Assistent-Panel (Kopfzeile neben „📍 Feedback“) zeigt die read-only Liste direkt im Chat-Drawer; Liste + Tooltip in wiederverwendbare Komponentefeedback-issues-liste.component.tsextrahiert (Formular + Panel nutzen dieselbe — Wiederverwendung statt Duplikat). Bilder laden best-effort (Access-/GitHub-gated Quellen brauchen ggf. Anmeldung; Link öffnet im Tab). Verifikation:test:assistant-feedback(+10 Asserts: Bild-Extraktion · Details ohne Meta/Bilder · Kappung · Mapping) · Server-tsc·ng build· Widget-JS-Syntax-Check grün. Merge-Auflösung: #379 (Feedback-Overlay statt Dialog-Liste) hat die Formular-Liste entfernt → dort gilt mains UX; die Panel-Liste bleibt als Gesamtsicht komplementär zum route-bezogenen Overlay; Server-Helfer beider Seiten (selektor+details/bilder) zusammengeführt. Doku:In-App-Assistent.md§9 Slice 15, HANDOFF (OP-AI-4), Tests.md, CHANGELOG, Timesheet. - Branch
claude/chatbot-docs-bug-6zvwnv(#324) — OP-DOCS-2: Doku-Chatbot-Widget funktionierte produktiv nicht → Same-Origin-Proxy (Version 0.53.0 → 0.54.0 — Bugfix + neues Feature „Feedback-Übersicht“, s. u.). Befund (Nutzer-Screenshot): jede Frage im Widget aufdocs.taktano.comendete mit „⚠ Server nicht erreichbar“. Ursache: der Cross-Origin-Fetch nachapp.taktano.comkam nie am Worker an — Cloudflare Access an der Edge fing CORS-Preflight (OPTIONS trägt nie ein Cookie) und credentials-POST (kein App-Access-Cookie im Docs-Browser-Kontext) mit einem Login-Redirect ohne CORS-Header ab →fetch-TypeError → Catch-Zweig des Widgets. Die Worker-seitige CORS-/OPTIONS-Behandlung (#291) war korrekt, lief aber hinter dem Edge-Gate; die Slice-11-Annahme „Access-Vars leer ⇒ Fetch klappt“ verwechselte Worker-JWT-Prüfung mit Edge-Gate. Entscheidung — Fix als Code statt Access-Dashboard-Konfiguration (Everything-as-Code): Same-Origin-Proxy auf der Docs-Site — neue Pages-Functiondocs-site/functions/parties/[[pfad]].js(bewusst eng: nur POST aufassistant·feedback·feedback/aehnliche, kein WS-/State-Durchgriff) + Service-BindingAPP_WORKERauf den Workertaktano(docs-site/wrangler.toml) — Worker-zu-Worker, nicht über die Edge ⇒ kein CORS-Preflight, kein zweites Access-Cookie; Alternative „gemeinsame Access-App + Access-CORS-Settings“ verworfen (Dashboard-Zustand außerhalb des Repos, hätte zusätzlich einen bestehenden App-Login im Browser vorausgesetzt). Widget +docusaurus.config.jsdefaulten auf same-origin (leererTAKTANO_APP_ORIGIN; Override für Preview/Staging bleibt). Sicherheit unverändert: Access gated weiterhindocs.taktano.com(intern-only); der DO erkennt das Doku-Frontend weiter über den Origin-Header (ASSISTENT_CORS_ORIGINS) → WerkzeugfilterdokuSuche+datenmodellgreift. Folge-Hinweis: beim Scharfschalten der Worker-JWT-Prüfung (OP-COST-3) Docs-AUD akzeptieren bzw. gemeinsame Access-App (In-App-Assistent.md §9 Slice 12). Verifikation:docs-sitenpm run buildgrün · Proxy-Pfad-Allowlist per Node geprüft · Servertscgrün. Zusätzlich im selben PR — Feedback-Übersicht (Nutzer-Wunsch, MINOR): App + Doku zeigen read-only, wo es offenes und geschlossenes Feedback gibt, gespeist aus den GitHub-Issues des Feedback-Pfads (Labelfeedback— kein zweiter Datenbestand). Server: neuer DO-EndpointGET /feedback/liste(FeedbackListe, dormant ohneTAKTANO_FEEDBACK_TOKEN, Berechtigung wie/assistant) + reine HelfergithubFeedbackListePfad(List-Issues,state=all),issuesAusListe(PRs raus, Status sprechendoffen/geschlossen),routeAusIssueBody(liest die beim Anlegen strukturiert hinterlegte Verortung/Route aus dem Issue-Body zurück). App: Sektion „Bisheriges Feedback“ im Feedback-Formular (Status-Badge amber/grün · Titel-Link · Route). Doku-Widget: dritter Tab „Issues“ (read-only Liste, über den Same-Origin-Proxy; Allowlist umGET feedback/listeerweitert; Formular im Issues-Tab ausgeblendet). DTO-SymmetrieFeedbackIssue/FeedbackListebeidseitig;test:assistant-feedbackum Listen-Pfad/Route-Rücklese/Status-Mapping erweitert (Tests.md nachgezogen). Verifikation: Servertsc+test:assistant-feedback· Clientng build+ No-Hex ·docs-site build· Proxy-Allowlist-Check (POST+GET) grün. Doku:In-App-Assistent.md(§9 Slice-11-Korrektur + Slice 12 + Slice 13), HANDOFF (§2-Tabelle + OP-AI-4), Tests.md, CHANGELOG, Timesheet. - Branch
claude/vectorize-rag-analysis-ad9mt5(neu vonmainaufgesetzt — #304 ist gemergt; #323) — OP-OBS-1/OP-DOCS-2: CI-Warnungen in den zentralen Log-Sink + Leitlinie „OTLP/Grafana ist DER Log-Sink" (Tooling/Workflows/Doku, kein App-Bump). Auftrag (Nutzer): „Can we make that step continue on error aber mit Warnung in log" + „Add general guideline: OTLP/Grafana is log sink". Befund: der RAG-Push-Step war bereitscontinue-on-error+::warning::-Annotation — aber die Annotation ist nur im Actions-Run sichtbar, nicht in Grafana, wo Warnungen betrachtet werden. Gebaut: (1)scripts/push-doku-index.mjssendet bei jedem Fehler zusätzlich ein WARN-Log-Event an den OTLP-Endpoint (meldeWarnungAnGrafana,service.name=taktano-ci, gleiche Konventionen wieserver/src/obs/otlp.ts:<endpoint>/v1/logs, Headerkey=value,…URL-dekodiert; best-effort mit Timeout, dormant ohne Endpoint) → gescheiterte Re-Indizierungen erscheinen im „Fehler & Warnungen"-Panel statt still zu bleiben; beide Workflow-Steps (ci.ymldeploy +docs-deploy) reichenOTEL_EXPORTER_OTLP_ENDPOINT/_HEADERSdurch. (2) Leitlinie verankert (Root-CLAUDE.md§Observability +Observability.md§1): OTLP/Grafana ist der zentrale Log-Sink für Laufzeiten UND Tooling-/CI-Schritte; console/Actions-Annotationen sind Kontext-Ergänzung, nie Ersatz; best-effort + dormant, bricht nie den Deploy-Pfad. Verifikation:node --check· Fehlerpfad-Dry-Run (Bogus-Creds + unerreichbarer OTLP-Endpoint → Actions-Warnung + „nicht zustellbar"-Hinweis + Exit 0) · Workflow-YAML valide ·doku-indexregeneriert. Doku:CLAUDE.md,Observability.md§1,ci.yml,docs-deploy.yml, CHANGELOG, Timesheet. - Branch
claude/chatbot-docs-bug-6zvwnv(2. Neuauflage) (PR folgt) — OP-DOCS-7: Neues Feedback in Echtzeit an alle (Partykit-Broadcast) (Version 0.55.0 → 0.56.0 MINOR). Nutzer-Befund: neues Feedback erschien nicht direkt in der UI — soll „weiterhin per Echtzeit/Broadcast/Partykit an alle mitgeteilt werden“. Gebaut: DO broadcastet nach erfolgreichem Anlegen inerstelleFeedbackIssue(deckt deterministischen/feedback-Pfad UND LLM-Tool) ein neues ServerMsg-Eventfeedback.neumit dem fertigenFeedbackIssue(Nummer aus der Issue-URL, Titel/Labels aus dem Entwurf, Route/Selektor aus dem Anker — kein GitHub-Re-Fetch; best-effort, bricht das Anlegen nie) an alle Verbindungen. App:LeitstandServicereicht an neuesFeedbackService.issueEingegangenweiter — mergt vorn+dedupliziert in die Übersicht (Marker/Seiten-Chip aktualisieren live über die Signals) + dezenter Info-Toast „💬 Neues Feedback · #N“ für alle. Doku bewusst ohne WebSocket (Doku-Frontend erhält keine Live-State-Broadcasts, OP-DOCS-5-Schranke): 60-s-Frische-Refresh solange das Overlay an ist + Refresh bei Seitenwechsel (TTL 60 s) + sofortiger Refresh nach eigenem Widget-Feedback. Verifikation: Servertsc· Clientng build(prod) ·docs-site buildgrün. Doku:In-App-Assistent.md§9 Slice 14a, HANDOFF, CHANGELOG, Timesheet. - Branch
claude/chatbot-docs-bug-6zvwnv(Neuauflage) (PR folgt) — OP-DOCS-7/OP-FEEDBACK-1: Feedback-UX-Umbau — Ein-Schritt-Screenshot · Feedback-Overlay statt Dialog-Liste · globaler Toggle (Version 0.54.0 → 0.55.0 MINOR). Nutzer-Feedback: „der Feedback-Dialog ist nicht gut“ — drei Wünsche: Markierung/Verpixelung direkt beim Screenshot (Element-Auswahl + Aufnahme + Nachbearbeitung = ein Schritt), bisheriges Feedback nicht im Dialog sondern als Overlay/„Tooltip“ in App & Doku, globaler Ein-/Aus-Toggle wie Light/Dark. Gebaut: (a) neues Vollbild-Editor-Overlayscreenshot-editor-overlay.component.ts(öffnet direkt nach Region-Ziehen ODER Element-Auswahl;bild-upload-gateunverändert wiederverwendet); der Feedback-Pin erfasst das angeklickte Element automatisch als Screenshot (sichtbarer Ausschnitt + 12 px Rand, best-effort; Pin-Overlay/Formular viadata-tk-screenshot-ignorenie im Bild); Formular verschlankt (nur Auslöser + Status). (b) Feedback-Overlay Appfeedback-marker-overlay.component.ts: Marker am verorteten Element — Server liest dafür den Element-Anker aus dem Issue-Body zurück (neuselektorAusIssueBody→FeedbackIssue.selektor, DTO beidseitig; kein zweiter Datenbestand) — Klick-Tooltip (● offen amber / ✓ geschlossen grün · Titel-Link), Seiten-Chip für Feedback ohne (auffindbaren) Anker, Positionen folgen Scroll/Resize/Navigation (rAF-gedrosselt); Dialog-Liste entfernt. Doku: Navbar-Toggle 💬 (html-Navbar-Item + Delegation im Client-Modul) + Seiten-Chip mit Popover der Issues dieser Seite; Widget-Tab „Issues“ (Gesamtliste) bleibt. (c) Toggle Rail-Button „Feedback-Anzeige“ (unter dem Theme-Umschalter) bzw. Doku-Navbar; localStoragetk-feedback-overlay, Default aus. Verifikation: Servertsc+test:assistant-feedback(Selektor-Rücklese) ·ng build+ No-Hex +test:bildgate·docs-site buildgrün. Doku:In-App-Assistent.md§9 Slice 14, HANDOFF, CHANGELOG, Timesheet. - Branch
claude/chatbot-docs-bug-6zvwnv(PR folgt) — OP-DOCS-2: Doku-Chatbot-Widget funktionierte produktiv nicht → Same-Origin-Proxy (Version 0.53.0 → 0.54.0 — Bugfix + neues Feature „Feedback-Übersicht“, s. u.). Befund (Nutzer-Screenshot): jede Frage im Widget aufdocs.taktano.comendete mit „⚠ Server nicht erreichbar“. Ursache: der Cross-Origin-Fetch nachapp.taktano.comkam nie am Worker an — Cloudflare Access an der Edge fing CORS-Preflight (OPTIONS trägt nie ein Cookie) und credentials-POST (kein App-Access-Cookie im Docs-Browser-Kontext) mit einem Login-Redirect ohne CORS-Header ab →fetch-TypeError → Catch-Zweig des Widgets. Die Worker-seitige CORS-/OPTIONS-Behandlung (#291) war korrekt, lief aber hinter dem Edge-Gate; die Slice-11-Annahme „Access-Vars leer ⇒ Fetch klappt“ verwechselte Worker-JWT-Prüfung mit Edge-Gate. Entscheidung — Fix als Code statt Access-Dashboard-Konfiguration (Everything-as-Code): Same-Origin-Proxy auf der Docs-Site — neue Pages-Functiondocs-site/functions/parties/[[pfad]].js(bewusst eng: nur POST aufassistant·feedback·feedback/aehnliche, kein WS-/State-Durchgriff) + Service-BindingAPP_WORKERauf den Workertaktano(docs-site/wrangler.toml) — Worker-zu-Worker, nicht über die Edge ⇒ kein CORS-Preflight, kein zweites Access-Cookie; Alternative „gemeinsame Access-App + Access-CORS-Settings“ verworfen (Dashboard-Zustand außerhalb des Repos, hätte zusätzlich einen bestehenden App-Login im Browser vorausgesetzt). Widget +docusaurus.config.jsdefaulten auf same-origin (leererTAKTANO_APP_ORIGIN; Override für Preview/Staging bleibt). Sicherheit unverändert: Access gated weiterhindocs.taktano.com(intern-only); der DO erkennt das Doku-Frontend weiter über den Origin-Header (ASSISTENT_CORS_ORIGINS) → WerkzeugfilterdokuSuche+datenmodellgreift. Folge-Hinweis: beim Scharfschalten der Worker-JWT-Prüfung (OP-COST-3) Docs-AUD akzeptieren bzw. gemeinsame Access-App (In-App-Assistent.md §9 Slice 12). Verifikation:docs-sitenpm run buildgrün · Proxy-Pfad-Allowlist per Node geprüft · Servertscgrün. Zusätzlich im selben PR — Feedback-Übersicht (Nutzer-Wunsch, MINOR): App + Doku zeigen read-only, wo es offenes und geschlossenes Feedback gibt, gespeist aus den GitHub-Issues des Feedback-Pfads (Labelfeedback— kein zweiter Datenbestand). Server: neuer DO-EndpointGET /feedback/liste(FeedbackListe, dormant ohneTAKTANO_FEEDBACK_TOKEN, Berechtigung wie/assistant) + reine HelfergithubFeedbackListePfad(List-Issues,state=all),issuesAusListe(PRs raus, Status sprechendoffen/geschlossen),routeAusIssueBody(liest die beim Anlegen strukturiert hinterlegte Verortung/Route aus dem Issue-Body zurück). App: Sektion „Bisheriges Feedback“ im Feedback-Formular (Status-Badge amber/grün · Titel-Link · Route). Doku-Widget: dritter Tab „Issues“ (read-only Liste, über den Same-Origin-Proxy; Allowlist umGET feedback/listeerweitert; Formular im Issues-Tab ausgeblendet). DTO-SymmetrieFeedbackIssue/FeedbackListebeidseitig;test:assistant-feedbackum Listen-Pfad/Route-Rücklese/Status-Mapping erweitert (Tests.md nachgezogen). Verifikation: Servertsc+test:assistant-feedback· Clientng build+ No-Hex ·docs-site build· Proxy-Allowlist-Check (POST+GET) grün. Doku:In-App-Assistent.md(§9 Slice-11-Korrektur + Slice 12 + Slice 13), HANDOFF (§2-Tabelle + OP-AI-4), Tests.md, CHANGELOG, Timesheet. - Branch
claude/vectorize-rag-analysis-ad9mt5(neu vonmainaufgesetzt — #304 ist gemergt; PR folgt) — OP-OBS-1/OP-DOCS-2: CI-Warnungen in den zentralen Log-Sink + Leitlinie „OTLP/Grafana ist DER Log-Sink" (Tooling/Workflows/Doku, kein App-Bump). Auftrag (Nutzer): „Can we make that step continue on error aber mit Warnung in log" + „Add general guideline: OTLP/Grafana is log sink". Befund: der RAG-Push-Step war bereitscontinue-on-error+::warning::-Annotation — aber die Annotation ist nur im Actions-Run sichtbar, nicht in Grafana, wo Warnungen betrachtet werden. Gebaut: (1)scripts/push-doku-index.mjssendet bei jedem Fehler zusätzlich ein WARN-Log-Event an den OTLP-Endpoint (meldeWarnungAnGrafana,service.name=taktano-ci, gleiche Konventionen wieserver/src/obs/otlp.ts:<endpoint>/v1/logs, Headerkey=value,…URL-dekodiert; best-effort mit Timeout, dormant ohne Endpoint) → gescheiterte Re-Indizierungen erscheinen im „Fehler & Warnungen"-Panel statt still zu bleiben; beide Workflow-Steps (ci.ymldeploy +docs-deploy) reichenOTEL_EXPORTER_OTLP_ENDPOINT/_HEADERSdurch. (2) Leitlinie verankert (Root-CLAUDE.md§Observability +Observability.md§1): OTLP/Grafana ist der zentrale Log-Sink für Laufzeiten UND Tooling-/CI-Schritte; console/Actions-Annotationen sind Kontext-Ergänzung, nie Ersatz; best-effort + dormant, bricht nie den Deploy-Pfad. Verifikation:node --check· Fehlerpfad-Dry-Run (Bogus-Creds + unerreichbarer OTLP-Endpoint → Actions-Warnung + „nicht zustellbar"-Hinweis + Exit 0) · Workflow-YAML valide ·doku-indexregeneriert. Doku:CLAUDE.md,Observability.md§1,ci.yml,docs-deploy.yml, CHANGELOG, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(#322) — OP-AI-4: Hybrid-Matching für Live-Daten (exakt + semantisch) (Version 0.52.0 → 0.53.0 MINOR — neues Feature). Befund (Nutzer-Screenshot): „Wer kann Kaffee kochen?“ fand den Skill „Kaffee machen“ nicht — derdatenListe-Filter war ein Ganz-Phrasen-Substring ("kaffee machen".includes("kaffee kochen")= false); die semantische Suche (RAG) deckte nur die Doku ab. Gebaut (Nutzer-Wunsch „Kombination aus exakter und semantischer Suche auch für Live-Daten“) — dreistufig: (1) Token-Matching (neues reines Modulserver/src/assistant/matching.ts:tokens/tokenTreffer— ein Anfrage-Wort genügt, Ganz-Phrase bleibt Teilmenge); (2) semantisch: ohne Token-Treffer wird die Anfrage eingebettet (EU-Modell, wie RAG) und per Cosine gegen lazy gecachte Embeddings der Skill-Namen gerankt (semantischeTreffer, Schwelle 0.6/top 3) — Vektoren transient im DO-Speicher (derived, nie persistiert, nicht Vectorize: nur Taxonomie-Namen, kein PII → RISK-17 unverändert), Treffer dem LLM transparent als „semantisch ähnlich“ markiert (Anti-Halluzination), Embed-Calls zählen intaktano_llm_tokens{zweck=embedding}; (3) Selbstkorrektur: bleibt alles leer, nennt das Werkzeug die verfügbaren Skill-Namen → das LLM matcht in der nächsten Tool-Runde selbst.datenListeTextasync (+llm), Token-Matching auch für skills/leistungen-Filter. Neuer Self-Testtest:matching(CI Server-Job +Tests.md— der neue Warn-Check aus #302 hat das Fehlen prompt selbst angemahnt, Regel wirkt). Verifikation:tsc+test:matching+test:assistant-tools+check-no-consolegrün. Doku:In-App-Assistent.md(§Hybrid-Matching),Tests.md,ci.yml, CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(#321) — OP-OBS-1/OP-AI-4: LLM-Dashboard + Token-Verbrauchs-Metrik (Version 0.51.1 → 0.52.0 MINOR — neues Feature). Auftrag (Nutzer): dediziertes Dashboard für die LLM-Nutzung, Variante „b — mit Token-Metrik“. Gebaut: (1) Token-Metrik:LlmKonfig.onUsage-Callback + reiner ParserleseUsage()(server/src/assistant/llm.ts, defensiv gegen fehlende/kaputteusage-Blöcke, wirft nie) — der DO zählttaktano_llm_tokens{zweck,art}(zweck=chat|embedding · art=prompt|completion) je API-Antwort;test:assistant-toolsumleseUsage-Asserts erweitert. (2) Neues Dashboardgrafana/dashboards/taktano-llm.json(uidtaktano-llm, wird vom #307-API-Push automatisch eingespielt): Turn-Rate je Frontend/Ergebnis · Turn-Latenz P50/P95 · Token-Verbrauch (Rate + Summe im Zeitraum) · RAG-Wirkung (3 Panels aus dem Technik-Board) · Kosten-Pull-Gesundheit · letzte Assistent-Fehler (Loki,detected_level). Scope-Leitplanke bestätigt: Nutzungs-/Technik-Sicht in Grafana — die Euro-Kosten bleiben im Kosten-Workspace der App (OP-COST-2). Verifikation:tsc+test:assistant-tools+test:grafana-dashboards(2 Dashboards) grün. Doku:grafana/README.md(Datei- + Metrik-Liste), CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(#320) — OP-OBS-1: Build-Nummer + Build-Zeit dezent im Grafana-Dashboard (Version 0.51.0 → 0.51.1 PATCH — kleiner Tweak). Auftrag (Nutzer): „Bitte auf dem Grafana Dashboard auch die Build-Nummer und Zeitstempel dezent anzeigen.“ Gebaut: (1) Server:OtlpResourceumbuildZeiterweitert (APP_BUILD_ZEIT→ Resource-Attributservice.build_zeitin Logs- und Metrics-Payload; alle 4 Resource-Stellen: DO-Flush, Verbindungstest, Client-Endpoint) — damit steht der Deploy-Zeitstempel an jeder Telemetrie-Zeile, nicht nur in der seltenen Boot-Zeile. (2) Dashboard: schmales Stat-Panel (h2, rechte Spalte unter Fehler/Warnungen,textMode=name, ohne Farbe/Graph = dezent) zeigtv{{service_version}} · Build {{service_build}} · {{service_build_zeit}}aus den Log-Resource-Labels; Fehler/Warnungen-Stats auf h3 verschlankt (Spalte bleibt bündig). Mehrere Werte im Zeitfenster = ehrlicher Rollover-Hinweis. Verifikation:tsc+test:obs+test:obs-client+test:grafana-dashboardsgrün. Doku: CHANGELOG, HANDOFF, Timesheet; Dashboard aktualisiert sich nach Merge automatisch (API-Push #307). - Branch
claude/llm-cost-auto-deduction-o3pd0p(#319) — OP-OBS-1: Dashboard-Queries auf OTLP→Loki-Realität umgestellt (Fix „No data“) (Dashboard/Doku, kein App-Bump). Befund (Nutzer-Screenshot): Dashboard „Taktano — Technik-Telemetrie“ zeigte überall „No data“ +JSONParserErr— die Daten waren in Loki (Serieservice_name=taktano-serversichtbar), aber die Panels parsten| json, während der Grafana-Cloud-OTLP-Gateway den Log-Body nur als Kurz-Nachricht (msg) liefert und Level/Attribute als Structured Metadata (detected_level,severity_text,dienst…). Fix: alle 5 Loki-Queries umgestellt — Volumen/Fehler/Warnungen filtern aufdetected_level(Label statt Parse), Kosten-Pull nutzt Zeilenfilter|= \"infraKosten.pull\"+dienst-Label; Legende{{detected_level}}; Panel-/README-Doku angepasst (Praxis-Befund festgehalten). Wirkung: erster echter Beleg der gesamten Kette — Dashboard aktualisiert sich nach Merge automatisch über den frisch gebauten API-Push (#307). Verifikation:test:grafana-dashboardsgrün (JSON valide). Doku:grafana/README.md(Label-Hinweis), CHANGELOG, HANDOFF, Timesheet.
2026-07-02
- Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #307) — OP-OBS-1: Grafana-Dashboards automatisch per API einspielen (Dashboards-as-Code end-to-end) (CI/Tooling + Doku, kein App-Bump). Auftrag (Nutzer): „Erst Dashboard-Push per API" — Antwort auf die Frage, ob Dashboards automatisch über OTLP erscheinen (nein — OTLP transportiert nur Daten; Dashboards mussten bisher von Hand importiert werden). Gebaut: dependency-freiesscripts/push-grafana-dashboards.mjs— spielt allegrafana/dashboards/*.jsonper Grafana-HTTP-API ein (POST /api/dashboards/db,overwrite: true; stabileuid⇒ Update-in-place, kein Duplikat; entferntid/__inputs/__requires). CI: (1) Deploy-Job pusht nach dem Worker-Deploy (dormant ohne GitHub-SecretsGRAFANA_URL+GRAFANA_DASHBOARD_TOKEN— Deploy bricht nie, Muster wie die Secret-Syncs); (2) neues netzfreies Gatetest:grafana-dashboards(--check) im Server-Job: JSON parsebar ·title/uidvorhanden ·uideindeutig · Payload baubar — ein kaputtes Dashboard bricht den PR, nicht erst den Deploy. Indocs/betrieb/Tests.mdeingetragen (mitführen-Regel). Entscheidungen: Repo = Single Source (Hand-Edits in Grafana werden beim Deploy überschrieben — Everything-as-Code); Grafana-API direkt statt Terraform/Grizzly (Leitprinzip Einfachheit: null neue Abhängigkeiten, ein 100-Zeilen-Script); Service-Account-Token mit Rolle Editor (least privilege). Aktivierung (Nutzer): Grafana-Service-Account + Token anlegen → 2 GitHub-Secrets setzen (grafana/README.md§Einspielen). Verifikation:--checkgrün (1 Dashboard valide) + dormant-Pfad verifiziert (übersprungen ohne Env). Doku:grafana/README.md(§Einspielen per API),Observability.md(§6a Auto-Provisioning),Tests.md,ci.yml, CHANGELOG, HANDOFF, Timesheet. - Branch
claude/ipdad-fix-rinfjx(#306) — Build-Zeit sichtbar (UI + Logs) (Version 0.49.1 → 0.50.0 MINOR — kleines rückwärtskompatibles Feature; Build auto). Auftrag (Nutzer): neben Build-Nummer auch die Build-Zeit anzeigen. Gebaut:scripts/stamp-build.mjsstempelt zusätzlichAPP_BUILD_ZEIT(Stempel-/Deploy-Zeitpunkt, ISO-UTC ohne Millisekunden) inserver/src/build-number.ts(committeter Fallback bleibt leer = ehrlicher „ungestempelter Dev-Stand“, keine Fake-Zeit);version.tsre-exportiert die Zeit und hängt sie ansAPP_VERSION_LABEL(→ Boot-Log-Zeile trägt sie automatisch); DO-State reichtappBuildZeitan den Client (baueState); Planung-Statuszeile zeigt „v… · Build … · 2026-07-02 18:30 UTC“ (kompakt bis Minute, Tooltip erklärt Leer=Dev). Entscheidungen: Stempel-Zeitpunkt = Deploy-Zeit (nicht Commit-Zeit — beantwortet „wann kam dieser Stand live?“); leerer Fallback statt Pseudo-Zeit; Anzeige im bestehenden Versions-Label (kein neues UI-Element). Verifikation: Stempel-Skript lokal (schreibt Nummer + Zeit, Fallback restauriert), Server-typecheck+ng build(prod) + No-Hex grün. Doku:CLAUDE.md§Versionierung, CHANGELOG, Timesheet. - Branch
claude/ipdad-fix-rinfjx(#305) — OP-FEEDBACK-1: Screenshot-Aufnahme auf dem iPad repariert (html2canvas→html2canvas-pro) (Version 0.49.0 → 0.49.1 PATCH — Bugfix; Build auto). Befund (Nutzer, iPad): beim Feedback-Screenshot erschien „Screenshot-Aufnahme nicht verfügbar: Attempting to parse an unsupported color function “color”“. Ursache (verifiziert): das unmaintaintehtml2canvas@1.4.1kann moderne CSS-Farbfunktionen (color(),oklch,lab,color-mix) nicht parsen; iPadOS/Safari liefert computed Styles alscolor(srgb …)→ die Aufnahme bricht genau dort ab (Desktop-Chrome serialisiert alsrgb(...), darum fiel es nur auf dem iPad auf). Fix (einfachste tragfähige Lösung): Wechsel aufhtml2canvas-pro@2.2.1— der gepflegte, API-kompatible Fork, dessen Kernfeature genau die Unterstützung dieser Farbfunktionen ist; imscreenshot.service.tsnur der Lazy-Import getauscht (OptionenbackgroundColor/useCORS/scale/ignoreElementsunverändert; deckender--tk-bg-Hintergrund bleibt wegenbackdrop-blur). Nebeneffekt: der Fork liefert ESM →allowedCommonJsDependencies-Workaround ausangular.jsonentfernt. Entscheidung: Fork statt Eigenbau/Workaround (kein CSS-Umschreiben auf Alt-Syntax, kein Patchen der Lib) — minimalste Änderung, gleiche API, Problem an der Wurzel. Verifikation:ng buildgrün (Capture-Lib bleibt Lazy-Chunkhtml2canvas-pro-esm~246 kB raw, Initial-Bundle unverändert). Doku:In-App-Assistent.md§9 Slice 10,Bildbewertung.md,Lastenheft.md§11 OP-FEEDBACK-1, HANDOFF §4, CHANGELOG, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #303) — OP-OBS-1 Slice C1: Client-Telemetrie (Angular) → Grafana (Version 0.48.4 → 0.49.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): Slice C, Variante A (minimal, dependency-frei). Warum: unbehandelte Frontend-Fehler waren bisher unsichtbar (Blindflug). Kern-Entscheidung — kein Token im Browser: der Client POSTet same-origin an den Access-gegateten Worker-EndpointPOST /api/obs/client; der Worker mappt (rein/gehärtet,server/src/obs/client-logs.ts:parseClientLogPayload+clientEventsZuLogs) aufLogEvent[](service=taktano-client) und leitet serverseitig viapostOtlpLogsweiter (ctx.waitUntil) → Grafana-Token bleibt im Worker. Dormant ohneOTEL_EXPORTER_OTLP_ENDPOINT→204. Client (client-obs.service.ts+TaktanoErrorHandler): Angular-ErrorHandler+window.onerror+unhandledrejection(+ manuelleerror/warn/info); Ringpuffer (50), Batch-Flush alle 10 s +pagehide/visibilitychange(sendBeacon); best-effort, kein Re-Queue (keine Endlosschleife); Konsole zeigt Fehler weiterhin. Härtung (Browser-Payload = unvertrauenswürdig): Level-Whitelist, Anzahl-Deckel (50), Längen-/Content-Length-Limits, PII-Scrubbing. Neuer Testtest:obs-client(CI Server-Job) + indocs/betrieb/Tests.mdeingetragen (dogfood der neuen „mitführen"-Regel). Scope: Fehler-Forwarder; volles RUM (Web-Vitals/Sessions) = Faro = Slice C2 (offen). Verifikation:tsc+test:obs-client+check-no-console+ng build+check-doc-consistencygrün. Doku:Observability.md(§ Slice C1),Tests.md,ci.yml, CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #302) — OP-DOCS-9: lebende Test-Übersicht + Regel „immer mitführen" (Doku + CI-Gate-Tweak, kein App-Bump). Auftrag (Nutzer): „Übersicht über alle automatischen Tests in der Doku immer mitführen." Gebaut: neue lebende Dokudocs/betrieb/Tests.md— vollständige Liste aller automatischen Prüfungen in Tabellen (29 Server-test:*-Selbsttests · Server-Smokes · Client-Tests · Solver-Self-Test · alle Gates), je mit Befehl · Prüfgegenstand · OP-Bezug · CI-Job + „alles-lokal-ausführen"-Block. Stehende Regel verankert:CLAUDE.md§Tests & CI +docs/konventionen/agents.md(neue/entfernte Prüfung je PR nachziehen, wie CHANGELOG/HANDOFF). Mechanischer Rückhalt (warnt, blockt nicht):scripts/check-doc-consistency.shBlock 5 flaggt jedestest:*-Script (server/ + client/package.json), das inTests.mdfehlt → „immer mitführen" ist durchsetzbar, nicht nur Vorsatz. In Landkarte (docs/README.md) + Tiefenquellen (CLAUDE.md) verlinkt. Verifikation:check-doc-consistency.shgrün (alle 31test:*erfasst, keine toten Links/Frontmatter-Lücken). Doku:Tests.md(neu),CLAUDE.md,agents.md,docs/README.md,check-doc-consistency.sh, CHANGELOG, HANDOFF, Timesheet. - Branch
claude/in-app-chatbot-feedback-vpv8ed(PR #301) — OP-FEEDBACK-1: Screenshot-Feedback-Bugfixes (Aufnahme sichtbar · Markierungen nutzbar · Bild landet im Issue) (Version 0.48.3 → 0.48.4 PATCH — Bugfix; Build auto). Befund (Nutzer): beim Feedback-Screenshot (1) wurde die Aufnahme nicht angezeigt, (2) ließen sich keine nummerierten Markierungen anbringen, (3) erschien das Bild nicht im GitHub-Issue. Ursachen (2 Wurzeln, verifiziert): (a) Kamera-Qualitäts-Gate blockierte den Upload — das Formular reichte den Screenshot durch das Standard-Gate (min. 640×480/Schärfe); ein UI-Ausschnitt ist fast immer „zu klein" → Status „Gesperrt" → „Hochladen" deaktiviert →freigegebenfeuert nie → keinscreenshotKey→ kein Bild im Issue. (b) Leere/transparente Aufnahme —html2canvasmitbackgroundColor: nullauf dem dunklencolor-mix/backdrop-blur-Cockpit ergab ein leer wirkendes Bild; Capture-Fehler wurden nur in ein Signal geschrieben, das das Formular nicht anzeigte → nichts zu sehen, nichts zu markieren. Fixes: (1)bild-upload-gate.component.tserhält@Input gateConfig(DefaultSTANDARD_GATE— Foto-Verhalten unverändert);analysiere()nutzt sie fürbewerteQualitaet+entscheideGate. (2)feedback-form.component.tsreicht eine entschärfte Screenshot-Konfig (keine Größen-/Schärfe-/Helligkeits-Sperre, NSFW-Schwelle bleibt) → „Hochladen" ist nicht mehr fälschlich gesperrt; Verpixeln + Markierungen unverändert. (3)screenshot.service.ts: Aufnahme mit deckendem Hintergrund (aufgelöste--tk-bg, Fallbackwhite— kein Hex) statt transparent; entarteter Zuschnitt (<8px) → ehrliche Meldung statt 1×1-„Bild". (4) Capture-Fehler werden jetzt im Formular angezeigt (Danger-Banner + „Erneut aufnehmen"). Verifikation:test:bildgate+ng build --configuration production+ No-Hex grün. Doku: CHANGELOG, Timesheet. - Branch
claude/ipdad-fix-rinfjx(#308) — Log-Hygiene (OP-PM-2): 10 CHANGELOG-Dubletten aus union-Merges entfernt (Doku-only, kein Bump). Wrap-up-Glättung nach den parallelen Merges #295–#306: zehn Einträge existierten doppelt — einmal final mit PR-Link (#230/#231/#243/#282/#286/#288/#295/#298/#302/#303), einmal als ältere „(#308)"-/Format-Variante desselben Inhalts (Diff-verifiziert: nur Präfix, kein Inhaltsverlust) → jeweils die verlinkte Fassung behalten. Die drei #257-Einträge sind bewusst nicht angefasst (inhaltlich verschiedene Folge-Captures). Historische Singleton-„(PR folgt)"-Einträge (Altbestand vor der PR-Link-Pflicht) bleiben unverändert. Verifikation:check-doc-consistency.shohne CHANGELOG-Hinweise; verbleibend nur die 11 bekannten Legacy-Timesheet-Session-IDs (OP-PM-3-grandfathered). Doku: CHANGELOG, Timesheet. - PR #304 (Branch
claude/vectorize-rag-analysis-ad9mt5) — OP-DOCS-2/OP-AI-4: RAG aktiviert — Vectorize-Self-Provisioning + Embeddings-Push + CI-Re-Index + Wirkungs-Metriken (Version 0.48.4 → 0.51.0 MINOR — Feature-Aktivierung; ursprünglich 0.49.0, wegen Versions-Kollisionen mit den parallel gemergten #303 [nahm 0.49.0] und #306 [nahm 0.50.0] auf 0.51.0 korrigiert; Build auto). Auftrag (Nutzer): „Implement RAG" — überstimmt die am selben Tag zunächst festgehaltene kriteriengebundene Zurückstellung (Eintrag darunter); Retrieval-Kern + Keyword-Fallback waren fertig, gebaut wurde die Aktivierungsschicht. Gebaut: (1)scripts/push-doku-index.mjs(npmdoku-index:push= frisch chunken + pushen): stellt den Vectorize-Indextaktano-dokuselbst sicher (GET→CREATE, 1024 Dims/cosine =mistral-embed), embeddet die Chunks batchweise über den EU-Endpoint (ASSISTENT_LLM_BASE_URL, Dimension validiert) und upsertet sie als NDJSON über die Cloudflare-REST-API (Metadaten =rankVectorize-Vertrag: datei/titel/text/sichtbarkeit; gleiche IDs → Re-Index überschreibt; bewusste Grenze: verwaiste Vektoren nach Abschnitts-Löschungen → Index neu anlegen, im Script dokumentiert). Dormant-sicher (Muster Assistent-Secrets): ohne CF-Token → Skip; ohneASSISTENT_LLM_KEY→ nur Index sicherstellen (Deploy-sicher), Retrieval fällt auf Keyword zurück. (2)[[vectorize]]-BindingDOKU_INDEXinwrangler.tomleinkommentiert → der bereits gebaute semantische Pfad (leitstand.tsdokuSuche) wird produktiv. (3) CI:deploy-Job pusht vorwrangler deploy(Self-Provisioning ⇒ Binding existiert garantiert);docs-deployre-indext bei Doku-only-Änderungen (Fast-Track überspringtdeploy) — OP-DOCS-1 d erfüllt. Compliance/Risiko nachgezogen: neue Zeile C-19 (Compliance.md: Vectorize ohne EU-Jurisdiktion, Datenminimierung by design — nur Doku-Chunks, kein PII/Kundendaten; AVV-Scope C-10) + RISK-17 → „in Arbeit (akzeptiert)". Verifikation:npm run doku-index(499 Chunks) · Push-Script-Dry-Run (dormant-Pfad) + Chunk-Parse-Check (Parser-BugDokuChunk[]vs. Array-Start gefunden + gefixt) ·tsc·test:assistant-retrievalgrün; echter Index-Push erfolgt beim erstenmain-Deploy (Secrets nur in CI). CodeRabbit-Review (5 Findings, alle umgesetzt — Leitsatz „Deploy-Verfügbarkeit > Index-Frische"): Push-Script nicht-blockierend gehärtet —AbortSignal.timeout(30 s) + 1 Retry (429/5xx/Netz) auf jedem externen Call, Top-Level-Catch →::warning::+ Exit 0 (Laufzeit-Keyword-Fallback trägt, nächster Deploy re-indext; echtes Existenz-Gate bleibtwrangler deploy); beide Workflow-Steps zusätzlichcontinue-on-error: true+timeout-minutes: 10(Crash/Hänger ≠ Deploy-Blocker); fragiles TS-Text-Scraping ersetzt durch JSON-Sidecardoku-index.generated.json(Build-Artefakt,.gitignore;build-doku-index.mjsschreibt beide). Fehlerpfad end-to-end verifiziert (Bogus-Creds → Warning + Exit 0). RAG-Wirkung messbar (Nutzer 07-02 „can we track the impact of the rag?"):dokuSucheinstrumentiert über den bestehenden OP-OBS-1-Stack — Countertaktano_doku_suche{pfad,grund,ergebnis}(semantischvectorize·okvs. Keyword-Fallback mit Grunddormant/fehler/leer;ergebnis=leer= Frage ohne Treffer → Recall-Signal, vormals das Aktivierungskriterium, jetzt Erfolgs-Monitor), Histogrammetaktano_doku_suche_dauer{pfad}(Pain live: Embed+Query-Latenz vs. Keyword ~0 ms) +taktano_doku_suche_score(Cosine-Top-Score,SCORE_BUCKETS0,4–0,95 — Match-Qualität/Index-Drift), Logzeileassistent.dokuSuche(pfad·grund·anzahl·topScore·dauerMs·frageLaenge — ohne Fragetext, OP-LOG-1) + 3 Grafana-Panels (RAG-Anteil & Fallback-Gründe · Latenz P95 je Pfad · Top-Score P50/P90). Doku:In-App-Assistent.md§8.1/§9,Compliance.md(C-19), Risikoregister (RISK-17),Observability.md(Slice A2),wrangler.toml,grafana/dashboards/taktano-technik.json, HANDOFF, CHANGELOG, Timesheet. - PR #304 (Branch
claude/vectorize-rag-analysis-ad9mt5) — OP-DOCS-2/OP-AI-4: Vectorize/RAG-Pain-Gain-Analyse → Aktivierung bewusst zurückgestellt (kriteriengebunden) + Residenz-Flag RISK-17 (Doku-only, kein App-Bump). Auftrag (Nutzer): „Vectorize/RAG — what is the pain/gain?" → Entscheidung festhalten. Analyse: Code ist fertig + dormant-sicher (semantischer Pfad inleitstand.tsaktiviert sich mitDOKU_INDEX-Binding, TF-IDF-Keyword-Fallback läuft); Rest-Pain = reine Ops (Index anlegen · Embeddings-Push · Re-Index je Doku-Deploy, Drift-Risiko) + Query-Latenz (~100–300 ms, Fallback fängt Ausfälle); Kosten vernachlässigbar (~460 Chunks × 1024 Dims). Gain = Recall bei Vokabular-Mismatch (deutsche Komposita/Flexion, Nutzer- vs. Glossar-Sprache) — für interne Nutzer heute ausreichend per Keyword, kritisch erst bei externen Widget-Nutzern/wachsendem Korpus. Entscheidungen (Nutzer 07-02): (1) Aktivierungskriterium statt Sofort-Provisionierung — scharf schalten erst bei externer Doku-Sicht/Widget (OP-DOCS-5) ODER realen Recall-Beschwerden interner Nutzer; Runbook-Kurzform dokumentiert (In-App-Assistent.md§8.1, Detailwrangler.toml). (2) Proaktiver DSGVO-Flag → neuer RISK-17: Vectorize bietet keine EU-Jurisdiktions-Option (anders als R2) — bei Aktivierung lägen Doku-Chunks (inkl.intern, aber kein PII/keine Kundendaten) global; bei Aktivierung Compliance-Zeile + RISK-17-Update Pflicht. Die EU-Residenz-Entscheidung 07-01 deckt nur das Embedding-/LLM-Modell, nicht den Vektor-Store. Doku:docs/architektur/In-App-Assistent.md(neu §8.1),docs/betrieb/Risikoregister.md(RISK-17), HANDOFF (§2 OP-AI-4-Zeile), CHANGELOG, Timesheet. - PR #302 (Branch
claude/llm-cost-auto-deduction-o3pd0p) — OP-DOCS-9: lebende Test-Übersicht + Regel „immer mitführen" (Doku + CI-Gate-Tweak, kein App-Bump). Auftrag (Nutzer): „Übersicht über alle automatischen Tests in der Doku immer mitführen." Gebaut: neue lebende Dokudocs/betrieb/Tests.md— vollständige Liste aller automatischen Prüfungen in Tabellen (29 Server-test:*-Selbsttests · Server-Smokes · Client-Tests · Solver-Self-Test · alle Gates), je mit Befehl · Prüfgegenstand · OP-Bezug · CI-Job + „alles-lokal-ausführen"-Block. Stehende Regel verankert:CLAUDE.md§Tests & CI +docs/konventionen/agents.md(neue/entfernte Prüfung je PR nachziehen, wie CHANGELOG/HANDOFF). Mechanischer Rückhalt (warnt, blockt nicht):scripts/check-doc-consistency.shBlock 5 flaggt jedestest:*-Script (server/ + client/package.json), das inTests.mdfehlt → „immer mitführen" ist durchsetzbar, nicht nur Vorsatz. In Landkarte (docs/README.md) + Tiefenquellen (CLAUDE.md) verlinkt. Verifikation:check-doc-consistency.shgrün (alle 31test:*erfasst, keine toten Links/Frontmatter-Lücken). Doku:Tests.md(neu),CLAUDE.md,agents.md,docs/README.md,check-doc-consistency.sh, CHANGELOG, HANDOFF, Timesheet. - PR #303 (Branch
claude/llm-cost-auto-deduction-o3pd0p) — OP-OBS-1 Slice C1: Client-Telemetrie (Angular) → Grafana (Version 0.48.4 → 0.49.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): Slice C, Variante A (minimal, dependency-frei). Warum: unbehandelte Frontend-Fehler waren bisher unsichtbar (Blindflug). Kern-Entscheidung — kein Token im Browser: der Client POSTet same-origin an den Access-gegateten Worker-EndpointPOST /api/obs/client; der Worker mappt (rein/gehärtet,server/src/obs/client-logs.ts:parseClientLogPayload+clientEventsZuLogs) aufLogEvent[](service=taktano-client) und leitet serverseitig viapostOtlpLogsweiter (ctx.waitUntil) → Grafana-Token bleibt im Worker. Dormant ohneOTEL_EXPORTER_OTLP_ENDPOINT→204. Client (client-obs.service.ts+TaktanoErrorHandler): Angular-ErrorHandler+window.onerror+unhandledrejection(+ manuelleerror/warn/info); Ringpuffer (50), Batch-Flush alle 10 s +pagehide/visibilitychange(sendBeacon); best-effort, kein Re-Queue (keine Endlosschleife); Konsole zeigt Fehler weiterhin. Härtung (Browser-Payload = unvertrauenswürdig): Level-Whitelist, Anzahl-Deckel (50), Längen-/Content-Length-Limits, PII-Scrubbing. Neuer Testtest:obs-client(CI Server-Job) + indocs/betrieb/Tests.mdeingetragen (dogfood der neuen „mitführen"-Regel). Scope: Fehler-Forwarder; volles RUM (Web-Vitals/Sessions) = Faro = Slice C2 (offen). Verifikation:tsc+test:obs-client+check-no-console+ng build+check-doc-consistencygrün. Doku:Observability.md(§ Slice C1),Tests.md,ci.yml, CHANGELOG, HANDOFF, Timesheet. - PR #301 (Branch
claude/in-app-chatbot-feedback-vpv8ed) — OP-FEEDBACK-1: Screenshot-Feedback-Bugfixes (Aufnahme sichtbar · Markierungen nutzbar · Bild landet im Issue) (Version 0.48.3 → 0.48.4 PATCH — Bugfix; Build auto). Befund (Nutzer): beim Feedback-Screenshot (1) wurde die Aufnahme nicht angezeigt, (2) ließen sich keine nummerierten Markierungen anbringen, (3) erschien das Bild nicht im GitHub-Issue. Ursachen (2 Wurzeln, verifiziert): (a) Kamera-Qualitäts-Gate blockierte den Upload — das Formular reichte den Screenshot durch das Standard-Gate (min. 640×480/Schärfe); ein UI-Ausschnitt ist fast immer „zu klein" → Status „Gesperrt" → „Hochladen" deaktiviert →freigegebenfeuert nie → keinscreenshotKey→ kein Bild im Issue. (b) Leere/transparente Aufnahme —html2canvasmitbackgroundColor: nullauf dem dunklencolor-mix/backdrop-blur-Cockpit ergab ein leer wirkendes Bild; Capture-Fehler wurden nur in ein Signal geschrieben, das das Formular nicht anzeigte → nichts zu sehen, nichts zu markieren. Fixes: (1)bild-upload-gate.component.tserhält@Input gateConfig(DefaultSTANDARD_GATE— Foto-Verhalten unverändert);analysiere()nutzt sie fürbewerteQualitaet+entscheideGate. (2)feedback-form.component.tsreicht eine entschärfte Screenshot-Konfig (keine Größen-/Schärfe-/Helligkeits-Sperre, NSFW-Schwelle bleibt) → „Hochladen" ist nicht mehr fälschlich gesperrt; Verpixeln + Markierungen unverändert. (3)screenshot.service.ts: Aufnahme mit deckendem Hintergrund (aufgelöste--tk-bg, Fallbackwhite— kein Hex) statt transparent; entarteter Zuschnitt (<8px) → ehrliche Meldung statt 1×1-„Bild". (4) Capture-Fehler werden jetzt im Formular angezeigt (Danger-Banner + „Erneut aufnehmen"). Verifikation:test:bildgate+ng build --configuration production+ No-Hex grün. Doku: CHANGELOG, Timesheet. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#295) — OP-DOCS-2: Doku-Widget-Bugfixes (Enter-Senden · Antworten/Fehler sichtbar · Art-Chips nur bei Feedback) (Version 0.48.2 → 0.48.3 PATCH — Bugfix; Build auto; nach Merge von #287/#292/#297/#298 u.a.). Befund (Nutzer-Screenshot): im Doku-Widget (1) ließen sich Fragen nicht per Enter absenden, (2) kam keine Antwort (auch kein Fehler) zurück, (3) wurden die Art-Chips (Fehler/Wunsch/Lob/Frage) auch im Doku-Frage-Tab angezeigt. Ursachen & Fixes (docs-site/src/clientModules/assistentWidget.js+custom.css): (1) ein<textarea>sendet bei Enter nicht → Keydown-Handler: Enter sendet, Umschalt+Enter = Zeilenumbruch (wie im App-Chat). (2) Antworten/Fehler wurden imperativ an den Body gehängt, aber das anschließenderender()imfinallyüberschrieb den Body sofort → sie verschwanden. Jetzt sind Chat-Antworten und -Fehler Teil desverlauf(Assistent-Blase) und die Feedback-Quittung eine persistentestatus-Zeile, dierender()mitzeichnet → nichts verschwindet mehr; HTTP-Status wird im Fehlertext genannt (Diagnose). (3) die Regelarten.hidden = tab !== 'feedback'griff nicht, weil.tk-assi-arten { display:flex }das[hidden]-Attribut schlug → CSS.tk-assi-arten[hidden] { display:none }ergänzt; Chips erscheinen nur noch im Feedback-Tab. Hinweis (Betrieb): Bleibt die Chat-Antwort „Server nicht erreichbar", ist es die dokumentierte Access-Cross-Origin-Voraussetzung (gemeinsame Access-App über*.taktano.com), nicht der Client. Zusatz-Fix (blockierte den Docs-Deploy): der beim Merge eingeflossene Glossar-Eintragnacharbeit-stufe(#287) trug einen ungültigenzielgruppen-Keybusiness→gen-glossarbricht hart ab (Durchsetzungspunkt der Single-Source-Daten) und der komplette Docs-Build/-Deploy scheiterte (auch aufmain). Korrigiert zu['nutzer','fach'](fach= „Fach/Management" deckt das ab). Verifikation:docs-sitenpm run buildgrün (Glossar generiert, Widget SSR-sicher) ·typecheckgrün. Doku: CHANGELOG, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #300) — OP-OBS-1/RISK-16: AVV/DPA mit Grafana dokumentiert (Compliance) (Doku-only, kein Bump). Kontext: OTLP-Secret vom Nutzer gefixt → Telemetrie-Export nach Grafana Cloud EU läuft (401 behoben). Verbleibende RISK-16-Restschuld = Auftragsverarbeitung/DPA belegen. Gebaut (Doku): neue Tracker-Zeile C-18 „Telemetrie-Datenverarbeitung EU-konform (Grafana)" inCompliance.md(Datenminimierung: nur PII-gescrubbte Betriebs-Telemetrie, keine Kundendaten by design; EU-Region belegt; nächster Schritt = Grafana-Labs-Standard-DPA gegenzeichnen + ins VVT); C-10 (AVV/Subdienstleister) um Grafana Labs ergänzt; C-06 (Logging-Prozess) auf „OTel-Wrapper + OTLP→Grafana EU live" aktualisiert; C-07 (EU-Residenz) + C-09 (PII-Scrubbing im Logger live) nachgezogen. RISK-16 aktualisiert: AVV/DPA dokumentiert (C-18), Rest-offen = Gegenzeichnung/VVT durch Nutzer/Legal (kein Code). Proaktiver DSGVO-Flag (verbindlich): die tatsächliche DPA-Unterzeichnung ist eine Rechts-/Betriebshandlung vor Go-Live — Taktano kann sie dokumentieren/vorbereiten, nicht abschließen. Doku:Compliance.md,Risikoregister.md, CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #298) — OP-OBS-1/OP-LOG-1: fehlgeschlagener Auto-Pull loggt jetztwarnstattinfo(Version 0.48.1 → 0.48.2 PATCH — Bugfix Log-Schärfe). Auslöser (Nutzer): eininfraKosten.pull.skipmitgrund=Mistral-Usage-API HTTP 401lief aufinfo— ein echter Auth-/API-Fehler gehört aufwarn(sichtbar in Grafana/Alerting), nicht in den Info-Strom. Fix: die drei Pull-Funktionen (pullGithubKosten/pullLlmKosten/pullMistralKosten) markieren den „kein Secret"-Fall explizit mitdormant: true; neuer HelperprotokollierePullFehler()unterscheidet sauber — dormant (erwartbarer Konfig-Zustand) →info, echter Fehler (HTTP 401/5xx, Timeout …) →warn, Teil-Erfolg (anzahl>0) →info. Statt String-Heuristik ein expliziter Diskriminator (robust, Leitprinzip Einfachheit). Log-Zeile bleibtinfraKosten.pull.skip(kein Dashboard/Metrik hängt daran — das trägt der Countertaktano_infra_pull{ergebnis}). Verifikation: Servertsc+check-no-console.shgrün. Doku:Observability.md, CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #297) — OP-OBS-1: selbsterklärender Fehler-Hinweis an der Telemetrie-Karte (Version 0.48.0 → 0.48.1 PATCH — UX-Tweak, keine neue Funktion). Auslöser (Nutzer-Screenshot): der neue Verbindungstest lieferte real HTTP 401 vom EU-Grafana-Gateway — der Test hat also sofort einen bis dahin still scheiternden Export sichtbar gemacht (Auth abgelehnt → Logs/Metriken kamen nie an). Code + CI-Secret-Sync verifiziert korrekt → Ursache ist der Credential-Wert im SecretOTEL_EXPORTER_OTLP_HEADERS, nicht der Code. Gebaut:obsHinweis()incosts.component.tsgibt je Fehlerbild einen Klartext-Tipp unter „Grund" (amber): 401/403 → „Authentifizierung abgelehnt — Token/Instance-ID im OTLP-Header prüfen (Grafana-Cloud-Access-Policy-Token mit logs:write + metrics:write, FormatAuthorization=Basic base64(InstanceID:Token))"; 404 → Endpoint (…/otlp ohne /v1/…); 5xx → vorübergehend, später testen. Macht die häufigen OTLP-Fehler ohne Doku-Blick lösbar (Leitprinzip Selbsterklärbarkeit). Verifikation:ng build+check-no-hex.shgrün (Hinweis nutztvar(--tk-amber), kein Hex). Doku:Observability.md(§6a Hinweis), CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #296) — OP-OBS-1: Telemetrie-Verbindung prüfbar + Status in der App (Version 0.47.0 → 0.48.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): „Können wir prüfen, ob die Weiterleitung der Logs und Metriken funktioniert? Den Status der Verbindung dann auch in der App anzeigen." Gebaut: (1) aktiver Verbindungstest — neuer DO-Handlerobs.test(admin-gegated, dormant ohneOTEL_EXPORTER_OTLP_ENDPOINT):testeObsExport()sendet synchron (await, nicht fire-and-forget) einen synthetischen Log + eine Test-Metrik (taktano_obs_test) an den OTLP-Endpoint und liefert das echte HTTP-Ergebnis (Log-/Metrik-Status) zurück → end-to-end-Beleg, dass Grafana wirklich annimmt (nicht nur „konfiguriert"). (2) laufender Status —obsStatus(transient je DO-Lebenszeit): jeder reguläreflushObs()-Export (Logs + Metriken) und jeder Test aktualisiertmerkeObsExport()(letztes ok/HTTP-Status/Grund/Zeit + ZählerlogsGesendet/metrikenGesendet);obsStatusDTO()gibt nur Host + letztes Ergebnis an den Client (Region sichtbar, kein Token/Secret), ausschließlich im Admin-Broadcast-Zweig. (3) UI — im Kosten-Workspace (Tab „Infra") eine Karte „Telemetrie · Grafana": Ampel (grün=letzter Export ok · amber=Fehler/dormant · faint=noch keiner), Host/Region, „Letzter Export" (rel. Zeit + HTTP-Status), Zähler Logs/Metrik-Exporte, Button „↻ Verbindung testen" → quittiert via Toast (ok/dormant/Fehler, eigeneseqje Klick, Muster wie Auto-Pull OP-COST-2). Entscheidungen: Verbindungstest admin-gegated wie die Kosten-Pulls (kein Info-Leak, kein Test-Spam durch Nicht-Berechtigte); Status transient (kein persistenter State, DTO ist reine Ableitung — Leitprinzip „derived state nie speichern"); Test synchron (Regulär-Export bleibt fire-and-forget viawaitUntil, nur der explizite Test wartet auf die Antwort). Verifikation: Servertsc+test:obs+check-no-console.sh+check-no-hex.sh+ Clientng buildgrün. Doku:Observability.md(§6a Verbindungstest/Status), CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #294) — OP-OBS-1 Slice A+B: Dauer-Histogramme +console→Wrapper-Migration + No-Console-Gate; RISK-16 EU-umgestellt (Version 0.46.0 → 0.47.0 MINOR; Build auto). Auftrag (Nutzer): „A, b, pr und merge" (Folge-Slices A+B). Slice A (Dauer-Histogramme): die Histogramm-Fähigkeit der Registry verdrahtet —taktano_solve_dauer{modus}(CP-SAT-Aufruf) +taktano_assistent_turn_dauer{frontend}(Assistent-Turn), ms-Buckets → P50/P95/P99 in Grafana. Slice B (console→Wrapper + Gate): die verbliebenen Laufzeit-console.*im DO (Boot bereits; jetzt Kosten-Protokoll, Assistent-Feedback/-Frage/-Fehler, Purge, Employee-Archiv/-Reaktivierung) auf den Logger-Wrapper migriert (this.log, strukturiert, PII-gescrubbt) → alle DO-Laufzeit-Logs erscheinen in Grafana/Loki. Neues CI-Gatescripts/check-no-console.sh(Server-Job) verhindert Rückfälle — Ausnahmen:*-demo.ts/spike.ts(CLI/Self-Tests) + Zeilen-Markerobs-allow-console(consoleSink-Transport inlogger.ts+ die 2 OTLP-Fehlversand-console.warn, die NICHT via Wrapper laufen dürfen → Endlosschleife). Review-Fixes (CodeRabbit, 3 valide): (a) Metrics-Export gedrosselt —flushObs()postete Metriken bei jeder Message (Registry ab Boot dauerhaft nicht-leer durchmetricsLogSink); jetzt Zeit-GateMETRICS_FLUSH_INTERVAL_MS=30_000(cumulative → 30-s-Kadenz reicht), Logs bleiben ereignis-getrieben; (b).catch()an beiden OTLP-waitUntil-Ketten (fire-and-forget-Schutz wied1Audit); (c) dienst-Label je Pull-Case in ein lokalesconstgehoben (kein 4-fach-Recompute, Counter-Label == Log-/Response-Label). RISK-16 (Nutzer stellte auf EU um): Stack jetzt Grafana Cloud EU (otlp-gateway-prod-eu-west-2) → DSGVO-Residenz erfüllt (US-Test-Stack abgelöst); RISK-16 gemindert, Rest-offen nur AVV/DPA-Beleg. Verifikation:test:obs+check-no-console.sh+check-no-hex.sh+ Servertscgrün. Doku:Observability.md(§6a Slice A/B + RISK-16 erfüllt),Risikoregister.md(RISK-16),ci.yml,scripts/check-no-console.sh, CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #294) — OP-OBS-1 Slice 2: native OTLP-Metrics (Prometheus/Mimir) (Version 0.45.0 → 0.46.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): „Emittieren wir auch Metriken?" → nein (nur Logs) → „go" für native Metriken. Gebaut: pureserver/src/obs/metrics.ts: Metrik-Registry (MetricsRegistry, Counter + explizite-Bucket-Histogramme, in-memory je DO-Lebenszeit, cumulative → mappt auf Prometheus-Counter) + dependency-freier OTLP/HTTP-JSON-Payload-Builder (resourceMetrics,sum/histogram) + best-effort POST an/v1/metrics.metricsLogSinkam Logger → jeder Log zählt alstaktano_log_events{level}(echte Fehler-/Volumen-Rate, nicht nur log-abgeleitet); zusätzlichtaktano_infra_pull{dienst,ergebnis}an den Auto-Pull-Pfaden; Histogramm-Fähigkeit (ms-Buckets) für künftige Dauer-Metriken. DO: Registry lazy je Boot,flushObs()schickt jetzt Logs + Metrik-Snapshot viactx.waitUntil(dormant ohneOTEL_EXPORTER_OTLP_ENDPOINT). Dashboardgrafana/um Prometheus-Panels ergänzt (Log-Events-Rate nach Level, Kosten-Pull-Rate je Dienst/Ergebnis). Naming-Konvention: Code ohne_total(OTel) → OTLP→Prometheus ergänzt_total→ PromQLtaktano_log_events_total/taktano_infra_pull_total(README-Hinweis, ggf. Serien-Name einmalig verifizieren). Verifikation:test:obserweitert (Registry-Aggregation label-reihenfolge-unabhängig, Histogramm-Buckets, OTLP-Metrics-Payload sum/histogram/ns,metricsLogSink, best-effort/dormant) grün + Servertsc+ Dashboard-JSON valide. Scope: technische Metriken (Grafana), True-North bleibt in der App. Offen: Traces (Tempo), Dauer-Histogramme verdrahten (Solve-/Request-Zeit), Client/Solver. Doku:Observability.md(§6a Slice 2),grafana/README.md, CHANGELOG, HANDOFF, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #294) — OP-OBS-1: Telemetrie-Residenz-Ausnahme dokumentiert (US-Test-Stack) (Doku-only, kein Bump). Kontext: Grafana-Cloud-Free-Stackdrkv+ OTEL-Secrets gesetzt → OTLP-Log-Export live. Der Endpoint liegt in der US-Region (otlp-gateway-prod-us-central-0). Proaktiver DSGVO-Flag (verbindlich): US-Telemetrie widerspricht der EU-Residenz-Leitplanke (DE/AT/CH). Nutzer-Entscheidung 07-02: „US erstmal zum Testen" (Dev/Non-Prod, PII-gescrubbt, geringes Volumen). Festgehalten als RISK-16 (akzeptiert/befristet) im Risikoregister +Observability.md§6a: verbindliche Maßnahme vor Go-Live = EU-Stack (Grafana Cloud Frankfurt oder self-hosted LGTM), code-frei via OTLP umstellbar. Doku:docs/betrieb/Risikoregister.md(RISK-16),docs/architektur/Observability.md, CHANGELOG, Timesheet. - Branch
claude/d5-1-implementation-qg0myg(#287) — OP-QS-4: QS-Nacharbeit direkt als zuweisbarer Prozessschritt + Leistungs-Schwellwerte (Version 0.45.0 → 0.46.0 MINOR — neue Features; Build auto, OP-PM-2). Auftrag (Nutzer): Nacharbeiten in der QS direkt als Prozessschritte (mit überschreibbaren Zeiten) erfassen, Mitarbeitern zuweisen (manuell + automatisch), Auftrag erst abschließbar wenn alle QS-Schritte erledigt; pro Leistung normal/gesteigert/extrem definieren und Aufträge bei Überschreitung markieren; Feature-Liste in der Doku führen. Befund: Abschluss-Gate (OP-QS-GATE, server-hartistAbnahmebereit) und Nacharbeit-Solver-Fluss (OP-UX-3) waren bereits gebaut → nur die echten Lücken umgesetzt. Gebaut: (1) einstufige Erfassungqs.nacharbeitErfassen(Auto-Mangel im Hintergrund + Nacharbeits-Schritt in einem Zug, überschreibbare Zeit; Bezug auf Ursprungsschritt speist die Qualitätsbewertung unverändert). (2) manuelle Zuweisungteilschritt.zuweisen+ FeldTeilschrittInstanz.manuellZugewiesen→ Crew bleibt bei Re-Opt fix (applyPlanungrespektiert die Hand-Zuweisung), automatisch bleibt Default. (3) Abschluss-Gate gehärtet:transition(→fertiggestellt)erledigt Nacharbeits-Schritte nicht mehr auto (schließt die in OP-QS-GATE vertagte Lücke). (4) Leistungs-SchwellwertenacharbeitSchwelleGesteigertMin/ExtremMin(Minuten, optional/admin-editierbar) + reine FnnacharbeitStufe()+AuftragDTO.nacharbeitStufe(aus max(geplant, tatsächlich), D-2) + Client-Badge (amber/rot) + Editor-Felder im Prozess-Katalog. (5) Nachzug:nacharbeitEinplanenüberspringt bereits verplante Mängel (keine Doppel-Einplanung). (6) Lebende Feature-Listedocs/betrieb/Funktionsumfang.md(neu, in Doku-Landkarte verlinkt) — ab jetzt pro PR mitpflegen. Entscheidungen (Sign-off, Nutzer): Mangel automatisch im Hintergrund · Schwellwerte absolute Minuten · erfassbar abfertiggestellt· Gate server-hart. Verifikation: neuer Self-Testtest:qs-nacharbeit(CI-Gate: Stufen · Auto-Erledigen-Härtung · Abnahme-Gate · fixe Hand-Zuweisung) +test:abnahme/test:nacharbeit/test:leistung/operativ/replanunverändert grün ·ng build+ No-Hex + Persistenz-Gate grün. Keine Migration (alle neuen Felder optional/additiv). Doku:Operative-Durchgaengigkeit.md(OP-QS-4 + Mermaid), Lastenheft §5.1, HANDOFF §4, IDs.md, Register.md, Glossar (Nacharbeit-Stufe), Funktionsumfang.md, CHANGELOG, Timesheet. Review-Nachzug (Commitsdaee056/7d10833): 6 CodeRabbit-Findings behoben (onStart-Boot-Repair nimmt Nacharbeit aus · Schwellwert-Patch validiert finite Zahlen ·zuweisen-Guard · manuelle Crew nurnurAktive· Badge-Typ verengt · Offline-Guard inerfasseNacharbeit) + 2 Re-Review-Funde (rohe WS-Payload-Validierung · Client filtert archivierte Mitarbeiter); 3 Findings begründet vertagt (mAufwand-Konvention · Crew-als-CP-SAT-Constraint · Voll-Idempotenz via Mutation-IDs). OP-QS-5 (mit dabei): Mangel bleibt eigenständiges Objekt, aber der Nacharbeitsschritt ist Single Source der Dauer —alleMaengelüberschreibt den Aufwand step-authoritativ (Fallback erfasster Wert), keine Dauer-Doppelführungs-Sync mehr;Mangel.nacharbeitAufwandMin= Ersterfassung/Intent. Entscheidung (Nutzer): eigenständig lassen + Duplikat entschärfen. Self-Testtest:qs-nacharbeit(5); kein Feld-Löschen/keine Migration.
2026-07-01
- Branch
claude/llm-cost-auto-deduction-o3pd0p(PR #294) — OP-OBS-1 / OP-LOG-1 Slice 1: Logs nach Grafana (Logger-Wrapper + OTLP-Export + Dashboards-as-Code) (Version 0.44.1 → 0.45.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): „Logs und Metriken in Grafana auswerten/visualisieren." Befund: OP-OBS-1 war bis dato nur Design — alle Laufzeitenconsole-basiert, kein OTLP-Export, keine Grafana-Instanz. Backend-Entscheidung (Nutzer 07-02): Grafana (löst die offene Wahl Grafana vs. Sentry); Cloud EU ↔ self-hosted LGTM dank OTLP code-frei umschaltbar. Gebaut (Slice 1, Worker/DO): (1) Logger-Wrapperserver/src/obs/logger.ts(OP-LOG-1) — strukturierte Events mitservice/version/build/trace_id, PII-Scrubbing (sensible Keys →[redacted], E-Mail-Maskierung, RISK-3), Level-Filter, child-Logger; Sinks: console (interim, deploy-sicher) + optional OTLP-Puffer. (2) OTLP/HTTP-Exportserver/src/obs/otlp.ts— dependency-freieresourceLogs-JSON-Payload + best-effort POST; nimmt jeder OTLP-Collector (Grafana Alloy/Cloud-Gateway). (3) DO-Verdrahtung — Logger (console + OTLP-Puffer nur wennOTEL_EXPORTER_OTLP_ENDPOINTgesetzt),flushObs()viactx.waitUntil(blockiert den Laufzeitpfad nicht); erste Adopter: Boot + Kosten-Pull-Pfade (roheconsole.logdort ersetzt). Dormant/deploy-sicher ohne Endpoint. (4) Dashboards-as-Codegrafana/dashboards/taktano-technik.json+grafana/README.md(Log-Volumen/Level, Fehler/Warnungen, Kosten-Pull-Ergebnisse, letzte Fehler); Metriken in Slice 1 aus Logs abgeleitet (LogQL), native OTLP-Metrics/Traces = Folge-Slices. (5) Env via GitHub-SecretsOTEL_EXPORTER_OTLP_ENDPOINT/OTEL_EXPORTER_OTLP_HEADERS/LOG_LEVEL(CI-deploy-Sync);wrangler.toml-Doku. Scope-Leitplanke: Grafana = technische Telemetrie; die fachlichen True-North-Dashboards bleiben in der App. Verifikation: neuer Self-Testtest:obs(Scrubbing/Level/child/Sink-Isolation + OTLP-Payload/severity/ns/KeyValue + best-effort-POST) grün (in CI verdrahtet) + Servertsc --noEmitgrün + Dashboard-JSON valide. Aktivierung (Pre-Prod, OP-OBS-1): Grafana-Instanz +OTEL_*-Secrets setzen → Export geht live. Offene Folge-Slices: Client (Faro/RUM), Python-Solver, native Metrics+Traces, Rest-console-Migration, Backend-Fixierung Cloud-EU-vs-self-host. Doku:docs/architektur/Observability.md(§6a + Env-Vertrag + Status),grafana/README.md,wrangler.toml,ci.yml, HANDOFF (§4 OP-OBS-1), CHANGELOG, Timesheet. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#291) — OP-DOCS-2: Doku-Widget auf docs.taktano.com (Assistent-Frontend Nr. 2) + CORS + Frontend-Werkzeug-Gate (Version 0.44.0 → 0.45.0 MINOR — neues Feature/Frontend; Build auto). Auftrag (Nutzer): das parked Doku-Widget bauen — dasselbe Assistent-/Feedback-Backend als Widget auf der Doku-Seite („ein Kern, mehrere Frontends"). Entscheidungen (Nutzer): docs.taktano.com ist intern-only (Access-gegated); Widget-Umfang Doku-Q&A + Feedback (keine Live-/Betriebsdaten übers Doku-Frontend). Gebaut: (1) CORS (App-Worker) — reiner Helferserver/src/http/cors.ts(parseCorsAllowlist/corsErlaubt/corsHeaders; spiegelt den konkreten Origin, nie*mit credentials; Self-Testtest:corsin CI). Im Worker-fetch: OPTIONS-Preflight vor dem Access-JWT-Check beantwortet (Preflight trägt kein Cookie → sonst 401), CORS-Header viamitCorsauf/parties/…- (Assistent/Feedback) +/api/feedback/screenshot-Antworten. Neue EnvASSISTENT_CORS_ORIGINS(wrangler.toml; leer ⇒ kein Cross-Origin, Same-Origin-App unberührt). (2) Doku-Frontend = beschränkter Werkzeugsatz — derselbe Origin-Allowlist-Treffer markiert im DO (leitstand.tsonRequest) das Doku-Frontend →fuehreDialogerhältwerkzeugFilter: ['dokuSuche','datenmodell'](keindatenListe/issueSuche/auslastung/…) + System-Zusatz;handler.tsfiltert die dem LLM angebotenenTOOL_DEFS.internbleibttrue(staff-only → volle Doku-Sicht). (3) Widget (Docs-Site) — SSR-sicheres Vanilla-Client-Moduldocs-site/src/clientModules/assistentWidget.js(schwebender Button → Panel mit Tabs Doku-Frage→/assistantund Feedback→/feedback,credentials:'include', minimales sicheres Text-Rendering), App-Origin via<meta name="taktano-app-origin">(headTags +customFields.appOrigin, override perTAKTANO_APP_ORIGIN), Styling über Infima-Variablen (custom.css, kein--tk-*); dormant-/fehlersicher (503/Netz → Hinweis). Entscheidungen: eine Origin-Allowlist steuert CORS + Werkzeug-Gate (eine Quelle); Doku-Frontend nie mit Live-Daten (OP-DOCS-5/OP-FEEDBACK-2). ⚠ Infra-Voraussetzung (dokumentiert, nicht Code): docs + app sind getrennte Origins → dasCF_Authorization-Cookie trägt nur mit einer Access-App über*.taktano.com; heute Access-Vars leer (Edge-only) → Fetch klappt mit CORS, beim Scharfschalten (OP-COST-3) gemeinsame App nötig. Verifikation:typecheck+test:cors+test:assistant-tools(Doku-Modus → nurdokuSuche+datenmodellerreichen das LLM; App-Modus → alle 10) +docs-sitenpm run build(Modul SSR-sicher) grün. Doku:In-App-Assistent.md§9 (Slice 11) + §6, CHANGELOG, Timesheet. Mergemain(nach #289/#290, OP-COST-2): nurversion.ts-Konflikt (0.44.1 vs. 0.45.0 → 0.45.0). CodeRabbit-Review-Fixes (#291): (a)mitCorsüberspringt WebSocket-Upgrades (status === 101unverändert zurückgeben — Rekonstruktion verlöre die Upgrade-Metadaten; latent, da nur der Doku-Origin gelistet ist); (b) CORS auch auf den Fehler-Pfaden von/api/feedback/screenshot(503/415/400/413) — sonst opaker Netzfehler statt echter Meldung; (c)normalisiereOrigin-Helfer incors.ts(Dedupe); (d)docusaurus.config.js:TAKTANO_APP_ORIGIN/TAKTANO_ROOMals je eine Konstante +<meta>; (e) Widget liest Room (wie App-Origin) aus<meta name="taktano-room">(Preview/Staging-override-bar); (f) PR-Links in CHANGELOG/Timesheet. - Root-
CLAUDE.md(#291) — Neues Leitprinzip „Einfachheit (geringste Komplexität)" (Nutzer-Vorgabe): immer die einfachste tragfähige Lösung in Code, Technik, UI und UX wählen (kleinste sinnvolle Änderung · Wiederverwendung statt Neuerfindung · YAGNI · keine ungefragten Refactorings · vorhandene Bausteine statt neuer Dienste · wenige klare Schritte). Guiding Principle, kein Code-Change. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#288) — OP-FEEDBACK-1: Screenshot-Feedback mit Bild-Schutz + nummerierten Markierungen (PR-B) (Version 0.43.0 → 0.44.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): den Screenshot-Feedback-Fluss auf Basis des in PR-A gebauten Markierungs-Layers fertigstellen (Region aufnehmen → Bild-Schutz → nummerierte Markierungen → ans Issue). Gebaut: (1) Aufnahme (Client) —services/screenshot.service.ts(Regions-Auswahl-State + lazyhtml2canvas-Import → eigener 38-kB-Chunk; rendert die Seite, schneidet auf die gezogene Region zu,ignoreElementsüberdata-tk-screenshot-ignore) +leitstand/screenshot-region-overlay.component.ts(Ziehen-zum-Auswählen-Overlay, inshell.component.tsgemountet). (2) Immer Bild-Schutz + Markierungen — das Feedback-Formular (feedback-form.component.ts) bettetapp-bild-upload-gate [bildQuelle]mit dem aufgenommenen Bild ein (Gate aus PR-A: Qualität/PII-Verpixeln/NSFW + „① Punkt markieren"); auffreigegeben {blob, markierungen}lädt der Client das geschützte + annotierte Bild hoch. (3) Transport (Server) — neuer Outer-Fetch-Zweig/api/feedback/screenshot(leitstand.ts): POST Bild-Bytes →FOTOS-Bucket-Keyfeedback/<uuid>→{ r2Key }; dormant → 503 ohneFOTOS-Binding (Feedback filet weiter als Text); Client-HelferFeedbackService.ladeScreenshotHoch. (4) Ans Issue —FeedbackAnfrage(+ Client-Spiegel) trägtscreenshotKey?+markierungen?; der/feedback-Handler validiert den Key (^feedback/…) und baut den Access-gated Link ausurl.origin;feedbackZuIssue(feedback.ts) hängt eine „Screenshot (intern, Access-gated)"-Sektion + die nummerierten Markierungen (als Bullet-Liste) an den Issue-Body. Entscheidungen: Aufnahme via html2canvas (lazy,allowedCommonJsDependencies); Bild im bestehenden EU-FOTOS-Bucket, Link Access-gated (intern; Kunden-Sichtbarkeit = OP-FEEDBACK-2). Verifikation:typecheck+test:assistant-feedback(Screenshot-Link + Markierungs-Mapping) +test:bildgate+ng build --configuration production+ No-Hex grün. Doku:In-App-Assistent.md§9 (Slice 10) + §6,Bildbewertung.md,Lastenheft.md§11 OP-FEEDBACK-1 (gebaut) / OP-FEEDBACK-2 (offen), CHANGELOG, Timesheet. ➡ OP-FEEDBACK-1 vollständig (PR-A+PR-B). - Branch
claude/llm-cost-auto-deduction-o3pd0p(#290) — OP-COST-2: Auto-Pull-Buttons quittieren sichtbar (Fix „Buttons reagieren nicht") (Version 0.44.0 → 0.44.1 PATCH — UX-Fix; Build auto). Befund (Nutzer-Screenshot): Klick auf „↻ GitHub/Mistral/Anthropic ziehen" zeigte keine Reaktion. Ursache (kein Fehler, fehlendes Feedback): ohne gesetztes Provider-Secret ist der Pull dormant (No-op) und der Server gab dem Client keine Rückmeldung → „reagiert nicht" war von „erfolgreich" nicht unterscheidbar. Gebaut: der DO schickt der auslösenden Verbindung nach jedem Pull eininfraKosten.pull.result({dienst, ok, anzahl, grund?}, analogauftrag.create.result); der Client (leitstand.service.ts) hält es alsinfraKostenPullResult-Signal (mitseq), die Kosten-Seite quittiert per Toast: Klick → „⟳ wird gezogen …", dann Erfolg („N Posten aktualisiert"), aktuell („keine Änderung") oder dormant/Fehler mit echtem Grund (z. B. „MISTRAL_ADMIN_KEY nicht gesetzt (dormant)", „HTTP 401"); Offline (nur Ansicht) → sofortiger Hinweis statt stiller Verwerfung. Effekt: die Buttons reagieren jetzt immer sichtbar und sind selbst-diagnostizierend (zeigen, dass nur noch der Admin-Key fehlt). Review-Fix (CodeRabbit): Teil-Erfolg ehrlich behandeln — der Mistral-Pull zieht 2 Monate; gelingt einer (anzahl>0) und scheitert der andere, quittiert der Toast jetzt „N Posten aktualisiert" (Warn-Ton + Grund) statt irreführend „nicht gezogen" (Client wertetanzahl>0unabhängig vonok). Verifikation: Servertsc --noEmit+ng buildgrün. Doku:costs.component.ts,leitstand.service.ts,server/party/leitstand.ts, CHANGELOG, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(#289) — OP-COST-2: Mistral (realer Anbieter) — ECHTE LLM-Kosten über die Admin-Usage-API ziehen (Version 0.43.0 → 0.44.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): „Checke die Mistral-API und nutze dort die tatsächlichen Kosten." Befund: Der In-App-Assistent läuft real über Mistral (EU), nicht Anthropic. Mistrals offizielles SDK exponiert keinen Usage-/Billing-Endpoint, aber es gibt eine Admin-(Beta-)API mit den echten Kosten (Nutzer-Screenshot verifiziert):GET https://console.mistral.ai/api/admin/usage?month=M&year=YmitAuthorization: Bearer <ADMIN_API_KEY>(Admin-Key ≠ASSISTENT_LLM_KEY), liefert Usage und Kosten je Modell/Zeitraum. Gebaut: pureserver/src/kosten/mistral-billing.ts(mistralUsageZuPosten/mistralUsageUrl) → ein Monatsposten „Mistral (LLM)" mit den tatsächlichen Beträgen der API (nicht Token×Listenpreis),quelle:'api'/quelleRef=mistral:YYYY-MM(idempotenter Upsert). DOpullMistralKosten()zieht laufenden + Vormonat (Monatswechsel-sicher), dormant/deploy-sicher ohne SecretMISTRAL_ADMIN_KEY; AktioninfraKosten.pullMistral(admin-gegated) + Button „↻ Mistral ziehen" (der bisherige generische LLM-Button ist jetzt „↻ Anthropic ziehen"); Pull = OP-AUDIT-1-Event; „zuletzt erfolgreich gezogen"-Stempel wie GitHub/Anthropic. Key via GitHub-Actions-SecretMISTRAL_ADMIN_KEY(CI-deploy-Job spiegelt es viawrangler secret put, Everything-as-Code). Schema-Unsicherheit (bewusst, ehrlich): Die Beta-Console-API ist öffentlich nicht dokumentiert (docs.mistral.ai bot-blockiert, SDK ohne Route) → der Kosten-Extraktor ist defensiv (explizites Gesamt-Kostenfeld bevorzugt, sonst Summe der Posten-Liste; Feldnamen/Einheit an EINER Stelle justierbar,MISTRAL_BETRAG_IN_CENTfür Cent-Antworten) und best-effort; nach dem ersten echten Pull Feld/Einheit einmalig verifizieren. Entscheidungen: echte API-Kosten statt Selbst-Messung Token×Preis (Nutzer-Vorgabe; Selbst-Messung verworfen, da die Admin-API die realen Kosten liefert); Anthropic-Pfad (Slice 2) bleibt parallel dormant nutzbar. Verifikation:test:kosten(Mistral-Mapper: beide Antwort-Formen, Cent-Einheit, URL-Bau, Leer/Kaputt) + Servertsc --noEmit+ng build+ No-Hex-Gate grün. Aktivierung = OP-COST-4: GitHub-SecretMISTRAL_ADMIN_KEY(Admin-Key) setzen. Doku:docs/architektur/Kosten.md(§4 + §11 Slice 3),wrangler.toml,ci.yml, HANDOFF (§4 OP-COST-2), CHANGELOG, Timesheet. - Branch
claude/llm-cost-auto-deduction-o3pd0p(#289) — OP-COST-2: LLM-API-Spend automatisch ziehen + „zuletzt erfolgreich gezogen"-Stempel je Auto-Pull-Komponente (Version 0.42.1 → 0.43.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): „Die LLM-Kosten sollen auch automatisch gezogen werden. Für jede automatisch gezogene Kosten-Komponente soll der Zeitstempel des letzten erfolgreichen Abholens dezent auch angezeigt werden." Gebaut: (1) Zweiter Auto-Pull-Provider analog GitHub (OP-COST-2): reine, I/O-freieserver/src/kosten/llm-billing.ts(llmCostZuPosten) bildet die Anthropic Usage-/Cost-API (/v1/organizations/cost_report,data[]-Zeitbucketsstarting_at+results[].amount/currency) je Monat auf einenInfraKostenPostenab (Dienst „Anthropic API (LLM)",quelle:'api',quelleRef=llm:YYYY-MM→ idempotenter Upsert), Beträge ganzzahlig in Cent, Betrag/Datum defensiv geparst (kaputt ⇒ 0/übersprungen). DOpullLlmKosten()dormant/deploy-sicher ohne SecretLLM_BILLING_KEY(Endpoint/Label perLLM_BILLING_URL/LLM_BILLING_DIENST[vars] überschreibbar, provider-flexibel); AktioninfraKosten.pullLlm(admin-gegated) + Button „↻ LLM ziehen"; Pull = OP-AUDIT-1-Event (infraKosten.pull, Actorllm-pull). Key-Bereitstellung wieASSISTENT_LLM_KEY: der CI-deploy-Job (.github/workflows/ci.yml) spiegelt das GitHub-Actions-SecretLLM_BILLING_KEYvorwrangler deployviawrangler secret putnach Cloudflare (Everything-as-Code; dormant-sicher übersprungen, wenn ungesetzt). (2) Zeitstempel des letzten erfolgreichen Abholens je Komponente: neuer persistierter FaktinfraKostenPull: Record<Dienst, epoch-ms>(State, schemaVersion 17→18, Merge-Default) — gesetzt bei jedem erfolgreichen HTTP-Abruf (auch ohne inhaltliche Änderung), auch für den bestehenden GitHub-Pull; im DTO alsletzterPullzum Client. Dezent angezeigt (costs.component.ts): Caption unter dem jeweiligen „↻ …ziehen"-Button (zuletzt: vor 3 Min/noch nie gezogen), Inline-Stempel jeAPI-Posten-Zeile und imAPI-Badge-Tooltip (relativ, ab 1 Tag absolut). Entscheidungen: Anthropic-Cost-API als LLM-Spend-Quelle (Doku-Vertrag §4; Endpoint/Label var-überschreibbar für den EU-/Mistral-Fall) · Stempel bei Erfolg (nicht nur bei Änderung), da „letztes erfolgreiches Abholen" · persistiert (Fakt, überlebt Reconnect) · Trigger interim on-demand (Cron-Automatik = Folge-Slice). Verifikation:test:kosten(LLM-Mapper: Monats-Aggregation, Idempotenz, Label/Währungs-Konfig, Betrag-Robustheit) +test:do-migrations(v0→v18) + Servertsc --noEmit+ng build+ No-Hex-Gate grün. Aktivierung = Pre-Prod-Requirement OP-COST-4: GitHub-Actions-SecretLLM_BILLING_KEYsetzen (CI-Sync nach Cloudflare). Doku:docs/architektur/Kosten.md(§4 + §11 Slice 2),wrangler.toml, HANDOFF (§4 OP-COST-2), CHANGELOG, Timesheet (taktano-2026-07-02-llm-cost-auto-deduction-o3pd0p).
2026-07-01
- Branch
claude/in-app-chatbot-feedback-vpv8ed(#286) — OP-FEEDBACK-1: Nummerierte Markierungen im Bild-Schutz (wiederverwendbar) (Version 0.42.2 → 0.43.0 MINOR — neues Feature; Build auto). Auftrag (Nutzer): die nummerierten Markierungen als Teil des allgemeinen Bild-Schutz-Features bauen (das kommende Screenshot-Feedback konsumiert sie; PR-A des 2-PR-Plans). Gebaut: (1) Reiner Kern (client/src/app/leitstand/bild/upload-gate.ts): TypMarkierung { nummer; xProzent; yProzent; notiz? }(Position prozentual → auflösungsunabhängig) + reine HelfermarkierungHinzufuegen/markierungEntfernen(lückenlose Re-Nummerierung ab 1) /markierungNotiz/markierungenText(Text fürs Feedback); vontest:bildgatemitgeprüft (Nummerierung/Clamp/Entfernen/Notiz/Reinheit). (2) Komponente (bild-upload-gate.component.ts): neuer Modus „① Punkt markieren" neben „✎ Bereich markieren" (schließen sich aus) — Tippen setzt einen nummerierten Pin (prozent-positionierte Vorschau-Kreise--tk-cyan), Liste mit optionaler Notiz + Entfernen. Beim Upload werden die Kreise auf eine Off-Screen-Kopie ins Bild eingebrannt (Canvasarc+fillText, Farben aus--tk-*viagetComputedStyle→ No-Hex-konform, idempotent). Neuer programmatischer EingangbildQuelle/ladeBlob(blob)(einbettbar, nicht nur Datei-Input); Ausgabe angereichert zufreigegeben: { blob; markierungen }. (3) Vorschau-Seite/bild-schutzkonsumiert die reichere Ausgabe (zeigt eingebrannte Markierungen als Text). Entscheidungen: eigenes Canvas (keine Annotation-Lib); Markierungs-Layer wiederverwendbar (nicht feedback-spezifisch); Einbrennen auf Off-Screen-Kopie (sichtbares Canvas bleibt sauber). Verifikation:test:bildgate+ng build --configuration production+ No-Hex grün. Doku:Bildbewertung.md§7 (Phase 1c),Lastenheft.md§11 OP-FEEDBACK-1 (Teil-gebaut), CHANGELOG, Timesheet. Offen (PR-B): Screenshot-Aufnahme (html2canvas) → Bild-Schutz+Markierungen → R2/D1-Eintrag. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#285) — OP-AI-4: Datenmodell-Grounding + Anti-Halluzinations-Regel (Assistent erfand Mitarbeiter/Fakten) (Version 0.42.1 → 0.42.2 PATCH — Accuracy-Bugfix; Build auto). Befund (Nutzer): Der Assistent (a) sollte die Wertebereiche/Ober-/Untergrenzen des Datenmodells kennen und (b) erfand Mitarbeiter und andere Fakten, statt nur echte Werkzeug-Daten zu nennen. Gebaut: (1) neuer Datenmodell-Steckbriefserver/src/assistant/datenmodell.ts(DATENMODELL: EnumFakt[]= verbindliche Skalen/Enums: Skill-Niveau/Vertrauensstufe/Güteklasse/Anspruch 1–3, Auftrag-Status-Lifecycle, Teilschritt-/Mitarbeiter-Status, fachliche Phasen, Abhängigkeit, Schicht-Art, Leistung-Status — synchron zumodel/types.ts+operativ/auftrag.ts, OP-DOCS-9), plusdatenmodellPrompt()/datenmodellText(). (2) System-Prompt (handler.ts) injiziert den Steckbrief immer (grounded) + zwei feste Regeln: „ERFINDE NIEMALS Fakten — nenne Mitarbeiter/Namen/Aufträge/Zahlen/Status nur, wenn ein Werkzeug sie geliefert hat; sonst ehrlich ‚keine Daten' sagen" und „halte dich strikt an die Wertebereiche (kein Niveau 4/5, Skala 1–3)"; die frühere Einzeiler-Niveau-Regel (#282) ist darin aufgegangen. (3) neues read-only Tooldatenmodell(Registrytools.ts9 → 10 Werkzeuge, gebunden inleitstand.ts) für Schema-/Wertebereichs-Fragen. Verifikation:typecheck+test:assistant-toolsgrün (10 Werkzeuge · Dispatchdatenmodell→„1–3" · System-Prompt enthält „ERFINDE NIEMALS" + Skill-Niveau-Skala). Doku:In-App-Assistent.md, CHANGELOG, Timesheet. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#282) — OP-AI-4: Skill-Niveau-Skala grounden (Assistent erfand Niveau 4) (Version 0.42.0 → 0.42.1 PATCH — Accuracy-Bugfix; Build auto). Befund (Nutzer-Screenshot): Der Assistent listete korrekt Mitarbeiter mit „Niveau 3", behauptete dann aber „keine mit höchstem Niveau (4)" und schlug „Schulung auf Niveau 4" vor —SkillNiveauist aber 1–3 (server/src/model/types.ts, „Sterne", 3 = höchste). Ursache:datenListegab(N3)ohne Skala aus → das LLM riet die Obergrenze. Fix: (a)datenListeText(Mitarbeiter) zeigt die Skala explizit als Sterne + „(n/3)" (z. B.Keramikversiegelung ★★★ (3/3)); (b) System-Prompt (handler.ts): Skill-Niveau ist 1–3, 3 ist das Höchste, keine höheren Stufen erfinden. Verifikation:typecheck+test:assistant-toolsgrün. Doku: CHANGELOG, Timesheet. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#281) — OP-DOCS-7 / OP-AI-4: Duplikat-Erkennung · Assistent liest Issues + Live-Listen · Erfolgs-Quittung (Version 0.41.4 → 0.42.0 MINOR — neue Features; Build auto). Auftrag (Nutzer): (1) Erfolgsmeldung bei angelegtem Issue, (2) beim Feedback nach offenen OPs+Issues suchen (Duplikate vermeiden), (3) OP für spätere Kunden-Sichtbarkeit aufnehmen, (4) Assistent soll auf Issues zugreifen, (5) Assistent soll konkrete Listen-/Daten-Fragen beantworten (nur Bedienungshinweise, wenn Daten zu groß / explizit gefragt). Gebaut: (a) reineserver/src/assistant/github-issues.ts(Suchterme, Such-Pfad GitHub-Search-API, Antwort-Mapping) + DOsucheOffeneIssues(dormant ohneTAKTANO_FEEDBACK_TOKEN). (b)/feedback/aehnliche-Endpoint → ähnliche offene Issues + OPs (OPs viakeywordSucheüber Lastenheft/Register/IDs); Client zeigt „Ähnliche offene Einträge", Nutzer bestätigt „Trotzdem anlegen" (warn+confirm). (c) neue Assistent-ToolsissueSuche(Issues nachschlagen/Duplikate vermeiden) +datenListe(Mitarbeiter/Aufträge/Skills/Leistungen/Buchten aus dem Live-State, gefiltert, gekappt); System-Prompt: Daten-Fragen mit echten Daten beantworten (behebt „kein Zugriff auf Live-Daten"). (d) Erfolgs-Toast „Issue #N". (e) OP-FEEDBACK-2 (Kunden-Sichtbarkeit einschränken, HANDOFF §4). Verifikation:typecheck+test:assistant-tools|-feedback|-retrieval(9 Werkzeuge, Issue-Such-Mapping) +ng build+ No-Hex grün. Doku:In-App-Assistent.md§9 (Slice 8), HANDOFF §4, CHANGELOG, Timesheet. Noch offen (nächster PR): Screenshot-Feedback mit Bild-Schutz + nummerierten Markierungen (OP-FEEDBACK-1). - Branch
claude/in-app-chatbot-feedback-vpv8ed(#278) — OP-DOCS-7: Feedback-Fehler sichtbar machen (Version 0.41.3 → 0.41.4 PATCH — Bugfix; Build auto). Befund (Nutzer): Bei einem Fehler beim Feedback-Senden wurde der Fehler nicht angezeigt. Ursache: Das Feedback-Formular ist ein Vollbild-Scrim (z-50) und liegt in der DOM-Reihenfolge nachapp-toasts(auchz-50) → der Fehler-Toast wurde hinter dem Formular gerendert (bei Erfolg schließt das Formular, daher war nur der Erfolgs-Toast sichtbar); zudem kappte der Toast-sub(truncate) lange Gründe. Gebaut: Fehler wird jetzt inline im Formular angezeigt (FeedbackService.fehler-Signal → Danger-Banner infeedback-form.component.ts, voller Text, Status-Tokens wierepark-modal), Formular bleibt offen für Retry; Erfolg quittiert weiter per Toast. Zusätzlich Toast-Container aufz-[70]gehoben (Toasts liegen generell über Modals — hilft auchrepark-modal). Verifikation:ng build --configuration production+ No-Hex grün. Doku: CHANGELOG, Timesheet. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#275) — OP-DOCS-7: deterministischer Feedback-Pfad (Fix „kein Issue") (Version 0.41.2 → 0.41.3 PATCH — Bugfix; Build auto). Befund (Nutzer): Element-Feedback legte kein GitHub-Issue an. Diagnose (Deploy-Log + D1): SecretsASSISTENT_LLM_KEY+TAKTANO_FEEDBACK_TOKENsind gesetzt, Issues aktiviert — die Ursache lag im Design: (1) das Anlegen hing davon ab, dass das LLM das ToolfeedbackAnlegenaufruft, und (2) API-Fehler wurden als „Feedback vermerkt" maskiert (403 = Erfolg nicht unterscheidbar). Entscheidung (Nutzer): GitHub-Issues beibehalten (nicht Discussions — REST/actionable). Gebaut: (a) Server — neuer DO-Endpoint/feedback(onRequest, kein LLM, deterministisch); Issue-Erstellung inerstelleFeedbackIssue(): FeedbackErgebnisextrahiert, liefert ehrlich{ ok, issueUrl?, status?, grund? }; LLM-Tool nutzt denselben Kern + gibt echte Fehler zurück; reinerfeedbackFehlerGrund-Mapper (test:assistant-feedbackerweitert); Audit-Event bleibt. (b) Client —feedback.service.tsPOSTet direkt/feedback, ehrliche Toasts (Erfolg mit Issue-Bezug / Fehler mit echtem Grund, z. B. „HTTP 403 — Token-Scope"); neuesfeedback-form.component.ts(Art-Chips + Text), der 📍-Pin öffnet es statt des Chats; toter LLM-Feedback-Pfad inchat.service.tsentfernt. Effekt: Anlegen ist deterministisch, Konfig-Fehler sind selbst-diagnostizierend. Verifikation:typecheck+test:assistant-*+ng build+ No-Hex grün. Doku:In-App-Assistent.md§9 (Slice 7), CHANGELOG, Timesheet. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#274) — OP-AI-4: Assistent-Antworten als Markdown rendern (Version 0.41.1 → 0.41.2 PATCH — UI-Fix; Build auto). Befund (Nutzer-Screenshot): Der Chat zeigte rohes Markdown (**,###,-) als Klartext — das Panel interpolierte den Text nur ({{ }}). Gebaut: kleiner, abhängigkeitsfreier Markdown→HTML-Rendererclient/src/app/services/markdown.ts(Überschriften, fett/kursiv/Inline-Code, geordnete/ungeordnete Listen, Absätze) — HTML wird zuerst escaped (kein Roh-HTML aus der LLM-Antwort), Ausgabe zusätzlich über Angulars[innerHTML]-Sanitizer gebunden (Defense-in-Depth, XSS-geprüft). Pure Pipemarkdown.pipe.ts(memoisiert);chat-panel.component.tsrendert Assistent-Antworten via[innerHTML], Nutzer-Nachrichten bleiben Klartext. Styles über Tokens (::ng-deep .tk-md, No-Hex-Gate grün). Entscheidung: eigener Mini-Renderer stattmarked-Lib (Bundle-Budget + kleinere XSS-Fläche). Verifikation:ng build --configuration productiongrün · Renderer-Ausgabe + XSS-Escaping manuell geprüft. Doku: CHANGELOG, Timesheet. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#273) — Doku-Nachzug: CodeRabbit-Review zu #272 (Doku/Kommentar-only, kein Bump). Drei ASSERTIVE-Findings adressiert: „PR folgt"-Platzhalter inCHANGELOG.md+Timesheet.md→ konkrete Referenz #272 (Traceability);wrangler.toml-Kommentar präzisiert (nur leereGITHUB_FEEDBACK_ORG/REPOfallen aufBILLINGzurück — der Token selbst hat keinen Fallback, ohne ihn bleibt Feedback dormant). CodeRabbit schlug fälschlich#271vor (die Vorgänger-PR); korrekt ist #272. - Branch
claude/in-app-chatbot-feedback-vpv8ed(#272) — OP-AI-4: Feedback-Token-Rename + CI-Secret-Sync (Version 0.41.0 → 0.41.1 PATCH — Config/CI, keine neue Funktion; Build auto). Auftrag (Nutzer): „RenameGITHUB_FEEDBACK_TOKEN→TAKTANO_FEEDBACK_TOKEN; API-Keys sind in GitHub-Secrets gesetzt, aus dort ziehen." Gebaut: (1) Worker-SecretGITHUB_FEEDBACK_TOKEN→TAKTANO_FEEDBACK_TOKENumbenannt (server/party/leitstand.tsEnv+feedbackAnlegen,wrangler.toml) — Grund: GitHub-Actions-Secrets dürfen keinGITHUB_-Präfix tragen (reserviert).GITHUB_FEEDBACK_ORG/_REPObleiben (sind[vars], kein Secret). (2) CI-deploy-Job (.github/workflows/ci.yml) spiegeltASSISTENT_LLM_KEY+TAKTANO_FEEDBACK_TOKENaus gleichnamigen GitHub-Secrets viawrangler secret put(stdin, non-interaktiv) vorwrangler deploynach Cloudflare — dormant-sicher (nicht gesetzt → übersprungen, Deploy bricht nicht). Kein neuer Token-Scope nötig (bestehendesCLOUDFLARE_API_TOKENmit „Edit Workers"). Entscheidung: CI-verwaltete Secret-Sync (Everything-as-Code) statt einmaligem CLI-secret put— Nutzer-Wunsch. Verifikation:npm run typecheckgrün ·test:assistant-*grün ·ci.ymlYAML valide. Doku:In-App-Assistent.md(§9 Aktivierung), CHANGELOG, Timesheet (2026-07-01-in-app-chatbot-feedback-vpv8ed-2). - Branch
claude/in-app-chatbot-feedback-vpv8ed(#271) — OP-AI-4 / OP-DOCS-2/-7: In-App-Assistent (Chatbot + Feedback), Slices 4–6 (Version 0.40.2 → 0.41.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): „Ein Chatbot in der App, der Fragen zur App + zu den Daten beantwortet und Feedback zu konkreten Elementen aufnimmt; dasselbe später in der Doku." Entscheidungen (Nutzer 07-01): App-first (Doku-Widget als Folge-PR) · EU-gehostetes LLM (DSGVO-Residenz) · RAG-Retrieval (Cloudflare Vectorize, mit Keyword-Fallback) · Feedback → GitHub-Issue. Gebaut (auf den bereits gebauten read-only Insights-Slices 1–3): (1) Reine, testbare Server-Kerne (server/src/assistant/):retrieval.ts(Keyword-Ranking + Berechtigungsfilter + Vectorize-Ranking),doku-index.generated.tsausdocs/**/*.md(scripts/build-doku-index.mjs, 458 Chunks),llm.ts(EU-OpenAI-kompatibler Client hinterLlmClient-Interface → Fake-testbar),tools.ts(7 Werkzeuge, 1:1 auf bestehende Funktionen),handler.ts(System-Prompt → Tool-Schleife → Antwort, Rundenlimit),feedback.ts(reiner Feedback→Issue-Mapper). (2) DO-Endpoint/assistant(leitstand.tsonRequest, am Live-State/Engine, §4): Tools binden aninsights.ts,konfliktHebel(nur Simulation, kein Auto-Apply, §3) und Doku-Suche; dormant ohneASSISTENT_LLM_KEY(503, deploy-sicher); Feedback→Issue dormant ohneGITHUB_FEEDBACK_TOKEN+ Audit-Eventassistent.feedback. (3) Angular (shell.component.ts):chat.service.ts(signals, POST same-origin ⇒ Access-Cookie, Route/Workspace-Kontext),chat-panel.component.ts(Drawer rechts, Tokens statt Hex),feedback-pin.service.ts+feedback-pin-overlay.component.ts(Capture-Klick → Element-Anker →feedbackAnlegen). Config:wrangler.toml(ASSISTENT_LLM_/GITHUB_FEEDBACK_/Vectorize dormant),Env-Felder. Verifikation:npm run typecheckgrün · neue Self-Teststest:assistant-retrieval|-tools|-feedbackgrün (in CI verdrahtet) ·ng build --configuration production+ No-Hex grün. Compliance/Risiko:Compliance.mdC-17 (LLM EU-Datenverarbeitung) + C-10 (AVV),Risikoregister.mdRISK-10 (Prompt-Injection, Härtung) + RISK-15 (EU-LLM-Datenfluss). Doku:docs/architektur/In-App-Assistent.md(§8 Entscheidungen, §9 Slices 4–6), HANDOFF (§4 OP-AI-4), CHANGELOG, Timesheet (2026-07-01-in-app-chatbot-feedback-vpv8ed). - Branch
claude/op-liste-doc-hyperlinks-7e3s6o(#267) — OP-Listen tragen klickbare OP-ID-Sprünge (Direkt-Navigation) (Doku-only, kein Bump; Build auto, OP-PM-2). Auftrag (Nutzer): „Die OP-Liste in der Doku soll immer Hyperlinks zum direkten Sprung dorthin enthalten." Gebaut (nur Doku): (1) In den beiden kuratierten OP-Navigations-Indizes —Register.md§1 (Navigations-Index) +IDs.md(Reverse-Lookup) — ist jede OP-ID jetzt selbst ein Sprung-Link an ihr Zuhause: Owning-Doc, sonst der passende Lastenheft-§11-Anker bzw.HANDOFF.md§4. (2) Dafür stabile explizite Heading-Anker ergänzt:docs/fachlich/Lastenheft.md§11.1–§11.10 ({#11-1-auftraege}…{#11-10-tests-qs}) undHANDOFF.md§4 ({#op-parked}). (3) Als verbindliche Konvention verankert (damit „immer"):agents.md§2 Punkt 5 (OP-Listen tragen klickbare OP-ID-Sprünge) + Pflege-Notizen in Register.md/IDs.md. Entscheidung: Link-Ziel je OP = Detail-Quelle (Owning-Doc, wo vorhanden; sonst fachliche Master-Spec Lastenheft §11; rein-geparkte OPs → HANDOFF §4) — reine Wiederverwendung bereits dokumentierter, verifizierter Ziele, keine erfundenen Anker. Folge-Ausbau (gleiche Session, „1 und 2"): (4) Per-OP-Präzision — jede führende OP-ID in Lastenheft §11 (80 OPs) und HANDOFF §4 (145 OPs) trägt nun einen eigenen<a id="op-<id>">-Anker; (5) die volle OP-Liste HANDOFF §4 verlinkt jede führende OP-ID auf ihre Detail-Quelle (Owning-Doc / Lastenheft-#op-<id>/ Selbst-Permalink); (6) die Register-Indizes springen für Einzel-OPs jetzt exakt auf#op-<id>(Familien-Zeilen weiter auf §11-Sektion). Transformation skriptgestützt + validiert (Anker eindeutig, alle internen Links auflösbar; nur echte Multi-OP-SammelzeilenOP-R7-1..9/OP-AUTH-1/2bewusst ausgelassen). Kein Code-/Schema-/Solver-Change. Doku: Lastenheft §11 (Sektions- + per-OP-Anker), HANDOFF §4 (Anker + OP-ID-Links), Register.md, IDs.md, agents.md §2.5, CHANGELOG, Timesheet (2026-07-01-op-liste-doc-hyperlinks-7e3s6o). - Branch
claude/coderabbit-config(PR folgt) — OP-DEVTOOL-1: versionierte.coderabbit.yaml(Review-Tiefe schärfen) (kein Versions-Bump — reine Dev-Tooling-Config, kein App-Change). Auftrag (Nutzer): „Wie kann CodeRabbit einen detaillierten Review durchführen, nicht nur Summary?" + Entscheidung „Nur CodeRabbit schärfen" (kein zusätzlicher GitHub-Copilot-Review). Befund: Review-Config lag bisher nur im CodeRabbit-Dashboard („Configuration used: Organization UI", Profilchill) → Verstoß gegen Everything-as-Code; die Detail-Findings kommen ohnehin (nach der Summary), aber Profilchill= bewusst wenige. Gebaut: neue.coderabbit.yamlim Repo-Root —reviews.profile: assertive(deutlich detailliertere Zeilen-Reviews),high_level_summary/review_status: true,auto_review.enabled: true,request_changes_workflow: false(CodeRabbit kommentiert, blockt nicht — Merge-Gate bleibt der aggregierte „CI Gate"),path_instructionsje Bereich (server/party/**→ DO-State/Migrationen/Idempotenz/Ownership;client/src/app/**→ Signals/Leak-Freiheit/No-Hex/Service-Zugriff;docs/**→ pyramidal/widerspruchsfrei/PR-Link). Entscheidung/Abwägung: kein Copilot-Review (Redundanz zu CodeRabbit + zweite externe Vendor-/DSGVO-Fläche; die Security-Achse ist via CodeQL Default Setup + Dependabot +security-auditbereits abgedeckt). Bewusst NICHT: CodeRabbit-als-MCP-Client (Richtung 1, Review-Kontext) — bleibt offener OP; optional Review-Sprache Deutsch. Verifikation: YAML valide; No-Hex/Doku-Konsistenz unberührt; nächster CodeRabbit-Lauf fährt mitassertive. Doku: HANDOFF (§4 OP-DEVTOOL-1 Schritt (i) ✅), CHANGELOG, Timesheet (2026-07-01-coderabbit-config). - Branch
claude/foto-varianten-3(PR #265) — OP-R4-1: drei Bild-Varianten (Thumbnail · verkleinert · Original), Thumbnail-priorisiert (Version 0.36.0 → 0.37.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): „immer 3 Varianten eines Bilds speichern: Original, verkleinert (~1024px) und Thumbnail; Thumbnails immer zuerst priorisiert bearbeiten/hochladen/runterladen." Gebaut: (1) Client-Aufbereitung (foto-kompression.ts): neueserzeugeFotoVarianten(file)dekodiert einmal (createImageBitmap, EXIF) und rendert thumb (256px, q0.70) · display (1024px, q0.82) · original (volle Auflösung = Datei); best-effort (kein Bild/Decode-Fehler → alle drei = Original). AlteskomprimiereFotoentfernt (Ersetzung). (2) Queue-Modell (offline-foto-queue.ts):FotoQueueEintraghält dreiFotoVarianteState(je eigeneuploaded/registered); reine MaschinenaechsterVariantenSchritt(v, connected)(upload→register→fertig/warten) +fotoEintragStatus(höchstpriorisierte offene Variante) +fotoEintragFertig(alle drei → löschen);FOTO_VARIANTEN_PRIO = [thumb,display,original]. (3) Drain (LeitstandService): iteriert Varianten AUSSEN, Einträge INNEN → Thumbnails aller wartenden Fotos zuerst, dann verkleinert, dann Original;putFoto(..., variante)+ WSfoto.variante; Ack-getriggert (fotoVarianteImStateprüftthumbR2Key/r2Key/originalR2Key). (4) Server (leitstand.ts):/api/foto/uploadakzeptiertvariante=thumb(Key-Pfadthumb/, Limit 5MB; display 15, original 30); neuer WS-Handlerfoto.variante= Upsert nachid(der zuerst eintreffende Thumbnail legt denFotoAttachmentan, weitere Varianten hängen an); DTO +FotoAttachment.thumbR2Key. Altefoto.registriert/foto.original-Handler bleiben (Back-Compat). (5) UI: Detail-Panel-Kacheln laden Thumbnail (thumbR2Key,loading=lazy), verkleinert beim Öffnen, Original via „HQ"; Popover zeigt Varianten-Status + FortschrittN/3. Migration:SCHEMA_VERSION 16 → 17(thumbR2Keyadditiv, kein Transform — fehlt ⇒ kein Thumbnail). Entscheidungen (Nutzer-bestätigt): Größen 256 / 1024 (Original voll); Download thumb-first, dann on-demand; Priorität absteigend Thumbnail → verkleinert → Original. Abwägung: ~3 R2-Objekte je Foto (Egress-Ersparnis beim Anzeigen via Thumbnails überwiegt; Original bleibt beweiskräftig). Review-Fixes (CodeRabbit, PR #265): (a) Drain bricht nach permanentem 4xx ab —abgebrochen-Set verhindert, dass weitere Varianten eines bereits als „nicht gespeichert" gemeldeten Fotos noch hochgeladen/registriert werden; (b) Server-Upsert mit Ownership-Guard —foto.variantehängt eine Variante nur an, wenn Auftrag/Instanz des Alt-Records übereinstimmen (schützt vor fotoId-Kollision/Replay-nach-Purge); (c) kein leeres Pflichtfeld — neu angelegterFotoAttachmentseedetr2Keymit der eintreffenden Variante statt""; (d) Kachel-Link-FallbackfotoUrl(foto.r2Key || foto.thumbR2Key || '')(öffnet nie einen leeren Key, solange Display aussteht); (e) CHANGELOG/Timesheet-PR-Link. Verifikation:test:fotoqueue(Varianten-Maschine + Priorität + Fertig-Kriterium) grün ·test:do-migrations(v0→v17) grün · Servertsc+operativgrün ·ng build+ No-Hex grün. Doku:docs/architektur/Offline-PWA.md(3-Varianten-Abschnitt), HANDOFF (§4), CHANGELOG, Timesheet (2026-07-01-foto-varianten-3). - Branch
claude/unused-skills-org-7r4k6l(PR #269) — OP-SKILL-1 Variante B: Skill-Pflege im Prozess-Editor (Skills „wandern" zu den Prozessen) (Version 0.38.0 → 0.39.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): „B" — die im Vor-Slice angebotene Variante B umsetzen (Skills dort pflegen, wo sie gebraucht werden). Gebaut: (Client) der Prozesse-Workspace (client/src/app/leitstand/pages/processes.component.ts) bietet je Teilschritt am „Geforderter Skill"-Picker zwei neue Aktionen: „+ neu" (Inline-Input → neuen Skill anlegen und sofort diesem Teilschritt zuweisen) und „✎ umbenennen" (benennt den aktuell geforderten Skill katalogweit um, viaupdateSkill); SignalsneuerSkillFuer/neuerSkillName, MethodenskillAnlegen/benenneSkillUm. (Service)createSkill(name, beschreibung?, teilschrittId?)reicht optional dieteilschrittIddurch. (Server) dieskill.create-Message trägt optionalteilschrittId; der Handler weist den (neu angelegten oder reaktivierten) Skill danach viasetzeSkillAnforderungdem Teilschritt zu (Mindest-Niveau/Personenzahl unverändert) — atomar in einem State-Broadcast, was die Race-Bedingung löst (die Skill-ID wird serverseitig generiert, der Client kann sie nicht vorher kennen). Entscheidungen: (a) atomar server-seitig (statt Client wartet auf neue ID + zweiter Message) — race-frei; (b) Katalog bleibt Single Source (kein zweiter Speicherort, kein Schema-Change); (c)skill.createbleibt ungegated + audit-frei wie die bestehenden Skill-Handler (Konsistenz; Härtung folgt mit OP-AUTH-1/OP-AUDIT-1). Verifikation: Servertsc --noEmit+test:prozessgrün ·ng buildgrün · No-Hex-Gate grün. Kein Solver-Redeploy, kein Schema-Change. Doku:processes.component.ts,leitstand.service.ts,server/party/leitstand.ts,server/src/version.ts,docs/fachlich/Lastenheft.md(§11.7 OP-SKILL-1 → Variante B ✅), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-unused-skills-org). Offen (C): Mitarbeiter-Sicht filtert verwaiste Skills. Bezug: OP-R3-3, OP-R1-3, OP-CRUD-1, OP-AUTH-1, OP-AUDIT-1, G-1, S-2. - Branch
claude/unused-skills-org-7r4k6l(PR #269) — OP-SKILL-1 Variante C: Mitarbeiter-Sicht priorisiert prozess-getragene Skills + CodeRabbit-Review-Fixes (Version 0.39.0 → 0.40.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): „C als gedimmt und nach unten sortiert inkl. Tooltip." Gebaut (Variante C, reiner Client-Pfad): an den beiden Skill-Auswahl-Pickern der Mitarbeiter-Sicht (Qualifikation hinzufügen · Ausbildungsziel,staff.component.ts) werden verwaiste Skills (in keinem Prozess/Teilschritt gefordert) ans Ende sortiert (verwaisteAnsEnde, stabil — prozess-getragene zuerst), gedimmt (--tk-text-faint) und mit Tooltip + Suffix „· in keinem Prozess" markiert; bewusst nicht ausgeblendet (Selbsterklärbarkeit — bleiben wählbar, nur nachrangig; bestehende Zuweisungen unberührt). Wiederverwendung vonistVerwaistaus Variante A (derived, kein Server/Schema). ➡ OP-SKILL-1 vollständig (A+B+C). CodeRabbit-Review-Fixes (PR #269, 4 Kommentare): (1) CHANGELOG doppelte## 2026-07-01-Überschrift → in die bestehende Sektion einsortiert (MD024); (2)neuerSkillNameleakte über Zeilen/Escape (Major) →toggleNeuerSkill/schliesseNeuerSkillleeren beide Signals synchron beim Öffnen/Wechseln/Schließen; (3)benenneSkillUmohne Namens-Eindeutigkeit → Duplikat-Check gegensvc.skills()vorupdateSkill(analog Anlegen/Server-Reaktivierung); (4) nativerautofocusunzuverlässig bei@if-Inputs → kleine standaloneAutofocusDirective(afterNextRender-Fokus). Verifikation: Servertsc+test:prozessgrün ·ng buildgrün · No-Hex-Gate grün. Kein Server/Solver/Schema/Token-Change (C ist rein Client; die Fixes ebenso). Doku:staff.component.ts,processes.component.ts,server/src/version.ts,docs/fachlich/Lastenheft.md(§11.7 OP-SKILL-1 → A+B+C ✅), HANDOFF (§4), Register, CHANGELOG, Timesheet (2026-06-29-unused-skills-org). Bezug: OP-R3-3, OP-R1-3, OP-R9-4/7, OP-CRUD-1, G-1, S-2. - Branch
claude/unused-skills-org-7r4k6l(PR #269) — CodeRabbit-Nachzug (Runde 3): Duplikat-Namens-Guard auch im Skill-Katalog-Dialog + Doku-Konsistenz (Version 0.40.0 → 0.40.1 PATCH — kleine Fixes; Build auto, OP-PM-2). (1)StaffComponent.benenneSkillUm(staff.component.ts, Skill-Katalog-Dialog) spiegelt jetzt den Duplikat-Namens-Check ausProcessesComponent.benenneSkillUm(kein zweiter Skill mit gleichem Label; bei Kollision Hinweis + Eingabe zurückgesetzt) — verhindert, dass der Katalog-Dialog die im Prozess-Editor blockierte Doppel-Label-Situation wieder erzeugt. (2) Doku-Konsistenz (Lastenheft.md§11.7): der veraltete „Zu klären"-Schwanz an der als A+B+C vollständig markierten OP-SKILL-1 (widersprach HANDOFF/CHANGELOG) → durch „Geklärt (durch A/B/C)" ersetzt (Anzeige-Ort/SoR/reservierte Skills beantwortet; offen bleibt nur die Stammdaten-Einzelfrageskill-ppfkonsolidieren vs. eigener PPF-Teilschritt). Verifikation:ng build+ No-Hex-Gate grün. Kein Server/Solver/Schema. Doku:staff.component.ts,docs/fachlich/Lastenheft.md§11.7,server/src/version.ts, CHANGELOG, Timesheet. - Branch
claude/unused-skills-org-7r4k6l(PR #269) — CodeRabbit-Nachzug (Runde 4): Katalog-Dialog Anlegen/Umbenennen gehärtet (Version 0.40.1 → 0.40.2 PATCH; Build auto, OP-PM-2). (1)legeSkillAn(Skill-Katalog-Dialog) warnt jetzt bei aktivem Namensgleichstand (Anlegen wäre ein No-Op, da der Server per Name dedupliziert) und bricht ab — bewusst nur bei aktiven Skills: ein deaktivierter gleichnamiger Skill wird weiterhin reaktiviert (dokumentiertes Feature „Reaktivieren statt Duplikat" imskill.create-Handler; CodeRabbits pauschaler Block hätte diese Reaktivierung gebrochen → bewusst abweichend umgesetzt). (2)benenneSkillUmsetzt bei leerem/unverändertem Namen das Eingabefeld auf den aktuellen Namen zurück (das[value]-Binding greift sonst nicht, Feld bliebe sichtbar leer). Verifikation:ng build+ No-Hex grün. Kein Server/Solver/Schema. Doku:staff.component.ts,server/src/version.ts, CHANGELOG, Timesheet.
2026-06-29
- Branch
claude/unused-skills-org-7r4k6l(PR #269) — OP-SKILL-1 Variante A: verwaiste Skills im Katalog markieren (Version 0.34.0 → 0.35.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): „Zeige mir Skills, die in keinem Prozess vorkommen" → kleinster Schnitt (Variante A) umgesetzt. Gebaut (reiner Client-Pfad): der Skill-Katalog-Dialog (client/src/app/leitstand/pages/staff.component.ts) markiert jeden Skill, den kein Teilschritt fordert, mit Badge „⚠ in keinem Prozess verwendet" + Kopf-Hinweis mit Zähler („N Skill(s) in keinem Prozess verwendet — … einem Teilschritt zuweisen oder deaktivieren"). Abgeleitet, nichts gespeichert (S-2):verwendeteSkillIds=computed-Set übersvc.teilschritteKatalog().map(t => t.benoetigteSkillId);istVerwaist(id)= nicht im Set;verwaisteAnzahl=computed-Zähler. Design: Amber (Hinweis/Achtung) via--tk-amber+color-mix, nicht Rot (Rot bleibt echten Warnungen/Klärfall vorbehalten, Design-G); kein Hardcoded-Hex (No-Hex-Gate grün). Verifikation:ng buildgrün · No-Hex-Gate grün. Kein Server/Solver/Schema/Token-Change. Entscheidung: verwaist ist abgeleitet (nicht persistiert) und ≠ inaktiv (einaktiv:true-Skill kann verwaist sein); die Sicht schlägt vor, archiviert/löscht nicht (Propose-not-execute, OP-CRUD-1 Klasse A). Offen (Folge-Slices): B = Skill-Pflege im Prozess-Editor · C = Mitarbeiter-Sicht filtert verwaiste. Doku:staff.component.ts,server/src/version.ts,docs/fachlich/Lastenheft.md(§11.7 OP-SKILL-1 → Variante A ✅), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-unused-skills-org). Bezug: OP-R3-3, OP-R1-3, OP-R1-6, OP-CRUD-1, OP-R3-1, G-1, S-2. - Branch
claude/unused-skills-org-7r4k6l(PR #269, reine Doku/OP-Capture) — OP-SKILL-1 + OP-R1-6 neu festgehalten (kein Bump, Doku-only). Auftrag (Nutzer, 2 Eingaben + Screenshot): (1) „Zeige mir Skills, die in keinem Prozess vorkommen — die Skills sollten zu den Prozessen/Teilschritten wandern, da passt es besser (und macht die Mitarbeiter-Sicht leichter)." (2) „Mitarbeiter-Seite für 10–50 Mitarbeiter optimieren — erst verschiedene Konzepte entwickeln und vergleichen, dann umsetzen." Erfasst (kein Code): OP-SKILL-1 — Befund verifiziert: Skill-Katalog ist Separat-Liste (7 Skills,vest-automotive.ts), Teilschritt referenziert genau einen Skill (benoetigteSkillId, F11); 5 von 7 verwendet, verwaist =skill-ppf+skill-klaerung(in keinem Teilschritt). Zwei Aspekte: (1) verwaiste Skills als abgeleiteten Hinweis sichtbar (derived, S-2; verwaist ≠ inaktiv), (2) Skills im Prozess-Editor verankern → schlankere Mitarbeiter-Sicht. Optionen A (Diagnose-Badge) / B (Pflege im Prozess-Editor) / C (Mitarbeiter-Sicht filtert). Bewusste Sonderfälle:skill-klaerungfür OP-R3-1 reserviert,skill-ppf= Variante vonskill-folie. Propose-not-execute (Klasse A, OP-CRUD-1). OP-R1-6 — Mitarbeiter-Seite (staff.component.ts, Karten je MA) skaliert nicht auf 10–50 MA; zweistufiges Vorgehen (Nutzer-Vorgabe): erst 2–3 Konzepte (Matrix/Heatmap · Tabelle+Filter+Detail-Panel · virtualisiertes Karten-Grid · Gruppierung) als Mockup vergleichen (Übersicht·Pflege·True North·Aufwand), dann bauen. Status: Konzeptphase. Doku:docs/fachlich/Lastenheft.md(§11.7 OP-SKILL-1, §11.3 OP-R1-6), HANDOFF (§4),docs/konventionen/Register.md, CHANGELOG, Timesheet (2026-06-29-unused-skills-org). Bezug: OP-R3-3, OP-R1-3, OP-R9-4/7/8, OP-CRUD-1, OP-R3-1, G-1, S-2. - Branch
claude/offline-foto-queue(PR #264) — OP-OFFLINE-1 Stufe C: verzögerter Foto-Upload (Offline-Queue) (Version 0.35.2 → 0.36.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): „Stufe c" (die aus der Offline-Anforderung vertagte versetzte Bild-Upload-Fähigkeit). Befund: Foto-Upload war rein online —putFoto()nutzt plainfetch(scheitert offline) undfoto.registriertläuft über densend()-Guard (verwirft offline) → ein offline erfasstes Foto war verloren. Gebaut: (1) Persistente Queue: neuerOfflineFotoQueueService(IndexedDBtaktano-offline-fotos, Storequeue/keyPathfotoId, nachStateCacheService-Muster) puffert die komprimierten Blobs (+ optional Original) bis Upload+Registrierung durch sind;count-Signal → Shell-Badge „N warten". (2) Reine ZustandsmaschinenaechsterFotoQueueSchritt(entry, connected)(offline-foto-queue.ts, Angular-frei) —upload → register → upload-original → register-original → fertig,wartenwenn WS zu;uploaded/registered-Flags = idempotenter Replay. (3) Enqueue+Drain inLeitstandService:uploadFoto()legt nur noch in die Queue (löst sofort auf) +drainFotoQueue()(Trigger: Socket-open/Reconnect +online-Event + nach Erfassung); HTTP-Fehler=offline → Eintrag bleibt liegen. (4) Server-Idempotenz (minimal):/api/foto/uploadleitet den R2-Key deterministisch aus?foto=<fotoId>ab (statt Zufalls-UUID) → Reconnect-Replay überschreibt denselben Key (kein Orphan); Fallback UUID wenn Param fehlt;foto.registriertdedupliziert schon nachid(unverändert). Kein Schema-Change. (5) UI: Detail-Panel-Toast „Foto erfasst" (+ „offline — wird bei Verbindung gesendet"), kein synchroner Fehler-Toast mehr; Shell-Badge im Footer. Entscheidungen: (a) always-enqueue + drain (uniform online/offline, keine Halb-Zustände); (b) R2-Key aus fotoId statt Client-Orphan-Management; (c) kein Background Sync in Stufe C (in-page-Drain deckt „offline erfassen → Reconnect bei offenem Tab"; Upload nach Tab-Schließen = Folge-Schritt). Review-Fixes (CodeRabbit, PR #264): (a) Persistenz-Fehler nicht mehr still verschlucken —put()/add()/update()liefernboolean;uploadFoto()wirft bei Puffer-Fehlschlag (Queue hält die einzige Kopie des Fotos), das Detail-Panel zeigt statt „erfasst" einen Warn-Toast. (b) Registrierung ack-getriggert — dieregistered-Flags werden nicht mehr blind nachsend()gesetzt (verpuffte WS-Meldung ⇒ Foto fehlt im State ⇒ Eintrag würde fälschlich gelöscht); erst wenn der Server das Foto in den State zurückspielt (fotoImState/fotoOriginalImState), gilt die Registrierung als bestätigt — der State-Broadcast triggert den nächsten Drain (idempotent, Server dedupt nachid). (c) Permanent vs. transient — ein Server-4xx (außer 408/429) entfernt den Eintrag + meldet zentral (fotoUploadFehler→ Shell-Toast) statt endlos zu retryen; Offline/5xx bleiben liegen. (d)update()-Persist-Fehler stoppt den Schritt (In-Memory-Flag darf dem IndexedDB-Stand nicht vorauslaufen). (e) Fehler-Liste statt Einzelwert —fotoUploadFehlerist eine Liste (mehrere 4xx-Ablehnungen im selben Drain-Turn würden bei einem Einzel-Signal koalieren → ein Toast ginge verloren); die Shell konsumiert je Fehler genau einen Toast. Nutzer-Wünsche (Folge in diesem PR): (1) Queue-Detailsicht (Popover): das Footer-Badge „N warten" ist klickbar → kompaktes Popover je wartendem Foto (Thumbnail via Objekt-URL, Auftragsnummer · Perspektive, Status lädt/registriert/wartet auf Verbindung, „HQ"-Marke bei Original); neueseintraege-Signal imOfflineFotoQueueService, Objekt-URLs per Effect synchron gehalten + bei Entfernen/Destroy freigegeben (kein Leak). (2) Original immer mitarchiviert (OP-R4-1): zu jedem Foto wird zusätzlich die volle Auflösung über die Queue nachgeladen (beweiskräftig QS/Audit) — der frühere „Original archivieren"-Schalter entfällt (Panel-Hinweis „Original wird mitarchiviert"). Entscheidung/Abwägung: ~doppeltes R2-Volumen bewusst in Kauf genommen (Nachweisbarkeit > Speicher). Klarstellung: die volle Auflösung liegt immer vor — hat die Kompression verkleinert, wird eine zweite (Original-)Datei nachgeladen; hat sie nichts verkleinert, ist die einzige gespeicherte Datei bereits das Original (kein zweiter Upload). Verifikation: neuertest:fotoqueue(blockierender CI-Gate, 8 Fälle) grün ·ng buildgrün · Servertscgrün. Doku:docs/architektur/Offline-PWA.md(Stufe C ✅ + Architektur/Verifikation),docs/konventionen/IDs.md(OP-OFFLINE-1), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-offline-foto-queue). - Branch
claude/ci-path-filters(PR folgt) — OP-CI-1 Folge-Hebel: Pfad-Filter je Bereich + SBOM nur auf main (Version 0.35.1 → 0.35.2 PATCH — reiner CI-Tweak; Build auto, OP-PM-2). Auftrag (Nutzer): „beide" (die im Vor-PR angebotenen Folge-Hebel umsetzen). Gebaut (nur.github/workflows/ci.yml+ Doku): (1) Pfad-Filter je Bereich: derchanges-Job (dorny/paths-filter) liefert jetzt Bereichs-Outputsserver/client/solver/design/security(OR-Quantifier; geteilte Dateienscripts/**+ci.ymltriggern per YAML-Anker&sharedalle Bereiche); jeder schwere Job läuft nur beineeds.changes.outputs.<Bereich> == 'true'‖github.event_name == 'push'→ ein bereichsfremder PR (z. B. nurclient/**) überspringtserver(27 tsx-Tests) +solver+persistence-gate. Sicherheitsnetz: aufmain-Push laufen via‖ pushalle Jobs voll → volle Validierung + korrektedeploy-needsvor jedem Release (Deploy bleibt unangetastet). Doku-only (docs/**+*.md) matcht keinen Bereich → Fast-Track bleibt. (2) SBOM nur auf main:sbom-Job aufgithub.event_name == 'push'gegated (Artefakt, kein Merge-Gate) → spart je PR 2×npm ci; „immer aktuell" aufmaingewahrt (OP-SBOM-1-Wortlaut in CLAUDE.md nachgezogen). Entscheidungen: (a) Bereiche sind physisch getrennt (server/ ↔ client/ ↔ solver-service/) → ein Bereichs-PR kann einen anderen nicht brechen; geteilte Dateien triggern sicherheitshalber alles; (b)main-Push validiert immer voll (fängt bereichsübergreifende Fälle vor dem Deploy). Verifikation: YAML-Parse (Jobs/ifs/Anker-Auflösung je Bereich geprüft) — keineoutputs.code-Reste; die vier übrigen Workflows unberührt (schon schlank). Kein Server-/Client-/Solver-/Schema-Change. Doku:.github/workflows/ci.yml(Kommentare),CLAUDE.md(OP-SBOM-1),konventionen/IDs.md(OP-CI-1), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-ci-path-filters). - Branch
claude/ci-optimize-minutes(PR #262) — OP-CI-1: GitHub-Actions-Build-Minuten halbieren (Doppelläufe weg + überholte Läufe abbrechen) (Version 0.35.0 → 0.35.1 PATCH — reiner CI-Tweak; Build auto, OP-PM-2). Auftrag (Nutzer): „Build-Minuten optimieren, damit das Actions-Kontingent nicht so schnell ausgeschöpft wird" (ausgelöst durch einen Actions-Kontingent-/Incident-Stau, der PR #261 zeitweise blockierte). Befund:ci.ymllief miton: pushundon: pull_requestohne Branch-Filter → jeder Push auf einen PR-Branch startete zwei komplette Läufe; zudem keinconcurrency→ überholte Läufe liefen weiter. Gebaut (nur.github/workflows/ci.yml): (1)pushaufbranches: [main]beschränkt — Feature-Branches werden nur noch über daspull_request-Event geprüft (keine Doppelläufe; Deploy = main+push bleibt unberührt). (2)concurrency-Gruppe jegithub.refmitcancel-in-progressaußer aufmain(kein Abbruch laufender Deploys). Entscheidungen: (a) Push-CI nur auf main — Preis: Branch ohne PR bekommt keine CI (läuft beim PR-Öffnen; üblicher Standard); (b) Concurrency canceled bewusst nicht auf main (Deploy-Schutz). Bewusst NICHT (als Folge-Hebel angeboten): Pfad-Filter je Bereich (server/client/solver/design nur bei Bereichs-Änderung) + SBOM von jedem PR auf main/Schedule verlegen. Verifikation:ci.ymlper YAML-Parse geprüft (top-keys +concurrencykorrekt); die anderen vier Workflows (docs-deploy/fly-deploy/sync-pr-logs/weekly-audit) sind bereits schlank (main+Pfad-Filter/Schedule/manuell). Kein Server-/Client-/Solver-/Schema-Change. Doku:docs/konventionen/IDs.md(OP-CI-1 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-ci-optimize-minutes). - Branch
claude/pwa-read-offline(PR #261) — OP-OFFLINE-1 Stufe B: Offline-Fähigkeit als PWA (Service Worker + Read-Offline), keine native App (Version 0.34.0 → 0.35.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): „Offline-fähig — abwägen App vs. Webbrowser nach einmaligem Laden; Bild-Upload soll definitiv versetzt erfolgen können." Entscheidung: PWA statt nativer App (Infra schon PWA-tauglich: HTTPS + statische Worker-Assets; ein Web-Deploy bedient alle Plattformen). Gebaut (Stufe B, reiner Client + Build-Konfig): (1) PWA-Shell:@angular/service-worker+client/ngsw-config.json(App-Shellprefetch, Fonts/Bilderlazy,navigationUrlsohne/api/**);angular.jsonserviceWorker+assets(public);provideServiceWorker(..., { enabled: !isDevMode(), registrationStrategy: 'registerWhenStable:30000' })inapp.config.ts(nur Prod); Web-Manifestclient/public/manifest.webmanifest+ SVG-Iconclient/public/icon.svg(everything-as-code, kein Binär-Master) +<link rel="manifest">inindex.html. (2) Read-Offline: neuerStateCacheService(IndexedDB, ein Snapshot desLeitstandState; IndexedDB statt localStorage wegen Größe);LeitstandServicepersistiert jestate-Broadcast (lastStateAt/hydratedFromCache) und hydriert beim Start aus dem Cache, solange kein Live-Broadcast kam (Broadcast hat Vorrang); Offline-Banner in der Shell (offlineStale→ „Offline — Stand von HH:MM · nur Ansicht"; Datum, wenn der Stand nicht von heute ist). Read-Only hart durchgesetzt:LeitstandService.send()verwirft Schreib-Kommandos bei!connected()→ offline landet nichts in PartySockets flüchtiger In-Memory-Queue (kein halb-abgesetzter, nicht-idempotenter Reconnect-Replay). Cache-Versionierung: der Snapshot trägt eineSCHEMA-Version;load()verwirft Alt-/inkompatible Snapshots (kein Hydrieren veralteterLeitstandState-Shapes). Review-Fixes (CodeRabbit, PR #261): PR-Link im CHANGELOG; Banner-Datum nach Mitternacht; Read-Only-send()-Guard; Cache-SCHEMA. Raster-PNG-Icons (192/512) als optionaler Folge-Schritt notiert (Toolchain hat keinen SVG→PNG-Rasterizer; Chromium akzeptiert SVG-Manifest-Icons; SVG bleibt everything-as-code-Master). Bewusst NICHT: Offline-Schreiben von Aktionen (großer Folge-OP, Idempotenz/Reconnect-Replay/Konflikte) und Foto-Upload-Queue (Stufe C / PR C, baut auf der PWA-Shell auf). Design-Gate:manifest/index.htmlliegen außerhalb des No-Hex-Scopes (check-no-hex.shscannt nurclient/src/app+styles.css) → literale Brand-Hex erlaubt; Banner nutztvar(--tk-amber)via color-mix (kein Hex). Verifikation:ng buildgrün →ngsw-worker.js+ngsw.json(assetGroupsapp/assets, Manifest + Icon im Hash-Table) erzeugt; No-Hex-Gate grün. Kein Server-/Solver-/Schema-Change. Doku:docs/architektur/Offline-PWA.md(neu, ADR + Stufenplan),docs/konventionen/IDs.md(OP-OFFLINE-1), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-pwa-read-offline). - Branch
claude/server-checks-timing-omm2he(PR #260) — OP-QS-GATE: QS-Vollständigkeits-Gate vor der Abholung (server-hart) + Nacharbeit als QS-Phasen-Schritt (Version 0.33.1 → 0.34.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): „Nacharbeit als Prozessschritte innerhalb der QS hinzufügen — dokumentiert, dass Nacharbeit erforderlich war; in der QS auch prüfen, dass alle Prozessschritte ausgeführt und dokumentiert wurden." Gebaut: (1) Nacharbeit = QS-Phasen-Schritt: neues optionalesTeilschrittInstanz.phase(Per-Instanz-Override);nacharbeitInstanzsetztphase: 'qs'→ die Nacharbeit dokumentiert sich als QS-Schritt (statt die Produktions-Phase des Original-Templates zu erben);aktuellePhase+ Teilschritt-DTO bevorzugen die Instanz-Phase vorphaseByTs. (2) Server-hartes Gate (abholen): neue pureistAbnahmebereit(auftrag, dokuPflichtByTs, fotoAnfByTs, fotosByInstanz)→{ ok, offen[] }: jeder nicht übersprungene Teilschritt muss erledigt + (falls pflichtig) dokumentiert (Kommentar) + Foto-Pflicht erfüllt sein und kein QS-Mangel offen; derauftrag.aktion-Handler lehntabholenab, wenn!ok(kein Übergang), sendetauftrag.aktion.result(neuer ServerMsg, mitoffen[]) + Auditauftrag.abnahme.abgelehnt(OP-AUDIT-1). Schließt die Lücke: bisher akzeptierte der Serverabholenblind (transition fertiggestellt→abgeschlossen ohne Prüfung). (3) Client (Qualität-Sicht): neue Prozess-Vollständigkeits-Tafel je Auftrag (pro Schritt erledigt?/Doku?/Foto? + offene Mängel, aus dem DTO) — spiegelt das Server-Gate; „Übergeben" zusätzlich anabnahmebereit(a)gebunden; abgelehnte Server-Abholung als Toast (auftragAktionResult-Signal); die manuelle Sicht-Checkliste startet frisch je QS-Runde (Schlüssel${id}:${nacharbeit-Schritt-Anzahl}→ kein veraltetes „Bestanden" nach Nacharbeit, kein neues Server-Feld). Entscheidungen (Sign-off): (a) kein separater Lifecycle-Statusnacharbeit— der bestehendenacharbeitEinplanen-Mechanismus (Solver-Replan) bleibt, die Nacharbeit wird stattdessen als QS-Phasen-Schritt geführt; (b) Gate server-seitig hart (auditierbar/manipulationssicher), nicht nur Client; (c) Sonderwünsche bewusst vertagt (eigener PR) —istAbnahmebereitist als Erweiterungspunkt dafür vorbereitet. Verwandte, bewusst NICHT in diesem PR:transition()→fertiggestelltsetzt offene Schritte weiterhin auferledigt(das Gate fängt undokumentierte ab) — optionale Härtung als Folge-Schritt notiert. Migration:SCHEMA_VERSION15 → 16 (additiv, Per-Instanz-Phase; kein Transform — fehlt ⇒ Template-Phase). Verifikation: Servertsc+ neuestest:abnahme(blockierender CI-Gate, 7 Fälle: erledigt/Doku/Foto/übersprungen/Mangel-Matrix) +test:do-migrations(v0→v16) +test:nacharbeit/operativ/replangrün ·ng buildgrün. Kein Solver-Redeploy. Doku:docs/fachlich/Lastenheft.md(§5.1 QS-Gate + Nacharbeit-als-QS-Schritt),docs/architektur/Operative-Durchgaengigkeit.md(OP-QS-GATE),docs/konventionen/IDs.md, HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-server-checks-timing-omm2he). - Branch
claude/nacharbeit-mangel-behoben(PR folgt) — OP-UX-3-Nachzug: Mangel automatischbehobenbeim Abschluss der Nacharbeit (Version 0.33.0 → 0.33.1 PATCH — kleiner Nachzug; Build auto, OP-PM-2). Auftrag (Nutzer): beim Abschluss des Nacharbeits-Schritts den zugehörigen Mangel automatisch aufbehobensetzen (blieb bisheroffen). Gebaut (reiner Server-Pfad): neue VerknüpfungTeilschrittInstanz.mangelId(gesetzt beinacharbeitInstanz, durchgereicht ausauftrag.nacharbeitEinplanen=mangel.id); die pureerledige-Funktion setzt beim Erledigen eines Nacharbeits-Schritts den verknüpftenAuftrag.maengel-Eintrag aufbehoben(idempotent, nur wenn nochoffen); derteilschritt.aktion-Handler ergänzt Protokoll + Auditmangel.behoben(OP-AUDIT-1, Actor aus per-Connection-E-Mail). Damit schließt sich der QS-Kreis Mangel → Nacharbeit → behoben. Kein Client-Change nötig (Mangel-Status fließt über das bestehendemaengel-DTO). Self-Testtest:nacharbeitum zwei Fälle erweitert: (5) Abschluss behebt den verknüpften Mangel; (6) ein normaler Schritt lässt Mängel unberührt. Verifikation: Servertsc+test:nacharbeit+operativ/replan/running-processgrün. Kein Solver-Redeploy, kein Schema (nested-optional). Doku:docs/architektur/Operative-Durchgaengigkeit.md(§OP-UX-3 Nachzug),docs/architektur/Audit-Log.md(Eventmangel.behoben), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-nacharbeit-mangel-behoben). - Branch
claude/nacharbeit-gantt(PR #258, gemergt) — OP-UX-3: Nacharbeit nach QS-Mangel live im Gantt (Version 0.32.0 → 0.33.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): Flow-Audit-Backlog — QS-Nacharbeit war nur eine Kennzahl (Auftrag.maengel[].nacharbeitAufwandMin+ client-lokale Markierung), kein geplanter Schritt: keine Kapazität, kein Gantt-Block, keine Verschiebung vongeplanteFertigstellung/Reserve → Cockpit beantwortete Auslastung & „wann fertig/frei?" falsch. Gebaut (voll solver-integriert): (1) Scheduler-Kern: dynamischezusatzSchritteimAuftragInputwerden inscheduleLeistung(TS) undbuildProblem(CP-SAT) nach dem Skip-Filter an den statischenLeistung.prozessangehängt (WiederverwendungProzessSchritt.dauerOverrideMin+abhaengigkeit); neueTeilschrittInstanz.nacharbeitMin(optional, abwärtskompatibel) trägt die Vorgabe-Dauer;toAuftragInputerzeugt daraus die Zusatzschritte;applyPlanungbleibt index-stabil (nach Reopen sind statische Schritte erledigt/geskippt → einziger planbarer Schritt = Nacharbeit). (2) Lifecycle: neue Transitionnacharbeiten: fertiggestellt → angeliefert. (3) Handlerauftrag.nacharbeitEinplanen: offene Aufwands-Mängel → je eine Nacharbeits-TeilschrittInstanz(Skill/Bucht-Typ vom betroffenen Schritt, Dauer = Aufwand, Bucht+Crew solver-frei), Reopen, sofortiger Einzel-Plan (konkrete Bucht/Zeit/Crew → live im Gantt) +REOPT_EVENTS(globale CP-SAT-Reopt als Vorschlag), Auditnacharbeit.eingeplant;TeilschrittDTO.nacharbeit-Flag. (4) Client: Qualität-Sicht-Button „⚠ Nacharbeit einplanen" (Sichtbarkeit/Badge persistiert über offene Mängel statt client-lokaler Set), Detail-Panel kennzeichnet Nacharbeits-Schritte (⚠), Gantt-Block trägt den „Nacharbeit: …"-Namen; Reserve/Konflikt aktualisieren sich automatisch übergeplanteFertigstellung. Entscheidungen (Sign-off): (a) erst bestätigen (expliziter Einplanen-Schritt statt Auto-Reopen); (b) voll solver-integriert (echter Solver-Schritt, TS+CP-SAT); (c) Solver wählt Bucht/Mitarbeiter frei (Skill+Dauer fix vom Mangel-Schritt). Verifikation: Servertsc+ neuestest:nacharbeit(blockierender CI-Gate: Zusatzschritt fließt durch Scheduler+Mapping, verschiebt Fertigstellung) +operativ/replan/running-process/spikegrün ·ng buildgrün · No-Hex +persistence:checkgrün (nested-optional → kein Gate-Treffer) ·ci.ymlstrict-YAML. Kein Solver-Redeploy, kein Schema-Change. Doku:docs/architektur/Operative-Durchgaengigkeit.md(§OP-UX-3 + Backlog abgehakt),docs/fachlich/Lastenheft.md§4.9.1,docs/konventionen/IDs.md+Register.md(OP-UX-3-Zeile), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-29-nacharbeit-gantt). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257) —maineingepflegt + Review-Fixes (CodeRabbit) + Version-Rebase (Version 0.31.2 → 0.32.1 PATCH; Build auto). (1) Mergeorigin/main(#254 Klärfälle-Workspace · #255 OP-/Entscheidungs-Register · #256 Wettbewerbsanalyse): einziger Konfliktserver/src/version.ts(main 0.32.0 ↔ Branch 0.31.2) → auf 0.32.1 rebased (PATCH über main); union-merge-Logs sauber konkateniert. (2) CodeRabbit-Review-Fixes: Tooltip inoccupancy.component.tsan „Vorbereitung starten" angeglichen (war noch „Produktion starten");addStep()nutzt jetztangeboteneTeilschritte()(nicht-archivierte) als Default statt der vollen Katalogliste (verhindert Einfügen archivierter Vorlagen — Folge des Bugfix-Katalogs); sprechende Labels in Prosa nachgezogen („Sprung zu QS" → „Sprung zu Quality-Check", „Annahme/Aufbereitung/QS" → „…/Vorbereitung/Quality-Check") inCLAUDE.md+Lastenheft.md§5.1/OP-R3-1 (technische Keysqs/aufbereitungunverändert); „PR folgt"-Platzhalter im CHANGELOG durch PR-#257-Link ersetzt;Roadmap.mdum Zielgruppe/Wofür-Zeile ergänzt. Verifikation: Servertypecheck+test:prozess+ Clientng buildgrün (nach Merge + Fixes). Doku:server/src/version.ts,client/.../{occupancy,processes}.component.ts,CLAUDE.md,docs/fachlich/Lastenheft.md,docs/betrieb/Roadmap.md, CHANGELOG, Timesheet. Offen (CodeRabbit-Nitpick, bewusst nicht umgesetzt): HANDOFF §4 thematisch gruppieren — gehört zur strukturellen OP-Entdoppelung (OP-DOCS-11), nicht in diesen PR.
2026-06-28
- Branch
claude/comments-image-support-caix8o(PR folgt) — OP-R4-3 / F16: Inhaltliche Doku-Vorgaben am Kommentar + OP-PM-3: Session-ID-Repo-Präfix (Version 0.40.2 → 0.41.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): Jede Kommentarfunktion (Auftragsabschluss/nächster Schritt) soll Bilder anzeigen, eine Mindestanzahl bestimmter Bilder erzwingen, und inhaltlich vorgeben, auf welche Aspekte eine Beschreibung eingehen soll (Diktat/Textbausteine/Mehrsprachigkeit „später"). Befund: Bild-Anzeige, Foto-Mindestanzahl je Perspektive (fotoPflicht, F15) und Pflicht-Kommentar (dokuPflicht, F14) sind bereits gebaut — alle Kommentar-Einstiege (Aufträge/Gantt/Tafel/Meine Arbeit) laufen durch dasselbe geteilte Detail-Panel-Gate. Neu gebaut (F16):Teilschritt.dokuAspekte: string[]— kuratierter inhaltlicher Leitfaden „Worauf eingehen?", der die geforderten Aspekte über dem Kommentarfeld einblendet (weiche Vorgabe; der Pflicht-Kommentar selbst bleibtdokuPflicht). End-to-end:types.ts(Feld + HelperdokuAspekte, normalisiert),setzeTeilschrittFelder-Patch (prozess.ts),TeilschrittDTOserver+client,toAuftragDTO/buildProzessKatalog/snapshot-Map, Anzeige im Kommentar-Gate (auftrag-detail-panel.component.ts); Seed-Beispiele an Annahme/Aufbereitung/Folierung/QM (vest-automotive.ts) + Ergebnis-Foto-Pflicht an der Endkontrolle;test:prozessAbschnitt 9b. Roadmap als Design-Docdocs/architektur/Doku-und-Kommentare.md(pyramidal, Zielgruppen, Mermaid-Durchstich): additive Folgestufen OP-DIKTAT-1 (Sprach-Diktat), OP-TEXTBLOCK-1 (Textbausteine), OP-I18N-1 (Mehrsprachigkeit), OP-AI-2 (KI-Plausibilität), OP-ABSCHLUSS-1 (separate Doku-/Übergabe-Notiz auf Auftrags-Ebene — heute liegt Doku nur je Teilschritt) — alle auf demselben Doku-Modell; Empfehlung Textbausteine → Diktat → Mehrsprachigkeit. Entscheidungen: (a)dokuAspekte= weiche Vorgabe (angezeigt, nicht je-Aspekt hart erzwungen — Erzwingung ob die Aspekte tatsächlich adressiert sind = KI-Plausibilität OP-AI-2); (b) keine neue Editor-UI fürdokuAspekte(server-seitig patchbar, konsistent mitdokuPflicht/fotoPflicht, Editor folgt mit OP-R3-3). OP-PM-3 (Nutzer-Wunsch dieser Session): Timesheet-Session-IDs ab jetzt mit Repository-Präfix<repo>-<Datum>-<branch-slug>(Timesheet §Protokoll/Kopf,agents.md§6.6,CLAUDE.md,session-start-hook.sh; erste Session mit der neuen ID = Dogfooding). Verifikation: Servertsc+test:prozess+operativ+ng build(prod) grün. Reiner Server+Client-Pfad, kein Solver-Redeploy. Doku:docs/architektur/Doku-und-Kommentare.md(neu), HANDOFF (§4 OP-R4-3/OP-PM-3/OP-DIKTAT-1/OP-TEXTBLOCK-1), CHANGELOG, Timesheet (taktano-2026-06-28-comments-image-support-caix8o). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257) — Fachliche Phasen-Labels umbenannt („Aufbereitung" → „Vorbereitung", „QS" → „Quality-Check") + OP-PHASE-1 (Produktions-Benennung & Vor-Produktion) festgehalten (Version 0.31.0 → 0.31.1 PATCH — sprechende Labels/kleiner Tweak; Build auto, OP-PM-2). Auftrag (Nutzer, iterativ): „Nenne ‚Aufbereitung' im Prozess ‚Vorbereitung & Car-Check'" → präzisiert: „Aufbereitung → Vorbereitung (inkl. Car-Check und Folien-Produktion)", „QS → Quality-Check", und „Folien-Produktion / bessere Produktions-Benennung als OP festhalten". Gebaut: (1) Rename (nur sprechende Labels): fachliche Phase 2 „Aufbereitung" → „Vorbereitung" (Scope: Waschen + Car-Check + Folien-Produktion/Zuschnitt) und „QS" → „Quality-Check"; die technischen Phasen-Keys bleibenaufbereitung/qs(Muster wie Status „Fahrzeug angeliefert"/Keyangeliefert— kein Schema-/Enum-Change, keine Migration). Single-Sourceclient/src/app/leitstand/phase.ts(PHASE_LABEL) → propagiert automatisch in Flow-Band/Orders/Detail-Panel; Wareneingang-Button „▶ Aufbereiten starten" → „▶ Vorbereitung starten" (occupancy.component.ts). (2) OP-PHASE-1 neu (zwei Aspekte): (a) bessere Benennung der Produktions-Phase (generisch „Produktion" vs. gewerk-/leistungs-spezifisch „Folien-Applikation"/„Lackierung"; multi-Gewerk → abgeleitet vs. Tenant-/Admin-konfigurierbar, G-1); (b) „Vor-Produktion" differenzieren — Folien-Zuschnitt/Druck + Material-Bestellung sind vorgelagert, können nach der Annahme beginnen, belegen Plotter/Zuschnitt-Kapazität (nicht die Fahrzeug-Bucht); Scheduler muss Zeitraum + Auslastung der Folienproduktion als eigene Kapazität einplanen (True-North-Frage 1), verzahnt mit OP-R3-2 (Folien-Vorlauf/Lieferzeit). Entscheidungen: (a) nur Labels, Key/Enum/Schema unangetastet (minimal, migrationsfrei); (b) Produktions-Spezialisierung + Vor-Produktion bewusst als OP geparkt (Tragweite: Scheduler/Datenmodell/multi-Gewerk). Verifikation: No-Hex-Gate unberührt (kein Hex); Label-Change rein textuell. Reiner Client + Doku, kein Server-/Solver-/Token-/Schema-Change. Doku:CLAUDE.md(Standard-Prozess),docs/fachlich/Lastenheft.md(§5.1 + Mermaid + OP-R3-1 + OP-PHASE-1 neu),docs/zielgruppen/Lesepfade.md,design/COMPONENTS.md,design/WORKSPACES.md, HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Captures derselben Session — reine Doku/OP) — drei weitere Nutzer-Eingaben als offene Punkte festgehalten (kein Code): (1) OP-FEEDBACK-1 neu — In-App-Feedback mit Screenshot-Markierung; Frage „Chatbot oder Plugin?" → Empfehlung schlankes Eigen-Widget (html2canvas+ Annotations-Overlay + Auto-Kontext Route/Version/Build/trace_id→ R2-Bild + D1 + Triage) statt SaaS-Plugin (DSGVO/EU-Residenz; Infra R2/D1/DO/OTel + Assistent ist da); Chatbot = optionaler Zusatzkanal über OP-AI-4. (2) OP-I18N-1 geschärft — UI-Sprachen ausdrücklich + Chinesisch + Ukrainisch (Treiber: mehrsprachige Werkstatt-Belegschaft, nicht nur EU-Markt); auch in Lastenheft §8 (Internationalisierung/NFA) nachgezogen. (3) OP-AI-3 erweitert — Audio-Notizen zusätzlich mit Translator (Muttersprache → Transkript + Übersetzung in die Auftrags-/UI-Sprache, Original erhalten) und Domänen-Anpassung an taktano (ASR + Übersetzung auf Werkstatt-/Glossar-Vokabular getrimmt). (4) OP-BRAND-2 neu — „Automotivo" defensiv als Marke schützen (Markteintritts-Barriere); mit Proaktiv-Flagging der rechtlichen Risiken (automotivo.de = bestehende Nutzung/ältere Rechte · Bad-Faith-/Sperrmarken-Angreifbarkeit · „Automotivo" stark beschreibend → ggf. schutzunfähig · Portfolio-Aufwand) — kein Rechtsrat, vor Anmeldung Anwalt/Recherche DE/AT/CH. Doku:docs/fachlich/Lastenheft.md(§11.8 OP-AI-3 + OP-FEEDBACK-1 neu, §8-Internationalisierung), HANDOFF (§4: OP-I18N-1 + OP-FEEDBACK-1 + OP-AI-3-Notiz), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R1-4 neu: Rückwirkende Abwesenheiten (Urlaub/Krank) trotz erfasster Arbeit + Abgrenzung gegen Datev/Lohnbuchhaltung (Nutzer). (1) Rückwirkend Urlaub/Krank eintragen, obwohl im Zeitraum Leistungsnachweise/Einsatz existieren → Widerspruch: flaggen (Klärfall) vs. blocken, Wirkung auf abgeleitete Urlaubs-/Krankheitstage + Überstundenkonto, Berechtigung + lückenlose Auditierung (OP-AUDIT-1). (2) Leitthese: taktano = SoR für operative Planung/Kapazität + Arbeits-Ist, nicht für die rechtsverbindliche Lohnabrechnung (bleibt Datev/Lohnbuchhaltung; Export/Schnittstelle statt Doppelpflege). ⚠ Proaktiv-Flagging DE/AT/CH (kein Rechtsrat): Arbeitszeiterfassungspflicht (BAG/EuGH), Krankheitsdaten = DSGVO Art. 9 (nur „krank", keine Diagnose), eAU als offizieller Nachweis, rückwirkende Korrektur = Manipulations-/Compliance-Risiko. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R1-4 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-ONBOARD-1 neu: In-App-Tutorials + sukzessive Feature-Freischaltung (Nutzer). (1) geführtes Onboarding/Tutorials in der App für die Kern-Flows in Werkstatt-Sprache (wiederverwendet Glossar-Sprechblasen, Empty-State-CTAs/OP-UX-1, In-App-Assistent/OP-AI-4; Form Coachmarks/Video/Doku-Link + „erledigt"-Status offen). (2) Features progressiv freischalten (progressive disclosure): Einsteiger sehen erst den Kern (Tafel/Annahme/Meine Arbeit), Fortgeschrittenes gestaffelt — Mechanik via Feature-Flags je Tenant (G-1)/Rolle (OP-AUTH-1)/Onboarding- bzw. Akademie-Fortschritt (OP-R1-3) offen; darf Funktionen gestaffelt einführen, nicht verstecken (Selbsterklärbarkeit). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.8 OP-ONBOARD-1 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Captures — reine Doku/OP) — zwei weitere offene Punkte (Nutzer): OP-CAL-1 neu — Feiertage je Bundesland vorschlagen (Betriebskalender): gesetzliche Feiertage je Bundesland (DE 16; analog AT/CH-Kantone) aus dem Region-Stammdatum des Tenants vorschlagen/vorbefüllen (inkl. beweglicher Feiertage), Vorschlag nicht hart (Betrieb bestätigt/überschreibt — Brückentage/Betriebsferien); Wirkung: betriebsweite Schließtage → Kapazität↓, Scheduler/Ausfall-Band „Geschlossen"/Termin+Reserve; Tenant-weiter Betriebskalender (admin-editierbar G-1); lohnrechtliche Feiertagsbehandlung bleibt Datev (OP-R1-4). OP-STAGE-1 neu — Mehrere Stages / Release-Stände: heute nur Produktion → getrennte Stages dev/test→staging/preview→production (Preview je Branch/PR, Promotion-Flow), via CF Worker-Environments (eigene DO/D1/R2 + Access je Stage), Fly separate App, Versions/Gradual Deployments (Canary), Release-Channels (komplementär OP-ONBOARD-1); ⚠ DSGVO: Non-Prod ohne echte PII → synthetischer Seed, strikte Trennung (OP-TENANT/OP-SEED-1). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-CAL-1, §11.10 OP-STAGE-1), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R7-12 neu: Kommentare/Notizen bei der Auftragsaufnahme (Annahme) (Nutzer; Phase per Rückfrage geklärt = Annahme). Das Annahme-Formular (/annahme) erfasst heute nur strukturierte Felder, kein Freitext-Kommentar — §5.1 fordert je Phase „Doku & Kommentar"; Annahme = Stelle für Zustand bei Annahme/Kundenhinweise/Sonderwünsche/Vorschäden. Gewünscht: Kommentar-/Notizfeld bei der Annahme → gespeichert am Auftrag (Chronik/protokoll, sichtbar Aufträge/Detail). Offen: Pflicht vs. optional (OP-R4-3-Doku-Gate/ts-annahme), Sichtbarkeit (intern vs. an Mitarbeiter, R1 §4.1), einheitliche Textfeld-Komponente mit Foto-Upload (R4) + Diktat/Übersetzer (OP-AI-3). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R7-12 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Captures — reine Doku/OP) — OP-R7-12 verallgemeinert + OP-R7-13 neu (Nutzer). OP-R7-12 (vorher „Kommentar bei der Annahme") auf die Leitlinie „immer Kommentare erlauben — je mit Foto/Voice" erweitert: einheitliche, überall verfügbare Kommentar-Fähigkeit (jede Phase/Auftrag/Teilschritt), jeder Kommentar mit Foto (R4/OP-R4-3) + Voice/Audio (Transkript+Übersetzer, OP-AI-3) + Freitext, als Verlauf in Chronik/protokoll; konkreter Auslöser bleibt das fehlende Kommentarfeld bei der Annahme. OP-R7-13 neu: Umgang mit „freien Aufträgen" — Begriff zu schärfen; Lesarten (a) freier Prozess/ad-hoc-Leistung ohne Katalog-Leistung (Taktung braucht dennoch Dauer/Skill/Bucht), (b) freier Termin/best_effort, (c) ohne Kunde/Fahrzeug (interner Auftrag/Demo); zu klären Lesart(en) + Mindestangaben + Verhältnis Prozess-Editor (OP-R3-3) + Auslastungs-Zählung. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R7-12 erweitert + OP-R7-13 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Captures — reine Doku/OP) — OP-R3-4 neu (Vorbedingungen) + OP-R7-14 (Anzahlungen-Feststellung) (Nutzer). OP-R3-4: Vorbedingungen je Auftrag/Schritt erfassen + rechtzeitig veranlassen — verallgemeinert OP-R3-2 (Folie/Material „bestellt & eingetroffen" + Lieferzeit) auf beliebige Vorbedingungen (z. B. Ersatzteil für eine kleine Reparatur rechtzeitig bestellen, Werkzeug, Kundenfreigabe): Status offen→bestellt→eingetroffen/erfüllt, Vorlaufzeit → früheste Startschranke + Start-Gate bis erfüllt + Verzugswarnung. OP-R7-14: Feststellung „Anzahlungen werden in taktano nicht erfasst" — Ist nur Preis-Snapshot (Auftrag.preisCent); Abgrenzung (vgl. OP-R1-4): Geldflüsse = SevDesk (OP-BILLING-1), nicht taktano; offene Entscheidung = operatives „Anzahlung erhalten?"-Flag/Gate (Produktionsstart erst nach Anzahlung, analog OP-ACCESS-1) ohne Beträge zu verbuchen. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R3-4 + OP-R7-14 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R7-15 neu: Prozess-Vorschau bei der Auftragserfassung + auftragslokal anpassen/kommentieren (Nutzer). Bei der Annahme (/annahme) nach Leistungswahl eine Vorschau des Prozesses (Teilschritte mit Dauer/Skill/Bucht/Phase ausbuildProzessKatalog) zeigen → erlaubt weitere Schritte hinzufügen + bestehende Schritte kommentieren (Kommentar mit Foto/Voice via OP-R7-12) vor/bei der Anlage. Auftragslokale Anpassung der Prozess-Instanz (≠ Katalog-Edit OP-R3-3, der auf alle wirkt; passt zur Materialisierung E-CRUD-2). Zusatz-Schritte brauchen Dauer/Skill/Bucht → fließen in die Taktung (§5.2.2 Angebotsmodus/Machbarkeit/Preis/Reserve). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R7-15 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Captures — reine Doku/OP) — OP-BACKOFFICE-1 neu + TODO „Umparken checken" (Nutzer). OP-BACKOFFICE-1: Backlog der Vorarbeiten für Back-Office/Vorgesetzte — die Vorbedingungen/Vorarbeiten (OP-R3-4: Teile/Material bestellen, Beschaffung, Freigaben) auftragsübergreifend als Backlog/Arbeitsliste für eine Back-Office-Rolle/Vorgesetzten anzeigen (analog Werker-Sicht „Meine Arbeit", aber dispositiv): je Vorbedingung Auftrag/Fahrzeug · Typ · Status · Fälligkeit (aus Vorlaufzeit) · Priorität; Aktionen setzen den Vorbedingungs-Status → Start-Gate auf; reine Projektion (S-2); beantwortet „was muss jetzt beschafft werden, damit Termine halten?"; OP-R3-4 um Cross-Ref ergänzt. TODO „Umparken checken": Verifikations-Notiz — Umpark-Funktion (Belegung-Drag&Drop +repark.service.ts/repark-modal, interrupt-aware) end-to-end + Edge-Cases prüfen; in HANDOFF §4 als TODO geparkt (noch nicht abgearbeitet). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.8 OP-BACKOFFICE-1 + §11.1 OP-R3-4 Cross-Ref), HANDOFF (§4 + TODO), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-QS-3 neu: Während der Bearbeitung verursachte Schäden erfassen → Nacharbeit-Kette mit Ersatzteil (Nutzer). Selbst verursachter Schaden beim Bearbeiten (z. B. Befestigungs-Clip bricht) direkt am laufenden Schritt/Auftrag als Mangel/Schaden erfassen (nicht erst in der QS) → durchgängige Kette: Schaden → Nacharbeit → Ersatzteil-Bedarf → Bestellung (als Vorbedingung OP-R3-4, im Back-Office-Backlog OP-BACKOFFICE-1, mit Vorlauf) → bei Eintreffen Einbau-Schritt planen/freigeben → eingebaut → behoben. Status-Workflow offen→bestellt→eingetroffen→Einbau geplant→behoben (erweitert OP-QS-1); Nacharbeit-Schritt trägt Ressourcen/Skill/Bucht → Taktung (Termin/Reserve); intern verursacht → Kosten/Verantwortung (OP-COST-1/OP-R10-1). Gleicher Mechanismus wie QS-Mangel (§4.9.1), aber Auslöser = während Bearbeitung. Erfassung mit Foto/Voice (OP-R7-12). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-QS-3 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R7-16 neu: Fahrzeug-Angaben bei der Annahme erfassen (Nutzer). Bei der Annahme (/annahme) direkt am Auftrag (§4.9: Fahrzeug = Attribute am Auftrag) Fahrzeugbeschreibung (Hersteller/Modell/Farbe), ein paar Fotos (Zustands-/Annahme-Doku, R4/OP-R4-3), Fahrgestellnummer (FIN) — immer (Pflicht), Kennzeichen — optional („manchmal"). Nutzen: eindeutige Identifikation (FIN), Beweissicherung/Vorschäden (verknüpft OP-R7-12/OP-QS-3), Wiedererkennung (OP-R6-1). Datenmodell:Auftrag.fahrzeug = {beschreibung, fin(Pflicht), kennzeichen?, fotos[]}, optional FIN-Plausibilität (17 Stellen ISO 3779). ⚠ DSGVO-Flag: FIN/Kennzeichen/Fotos personenbezogen → Zweckbindung + Löschkonzept (OP-CRUD-1, Fotos R2 eu). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R7-16 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R6-2 neu: Fahrzeug-Visualisierung (Silhouette/3D/AR) + Besonderheiten-Wissensbasis je Modell (Nutzer). (1) Immer eine Fahrzeug-Silhouette anzeigen — 2D min., Ziel 3D (drehbar), AR vorbereiten — zum räumlichen Markieren von Schäden/Besonderheiten (⚠ 3D-Asset-Pipeline je Modell erheblich → stufenweise 2D→3D→AR). (2) Besonderheiten je Fahrzeugmodell aus dem Learning festhalten (Bsp. Nutzer: Porsche 911 ab GT mit Leichtbauscheiben); bei Annahme bekanntes Modell erkennen (FIN/Beschreibung, OP-R7-16) → Besonderheiten vorschlagen, sonst anlegen (Fahrzeugmodell-Katalog, getrennt von der auftragslokalen Fahrzeug-Instanz §4.9). (3) Cross-Tenant-Wissen als kostenpflichtiges Add-on (Schwarm-Wissen) — ⚠ Flag: widerspricht der Tenant-Isolation (OP-TENANT) → bewusst geteilte, opt-in + anonymisierte zentrale Wissensbasis (kein PII-Leak), Add-on-Subscription (OP-BILLING-1), Wettbewerbs-/Einwilligungs-Abwägung. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R6-2 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R6-2 erweitert: Silhouette schon bei der Annahme zum Markieren von Arbeitsbereichen (Nutzer). Die Fahrzeug-Silhouette (OP-R6-2 Aspekt 1) direkt in der Annahme nutzen, um Arbeitsbereiche/Scope am Fahrzeug zu markieren (Beispiel: „länger gezogene Ladekante") — markierte Zonen verknüpfen Arbeitsumfang/Leistung mit dem Ort am Fahrzeug (Bezug OP-R7-15 Prozess-Vorschau, OP-R7-16 Fahrzeug-Angaben) und dienen Produktion/Quality-Check als gemeinsame Referenz; Annahme-Erststufe = 2D-Silhouette mit Zonen-Markierung (volle 3D/AR später, stufenweise). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R6-2 Aspekt 1 erweitert), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R2-3 neu: Buchten-Gantt aus der Planung in die Belegung verschieben + mehr Detail (Nutzer). Den Bucht-bezogenen Gantt (zeitliche Belegung je Arbeitsplatz/Bucht) aus Planung → Belegung verschieben (gehört thematisch zur Belegung, ergänzt den Hallen-/Hofplan OP-R2-2; beantwortet True-North-Frage 2 Standort-über-Zeit + 3 nächste freie Kapazität via Bucht-Lücken). Mehr Detail als Voraussetzung: je Bucht-Block Auftrag/Fahrzeug · Teilschritt · Mitarbeiter · Status/Phase · Standort · Cool-down/Settle · Ausfall-Bänder (scheduler/ausfall.ts) · freie Slots hervorheben. Offen: verschieben vs. duplizieren (Planung behält MA-/Optimierer-Sicht),gantt.component.tsauf Bucht-Zeilen parametrisieren, Detailtiefe vs. Übersicht. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.2 OP-R2-3 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-OPT-8 neu: Zeitlage-Präferenz je Leistung/Teilschritt (asap vs. jit/spät) (Nutzer). Auf Prozess-/Leistungs-Ebene festlegen, ob ein Schritt so früh wie möglich (asap) oder so spät wie möglich / just-in-time (jit, „optimiert/geplant") getaktet wird. Bsp.: Folierung asap, Fahrzeug-Aufbereitung/Endreinigung spät (kurz vor Abholung, damit es nicht wieder einstaubt). Heute nur Terminklasse je Auftrag + globale asap/jit-Zielmodi (§6.2); neu = teilschritt-/leistungsspezifisch (zeitlage: asap|jit|neutral, Prozess-Editor OP-R3-3, G-1). Scheduler als Soft-Goal (asap min. Startzeit, jit max. Startzeit bei harten Terminen), CP-SAT + TS. ⚠ Abwägung: jit reduziert Reserve/Puffer → nur weich, nachrangig zur Termintreue. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.2 OP-OPT-8 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-DATE-1 neu: konsistente, kontext-bewusste Datums-/Zeit-Darstellung (Nutzer; Ansatz entworfen + zur Diskussion). Statt nur „Di 08:00 Uhr" (mehrdeutig) generell Wochentag + Uhrzeit + Datum + relativen Bezug („heute/morgen/nächste Woche Dienstag"). Vorgeschlagener Ansatz: ein zentraler FormatterformatZeitpunkt(ts,{now,stil})(Single-Source analogphase.ts), distanz-abhängig (heute/morgen relativ · gleiche Woche Wochentag+Datum · nächste Woche „nächste Woche Di, Datum" · weiter volles Datum · Vergangenheit analog), Datum immer ab >übermorgen, Tooltip = voller absoluter Zeitstempel, locale-aware (OP-I18N-1); ersetzt die ad-hoc-toLocale*-Aufrufe + die bestehende „morgen 08:00"-Logik überall (Karten/Gantt-Tooltips/Detail/Tafel/Shell/Annahme). Offen (Diskussion): Schwellen, Kurz-/Langform je Kontext, Zeitzone/Sommerzeit. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.8 OP-DATE-1 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R8-13 neu: Konfliktvermeidungs-Hebel „Bereitschaft / (genehmigte) Wunschfrei heranziehen" (Nutzer, als Beispiel). Bei Termin-/Kapazitätskonflikt (§5.2.3) zusätzliche Kapazitäts-Hebel: (1) Bereitschaft (Überlauf-/Bereitschaftsschicht öffnen), (2) (genehmigte) Wunschfrei (weichen Frei-Wunsch zugunsten der Konfliktlösung überschreiben). Bausteine + Pönale-Reihung existieren aus OP-OPT-7 (Wunsch 2 < Bereitschaft 5 < genehmigte Überstunde 200 → weichste Quelle zuerst); neu = als konkrete, quantifizierte Hebel im Konflikt-Wizard, Propose-not-execute. ⚠ Zu klären: das „Ziehen" einer genehmigten Wunschfrei braucht ggf. MA-Zustimmung/Benachrichtigung (arbeitsrechtlich/Fairness sensibel) + Audit (OP-AUDIT-1). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.2 OP-R8-13 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R3-5 neu: Reihenfolge der Prozessschritte hart durchsetzen — kein Überspringen (Nutzer). Ein Schritt startet erst, wenn die laut Abhängigkeit (nach_vorherigem) vorausgehenden erledigt sind; kein Out-of-Order-Start/Überspringen von Pflicht-Schritten (Guard inteilschritt.aktion; der Optimierer respektiert Abhängigkeiten bereits hart §6.1 — hier geht es um die manuelle Ausführung/UI); schließt die Flow-Analyse-Lücke (Start Schritt 3 vor Schritt 1). ⚠ Abgrenzung/Konsistenz (OP-DOCS-9): scheinbarer Widerspruch zu bestehenden Skip-Mechanismen —optional-Schritte (F05), Konflikt-Hebel „optionalen Schritt überspringen" (§5.2.3),frei/parallel-Abhängigkeit (G-1), Klärfall „Sprung zu QS"; Leitlinie: Pflicht-Schritte mitnach_vorherigem= hart/nicht überspringbar, abweichen nur explizitoptional/frei/parallel+ Klärfall; zu entscheiden: ob „kein Überspringen" auch optionale Schritte sperrt (Konflikt mit Skip-Hebel) + Override/Audit. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R3-5 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257) — Bugfix: neu angelegte Teilschritte erscheinen nicht (auch nach Reload) (Version 0.31.1 → 0.31.2 PATCH; Build auto). Befund (Nutzer-Bug): „+ Neuer Teilschritt" (OP-CRUD-1 C3) legte die Vorlage zwar persistent an, sie war aber nirgends sichtbar. Ursache: die Teilschritte-Liste im Prozesse-Workspace wurde ausschließlich aus den Leistungen abgeleitet —buildProzessKatalogemittiert Teilschritte nur, wenn sie in einer Leistung verwendet werden (Clientprocesses.componentbauteteilschritteausprozesse()), also blieb ein neuer, noch keiner Leistung zugeordneter Teilschritt unsichtbar (auch nach Reload, da serverseitig dieselbe Ableitung). Fix: Server liefert jetzt einen vollen Teilschritt-Katalog (buildTeilschrittKatalog→ neues State-FeldteilschritteKatalog: ProzessSchrittDTO[], ALLE Vorlagen unabhängig von der Verwendung); der Client seedet die Teilschritte-Liste aus dem Katalog und reichert die „Verwendet in: …"-Info aus den Leistungen an. Verifikation: Servertypecheck+test:prozessgrün · Clientng buildgrün. Reiner Server+Client-Pfad, derived (kein Schema/Migration), kein Solver-Redeploy. Folge-Hinweis (Prod, OP-AUTH-1): die Create-/Archiv-Mutationen sind interim überistKostenAdmingegated — in Prod kann ein Nicht-Kosten-Admin keine Katalog-Einträge anlegen (lokal fail-open); die saubere Rollentrennung (Katalog-Admin ≠ Kosten-Admin) gehört zu OP-AUTH-1. Doku:server/party/leitstand.ts,client/.../leitstand.service.ts,client/.../pages/processes.component.ts,server/src/version.ts, CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Captures — reine Doku/OP) — drei neue OPs (Nutzer): OP-R3-6: Kommentare & besondere Hinweise je Teilschritt und Leistung (Katalog-Ebene) — dauerhafte Hinweise an der Vorlage (gilt bei jeder Verwendung; ≠ auftragslokaler Kommentar OP-R7-12 ≠ Modell-Besonderheit OP-R6-2),Teilschritt.hinweis/Leistung.hinweis(Text + Foto/Voice), Prozess-Editor (OP-R3-3). OP-AI-5: KI-gestützte Meeting-Minutes — Besprechungs-Protokolle (docs/betrieb/meetings/besteht) per ASR/KI: Transkript rein → Zusammenfassung auf taktano-Vokabular/Glossar („taktano lingo") →.md; offen Provider/EU-DSGVO, Glossar-Prompt-Kontext (OP-AI-3 (e)), PII-Scrubbing, Mensch-Bestätigung. OP-FIND-1 (Owner: Dominik & Julian): Sonderwünsche — Häufigkeit + Auffindbarkeit — welche Sonderwünsche kommen häufig vor (Auswertung); auffindbar über Synonyme + über den Nutzen (nicht nur Fachbegriff); später Chatbot (OP-AI-4) macht Begrifflichkeiten zugänglich; fachliche Vorarbeit Dominik/Julian. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R3-6, §11.8 OP-AI-5 + OP-FIND-1), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Captures — reine Doku/OP) — zwei neue OPs (Nutzer): OP-COST-5 (Roadmap): Rentabilitätsberechnung & Prognosen / Ziel-Tracking — Leitfrage „wieviele Aufträge muss ich noch abwickeln, um unser Ziel zu erreichen?"; kombiniert Umsatz/Marge (OP-R7-6/SevDesk) × Auslastung/Kapazität (True North 1+3) × Zielvorgabe → Forecast (Ist vs. Plan, „noch X Aufträge à Ø-Marge bis Ziel", Szenarien); grob umrissen, Konzept noch ordentlich auszuarbeiten (Ziel-Datenmodell, Forecast-Methodik, Dashboard OP-R9-10). OP-R7-17: Rabatte / Nachlässe — welche Rabatte sind möglich; auf dem Preismodell (OP-R7-6) prozentual/absolut, je Auftrag/Position/Kunde, Aktions-/Mengen-/Treue-/B2B/Kulanz; Wirkung auf Auftragswert + Marge (OP-COST-1); Audit (wer/wieviel/warum, OP-AUDIT-1); Berechtigung/Freigabe (OP-AUTH-1); Rechnung/Steuer bleibt SevDesk (OP-BILLING-1). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.3 OP-COST-5, §11.1 OP-R7-17), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, Folge-Capture — reine Doku/OP) — OP-R1-5 neu: Arbeitszeitkonten & Abfeiern + „Auftrag fertigstellen trotz Schichtende" (Nutzer). (1) Überstundenkonto (derived, §4.1) + Abfeiern (Comp-Time als planbare Abwesenheit, reduziert Verfügbarkeit wie Urlaub/Wunschfrei). (2) „Erst nach Hause, wenn das fertig ist": Auftrag/Schritt als „muss jetzt fertig" markieren → plant Überstunden (pönalisiert, mit Zustimmung), Mehrzeit → Arbeitszeitkonto (später abfeierbar) — schließt den Kreis Überstunde⇄Abfeiern. ⚠ Abgrenzung (OP-R1-4): rechtsverbindliches Konto = Datev/Lohn; taktano operativ + Export. ⚠ Flag DE/AT/CH: ArbZG-Grenzen (Höchstarbeitszeit/Ruhezeiten) bei geplanten Überstunden. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R1-5 neu), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, reine Doku/OP) — OP-PM-3 neu: OP-Priorisierung nach Dringlichkeit + rollierende 4-Wochen-Planung (Nutzer) → neues lebendes Dokumentdocs/betrieb/Roadmap.md. OPs aus §11/§4 nach Dringlichkeit gruppiert (🔴 Jetzt / 🟠 Next / 🟢 Später) + 4-Wochen-Plan (Entwurf ab 29.06): W1 Umparken-Check/OP-DATE-1/OP-R7-16, W2 OP-R7-12-Text/OP-R7-15, W3 OP-R3-4+OP-BACKOFFICE-1, W4 OP-QS-3/OP-R2-3. Status: Entwurf — Priorisierung vom PO zu bestätigen (offene Fragen: Goal der 4 Wochen, OP-R3-5 optional-skip, früh-wichtige „Später"-Themen). Lebend (Session-Start + nach Merges nachziehen, wie Sanity-Checkliste); indocs/README.md-Landkarte registriert. North Star = MVP 1.0.0. Kein Code. Doku:docs/betrieb/Roadmap.md(neu),docs/README.md, HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, reine Doku/OP) — OP-R7-7 geschärft (Roadmap): Customer Self-Service per Web-Portal + WhatsApp (Nutzer). Über den reinen Self-Service-Link hinaus ein Kunden-Kanal (Web-Portal + WhatsApp): Auftragsstatus verfolgen, Freigaben/Kostenvoranschlag bestätigen (OP-R3-4), Kommunikation, Fotos/Doku ansehen (OP-R7-12/-16), Wunsch-/Abholtermin abstimmen; Zielgruppe Customer Service; Sicherheit Token/Magic-Link bzw. IdP (OP-AUTH-1), DSGVO/EU. ⚠ WhatsApp: Business-API, Opt-in, Templates, Meta/US-Transfer datenschutzrechtlich prüfen. Indocs/betrieb/Roadmap.md(🟢 Später, Kunde/Self-Service) aufgenommen. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R7-7 geschärft),docs/betrieb/Roadmap.md, HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, reine Doku/OP) — OP-PM-3: PO-Priorisierung bestätigt + OP-R3-5 entschieden (Nutzer-Sign-off 06-28, via Rückfrage). (1) Fokus der nächsten 4 Wochen = „Annahme-Flow meisterhaft" (OP-R7-16 Fahrzeugdaten → OP-R7-12 Kommentar → OP-R7-15 Prozess-Vorschau; + OP-DATE-1 + Umparken-Check); 4-Wochen-Plan indocs/betrieb/Roadmap.mdentsprechend gesetzt. (2) E-R3-5 ✅: nur Pflicht-Schritte (nach_vorherigem) unüberspringbar; optionale/frei/parallelbleiben überspringbar, der Konflikt-Hebel „optionalen Schritt überspringen" (§5.2.3) bleibt (Lastenheft §11.1 OP-R3-5 + HANDOFF aktualisiert). (3) In-App-Feedback (OP-FEEDBACK-1) aus „Später" in Woche 2 vorgezogen (frühes Betriebs-Feedback). Kein Code. Doku:docs/betrieb/Roadmap.md,docs/fachlich/Lastenheft.md(OP-R3-5 Entscheidung), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, reine Doku/OP) — OP-R3-5 ergänzt: Konsistenz-Check bestehender Prozess-Instanzen (Nutzer). Mit der harten Reihenfolge müssen bereits materialisierteTeilschrittInstanz(E-CRUD-2) auf Status-Konsistenz geprüft werden — die frühere Heuristik ließ Out-of-Order zu, also kann ein Schritterledigtsein, obwohl einnach_vorherigem-Vorgänger noch offen ist. Vorgehen: idempotenter Prüf-/Reparatur-Lauf (schemaVersion-Migration, OP-DATA-1) + laufender Invarianten-Check (eindeutige Fälle glätten, sonst als Klärfall §5.1 markieren — nicht still überschreiben), abgesichert als blockierender Self-Test (analogtest:running-process). Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.1 OP-R3-5), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, reine Doku/OP) — OP-DOCS-11 neu: OP-Verwaltung als Single Source + Query-Views (Nutzer-Frage „GitHub Issues o. Ä. + Query in der Doku, keine Inkonsistenzen — sinnvoll?"). Befund: OPs liegen heute redundant über Lastenheft §11/HANDOFF §4/Roadmap/Timesheet/CHANGELOG → Drift-Risiko (manuell via OP-DOCS-9 gehütet). Optionen knapp verglichen: (A) Markdown-Listen Status quo; (B) GitHub Issues als Quelle (Workflow-stark, verlässt das Repo → gegen Everything-as-Code); (C) Hybrid: ein Markdown-File je OP (Frontmatter) als In-Repo-Quelle → generierte Views (analoggen-glossar.mjs), Issues optional als Spiegel; (D) In-Doc-Feedback = anderes Thema. Empfehlung (C) Hybrid — löst Inkonsistenz an der Wurzel (eine Quelle statt fünf) ohne Repo-als-Wahrheit aufzugeben. Kein Code. Doku:docs/fachlich/Lastenheft.md(§11.10 OP-DOCS-11), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/aufbereitung-folien-produktion-mvn691(PR #257, reine Doku/OP) — OP-Konsolidierung (Session 2026-06-28): Konsistenz-Audit + konsolidierter OP-Index. Audit: alle ~30 heutigen OPs in Lastenheft §11 UND HANDOFF §4 vorhanden, keine Doppel-IDs (mechanisch geprüft);check-doc-consistency+smooth-logsgelaufen — 0 neue Befunde (die 11 Warnungen sind vorbestehende Timesheet-Session-Dubletten 37–47 aus parallelen Alt-Sessions, abweichender Inhalt → manuell). Neu: Konsolidierter OP-Index indocs/betrieb/Roadmap.md— eine Tabelle aller Session-OPs (ID · Kurztitel · Dringlichkeit · Status neu/erweitert/entschieden/✅gebaut), inkl. Owner (FIND-1 = Dominik & Julian) und Code-Stände (Phasen-Rename v0.31.1, Bugfix v0.31.2). Strukturelle Entdoppelung (eine Quelle je OP) bleibt als OP-DOCS-11 vorgemerkt. Kein Code. Doku:docs/betrieb/Roadmap.md(Konsolidierter OP-Index), CHANGELOG, Timesheet (2026-06-28-aufbereitung-folien-produktion). - Branch
claude/competitive-analysis-market-entry-vb79s4(PR folgt) — Team-Seite: namenloses Mitglied benannt — „Lucas Tiede" (Doku-Site-only → kein Version-/Build-Bump). Nutzer-Angabe: „im Team: Der unbenannte heisst Lucas Tiede". Gebaut: indocs-site/src/pages/team.jsden Platzhalter-Eintrag'Mitarbeiter von Dominik'(Initialen?, To-do „Namen ergänzen") ersetzt durchname: 'Lucas Tiede'(InitialenLT, Foto-Pfad-Kommentar/img/team/lucas-tiede.jpg, To-do auf „Rolle & Titel schärfen" reduziert); die globale To-do-Zeile „Namen des Mitarbeiters von Dominik ergänzen." entfernt; Rolle/Schwerpunkte unverändert (nur der Name war offen).docs-site/static/img/team/README.mdum das Beispiellucas-tiede.jpgergänzt. Kein Code-/Solver-/Token-Change. Doku:docs-site/src/pages/team.js,docs-site/static/img/team/README.md, CHANGELOG, Timesheet (2026-06-28-competitive-analysis-market-entry). - Branch
claude/competitive-analysis-market-entry-vb79s4(PR folgt) — Mitbewerbsanalyse + Marktabschätzung/Markteintrittsstrategie als neue Produkt-Docs (OP-COMPETE-1 + OP-MARKET-1; reine Doku → kein Version-/Build-Bump, Präzedenz pure-docs 2026-06-28 optimizer-docs/glossary). Nutzer-Auftrag: „ergänze Mitbewerbsanalyse und Marktabschätzung/Markteintrittsstrategie in die docs". Befund:docs/produkt/Produkt-und-Marketing.mdhatte nur eine Mitbewerber-Beobachtung (Automotivo) + ROI-Gerüst — keine eigenständige Wettbewerbs- oder Marktsicht. Gebaut — zwei neue Business/Management-Docs (pyramidal, Mermaid, alle Zahlen/Einschätzungen als Annahme markiert + Spalte „zu validieren", Stil wie der ROI-Rechner): (1)docs/produkt/Wettbewerbsanalyse.md(OP-COMPETE-1) — Kernaussage „kein direkter Vollkonkurrent, Wettbewerb fast nur indirekt"; 4-Kategorien-Landschaft (Automotivo / KFZ-DMS / generische Tools / Status quo „Zettel & Whiteboard" = häufigster Gegner) als Tabelle + Mermaid-Positionierung, Differenzierungsmatrix (Burggraben = Domänenmodell und echte Taktung/CP-SAT — kein Wettbewerber hat beides), SWOT, Risiko-Verweise. (2)docs/produkt/Markt-und-Markteintritt.md(OP-MARKET-1) — TAM/SAM/SOM mit transparentem Rechenweg + Mermaid-Trichter (Annahme ~8–15k Betriebe DACH → SAM ~3–5k → SOM ~150–400, ARPA-Hypothese ~3.000 €/J), Segmentierung (Gewerk × Größe × Region, Beachhead = Folierbetriebe DE), Go-to-Market (Mermaid-Gantt: Pilot → Referenz → Verband/Hersteller-Hebel → Skalierung + Phasen-Tabelle, zwei Kanäle Direkt + Multiplikator), Pricing-Hypothese (verweist auf OP-BILLING-1, kein Festpreis), Compliance als Kaufanlass (E-Rechnung DE/DSGVO). Entscheidungen: (a) zwei eigene Docs (statt Einbau/Kombi) — je eigene OP-ID, Pattern „ein Doc pro Belang"; die belegte Automotivo-Tabelle bleibt im Produkt-Doc, der Rest verlinkt; (b) Gerüst mit markierten Annahmen statt erfundener Präzision — Validierung via Pilot/Verbandsstatistik vor großer Vertriebsinvestition; (c) kein Version-Bump (reine Doku). Registriert:docs/README.md(produkt-Tabelle),docs/zielgruppen/Lesepfade.md(§Fach),docs/konventionen/IDs.md(OP→Doc), HANDOFF (§2 + §4 OP-COMPETE-1/OP-MARKET-1),docs/betrieb/Risikoregister.md(RISK-13 Wettbewerber kopiert Nische, RISK-14 Markt zu klein/SOM überschätzt), Produkt-und-Marketing.md (Querverweis-Block). Glossar (docs-site/src/glossar/glossar.mjsSingle-Source →npm run glossar): vier neue fachliche Begriffe TAM/SAM/SOM · Beachhead · ARPA · Go-to-Market (50 → 54). Verifikation: alle 3 Mermaid-Diagramme via MCP validiert (valid:true: flowchart/flowchart/gantt);npm run glossargrün (54 Begriffe/4 Rubriken). Kein Code-/Solver-/Token-Change. True North: indirekt (Business-Entscheidungsgrundlage · „Dokumentation als Meisterwerk"). Doku:docs/produkt/Wettbewerbsanalyse.md(neu),docs/produkt/Markt-und-Markteintritt.md(neu),docs/produkt/Produkt-und-Marketing.md,docs/README.md,docs/zielgruppen/Lesepfade.md,docs/konventionen/IDs.md,docs/betrieb/Risikoregister.md,docs-site/src/glossar/glossar.mjs,docs/glossar/Glossar.md(generiert), HANDOFF, CHANGELOG, Timesheet (2026-06-28-competitive-analysis-market-entry). - Branch
claude/op-register(PR folgt) — Doku: „OP- & Entscheidungs-Register" (navigierbarer Gesamt-Index) (Doku-only → kein Version-Bump). Nutzer: „eine explizite Seite mit den OP und weiteren Entscheidungspunkten — keine Duplikate, ggf. verlinken". Neudocs/konventionen/Register.md: ein Einstieg zu allen offenen Punkten (OP-*, thematisch gruppiert; Modul-FamilienOP-R*-nals Sammelzeile) und allen Entscheidungen/Constraints (G·A·S·UC·E) — je ID · Kurz-Gloss · Link. Bewusst Duplikat-frei („Nicht-Duplikat-Vertrag"): Status/Detail bleibtHANDOFF.md§4, ID→Owning-Doc bleibtIDs.md, G/A/S/UC-Definitionen bleiben Lastenheft §2/§3/§9/§10, E-* in den Owning-Docs — das Register verlinkt nur. Quervernetzt:docs/README.md(Lesepfad „Architektur-Entscheidung nachschlagen" + konventionen-Tabelle) unddocs/konventionen/IDs.md(Kopf-Hinweis) zeigen aufs Register; IDs.md bleibt die kuratierte Owning-Doc-Lookup (Arbeitsteilung, kein Voll-OP-Index-Duplikat). Entscheidung: Register = Navigations-Index, keine Status-/PR-Pflege (die bleibt HANDOFF §4/CHANGELOG); Modul-OP-Familien gruppiert statt ~50 Sub-IDs transkribiert (Drift-arm). Reine Doku, kein Code/Token/Schema. Verifikation: alle Doku-internen Links existieren (geprüft);check-doc-consistency.shohne neue Befunde. Doku:docs/konventionen/Register.md(neu),docs/README.md,docs/konventionen/IDs.md, CHANGELOG, Timesheet (2026-06-28-op-register). - Branch
claude/klaerfaelle-workspace(PR folgt) — OP-UX-2 / U8: Klärfälle-Workspace (Störung-Achse: Sicht + Zähler) (Version 0.31.0 → 0.32.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): Folge aus U7 — die in U7 entwirrten zwei roten Warn-Achsen symmetrisch machen: die Termin-Achse hatte mit dem Konflikte-Workspace + Nav-Badge ein Zuhause, die Störung-Achse (Klärfall) nur Inline-Anzeigen. Gebaut (reiner Client-Pfad): neuer Workspace „Klärfälle" (client/src/app/leitstand/pages/klaerfaelle.component.ts; Cluster Steuerung, nach Konflikte; Signaturfarbe--tk-ws-klaerfaelle= Amber/Gold#f59e0b, Glyph ⚠, Route/klaerfaelle) — listet alle Aufträge mit aktivemklaerfall(svc.klaerfaelle()), dringlichkeits-sortiert (eskaliert zuerst, dann am längsten ungeklärt viaklaerfall.seit); je Zeile Auftragsnummer · ★ ·⚠ eskaliert-Pille · Grund · „seit … · X offen"; Klick → geteiltesauftrag-detail-panelmit bestehendem „✓ Klärfall lösen" (keine eigene Lös-Logik). Service:klaerfaelle+klaerfaelleCount(computed) → Nav-Badge. Token--tk-ws-klaerfaelleintokens.json(+build.mjs-NAME-Map) →npm run tokens→tokens.css. Entscheidung (Sign-off): Workspace-Signaturfarbe Amber/Gold (nicht rot) — rot bleibt der Termin-Achse (Konflikte) vorbehalten; die inline Klärfall-Pille bleibt rot. Damit haben beide Warn-Achsen je Liste + Badge (Symmetrie). Kein Server/Solver/Schema (Klärfall-Modell + Handler bestehen, OP-R3-1). Verifikation:ng buildgrün · No-Hex grün (Hex nur intokens.json) ·persistence:checkgrün · Token-Staleness grün (npm run tokenslief). Doku:docs/architektur/Operative-Durchgaengigkeit.md(OP-UX-2/U8 ✅),design/COMPONENTS.md+WORKSPACES.md+DESIGN_TOKENS.md,docs/konventionen/IDs.md(OP-UX-2-Zeile), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-klaerfaelle-workspace). - Branch
claude/team-lucas-tiede(PR #253) — Team-Seite: Platzhalter „Mitarbeiter von Dominik" → „Lucas Tiede" (Docs-Site-only → kein Version-Bump). Nutzer: „‚Mitarbeiter von Dominik' durch ‚Lucas Tiede' ersetzen". Indocs-site/src/pages/team.jsdie Platzhalter-Person konkretisiert: NameLucas Tiede, InitialenLT(Avatar-Fallback), Foto-Pfad-Hinweis/img/team/lucas-tiede.jpg, To-do auf „Rolle & Titel schärfen" reduziert; den erledigten Listenpunkt „Namen des Mitarbeiters von Dominik ergänzen" aus den Team-To-dos entfernt. Reine Inhalts-/Doku-Änderung, kein Code/Token/Schema. Doku:docs-site/src/pages/team.js, CHANGELOG, Timesheet (2026-06-28-team-lucas-tiede). - Branch
claude/warn-achsen-entwirren(PR #252, gemergt) — OP-UX-1 / U7: Zwei rote Warnsysteme entwirrt (Störung-Achse ⚠ vs. Termin-Achse) (Version 0.30.0 → 0.31.0 MINOR — UX-Optimierung; Build auto, OP-PM-2). Auftrag (Nutzer): die zwei roten Warnsysteme entwirren (Backlog aus dem Flow-Audit). Befund: Auf der Werkstatt-Tafel kollidierten zwei rote Signale gleicher Optik (--tk-red/danger-bg) für Verschiedenes — eine Zeile konnte−3T über(rote Reserve-Pille) +⚡ überfällig(rotes Flag) +⚠ Klärfall(rotes Flag) zeigen: drei rote Pillen, zwei davon für dieselbe Termin-Bedingung. Gebaut (tafel.component.ts): zwei klar getrennte Achsen — (1) Störung-Achse = Klärfall ⚠ (rot), das einzige rote Flag (Prozess-Störung, Mensch muss eingreifen); (2) Termin-Achse = Reserve-Pille mit Schweregrad statt zweitem rotem Icon:≥0grün ·−1…−3Tamber (Achtung) ·≤−4Trot (Warnung) — die 4-Tage-Schwelle spiegelt die Konflikte-Triage (conflicts.component) → eine Termin-Logik über beide Sichten. Das redundante⚡ überfällig-Flag auf der Tafel entfällt (die Reserve-Pille trägt die Termin-Achse, quantifiziert + mit Tooltip). Effekt: Rot auf einer Zeile heißt jetzt Klärfall (Eingriff) oder ernster Verzug (≤−4T) — nicht mehr jeder kleine Slip. Entscheidungen: (a) Termin-Achse quantifiziert (Reserve-Pille) statt generisches rotes Icon; (b) Schweregrad-Farbe (Amber=Achtung/Rot=Warnung) statt binär, an die Konflikte-Schwelle (4 T) angeglichen; (c)⚠reserviert für die Störung-Achse. Folge-Idee (offen): symmetrische Klärfall-Sicht/-Zähler (Störung-Achse) analog zum Konflikte-Workspace — eigener OP, falls gewünscht. Verifikation:ng buildgrün (Template-Typecheck) · No-Hex grün (nur Tokens). Reiner Client-Pfad, kein Server-/Solver-/Schema-Change. Doku:docs/architektur/Operative-Durchgaengigkeit.md(U7 ✅ + Backlog-Zeile),design/COMPONENTS.md(„Warn-Achsen"-Pattern), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-warn-achsen-entwirren). - Branch
claude/annahme-zuletzt-update(PR #251, gemergt) — OP-UX-1 / U5: „Zuletzt angenommen"-Panel + Kunde/CRM nachtragen (Version 0.29.0 → 0.30.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): rechts im Annahme-Schirm die zuletzt angenommenen Fahrzeuge zeigen — „falls man noch etwas nachtragen möchte". Gebaut: (Server) neue Messageauftrag.update({ id, kunde: {name?, crmLink?} }) — ändert nur die R5-v1-Kunde-Felder eines bestehenden Auftrags (Name bleibt Pflicht), schreibt ein Audit-Eventauftrag.aktualisiert(OP-AUDIT-1, Actor aus der per-Connection verifizierten Access-E-Mail) + Chronik-Eintrag und broadcastet; kein Leistung-/Termine-Edit. Neuer per-Connection-connEmail-Actor-Map (alle Verbindungen, nicht nur Kosten-Admins). (Client) Annahme-Workspace jetzt zweispaltig (grid lg:grid-cols-[minmax(0,1fr)_340px], stapelt mobil): rechts „Zuletzt angenommen" mit den letzten ~6 aktiven Aufträgen (neueste zuerst, sortiert über die Anlage-Reihenfolge ausidAU-<seq>— keincreatedAtvorhanden); je Zeile Auftragsnummer · Status · Kunde, Inline-„✎ nachtragen" für Kunde-Name + CRM-Link →updateAuftragKunde+ Toast; CRM-Link klickbar. Entscheidungen (Sign-off): (a) Kunde/CRM nachbearbeitbar (statt nur Schnellzugriff) — neueauftrag.update-Aktion, bewusst eng auf die R5-v1-Felder begrenzt; (b) Recency überAU-<seq>(kein neues Timestamp-Feld). Verifikation: Servertsc+operativgrün ·ng buildgrün · No-Hex +persistence:checkgrün. ➡ OP-UX-1 inkl. aller Annahme-Slices komplett (U1–U6). Reiner Server+Client-Pfad, kein Solver-Redeploy, kein neues Schema (Kunde-Feld bestand). Doku:docs/architektur/Operative-Durchgaengigkeit.md(U5 ✅), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-annahme-zuletzt-update). - Branch
claude/annahme-reopt(PR #250, gemergt) — OP-UX-1 / U6: Reopt bei Annahme (globale CP-SAT-Optimierung nach Anlage) (Version 0.28.0 → 0.29.0 MINOR — neues Verhalten; Build auto, OP-PM-2). Auftrag (Nutzer-Sign-off): die Annahme soll zusätzlich eine globale Reopt anstoßen, damit der neue Auftrag sofort optimal unter allen eingeplant wird. Gebaut:auftrag.createist jetzt einREOPT_EVENT— nach erfolgreichem Anlegen läuft (wie beiliefern/starten/teilschritt.aktion/verzoegerung) automatisch ein globaler CP-SAT-Reopt (aktualisiereVorschlaegeAuto, TS-Fallback), der den neuen Auftrag optimal unter allen einplant und das Ergebnis als Idee/Vorschlag in den Feed schiebt (Propose-not-execute, §7 — kein stilles Umplanen). Der Dry-Runauftrag.pruefenlöst keinen Reopt aus (reine Vorschau). Damit ist die Solver-Frage vollständig beantwortet: TS-Machbarkeit sofort bei der Prüfung, CP-SAT-Global-Reopt nach Anlage (als Vorschlag). Entscheidung: exakt das bestehende Event-Reopt-Muster wiederverwendet (kein neuer Solver-Pfad, kein Auto-Apply — konsistent mit „Propose-not-execute"). Verifikation: Servertsc+operativgrün. Einzeiler im Server-Pfad (REOPT_EVENTS +=auftrag.create), kein Solver-Redeploy, kein Schema-Change. Doku:docs/architektur/Operative-Durchgaengigkeit.md(U6 ✅), HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-annahme-reopt). - Branch
claude/annahme-preis-vorschau(PR #249, gemergt) — OP-UX-1 / U4: Annahme-Vorschau (Preis & Reserve) + „Wirklich anlegen?"-Bestätigung (Version 0.27.0 → 0.28.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag (Nutzer): vor dem Anlegen erst Preis + Reserve zeigen und „Wirklich anlegen?" abfragen (kostenpflichtiger Auftrag); plus die Frage „läuft bei der Prüfung nicht auch der Solver?". Solver-Antwort: die Annahme-Prüfung läuft den TS-Scheduler (angebot()/scheduleLeistung, synchron im DO) — schnelle Einzelauftrags-Machbarkeit; der CP-SAT (SOLVER_URL) macht die globale Mehrauftrags-Optimierung (separat, event-getriggert; eine Reopt-bei-Annahme folgt als Slice U6). Gebaut: (1) Preismodell (OP-R7-6 erster Schnitt):Leistung.grundpreisCent(Seed: Basic 1.400 € < Premium 3.200 € < Super-Premium 4.800 €; optional → keine Migration), pure Summen-FunktionauftragspreisCentinserver/src/operativ/preis.ts(+ Self-Testtest:preis+ CI-Step), Preis-SnapshotAuftrag.preisCentbei Anlage; Picker zeigt „ab X €". Güteklasse-/Anspruch-Zuschläge bleiben OP-R7-6-Folge. (2) Vorschau-Dry-Run: neue Messageauftrag.pruefen+ServerMsgauftrag.pruefen.result(per-Connection, Muster wie U3b) — läuftangebot(), leitet Machbarkeit + Reserve (floor((abholtermin−earliest.completion)/1440)) + Preis ab, legt nichts an. (3) Annahme-UI zweistufig: „Prüfen & anlegen" → Spinner „prüft …" → bei Machbarkeit Bestätigungs-Dialog (Kunde · Leistung · Termine · Reserve grün/rot · Preis · ggf. Termin-Warnung) mit „Abbrechen" / „✓ Wirklich anlegen (kostenpflichtig)" → erst Bestätigung ruftauftrag.create; nicht machbar → Grund inline (kein Dialog). Entscheidungen (Sign-off): (a) einfaches Preismodell jetzt (Grundpreis je Leistung) statt Preis vertagen; (b) Geld als Cent-Integer (wieinfraKosten.betragCent); (c) Reserve/Preis über einen echten Dry-Run statt optimistischer Anzeige. Verifikation: Servertsc+test:preis+operativ+test:running-process+spikegrün ·ng buildgrün · No-Hex +persistence:checkgrün ·ci.ymlstrict-YAML (keine Dup-Keys). Reiner Server+Client-Pfad, kein Solver-Redeploy. Doku:docs/architektur/Operative-Durchgaengigkeit.md(U4 ✅), HANDOFF (§4, OP-R7-6-Notiz), CHANGELOG, Timesheet (2026-06-28-annahme-preis-vorschau). - Branch
claude/optimizer-docs-rationale-ypqmcl(PR folgt) — Doku: Problematik der Optimierung + Begründung der mehreren Optimierer indocs/fachlich/solver.md(reine Doku → kein Version-/Build-Bump). Nutzer-Auftrag: „beschreibe in der Doku die Problematik bei der Optimierung, auch warum es die unterschiedlichen Optimierer gibt". Gebaut: zwei vorangestellte, pyramidale (Minto — Kernaussage zuerst) Abschnitte: §1 Die Problematik: Warum Taktung schwer ist — benennt das Problem als NP-schwer (verwandt mit Job-Shop-Scheduling) mit vier Treibern: (a) kombinatorische Explosion (Reihenfolge N! + voller Entscheidungsraum Startzeit/Bucht/Mitarbeiter), (b) widersprüchliche Ziele (§6.2: Durchlaufzeit ↔ Makespan ↔ Wechsel G-2 ↔ Lücken G-3 → bewusste lexikografische Reihenfolge nötig), (c) gekoppelte harte Constraints (§6.1: Skill, Bucht-No-Overlap+Cool-down, Abhängigkeiten, Standzeit, getypte Parkplätze), (d) Dynamik + Worker-Laufzeit (harte Reservierungen, Eilaufträge, live; CF Worker/DO kann OR-Tools nativ nicht ausführen). §2 Warum es mehrere Optimierer gibt — das Konflikt-Dreieck Optimalität × Antwortzeit × Worker-Lauffähigkeit lässt sich nicht gleichzeitig maximieren → gestaffelte Kaskade mit Fallback (Greedy-Decoder → TS-Decoder-Optimierer → CP-SAT-Service), mit Vergleichstabelle (Code/Freiheitsgrade/Optimalität/Tempo/Worker/Rolle), Dispatch-Mermaid (Laufzeit-Auswahl im Leitstand) und expliziter „warum nicht nur einer?"-Begründung (graceful degradation). Entscheidung: bestehende Lösungs-Beschreibung beibehalten, aber die Problematik & Rationale pyramidal voranstellen (statt nur „Ansatz") — die Folgeabschnitte (Ansatz/Zielfunktion/Demo/CP-SAT/Leitstand) wurden 1→3 … 5→7 umnummeriert und mit Querverweisen verzahnt. Verifikation: neues Mermaid via MCP validiert (valid:true, flowchart);check-doc-consistency.shzeigt nur Vorbestands-Timesheet-Dubletten (union-Merge), nichts Neues. Kein Code-/Solver-/Token-Change. True North: indirekt (Selbsterklärbarkeit · „Dokumentation als Meisterwerk"). Doku:docs/fachlich/solver.md, CHANGELOG, Timesheet (2026-06-28-optimizer-docs-rationale). - Branch
claude/glossary-classification-filtering-vpb0ub(PR folgt) — OP-DOCS-10 Slice 2: Glossar-Klassifikation (Art × Ebene) + interaktiver Filter; Lesepfade/Glossar/Sprechblasen auf der Startseite; Sidebar-Rubrik umbenannt (Doku-Site-only → kein Version-/Build-Bump, Präzedenz Slice 1/#205/#206). Drei Nutzer-Wünsche: (1) Glossar-Begriffe nach technisch/fachlich klassifizieren und je Art nach Grundprinzip vs. erweiterter Liste, jeweils sinnvoll filterbar („um sich einen Eindruck zu verschaffen"); (2) Lesepfade nach Zielgruppe auf die Doku-Startseite + dort Mouse-over und Glossar erwähnen; (3) Sidebar-Rubrik „Betrieb · Compliance · Governance" → „Governance · Compliance". Gebaut — selbe Single-Source (docs-site/src/glossar/glossar.mjs): zwei neue Pflichtfelder je Eintragart(fachlich|technisch) +ebene(grund|erweitert) + Label-MapsART/EBENE; alle 50 Begriffe klassifiziert (Fachlich 20 = 7 Grund/13 Erw · Technisch 30 = 6 Grund/24 Erw). Generatorscripts/gen-glossar.mjsgruppiert in vier Rubriken (stabile Anchor#kat-fachlich-grundu. a., Begriffe alsh3+ Badges 🔧/💻 · ⭐/➕, Erklär-Sektion + Anzahl-Matrix) → dieGlossar.mdliest sich schon statisch (GitHub) als Filter/Eindruck. Interaktiv auf/docs/glossar/: neues Client-Modulsrc/clientModules/glossarFilter.js(registriert indocusaurus.config.js, Styles insrc/css/custom.css, kein Hex → Infima-Variablen) baut eine Filter-Leiste — Chips Art × Ebene + Volltext-Suche + Trefferzähler; blendet Einträge/Rubriken datengetrieben (importiertGLOSSAR) per Heading-#idein/aus; ohne JS bleibt die Seite voll lesbar. Startseitesrc/pages/index.js: Button „Lesepfade nach Zielgruppe" + Absatz, der die vier Zielgruppen-Pfade nennt und auf Mouse-over/Klick-Sprechblasen + Glossar (filterbar) hinweist. Rubrik-Umbenennung in allen kanonischen Quellen (docs/betrieb/_category_.jsonLabel+Title,docs/README.md,docs/betrieb/meetings/README.md). Entscheidungen: (a) Klassifikation als zwei orthogonale Achsen (Art × Ebene) statt flacher Liste; (b) Filter datengetrieben aus der Single-Source (keine DOM-Heuristik); (c) kein App-Bump (Doku-Site-only). Verifikation:npm run build(Docusaurus) grün; Playwright gegen den Build: Leiste vorhanden, „Technisch" → 30, „Technisch+Grundprinzip" → 6 (nurkat-technisch-grundsichtbar), Suche „makespan" → 4; Startseite zeigt Lesepfade/Mouse-over/Glossar; Label „Governance · Compliance" im Build, alte Bezeichnung nirgends mehr. Kein Code-/Solver-Change. Doku:docs-site/src/glossar/glossar.mjs,docs-site/scripts/gen-glossar.mjs,docs/glossar/Glossar.md(generiert),docs-site/src/clientModules/glossarFilter.js,docs-site/docusaurus.config.js,docs-site/src/css/custom.css,docs-site/src/pages/index.js,docs/betrieb/_category_.json,docs/README.md,docs/betrieb/meetings/README.md,CLAUDE.md, HANDOFF (§4), CHANGELOG, Timesheet (2026-06-28-glossary-classification-filtering). True North: indirekt (Selbsterklärbarkeit/Doku als Meisterwerk). - Branch
claude/op-ux-empty-states(PR folgt) — Einheitliche Leere-Zustände (app-empty-state) (Version 0.26.0 → 0.27.0 MINOR — neue wiederverwendbare Komponente + UI-Konsistenz; Build auto, OP-PM-2). Auftrag: „inkonsistente Leere-Zustände vereinheitlichen" (Flow-Audit-Backlog, OP-UX-1). Problem: Inventur fand 25 „Keine …"-Platzhalter quer durch die Workspaces — alle inline/ad-hoc, nur 2 reich, 20 dünn; manche ließen den Nutzer in einer Sackgasse. Gebaut: eine Standalone-Komponenteclient/src/app/leitstand/empty-state.component.ts(Signal-Inputsvariant/glyph/glyphColor/title/sub/dashed, optionaler CTA-Slot via<ng-content>) mit 3 Varianten — card (Voll-Raum,dashed=„wartet auf Daten"), bare (in bestehender Karte, ohne Rahmen), inline (verschachtelte Unterliste, eine gedämpfte Zeile). Alle Fundstellen migriert (~12 Dateien: tafel, meine-arbeit, orders, conflicts, quality, recommendations, overview, annahme, processes, administration, staff, insights-panel). CTAs ergänzt, wo der Flow es trägt (Nutzer-Entscheidung): leere Tafel/Aufträge → „+ Auftrag annehmen" (/annahme), Überblick „keine Produktion" →/annahme, Vorschläge leer → „Zur Planung" (/planning), Annahme ohne Leistung → „Zu Prozesse" (/processes); Erfolgs-/Auswahl-Prompts (keine Konflikte/Endkontrollen, „Auftrag wählen") bleiben CTA-frei. Entscheidungen (Sign-off): (a) Shared-Komponente + alle migrieren (statt nur die dünnen primären aufwerten); (b) CTAs hinzufügen, wo es den Flow trägt. Glyph-Farbe = Workspace-Signatur, wo es Identität stärkt; Erfolg =var(--tk-green). Nur--tk-*-Tokens (No-Hex). Verifikation:ng buildgrün · No-Hex-Gate grün. Reiner Client + Doku, keine Token-/Schema-/Server-/Solver-Änderung. Doku:design/COMPONENTS.md(## Empty state), HANDOFF (§2), CHANGELOG, Timesheet (2026-06-28-op-ux-empty-states). - #245 (gemergt) — OP-UX-1 / U3b: Machbarkeits-Rückmeldung der Annahme (Version 0.25.0 → 0.26.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag: „Infeasibility-Rückmeldung" (Folge-Punkt aus U3). Problem:
auftrag.createwar fire-and-forget — bei nicht machbarem Plan legte der Server still nichts an, der Anwender bekam kein Feedback. Gebaut: (Server)auftrag.createantwortet jetzt der anlegenden Verbindung über eine neueServerMsg-Varianteauftrag.create.result(conn.sendinonMessage): abgelehnt (ok:false) mit konkretem Grund — strukturell nicht planbar →ScheduleResult.reasonaus dem fehlgeschlagenen Schritt (z. B. kein qualifizierter Mitarbeiter/keine passende Bucht für die Güteklasse), plus Validierung „Abholung muss nach Anlieferung liegen" / „ungültige Zeitangaben"; angenommen (ok:true) mit Auftragsnummer + optionaler Termin-Warnung, wenn der Auftrag planbar ist, aber frühestens nach der Wunsch-Abholung fertig wird (earliest.abholbereit > abholtermin,formatIso). (Client) neuesLeitstandService.auftragCreateResult-Signal (gesetzt aus dem Socket-Handler,seqmacht jede Antwort eindeutig); der Annahme-Workspace zeigt jetzt einen Spinner („prüft …", Button deaktiviert), bei Erfolg Toast + Formular-Reset (+ ggf. Termin-Warn-Toast), bei Ablehnung den Grund inline (rot) + Toast, Formular bleibt zum Korrigieren; 8-s-Sicherheitsnetz gegen hängenden Spinner (z. B. Verbindungsabriss). Entscheidungen: (a) per-Connection-Antwort (kein Broadcast — nur der Anleger sieht das Ergebnis), Muster wie die per-Connection State-Sends; (b)reasonaus dem Scheduler durchreichen statt generischer Text (konkret = handlungsleitend); (c) Deadline-Miss bleibt nicht-blockierend (Auftrag wird angenommen + Warnung), nur strukturelle Infeasibility lehnt ab — verhaltenskonsistent zu vorher. Verifikation: Servertsc+operativ+test:running-processgrün ·ng buildgrün · No-Hex-Gate grün. Reiner Server+Client-Pfad, kein Solver-Redeploy, kein neues Schema. Doku:docs/architektur/Operative-Durchgaengigkeit.md(U3b ✅), HANDOFF (OP-UX-1 §4), CHANGELOG, Timesheet (2026-06-28-op-ux-u3b-annahme-feedback). - #244 (gemergt) — OP-UX-1 / U3: Annahme „Auto kommt → Auftrag anlegen" → OP-UX-1 vollständig (Version 0.24.0 → 0.25.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag: „u3". Entscheidung vorab (Nutzer-Sign-off 06-28): E-UX-3 = eigener Annahme-Workspace (statt „+ Auftrag"-Button). Gebaut: (1) Workspace „Annahme" (
client/src/app/leitstand/pages/annahme.component.ts, Route/annahme, erster Eintrag im Operativ-Cluster = Start des Flows, Signaturfarbe--tk-ws-annahme[neuer Token], Glyph ⊕): Formular (Single-Modal-Geist, S-1) Kunde (Name + CRM-Link) · Leistung (Picker aus aktivem Prozess-Katalogprozesse()) · Güteklasse + Anspruch (Segmente) · Anlieferung + Wunsch-Abholung (datetime-local, UTC) · Termin-Härte → bestehenderauftrag.create-Handler (prüft Machbarkeit im Angebotsmodus, legt nur machbare Aufträge an); Eingabe-Validierung clientseitig, Erfolg-Toast, Formular-Reset. Ersetzt die Demo-Buttons als realer Eingang. (2) Kunde v1 neu im Datenmodell (R5-v1 — war in §4.9 spezifiziert, aber nie gebaut):Auftrag.kunde = {name, crmLink?}+AuftragMeta.kunde, inmaterialisiereAuftraggesetzt, imauftrag.create-Handler sanitisiert (Name-Pflicht, sonst weggelassen), intoAuftragDTO+ Client-AuftragDTOexponiert. Optionales Feld → keine Migration. Entscheidungen: (a) eigener Workspace (E-UX-3); (b) Kunde = nur Name + CRM-Link am Auftrag (kein eigenes Kundenobjekt, Voll-Modell = FR-1); (c) Machbarkeits-/Infeasibility-Rückmeldung bewusst als Folge-Punkt vermerkt (heute kein Feedback bei nicht machbarem Plan — braucht Request/Response-Kanal). ➡ OP-UX-1 VOLLSTÄNDIG (U1 Tafel · U2 Meine Arbeit · U3 Annahme gebaut; E-UX-1…3 entschieden) — der Flow ist von der Vordertür bis zur Abholung durchgängig. Verifikation: Servertsc+operativ+replan+test:teilplan+test:running-process+test:archivgrün ·ng buildgrün · No-Hex-Gate grün ·tokens.cssneu generiert (nicht stale). Reiner Server+Client-Pfad, kein Solver-Redeploy. Doku:docs/architektur/Operative-Durchgaengigkeit.md(U3 ✅ + E-UX-3 ✅),design/DESIGN_TOKENS.md(Workspace-Farben tafel/werker/annahme nachgezogen), HANDOFF (§2+§4), CHANGELOG, Timesheet (2026-06-28-op-ux-u3-annahme). - #243 (gemergt) — OP-UX-1 / U2: Werker-Sicht „Meine Arbeit" (Version 0.23.0 → 0.24.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag: „dann U2". Entscheidungen vorab (Nutzer-Sign-off 06-28): E-UX-2 = eigener Workspace „Meine Arbeit" (statt Filter-Modus der Tafel) + Mitarbeiter-Picker (Schichtterminal) als Identität für den ersten Slice (echtes Per-MA-QR/Login = R1-Future). Gebaut: neuer touch-/tablet-tauglicher Workspace (
client/src/app/leitstand/pages/meine-arbeit.component.ts, Route/meine-arbeit, Nav-Cluster Operativ, Signaturfarbe--tk-ws-werker[neuer Token intokens.json→npm run tokens], Glyph ⬣): Schichtterminal-Picker (aktive Mitarbeiter, Offen-Badge je Person) → darunter nur seine offenen/laufenden Schritte über alle aktiven Aufträge (produktiv ausmitarbeiterIds, zusätzlich als 🎓 Helfer aushelferIds), laufend zuerst sortiert; je Schritt Auftrags-Kontext (Nr./★/Bucht/📍 Standort) + große Aktionen ⏸ Pause / ▶ Weiter / ✓ Fertig überteilschrittAktion. Doku-/Foto-Pflicht (OP-R4-3) ohne Duplikat: braucht „Fertig" ein Gate (Pflicht-Kommentar/-Fotos), führt der Klick ins geteilte Detail-Panel (dort lebt Gate + Foto-Upload); sonst direkt erledigt; Inline-Hinweis nennt das Fehlende. Reine Projektion des Live-States — kein neues Schema, keine Server-/Solver-Änderung (Aktionen über bestehende Handler). Macht aus dem Leitstand erstmals eine Hand-Sicht. Offen: U3 Annahme-Maske (E-UX-3). Verifikation:ng buildgrün · No-Hex-Gate grün ·tokens.cssneu generiert (nicht stale) · Servertscgrün. Doku:docs/architektur/Operative-Durchgaengigkeit.md(U2 ✅ + E-UX-2 ✅), HANDOFF (§2+§4), CHANGELOG, Timesheet (2026-06-28-op-ux-u2-meine-arbeit).
2026-06-27
- #242 (gemergt) — OP-UX-1 / U1: Werkstatt-Tafel — durchgängige Auftragszeile (Version 0.22.0 → 0.23.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag: Flow-Audit „ein Auto kommt, was passiert dann? Ist die UI/UX ein echtes Meisterwerk?" → Befund: Cockpit nahe am Meisterwerk, aber Alltags-Fakten über drei Seiten (Aufträge · Gantt · Belegung) verstreut, keine Werker-Sicht, keine echte Annahme-Maske → als OP-UX-1 aufgenommen + Design-Doc, Slice U1 (Dashboard) gebaut. Gebaut: neuer Workspace „Tafel" (
client/src/app/leitstand/pages/tafel.component.ts, Route/tafel, Nav-Cluster Überblick, Signaturfarbe--tk-ws-tafel[neuer Token intokens.json→npm run tokens], Glyph ▤): je aktivem Auftrag eine Zeile mit Auftragsnummer/★ · Status- + Phase-Pill · aktuellem Schritt (in_arbeit→pausiert→nächster geplanter) mit Mitarbeiter-Namen + Bucht · 📍 Standort · Fortschrittbalken (erledigt/gesamt) · Reserve · Warn-Flags (⚠ Klärfall · ⚡ überfällig · ⚠ Zuweisung nötig · ⏱ verzögert); operativ dringlichkeits-sortiert; Klick öffnet das geteilte Detail-Panel. Reine Projektion des Live-States (AuftragDTO+RessourcenDTO+employees) — Derived-State (S-2), kein neues Schema, keine Server-/Solver-Änderung. Beantwortet True-North-Frage 2 (Wo stehen die Fahrzeuge — physisch und in Bearbeitung) auf einen Blick. Entscheidung E-UX-1 ✅ = U1 als eigener Workspace (statt Umbau Aufträge/Überblick) — hält bestehende Seiten unverändert, gibt der Durchgängigkeit einen klaren Ort. Offen (dokumentiert): U2 Werker-Sicht (E-UX-2), U3 Annahme-Maske (E-UX-3). Verifikation:ng buildgrün · No-Hex-Gate grün ·tokens.cssaustokens.jsonneu generiert (nicht stale) · doc-consistency nur Vorbestands-Timesheet-Dubletten. Doku:docs/architektur/Operative-Durchgaengigkeit.md(neu),docs/README.md,docs/konventionen/IDs.md, HANDOFF (§2+§4), CHANGELOG, Timesheet (2026-06-27-op-ux-1-tafel). - Branch
claude/e-crud-4-decision(PR folgt) — OP-CRUD-1: E-CRUD-4 entschieden → OP-CRUD-1 abgeschlossen (reine Doku → kein Version-/Build-Bump). Nutzer-Sign-off (06-27): E-CRUD-4 = (A) Hart-Delete für Infra-Kosten/Foto beibehalten — die einzigen referenzfreien, nicht-historischen Entitäten (Klasse C) bleiben physisch löschbar (infraKosten.entfernen/foto.entfernen), aber mit Audit-Event (OP-AUDIT-1). Begründung: kein Schutzgewinn durch ein zweites Soft-Delete-Modell (keine verwaisten Referenzen; Audit hält den Vorgang fest); bei Fotos spricht DSGVO/„Recht auf Vergessen" sogar für echtes Löschen statt dauerhaftes Liegenlassen im R2-Speicher. ➡ OP-CRUD-1 ist damit vollständig entschieden UND umgesetzt (alle Slices C1–C4 gebaut, alle E-CRUD-1…4 entschieden): jede Entität hat ein bewusstes Lösch-/Lebenszyklus-Verhalten, der Prozess-Katalog ist voll editierbar, und die Running-process-Schutz-Invariante ist als blockierender CI-Gate gesichert. Aktualisiert:docs/architektur/Entitaeten-Lebenszyklus.md(§7), HANDOFF (OP-CRUD-1 abgeschlossen). Kein Code. Doku:architektur/Entitaeten-Lebenszyklus.md, HANDOFF, CHANGELOG, Timesheet (2026-06-28-e-crud-4-decision). - #240 — OP-CRUD-1 / C3: Prozess-Katalog Create (neue Teilschritte + Leistungen) (Version 0.21.0 → 0.22.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag: „weiter" → C3 (letzter Slice). Gebaut: (1) pure, testbare
erstelleTeilschritt/erstelleLeistunginserver/src/operativ/prozess.ts(sinnvolle Defaults: Teilschritt 30 Min [G-3-konform], 1 Person, Phaseproduktion; Leistung aktiv + leerer Prozess) + Self-Testtest:prozess(Anlegen, Defaults, leerer Name → No-op, neue Leistung sofort komponierbar). (2) Handlerteilschritt.create/leistung.create(admin-gegated; Skill/Kategorie aus msg falls gültig, sonst erste; Auditteilschritt.erstellt/leistung.erstellt); ID-GeneratorenneueTeilschrittId/neueLeistungId. (3) Client (processes.component): „+ Neuer Teilschritt"/„+ Neue Leistung"-Button je Tab (prompt-basiert). Damit ist der Prozess-Katalog voll editierbar (Create neu; Update bestand; Delete = Teilschritt-Archiv [C2] / Leistung-status-Soft). Entscheidungen: (a) Create-Logik pure inprozess.ts(CI-getestet) statt im DO; (b) neue Leistung mit leerem Prozess (Schritte folgen viasetProzess) — Running-process-Sicherheit durch E-CRUD-2 + C4-Gate bereits abgedeckt; (c) kein Hard-Delete ergänzt (Delete bleibt Soft/Archiv, OP-COMPLIANCE-1). ➡ OP-CRUD-1 bis auf E-CRUD-4 vollständig. Verifikation:typecheck+test:prozess+test:archiv+test:running-process+ Smokes +ng build+ No-Hex +persistence:checkgrün. Reiner Server+Client-Pfad, kein Solver-Redeploy. Doku:docs/architektur/Entitaeten-Lebenszyklus.md(C3 ✅ + §1-Matrix), HANDOFF (OP-CRUD-1), CHANGELOG, Timesheet (2026-06-27-op-crud-c3-katalog-create). - #239 — OP-CRUD-1 / C4: Running-process-Testmatrix (blockierender CI-Gate) (Version 0.20.0 → 0.21.0 MINOR — neue Sicherungs-/Test-Infrastruktur; Build auto, OP-PM-2). Auftrag: „weiter" → C4 (entschiedene Reihenfolge C2→C4→C3). Gebaut: Self-Test
test:running-process(server/src/operativ/running-process-demo.ts) als blockierender Server-CI-Step (vorsolve) — beweist die E-CRUD-2/Running-process-Schutz-Invariante über die purebuildProblem-Fläche: (1) Mitarbeiter archiviert →nurAktivenimmt ihn aus dem Solver-Input,buildProblemläuft ohne Crash weiter und plant dieselben Aufträge (genau der Archivierte fehlt im Pool, Auftrags-Schritte unverändert); (2) Teilschritt-Vorlage archiviert (bleibt im Input —schedulerInputfiltert Vorlagen nicht) → die Aufträge behalten alle Schritte (Resolve/Materialisierung schützt Laufendes, kein verlorener Prozessschritt). Entscheidungen: (a) Test gegen die purebuildProblem-Funktion insrc/(der DO ist nicht leicht instanziierbar) — deckt die korrektheitskritischen Eigenschaften maschinell ab; (b) als blockierender Gate verdrahtet (E-CRUD-3), damit künftige Slices (C3 Katalog-Create/Delete) die Schutz-Invariante nicht still brechen; (c)ci.ymlstrikt auf doppelte YAML-Keys geprüft (Lehre aus D5-4). Verifikation:test:running-processgrün;typecheck+ Smokes grün;ci.ymlstrict-YAML ok (keine Dup-Keys). Kein App-Laufzeit-/Verhaltens-Change (nur Test + CI), kein Solver-Redeploy. Doku:docs/architektur/Entitaeten-Lebenszyklus.md(C4 ✅), HANDOFF (OP-CRUD-1), CHANGELOG, Timesheet (2026-06-27-op-crud-c4-running-process-tests). - #238 — OP-CRUD-1 / C2: Soft-Delete vereinheitlichen — Teilschritt-Archivierung (Version 0.19.0 → 0.20.0 MINOR — neues Feature; Build auto, OP-PM-2). Auftrag: „weiter" → C2 (entschiedene Reihenfolge C2→C4→C3). Befund bei der Umsetzung: Skill (
aktiv,createreaktiviert) und Leistung (status=inaktiv, UI dimmt) haben bereits funktionierenden Soft-Delete — ein zweitesarchiviert-Flag wäre redundant; die einzige echte Lücke war Teilschritt (gar kein Flag). Gebaut: (1)Teilschritt extends Archivierbar(generisches Flag aus C1) + Handlerteilschritt.archivieren/reaktivieren(admin-gegated; Auditteilschritt.archiviert/.reaktiviertviad1Audit). (2) Running-process-Schutz (E-CRUD-2): archivierte Vorlagen werden NUR am Angebots-Punkt gefiltert (Add-Dropdown der Prozess-Komposition,angeboteneTeilschritte);buildProzessKatalogresolved sie weiter → bestehende Leistungs-Prozesse + materialisierte Auftrags-Instanzen bleiben intakt (ProzessSchrittDTO.archiviert). (3) Client (processes.component): Archivieren/Reaktivieren-Button im Teilschritt-Katalog + dimmt archivierte Vorlagen. Entscheidungen: (a) kein redundantes Flag für Skill/Leistung — ihr fachlichesaktiv/statusIST der Soft-Delete (Doku §1-Matrix nachgezogen); (b) Filterung nur am Angebots-Punkt, nicht im Resolve/Lookup (Running-process-Safety); (c) MINOR (neues Feature, verhaltensgleich für Bestehendes). ➡ Damit haben alle Klasse-A-Entitäten „archiv statt löschen". Verifikation:typecheck+test:archiv+test:prozess+ Regression-Smokes (operativ/replan/solve/teilplan) +ng build+ No-Hex +persistence:checkgrün. Reiner Server+Client-Pfad, kein Solver-Redeploy. Doku:docs/architektur/Entitaeten-Lebenszyklus.md(C2 ✅ + §1-Matrix), HANDOFF (OP-CRUD-1), CHANGELOG, Timesheet (2026-06-27-op-crud-c2-soft-delete). - #237 — OP-CRUD-1: E-CRUD-3 entschieden (Slice-Reihenfolge + Running-process-Testmatrix als Gate) (reine Doku → kein Version-/Build-Bump). Nutzer-Sign-off (06-27): Reihenfolge nach C1 ✅ = C2 → C4 → C3 (erst das generische
archiviert-Flag über die restlichen Klasse-A-Entitäten — Skill/Leistung/Teilschritt — vereinheitlichen, dann die Running-process-Testmatrix als blockierenden CI-Gate festzurren, zuletzt Prozess-Katalog Create/Delete). Die Testmatrix („archiviere/ändere Stammdatum während laufendem Prozess → läuft/pausiert sauber, kein Crash/Datenverlust") läuft als blockierender Server-CI-Job (wietest:archiv). Begründung: Konsistenz vor neuer Fläche; die Schutz-Invariante ist billige Dauer-Versicherung. Aktualisiert:docs/architektur/Entitaeten-Lebenszyklus.md(§5/§6/§7), HANDOFF (OP-CRUD-1). Kein Code. Doku:architektur/Entitaeten-Lebenszyklus.md, HANDOFF, CHANGELOG, Timesheet (2026-06-27-e-crud-3-decision). - #236 — OP-CRUD-1 / C1: Mitarbeiter-Archivierung (Archiv statt Hard-Delete) (Version 0.18.0 → 0.19.0 MINOR — neues Feature; Build auto-gestempelt, OP-PM-2). Auftrag: „Op-crud slice c1" (erste echte CRUD-Lücke aus
docs/architektur/Entitaeten-Lebenszyklus.md). Gebaut: (1) generisches Archiv-Flag (E-CRUD-1) inserver/src/model/types.ts:Archivierbar-Interface (archiviert?/archiviertAm?) +istArchiviert/nurAktive;Mitarbeiter extends Archivierbar. (2) Handleremployee.archivieren/employee.reaktivieren(admin-gegated wie übrige Stammdaten; Audit-Eventmitarbeiter.archiviert/.reaktiviertviad1Audit, OP-AUDIT-1; Ops-Log ohne PII). (3) Aus aktiver Verwendung genommen vianurAktivean allen Workforce-Punkten: SolverschedulerInput,mitarbeiterGesamt, Ausbildungs-/Niveau-Vorschläge, Engpass-Hinweis, Ausfall-/Ressourcen-Sicht — referenzstabil (Leistungsnachweise/Historie/Audit lösen archivierte weiter auf). (4) Running-process-Schutz: beim Archivieren wird der Live-Task gelöst (Schritt → Neuzuweisung, wie bei Verfügbarkeit≠aktiv) — geordnete Übergabe statt Entzug. (5) Client (staff.component): „Archivieren"-Button (Rückfrage) + eigener Archiviert-Abschnitt mit „Reaktivieren";archiviertimEmployee-DTO; aktive Zähler/Filter nutzen nur Aktive. (6) Self-Testtest:archiv+ CI-Step. Entscheidungen: (a) generisches Flag statt Status-Enum (E-CRUD-1-Sign-off) — orthogonal zuMitarbeiterStatus(fachliche Zustände bleiben),archiviert= Lebenszyklus-Dimension. (b) Kein Hard-Delete (referenzstabil/revisionssicher, OP-COMPLIANCE-1). (c) Kein Migrationsbedarf (archiviert?optional, undefiniert = aktiv) → keinSCHEMA_VERSION-Bump. (d) Cards behalten alle Mitarbeiter im DTO (mitarchiviert-Flag) → Client steuert Anzeige/Reaktivierung. Verifikation:typecheck+test:archiv+ Regression-Smokes (spike/operativ/replan/solve/teilplan/eligibility/prozess/leistung/progression) +ng build+ No-Hex +persistence:checkgrün. Reiner Server+Client-Pfad, kein Solver-Redeploy. Doku:docs/architektur/Entitaeten-Lebenszyklus.md(C1 ✅ + §1-Matrix), HANDOFF (OP-CRUD-1), CHANGELOG, Timesheet (2026-06-27-op-crud-c1-mitarbeiter-archiv). - #232 — OP-DATA-1 / D5-4: CI-Gate vereinheitlichen — Persistenz-Gate (Drizzle-Staleness + DO-State-Coverage) (Version 0.17.0 → 0.18.0 MINOR — neues CI-Gate/Tooling; Präzedenz D5-1 #230; Build auto-gestempelt, OP-PM-2). Auftrag: D5-4-Slice aus
docs/architektur/Persistenz.md§5 + das aus D5-2 vertagte Token-Muster-Gate. Gebaut: (1) DO-State-Migrations-Coverage-Gatescripts/check-do-state-coverage.mjs— Token-Muster (CLAUDE.md §Repo): jedes nicht-optionalePersistedState-Feld braucht einen explizitensaved.<feld> ??-onStart-Default; statisch/heuristisch (parst denPersistedState-Typ + den Hydrations-Merge ausleitstand.ts, kein TS-Compile). Verhindert den S-SEED-5-Schmerzpunkt (neues Feld ohne Backfill fällt erst zur Laufzeit auf). (2) Vereinheitlichtesscripts/check-persistence.sh(npmpersistence:check) bündelt Drizzle-Schema-Staleness (D5-1,check-drizzle.sh) + das Coverage-Gate in EIN Gate (analogcheck-no-hex.sh); beide Teil-Checks bleiben einzeln aufrufbar. (3) CI: der bisherigedb-check-Job →persistence-gateumbenannt (läuftpersistence:check), inci-gate-Required-Liste nachgezogen. (4)leitstand.ts: expliziterbays: saved.bays ?? this.state.bays-Default ergänzt (verhaltensgleich —bayskam bisher nur über...saved/...this.state) → Coverage-Invariante lückenlos (19/19 Pflichtfelder). Entscheidungen: (a) Coverage prüft explizitesaved.X ??-Defaults (nicht den...saved-Spread) — eindeutig, low-false-positive; der eine reale Gap (bays) wurde geschlossen statt ausgenommen. (b) Optionale Felder (schemaVersion?/demoHistorieGeseedet?) sind exempt (über die Versions-Registry bzw. falsy-Default abgedeckt). (c) Job umbenannt (idpersistence-gate) statt zweiten Job — „vereinheitlichen" wörtlich; Branch-Protection verlangt ohnehin nurCI Gate, daher kein Required-Check-Bruch. Verifikation:persistence:checkgrün (Drizzle synchron + 19/19 Felder); Negativtest (Pflichtfeld-Default entfernt → Gate exit 1 mit klarer Meldung, danach restauriert exit 0);typecheckgrün. Kein Code-/Verhaltens-Change am Laufzeitpfad (nur additiverbays-Default), kein Solver-Redeploy. ➡ Damit ist OP-DATA-1 bis auf den optionalen DO-SQLite-Pilot (D5-3) umgesetzt. Doku:docs/architektur/Persistenz.md(D5-4 ✅), HANDOFF (OP-DATA-1), CHANGELOG, Timesheet (2026-06-27-d5-4-persistence-gate). - #231 — OP-DATA-1 / D5-2: DO-Blob-Migrations-Registry (Variante A, verhaltenstreu) (Version 0.16.0 → 0.17.0 MINOR — neue, verhaltensgleiche Abstraktion; Präzedenz S-SEED-4 #225; Build auto-gestempelt, OP-PM-2). Auftrag: D5-2-Slice aus
docs/architektur/Persistenz.md§5. Gebaut: (1) neue Registryserver/src/persistence/do-state-migrations.ts— die früher inline inLeitstandServer.onStartverstreuten versionsgegatetenif (sv < N)-Remaps (v2/3/4/5/7/12/14) als geordnete, benannteDO_MIGRATIONS-Liste + RunnermigriereDoState(state, fromVersion);SCHEMA_VERSION(=15) wandert hierher als Single Source (vonleitstand.tsre-importiert). (2) Round-Trip-Self-Testserver/src/persistence/do-migrations-demo.ts+ npm-Script/CI-Steptest:do-migrations: Voll-Migration v0→v15, Idempotenz (sv=15-Blob bleibt byte-gleich), Versions-Gating (gültiges „abgeschlossen" bei sv≥2 bleibt unangetastet), Registry-Invarianten (aufsteigend/eindeutig/≤SCHEMA_VERSION). (3)onStartruft nur nochmigriereDoState. Entscheidungen: (a) Scope = nur versionsgegatete Remaps (empfohlene, risikoärmste Variante); der emptiness-gegatete Abwesenheits-Historie-Backfill (v11) und die idempotenten Feld-Default-Merges (saved.x ?? this.state.x) bleiben bewusst inonStart— sie sind nichtsv-gegatet, ihre Verlagerung in die Versions-Registry würde die Semantik ändern. (b)SCHEMA_VERSIONbleibt eine eigene Konstante (nicht ausmax(migration.version)abgeleitet) — spätere Bumps (v13/v15) waren reine Feld-Ergänzungen via Default-Merge, daher ist die Registry lückenhaft. (c) Migrationen arbeiten auf einem losenDoStateBlob(untypisierte Altdaten) — wie zuvor mitas-Casts; das vermeidet Import-Verflechtung mit dem Worker-Runtime und hält den Self-Test isoliert lauffähig. (d) Token-Muster-Gate („neues PersistedState-Feld ⇒ Migration/Default vorhanden") nach D5-4 verschoben (CI-Gate-Bündelung). Verifikation:typecheckgrün;test:do-migrationsgrün; Regression-Smokesoperativ/replan/test:teilplan/test:fairnessgrün. Kein Storage-/Verhaltens-Change, kein Solver-Redeploy. Doku:docs/architektur/Persistenz.md(D5-2 ✅ + §1-Ist-Zustand), HANDOFF (OP-DATA-1), CHANGELOG, Timesheet (2026-06-27-d5-2-do-state-migrations). - Branch
claude/taktano-meeting-minutes-jfekpr(PR folgt) — Besprechungs-Protokolle (Meeting-Minutes) als Doku-Struktur (Version 0.17.0 → 0.17.1 PATCH — Doku-Zuwachs, kein Code/Verhalten). Auslöser: Frage „Welche Meeting-Minutes gibt es zu Taktano?" → Befund: keine vorhanden (weder im Repo noch via angebundenem Notion — kein Notion-MCP-Connector aktiv). Gebaut: neuer Ordnerdocs/betrieb/meetings/mit (1)README.md(Index + Anleitung + Konventionen, pyramidal), (2)_Vorlage.md(Protokoll-Template: TL;DR → Beschlüsse → Action Items → Diskussion → True-North-Bezug), (3)_category_.json(Docusaurus-Sidebar). Eintrag indocs/README.md(Landkarte). Entscheidungen: (a) Meeting-Minutes leben im Repo (Everything-as-Code, einzige Quelle der Wahrheit) statt nur in externem Tool; (b) eine Datei je TerminJJJJ-MM-TT-thema-slug.md(chronologisch, kollisionsfrei — analog Timesheet-Session-IDs, OP-PM-2); (c) protokollierte Beschlüsse werden zusätzlich am verbindlichen Ort gespiegelt (CHANGELOG/HANDOFF §4/design/CLAUDE.md) und per ID referenziert — das Protokoll ersetzt den Audit-Trail nicht, es ergänzt ihn; (d) Notion-Anbindung als Option dokumentiert (Connector erforderlich, DSGVO-Drittland-Hinweis → Risikoregister-Kandidat). Doku:docs/betrieb/meetings/*,docs/README.md, CHANGELOG, HANDOFF, Timesheet (2026-06-27-taktano-meeting-minutes). - Branch
claude/op-crud-lifecycle(PR folgt) — Neuer OP-CRUD-1: Entitäten-Lebenszyklus (CRUD · Versionierung · Archiv statt Löschen · Schutz laufender Prozesse) (reine Doku → kein Version-/Build-Bump). Nutzer-Wunsch: „Für alle Entitäten die CRUD durchgehen — welche sollten versioniert sein, beim Löschen ggf. nur archivieren statt hart löschen; laufende Prozesse dürfen nicht gestört werden, sondern ordentlich weiterlaufen." Gebaut: neuer Design-Docdocs/architektur/Entitaeten-Lebenszyklus.mdmit (1) CRUD-Ist-Matrix je Entität → echte Lücken benannt (Mitarbeiter-/Skill-Delete fehlen; Leistung/Teilschritt ohne Create/Delete); (2) drei Lösch-Klassen (A archivieren/soft-deaktivieren für referenz-/historie-behaftete Stammdaten · B Lifecycle-Archiv = Auftrag · C hart+Audit nur referenzfrei = Infra-Kosten/Foto) + Business-Begründung „warum nie hart löschen" (verwaiste Verweise/Statistik/Revisionssicherheit/DSGVO); (3) Versionierung = OP-AUDIT-1 generisch, eigene Versionierung nur für Prozess-Katalog; (4) Running-process-Schutz als Invariante (Materialisierung bei Auftragsstart + Referenz-Guards + geordnete Übergabe via Klärfall); (5) Lücken-Slices C1…C4 + (6) Entscheidungen E-CRUD-1…4. Entscheidungen (Nutzer-Sign-off 06-27): E-CRUD-1 ✅ = generischesarchiviert-Flag (orthogonal zu den fachlichen Status-Enums, uniform filterbar) · E-CRUD-2 ✅ = Materialisierung-bei-Start bestätigt (keinegültigAb-Versionierung jetzt); E-CRUD-3/4 bleiben offen. OP als Design-Doc + HANDOFF §4 registriert — noch keine Code-Änderung (Umsetzung der Slices C1…C4 folgt separat). Registriert:docs/README.md(Landkarte),docs/konventionen/IDs.md(OP→Doc), HANDOFF §4 (OP-CRUD-1). Kein Code, keine Gates/Solver berührt. Doku:architektur/Entitaeten-Lebenszyklus.md(neu), HANDOFF, README, IDs, CHANGELOG, Timesheet (2026-06-27-op-crud-lifecycle). - Branch
claude/notion-claude-code-integration-4yxtzf(PR folgt) — Notion-Anbindung via MCP für Claude (Contributor-Tooling) (kein Versions-Bump — reines Dev-/Doku-Tooling, kein Worker-/Laufzeit-/Build-Change; Präzedenz Doku/Tooling-only #182/#185/#188/Session 40). Auftrag: „Notion in Claude Code nutzen — sowohl lokal in Claude Desktop als auch in Claude Code in der Cloud" (Nutzer-Wahl: Ziel-Repo taktano, Auth Integrations-Token). Gebaut: (1) eingecheckte.mcp.jsonim Repo-Root — Servernotionvianpx -y @notionhq/notion-mcp-server, Token als${NOTION_TOKEN}-Env-Expansion (kein Secret im Repo) → Claude Code findet den Server lokal und in der Cloud automatisch. (2) Dokudocs/konventionen/Notion-Integration.md(zielgruppen-gerecht IT-Dev/DevOps, pyramidal + Mermaid): Setup für Claude Code (lokal: Shell-Env; Cloud: Umgebungs-Secret) und Claude Desktop (Connector-OAuth oderclaude_desktop_config.json), Bereichs-Freigabe (Container-Seite, Freigabe vererbt sich → least privilege), Troubleshooting. (3) Doku-Landkartedocs/README.md(konventionen-Tabelle) ergänzt. Entscheidungen: (a) Token statt OAuth für die Cloud — headless-Sessions können den Browser-OAuth-Flow (https://mcp.notion.com/mcp) nicht durchführen; Token via Env-Secret ist robust und hält das Geheimnis aus dem Code (${NOTION_TOKEN}). (b) stdio + npx (offizielles@notionhq/notion-mcp-server, EnvNOTION_TOKENverifiziert gegen das Paket-README) statt gepinnter Version —-yzieht aktuell. (c) kein Versions-Bump — ändert wederserver/-Runtime noch Build/Deploy. (d) Claude Desktop bleibt geräte-lokal (claude_desktop_config.json, nicht im Repo) — die Repo-.mcp.jsongilt nur für Claude Code. Compliance: Token = Geheimnis (nie im Klartext, Rotation bei Verdacht); von Claude gelesene Notion-Inhalte werden vom Modell verarbeitet → nur freigeben, was vorgesehen ist (Hinweis in der Doku + Verweis Compliance/Risikoregister). Verifikation:.mcp.jsonvalides JSON; Paketname/Env-Var gegen offizielles README geprüft. Kein Solver-/Daten-/Verhaltens-Change. Doku:docs/konventionen/Notion-Integration.md(neu),docs/README.md, HANDOFF (§2), CHANGELOG, Timesheet (2026-06-27-notion-claude-code-integration). - #230 — OP-DATA-1 / D5-1: Drizzle-Toolchain auf der bestehenden Audit-D1 (Schema-First, kein Verhaltens-Change) (Version 0.15.0 → 0.16.0 MINOR — neue, rückwärtskompatible Toolchain; Build auto-gestempelt, OP-PM-2). Auftrag: „Implementiere d5-1" (Slice aus
docs/architektur/Persistenz.md§5). Gebaut: (1)drizzle-orm+drizzle-kitals devDependencies inserver/— bewusst nicht Prod (die Schema-Datei wird nur vondrizzle-kitkonsumiert, nicht vom Worker-Laufzeitpfad → kein Prod-Bundle, keinnpm audit --omit=dev-Surface; verifiziert: 0 prod-Vulns). (2)server/src/db/schema.ts= Single Source des SQL-Schemas: das schon existierendeaudit_entries-Schema (rawserver/migrations/0001_audit_entries.sql, remote bereits angewandt) deklarativ als Drizzle nachgezogen — gleiche Tabelle/Spalten/Nullability/Indizes (ausloeserstatt SQLite-Keywordtrigger,tenant_idfirst-class). (3)server/drizzle.config.ts(dialect: 'sqlite',out: ./drizzle) + generierte Migrationserver/drizzle/0000_*.sql(+meta/), deckungsgleich zu0001. (4) CI-Gatedb-checkin.github/workflows/ci.yml(npm run db:check→scripts/check-drizzle.sh:drizzle-kit generate→git statusmuss leer sein) + npm-Scriptsdb:generate/db:check; als Required-Job inci-gateverdrahtet. Entscheidungen: (a) getrennte Migrations-Verzeichnisse — Drizzle schreibt nachserver/drizzle/, wrangler liest weiter nurserver/migrations/(migrations_dir) → die remote angewandte, idempotente (IF NOT EXISTS) raw-0001bleibt der einzige Apply-Pfad, kein Doppel-Apply; das Drizzle-Pendant ist rein der maschinen-geprüfte Schema-Beweis. (b) Drizzle als devDependency (s. o.) — kein Laufzeit-Query in D5-1, daher kein Prod-Risiko/Bundle-Zuwachs. (c) Das Staleness-Gate prüftgit status(nicht nurgit diff --exit-code), damit neue, untracked Migrationsdateien (= Schema editiert, aberdb:generatevergessen) nicht durchrutschen. Verifikation:npm run typecheckgrün;drizzle-kit generatezweifach → „No schema changes" (idempotent);npm audit --omit=dev --audit-level=high→ 0 Vulns. Kein Solver-/Daten-/Verhaltens-Change. Doku:docs/architektur/Persistenz.md(D5-1 ✅ gebaut), HANDOFF (OP-DATA-1), CHANGELOG, Timesheet (2026-06-27-d5-1-implementation). - Branch
claude/docs-navigation-structure-wf696m(PR folgt) — Doku-Navigation: Findability-Layer (Frontmatter-Lesereihenfolge · Kategorie-Index · Glossar · ID-/OP-Index · Lesepfade · Drift-Checks) (Doku/Tooling-only → kein App-Version-/Build-Bump,APP_VERSIONbleibt 0.14.4; Build auto-gestempelt; Präzedenz #205/#218/#222). Nutzer-Wunsch: „Doku ist unübersichtlich/schwer navigierbar — zum Masterpiece machen." Das Fundament (5 Themenordner + Docusaurus + Volltextsuche, #205) stand; diese PR schließt die Detail-Lücken. Gebaut: (1) YAML-Frontmatter in allen 19docs/**-Dateien —sidebar_positionin 10er-Schritten = sinnvolle Lesereihenfolge (statt alphabetisch),sidebar_labelfür kurze Sidebar-Titel; keintitle:(Titel bleibt aus H1 = Single Source). (2) Kategorie-Landing-Pages:link: generated-index+ Beschreibung in allen 5_category_.json→ jede Gruppe hat eine echte Übersichtsseite statt nur Aufklappen. (3) Glossardocs/konventionen/Glossar.md(A–Z, Pointer-Stil → Link zur maßgeblichen Definition; Master bleibt Lastenheft §13, keine Zweitdefinition). (4) ID-/OP-Indexdocs/konventionen/IDs.md(Präfix-Legende + Reverse-Lookup „OP → Owning-Doc"; volle OP-Liste bleibt HANDOFF §4 — bewusst kein Voll-Index/Generator). (5) Landkartedocs/README.md: neuer Abschnitt Lesepfade nach Aufgabe (Onboarding · Scheduler verstehen · PR machen · Architektur nachschlagen · Begriff nachschlagen) + fehlendesarchitektur/Bildbewertung.mdnachgetragen (Drift geschlossen). (6) Drift-Checks inscripts/check-doc-consistency.sh(warnt, blockt nicht, OP-DOCS-9): jededocs/**-Datei ist in der Landkarte verlinkt · hat Frontmatter (sidebar_position) · jeder Ordner hat_category_.json(hätte das Bildbewertung-Loch gefangen; Negativtest bestätigt). (7) Navbar (Glossar + IDs) indocs-site/docusaurus.config.js; Lastenhefttoc_max_heading_level: 3(tiefere On-Page-TOC). (8) Konsistenz-Pass: veraltete Pfad-Referenzen aus dem Ordner-Umzug korrigiert (docs/Lastenheft.md→docs/fachlich/Lastenheft.md, analog Risikoregister/Sanity/Timesheet/Compliance/agents) in 9 Docs. Entscheidungen: (a) keine Datei-Renames — sichtbare Konsistenz übersidebar_label/H1 statt riskanter Umbenennungen (würde ~25+ Pfad-Referenzen + Site-URLs/Bookmarks brechen; „keine ungefragten Refactorings"); (b) bestehende Status-/Bezug-Kopfblöcke bewahrt (architektur/* sind dicht & als Audit-Trail wertvoll) statt in ein starres Template zu pressen — Konvention dafür neu in agents.md §2.1 dokumentiert; (c) Glossar/IDs als Pointer, nicht als Zweitquelle (G-2, keine Decision-Sprawl); (d) Lastenheft nicht gesplittet (meist-referenziert, hunderte §-Anker) — nur TOC-Tiefe verbessert; (e) kein Version-Bump (Doku/Tooling). Verifikation:scripts/check-doc-consistency.shgrün (inkl. der neuen Checks; Negativtest erkennt fehlendes Frontmatter + Landkarten-Eintrag);cd docs-site && npm run builderfolgreich — keine neuen Broken-Link-Warnungen (die zwei neu eingeführten Cross-Instance-Links zuHANDOFF.md/design/WORKSPACES.mdals Backtick-Referenz entschärft; die verbleibenden Warnungen sind vorbestehend/cross-instance, nicht aus dieser PR). (9) Warnungsfreier Doku-Site-Build (Folge-Commit, „Copy-+-Rewrite"-Ansatz auf Nutzer-Wunsch): die Site rendert jetzt eine Staging-Kopie der Repo-Markdown (docs-site/prepare-content.mjsersetzt das altecopy-projekt;docs-staged/+projekt-docs/gitignored) und schreibt die wenigen Cross-Instance-Links (Haupt-Instanzdocs/↔ Projekt-Instanz aus HANDOFF/README/CHANGELOG/CLAUDE) resolve-basiert auf Site-Routen um — die Original-.mdbleiben GitHub-korrekt (Single Source). Ergebnis:npm run buildohne Broken-Link-Warnungen (vorher 7 vorbestehende Cross-Instance-Warnungen → 0); CHANGELOG + CLAUDE sind nun ebenfalls auf der Site (/projekt/…). Resolve-basiert, damit z. B.../README.mdausagents.md(zeigt auf die Landkarte docs/README.md) korrekt unangetastet bleibt, während../README.mdaus der Landkarte (Root-README) zur Instanz-Index-Route/projekt/wird. Kein Solver-/Worker-Redeploy. Doku: alledocs/**-Frontmatter,docs/konventionen/{Glossar,IDs}.md(neu),docs/README.md,docs/*/_category_.json(5),docs/konventionen/agents.md(§2.1),scripts/check-doc-consistency.sh,docs-site/{docusaurus.config.js,package.json,.gitignore,prepare-content.mjs}, CLAUDE.md (Tiefenquellen), HANDOFF (§2), CHANGELOG, Timesheet (Session2026-06-27-docs-navigation-structure). True North: indirekt (schnellere/korrektere Navigation → die 3 Leitfragen-Antworten leichter auffindbar). - #226 — North Star erweitert: „Dokumentation als Meisterwerk" (zielgruppen-gerecht · pyramidal · visuell) (Doku-only → kein Version-/Build-Bump, Präzedenz #205/#207). Nutzer-Wunsch: „Add to North Star: clear and concise documentation as a masterpiece, per audience (IT-Dev / Business-Manager / User / IT-Ops / DevOps / CISO / Customer-Service), pyramidal structure, visualisations where helpful." Gebaut: (1) Neues Leitprinzip in
CLAUDE.mddirekt nach Selbsterklärbarkeit — Doku als Liefergegenstand, pyramidal (Minto: Kernaussage→Gründe→Details), zielgruppen-gerecht (sieben benannte Leserkreise), visuell wo es trägt (Mermaid/Tabellen/Beispiele), selbsterklärbar & OP-DOCS-9-konsistent; True-North-Regel um den Doku-Halbsatz ergänzt. (2)docs/zielgruppen/Lesepfade.mdvon 4 → 7 Zielgruppen erweitert (neu: DevOps, CISO/Security, Customer Service) inkl. kuratiertem Lesepfad + Glossar-Begriffen je Rolle und einer Mermaid-Rollen-Landkarte (verkörpert das Visuell-Prinzip). Entscheidungen: (a) Prinzip lebt inCLAUDE.md(Guiding-Principles-Heimat), Rollen-Detail inLesepfade.md(keine Duplizierung); (b) Audience-Mappingbusiness-manager=fach,user=nutzer; (c) keine Links auf noch-ungemergte Docs (Backup-Restore/Persistenz aus #225) → Security-Pfad referenziert bestehende Observability/Audit-Log. Verifikation:check-doc-consistency.shgrün (keine toten Links). Doku:CLAUDE.md,docs/zielgruppen/Lesepfade.md, HANDOFF, CHANGELOG, Timesheet. - #225 — Seed-Ablösung: Stammdaten persistiert + admin-editierbar + Seed → benannte Tenant-Vorlage (OP-SEED-1 / S-SEED-1…4 / OP-TENANT) — konsolidierter PR der Branch
claude/seed-usage-audit-frsx52, aufmain@0.14.4 rebased (Version 0.14.4 → 0.15.0 MINOR; Build automatisch, OP-PM-2). Bündelt die unten als „(PR folgt)" geführten Slices (OP-SEED-1 · S-SEED-1..4 · Design-Docs OP-DATA-1/OP-BACKUP-1) zu einem Merge. Rebase-Entscheidungen:version.tsbehält die Build-Count-Mechanik (OP-PM-2) + Version auf 0.15.0;auftrag.startenkombiniert die R7-Invariante (hatZuweisung, aus main) mit den dynamischenbelegungSlots(Branch); die drei neuen Architektur-Docs (Seed-Abloese-Plan/Persistenz/Backup-Restore) in die OP-DOCS-8-Strukturdocs/architektur/eingepasst (Querverweise nachgezogen); append-only Logs union-gemergt, kollidierende Timesheet-Session-IDs (37–42) auf sprechende Branch-IDs geglättet (OP-PM-2). CodeRabbit-Review (9 Funde) adressiert — Entscheidungen: (1) alle neuen Stammdaten-CRUD-Nachrichten (arbeitsplatz/taxonomie/schicht.*) server-seitig gegatet (istKostenAdmin, wieadmin.purge) — die UI-Gate allein reichte nicht (Critical, Security); (2) keine Actor-PII (E-Mail) im Laufzeit-consoledes Purge — Identität gehört in die D1-Audit-Senke (OP-LOG-1/OP-AUDIT-1); (3)taxonomieInUsezählt jetzt auch die append-onlyabwesenheitHistorie(keine verwaisten Typ-IDs); (4)arbeitsplatz.removelöscht keine referenzierten Buchten (Belegung/geplante Schritte) mehr — nur deaktivieren; (5)taxonomie.updateverhindert, dass eine Umbenennung die logik-tragende Parkplatz-Semantik (G-1,/parkplatz/i) eines genutzten Typs kippt; (6) Client-[(ngModel)]→Signal-Felder auf[ngModel]="x()"+(ngModelChange)="x.set($event)"umgestellt (Signal wurde sonst beim Editieren durch einen Plain-Wert ersetzt); (7) Purge meldet Erfolg erst nach Server-Ack (neuer State) statt Fire-and-forget — inkl. Nicht-verbunden-/Timeout-Fehlermeldung; (8) logik-tragende Taxonomie-Einträge (Parkplatz/Indoor/Folierbucht) im Editor nicht umbenennbar/löschbar (G-1); (9) gemeldetes „doppeltesBelegungSlot" als False-Positive begründet beibehalten (genau eine Deklaration;BelegungSlotDTOist ein anderer Typ;tscgrün). Verifikation: servertypecheck+ Self-Tests (spike/operativ/replan/solve/teilplan/prozess) + clientng build(prod) + No-Hex + Doc-Consistency grün. Kein Solver-Redeploy. Doku:docs/architektur/{Seed-Abloese-Plan,Persistenz,Backup-Restore}.md, HANDOFF (OP-SEED-1/OP-TENANT/OP-BACKUP-1/OP-DATA-1), CLAUDE.md (Tiefenquellen), CHANGELOG, Timesheet (2026-06-27-branch-ahead-review-pr). - Branch
claude/seed-usage-audit-frsx52(PR folgt) — Entscheidung: Tenant-Isolation (OP-TENANT) — Daten pro Tenant physisch getrennt (reine Doku → kein Version-/Build-Bump). Nutzer-Entscheidung (06-27): Mandantendaten + Audit je Tenant in DO-SQLite (Isolations-Option A, „Room=Tenant", physische Trennung, kein Cross-Query-Surface); Tenant-Registry zentral via Better Auth Organizations (EU-D1, OP-AUTH-1). Folgen festgehalten: (1) löst zugleich E-DATA-1 = B (DO-SQLite) indocs/Persistenz.md; (2) proaktiv geflaggte Compliance-Folge beim Audit — verlässt die separate D1 (= physische Gewaltenteilung): Mitigation = Audit in der Tenant-DO-SQLite append-only + Hash-Chain (Tamper-Evidenz) + das bestehende live D1taktano-audit(#186) umgewidmet zum zentralen forward-only Compliance-/Cross-Tenant-Sink (nicht weggeworfen); ⮕ E-TENANT-1 (Sink ja/nein) offen. Neu:docs/architektur/Mandantenfaehigkeit.md(OP-TENANT — Entscheidungs-Record: Datenhaltung je Klasse, Audit-Reconciliation §4, Enforcement Identität→Tenant→DO-Room, Slices T-1…T-6, ⮕ E-TENANT-1/2/3). Aktualisiert:docs/Persistenz.md(E-DATA-1 ✅ entschieden = B),docs/Audit-Log.md(§2 Speicher-Verfeinerung: primär DO-SQLite je Tenant + Hash-Chain, D1 → zentraler Sink; alte D1-Hybrid-Entscheidung als §2.1 erhalten), HANDOFF §4 (OP-TENANT/OP-DATA-1/Audit),CLAUDE.md(Tiefenquellen). Kein Code, keine Gates/Solver berührt; der heutige D1-Dual-Write bleibt bis zu den Folge-Slices (T-3/T-4) unverändert nutzbar. - Branch
claude/seed-usage-audit-frsx52(PR folgt) — E-TENANT-1 entschieden: (C) zentraler Hash-Anker fürs Audit (reine Doku → kein Bump). Nach Abwägung A (voller zentraler Event-Sink) · B (rein per-Tenant + Fan-out) · C (nur Chain-Kopf zentral) wählt der Auftraggeber C: per-Tenant-Audit in DO-SQLite append-only + Hash-Chain (eintrag_n.hash = H(payload ‖ vorheriger_hash)); zentral wird nur der Chain-Kopf je Tenant verankert ({tenant_id, seq, head_hash, ts},taktano-auditumgewidmet zu Tabelleaudit_anchors) — keine Events, keine PII zentral. Liefert off-box-Manipulationsnachweis ohne zentrale Datenhaltung (ehrt „komplett getrennt" maximal); Cross-Tenant-Reporting bleibt Fan-out, Upgrade-Pfad C→A nur bei echtem Bedarf. Heutiger D1-Dual-Write schreibt interim noch volle Events → End-Zustand reduziert auf den Anker (Folge-Slices T-3/T-4). Festgehalten indocs/architektur/Mandantenfaehigkeit.md§4/§6/§7,docs/architektur/Audit-Log.md§2, HANDOFF §4 (OP-TENANT). Kein Code. - Branch
claude/seed-usage-audit-frsx52(PR folgt) — E-TENANT-2 entschieden: (3) ein R2-Bucket + Prefix je Tenant, gekapselt (reine Doku → kein Bump). Nach Abwägung 1 (Prefix) · 2 (Bucket je Tenant, physisch) · 3 (Prefix gekapselt + Opt-in-Split) wählt der Auftraggeber 3: Fotos in einem EU-Bucket untertenant/<id>/…, ausschließlich übertenantBucket()/tenantKey()+ unrätbare Ids + signierte URLs;tenant_idaus verifizierter Identität. Begründung (bewusst nicht „physisch um jeden Preis"): (a) die sensible Relation Foto↔Tenant↔Auftrag liegt bereits physisch in der DO-SQLite — R2 hält nur opake Bytes; (b) Zielmarkt = viele kleine Betriebe → tausende Mandanten → Bucket-je-Tenant rennt ins R2-Bucket-Limit/Konto + Provisionierungs-Ops, Prefix skaliert unbegrenzt. Bucket-je-Tenant = dokumentiertes Opt-in-Upgrade für einzelne High-Compliance-Tenants (mechanisch dank Kapselung) — gleiches „minimal jetzt, Upgrade auf Bedarf"-Muster wie E-TENANT-1=C. Festgehalten indocs/architektur/Mandantenfaehigkeit.md§3/§5/§6 (T-7)/§7. Kein Code. - Branch
claude/seed-usage-audit-frsx52(PR folgt) — E-TENANT-3 entschieden: zurückgestellt („auf Anforderung") (reine Doku → kein Bump). Per-Tenant-Verschlüsselung at-rest (Envelope, eigene Keys) wird nicht vorab gebaut — bis ein konkreter Compliance-/Vertragsbedarf sie fordert gilt die Plattform-Verschlüsselung at-rest (DO/D1/R2 EU) als ausreichend; Re-Evaluierung bei Enterprise-/regulatorischen Anforderungen (OP-COMPLIANCE-1). ➡ Damit sind alle Tenant-Isolations-Sign-offs abgeschlossen (E-DATA-1=B · E-TENANT-1=C · E-TENANT-2=3 · E-TENANT-3=zurückgestellt); offen bleiben nur die OP-BACKUP-1-Detailfragen (E-BACKUP-1/2/3). Festgehaltendocs/architektur/Mandantenfaehigkeit.md§7. Kein Code. - Branch
claude/seed-usage-audit-frsx52(PR folgt) — E-BACKUP-1/2/3 entschieden + Housekeeping (reine Doku → kein Bump). E-BACKUP-1 = native DO-SQLite-PITR, SELEKTIV angewandt: Restore stellt nur die Fachtabellen auf T wieder her, die Audit-Tabelle bleibt unangetastet — Cross-Check mit E-TENANT-1=C ergab, dass ein blindes Whole-DO-PITR das in derselben DO-SQLite liegende Audit mitrollen und die Events zwischen T↔jetzt vernichten würde (Konsistenz-Falle, proaktiv gelöst); + B5-1 Pre-Purge-Snapshot als Sofort-Netz, kein eigenes Event-Log. E-BACKUP-2 = 30 Tage rollierende Retention (= PITR-Fenster) + Plattform-Verschlüsselung at-rest; Recht-auf-Vergessen via Aging (Lösch-SLA „aus Backups ≤30 Tage"), Audit ausgenommen (PII-gescrubbt). E-BACKUP-3 = ja, „durch Restore überholte" Audit-Einträge nur darstellungsseitig markieren (kein Schreibzugriff). ➡ OP-BACKUP-1 vollständig entschieden. Housekeeping: veraltete „auszuarbeiten"-Stub im HANDOFF-OP-BACKUP-1 entfernt; alle flachendocs/<x>.md-Verweise in HANDOFF auf diedocs/architektur/-Struktur (OP-DOCS-8) nachgezogen; drei doppelte „## Summe"-Kopfzeilen im Timesheet (Union-Merge-Artefakt) auf die main-Linie (~102.0 h) kollabiert. Festgehaltendocs/architektur/Backup-Restore.md§5/§6/§7/§8, HANDOFF §4. Kein Code. - Branch
claude/seed-usage-audit-frsx52(PR folgt) — Design-Docs: S-SEED-5/OP-DATA-1 (Persistenz) + OP-BACKUP-1 (Backup/Restore) ausgearbeitet (reine Doku → kein Version-/Build-Bump, Präzedenz #182/#185). Nutzer-Auftrag: „1, dann 2" — erst S-SEED-5 als Design-Doc mit der DO/D1-Entscheidung als Kern, dann OP-BACKUP-1 ausarbeiten. (1)docs/Persistenz.md(OP-DATA-1 / S-SEED-5): Ist-Zustand (DO-Blob + handgepflegteonStart-Remaps +SCHEMA_VERSION15, nicht maschinell geprüft; D1 nur fürs Audit, raw-SQL0001, kein Drizzle) → Ziel: Drizzle als Single Source + generierte Migrationen + CI-Gate. Drei Daten-Heimaten abgewogen (DO-Blob · DO-SQLite · D1) mit Leitkonvention je Datencharakter; ⮕ E-DATA-1 (Sign-off): (A) DO-Blob + Migrations-Hygiene [empfohlen sofort] · (B) DO-SQLite + Drizzle [Zielbild, koppelt an OP-TENANT + OP-BACKUP-1] · (C) D1 für Stammdaten. Slices D5-1 (Drizzle-Toolchain auf bestehender D1 retrofitten, kein Verhaltens-Change) · D5-2 (DO-Blob-Migrations-Registry + Round-Trip-Test + Token-Gate) · D5-3 (DO-SQLite-Pilot) · D5-4 (CI-Gate). (2)docs/Backup-Restore.md(OP-BACKUP-1): Snapshot vs. echtes PITR; drei Wege (Snapshot-Kadenz · Event-Sourcing · DO-SQLite-natives PITR) — Kern-Erkenntnis: DO-SQLite hat natives Point-in-Time-Recovery → mit OP-DATA-1 gemeinsam entscheiden, dann PITR fast geschenkt. Beantwortet die zwei Nutzer-Kernfragen: (a) Restore-Punkt über die Audit-Timeline wählen; (b) Audit-Log wird NICHT mitgerollt — bleibt append-only/unveränderlich (OP-AUDIT-1), der Restore ist selbst ein neuesstate.restore-Event; bewusste Divergenz Fachzustand↔Audit + Reconciliation-Regel. Sofort-Netz B5-1 (Pre-Purge-Snapshot nach R2). DSGVO/Retention vs. Recht-auf-Vergessen behandelt; ⮕ E-BACKUP-1/2/3. Doku-Registrierung: beide Docs inCLAUDE.md(Tiefenquellen) + HANDOFF §4 (neuer OP-DATA-1-Bullet, OP-BACKUP-1 von „auszuarbeiten" → ausgearbeitet) +docs/Seed-Abloese-Plan.md(S-SEED-5-Verweis). Kein Code, keine Gates berührt. - Branch
claude/seed-usage-audit-frsx52(PR folgt) — S-SEED-4: Seed → benannte Tenant-Vorlage extrahiert (server/src/tenants/) (Version 0.15.0 → 0.16.0 MINOR, Build 18 → 19). Nutzer-Auftrag: „ja" (S-SEED-4 weitermachen). Ziel: den (nach S-SEED-1/2/3 nur noch als Vorlage genutzten) Seed formal zur benannten Tenant-Vorlage machen — kein impliziter Laufzeit-Default mehr. Gebaut: (1) Stammdaten pergit mv(Historie erhalten) vonserver/src/model/seed.ts→server/src/tenants/vest-automotive.ts; Modul-Typ-Import./types→../model/typesangepasst; (2) neuer TypTenantVorlage({ id, name, daten: SchedulerInput },server/src/tenants/types.ts) + Wrapperexport const vestAutomotive: TenantVorlage = { id: 'vest-automotive', name: 'Vest Automotive GmbH', daten: vestAutomotiveSeed }; (3) Registryserver/src/tenants/index.ts(TENANT_VORLAGEN,tenantVorlage(id),DEFAULT_TENANT_ID,aktiveTenantVorlage()); (4)leitstand.tsbezieht die Vorlage überaktiveTenantVorlage()→const AKTIVE_TENANT,TENANT_ID = AKTIVE_TENANT.id, internevestAutomotiveSeed = AKTIVE_TENANT.daten(alle bestehendenvestAutomotiveSeed.*-Referenzen unverändert); (5)model/seed.ts= dünner Re-Export-Shim (export { vestAutomotiveSeed } from '../tenants/vest-automotive'), damit die Demo-/Spike-/Self-Test-Skripte (*-demo.ts,spike.ts) ihren Importfrom '../model/seed'behalten. Entscheidungen: (1) Re-Export-Shim statt ~11 Demo-Imports umzubauen — niedrigeres Risiko, der Runtime-Pfad (DO) nutzt bereits die Registry (Ziel erreicht); Shim-Entfernung als Folge notiert; (2)vestAutomotiveSeed-Name im DO lokal beibehalten (=AKTIVE_TENANT.daten) → keine Churn an den vielen Referenzstellen; (3) MINOR statt PATCH, da neue Abstraktion (TenantVorlage+ Registry) = Fundament für OP-TENANT, rückwärtskompatibel/verhaltensgleich. ➡ Damit ist der Seed kein impliziter Laufzeit-Default mehr, sondern eine explizit benannte Vorlage — Code-Fundament für echtes Multi-Tenancy (OP-TENANT). Verbleibend im Ablöse-Plan: nur S-SEED-5 (Drizzle/Migrationen, OP-DATA-1). Verifikation: Server-Typecheck (inkl. aller Demos via Shim) +spike/operativ/replan/solve/test:teilplan/test:prozess+ng build(prod, Client unverändert) + No-Hex grün. Reiner Restrukturierungs-/Server-Pfad — kein Verhaltens-/Datenmodell-Change, kein Solver-Redeploy. Doku:docs/Seed-Abloese-Plan.md(S-SEED-4 ✅ + §4-Abschluss), HANDOFF §4 (OP-SEED-1 + OP-TENANT-Fundament), CHANGELOG,docs/Timesheet.md(Session 41). - Branch
claude/seed-usage-audit-frsx52(PR folgt) — S-SEED-3: Schicht-Katalog (R1-S2) persistiert + admin-editierbar (Schicht-Editor) (Version 0.14.0 → 0.15.0 MINOR, Build 17 → 18). Nutzer-Auftrag: „S-SEED-3". Befund: der Schicht-Katalog war der letzte Stammdaten-Block am Seed im Laufzeitpfad —SCHICHTEN/SCHICHT_DTOS/SCHICHT_IDSlasenvestAutomotiveSeed.schichtenread-only, und der Scheduler bezieht Verfügbarkeits-/Ausfallfenster überinput.schichten. Gebaut (Server):schichten: SchichtKatalog[]in den DO-State (persistiert;onStart-Backfill; inbaueState/Purge unter „Taxonomie & Struktur");SCHICHTEN→schichtenMap,SCHICHT_DTOS→schichtDtos,SCHICHT_IDS→schichtIdsals Instanz-Getter überstate.schichten;schedulerInput()reichtschichten: state.schichtendurch → editierte Schichten wirken direkt aufmitarbeiterAusfall/mitarbeiterAvailability/Solver. CRUDschicht.create|update|remove: Name + Wochentage (bereinigeTage→ gültig/dedupliziert/Mo→So) + Zeit-Slots (bereinigeSlots→HH:mm-Regex,start<ende) +art(regulär/standard/überlauf) +aktiv-Soft-Deaktivierung; hartes Löschen nur unzugewiesen (schichtInUseprüftmitarbeiter.schichtIdsund Abwesenheits-Schichtbezug); Snapshot umschichtenKatalog: SchichtKatalogDTO[](rohe editierbare Struktur inkl.inUse) erweitert, die kompaktenschichten-Anzeige-DTOs (Tage/Zeiten als Strings) bleiben für die Mitarbeiter-Schicht-Zuweisung. Gebaut (Client): Schicht-Editor im Admin-Workspace/administration— Liste (Name/Tage/Zeiten/Art/Aktiv) + Anlegen/Bearbeiten-Formular mit Wochentag-Picker, variabler Zeit-Slot-Liste (type=time, Hinzufügen/Entfernen, Rot-Markierung beistart≥ende), Art-Dropdown; Service-TypenSchichtKatalogDTO/SchichtSlot/Wochentag+ Actions + State-Feld. Entscheidungen: (1) Logik-tragend bleibt fix: Wochentage/Zeitfenster steuern die Solver-Verfügbarkeit — Werte editierbar, dasHH:mm-Format ist validiert/fix; (2) zwei DTO-Sichten (kompakt für Zuweisung, roh für Editor) statt die bestehendeSchichtDTO-Anzeige umzubauen (kein Bruch der Mitarbeiter-Seite); (3) Löschen-vs-Deaktivieren wie bei Taxonomie/Arbeitsplatz; (4) CRUD ungated wie übrige Stammdaten (Nav admin-gegated, OP-AUTH-1). ➡ Meilenstein: nach S-SEED-1/2/3 liest kein Produktivpfad mehrvestAutomotiveSeed.{arbeitsplaetze,taxonomy,schichten}direkt — verbleibend nur S-SEED-4 (Vorlage formal extrahieren) + S-SEED-5 (Drizzle, OP-DATA-1). Verifikation: Server-Typecheck +spike/operativ/replan/solve/test:teilplan/test:prozess+ng build(prod) + No-Hex grün. Reiner Server+Client-Pfad — kein Solver-Redeploy (SchedulerInput.schichtenunverändert, nur Quelle Seed→State). Doku:docs/Seed-Abloese-Plan.md(S-SEED-3 ✅), HANDOFF §4 (OP-SEED-1), CHANGELOG,docs/Timesheet.md(Session 40). - Branch
claude/seed-usage-audit-frsx52(PR folgt) — S-SEED-2: Taxonomien (G-1) persistiert + admin-editierbar (Taxonomie-Editor) (Version 0.13.0 → 0.14.0 MINOR, Build 16 → 17). Nutzer-Auftrag: „S-SEED-2". Befund: die Taxonomie (Abteilungen, Arbeitsplatz-/Abwesenheits-/Sperre-Typen, Ausstattung, Leistung-Kategorien) war der letzte große read-only Seed-Block im Laufzeitpfad — ~11 Modul-Konstanten (ABTEILUNGEN,TYP_LABEL,ARBEITSPLATZ_TYPEN,AUSSTATTUNG_TYPEN,ABWESENHEIT_TYPEN, Validierungs-Sets …) + 3 Modul-Funktionen lasenvestAutomotiveSeed.taxonomy; auch der Scheduler/CP-SAT erkennt Parkplatz/Indoor überinput.taxonomy-Labels. Gebaut (Server):taxonomy: TaxonomyValue[]in den DO-State (persistiert;onStart-Backfill für Altzustände; inbaueState/Purge unter Kategorie „Taxonomie & Struktur"); alle Modul-Konstanten → Instanz-Getter überstate.taxonomy(this.abteilungen,this.typLabel,this.arbeitsplatzTypen,this.ausstattungTypen,this.abwesenheitTypen,this.arbeitsplatzTypIds, …); die Modul-FunktionentoAuftragDTO/buildProzessKatalog/bauBelegungSlotsbekommen die Taxonomie bzw. Label-Map als Parameter (statt Seed-Zugriff);schedulerInput()reichttaxonomy: state.taxonomydurch → editierte Taxonomie wirkt direkt auf Eignung/Belegung/Solver. CRUDtaxonomie.create|update|remove: Anlegen (Art + Label, reaktiviert gleichnamige deaktivierte Werte case-insensitive), Umbenennen +aktiv-Soft-Deaktivierung (G-1 „Soft-Deaktivierung statt Löschen"), hartes Löschen nur unreferenziert (taxonomieInUseprüft Mitarbeiter/Arbeitsplätze/Teilschritte/Leistungen/Sperren); Snapshot umtaxonomie: TaxonomieDTO[](inkl.inUse-Flag). Gebaut (Client): generischer Taxonomie-Editor im Admin-Workspace/administration— Art-Auswahl (6 Arten) × Werte-Liste mit Inline-Umbenennen, Aktiv-Toggle und Löschen (deaktiviert beiinUse), plus Anlegen; Service-TypenTaxonomieDTO/TaxonomyKind+ Actions + State-Feld. Entscheidungen: (1) Logik-tragende Konventionen bleiben fix (G-1): der Scheduler erkennt Stellplätze/Indoor über Label-Regex (/parkplatz/i,/indoor|folierbucht/i) — die Regex bleibt im Code, der Editor warnt sichtbar, solche Typen nicht umzubenennen (robustereskind-Flag als Folge notiert); (2)kind/idunveränderlich, nur Label +aktiveditierbar (Referenz-Stabilität); (3) Löschen vs. Deaktivieren: referenzierte Werte können nur deaktiviert werden (keine verwaisten IDs), unreferenzierte hart löschbar; (4) Mangel-Kategorien (§4.9.1,MANGEL_KATEGORIEN) sind eine separate feste Liste (nicht Teil der Stamm-Taxonomie) und bleiben vorerst hart (als Folge notiert); (5) CRUD ungated wie die übrigen Stammdaten, erreichbar nur über die admin-gegatete/administration-Nav (OP-AUTH-1). Verifikation: Server-Typecheck +spike/operativ/replan/solve/test:teilplan/test:prozess+ng build(prod) + No-Hex grün. Reiner Server+Client-Pfad — kein Solver-Redeploy (das Resource-/Taxonomie-Modell ist unverändert, nur die Quelle wandert Seed→State). Doku:docs/Seed-Abloese-Plan.md(S-SEED-2 ✅), HANDOFF §4 (OP-SEED-1 aktualisiert), CHANGELOG,docs/Timesheet.md(Session 39). ➡ Nach S-SEED-1+2 berührt kein Produktivpfad mehrvestAutomotiveSeed.{arbeitsplaetze,taxonomy}direkt — verbleibend: Schichten (S-SEED-3) + Vorlage-Extraktion (S-SEED-4). - Branch
claude/seed-usage-audit-frsx52(PR folgt) — S-SEED-1: Arbeitsplätze/Buchten persistiert + editierbar (Seed-Ablösung) + neuer OP-BACKUP-1 (Version 0.12.0 → 0.13.0 MINOR, Build 15 → 16). Nutzer-Auftrag: „S-SEED-1 angehen" + „neuer OP: Backup & Restore (gern Point-in-Time; ggf. Rollback-Zeitpunkt am Audit-Log bestimmen; auch klären, was mit dem AuditLog beim Rollback passiert)". Befund: die Buchten/Arbeitsplätze (Arbeitsplatz, R2) waren der nächste noch hart verdrahtete Stammdaten-Block — der Solver/schedulerInput(),BELEGUNG_SLOTS(Belegung/Inventur) undressourcenDTO().bays(Ausfallbänder) lasenvestAutomotiveSeed.arbeitsplaetzeread-only. Gebaut (Server):arbeitsplaetze: Arbeitsplatz[]in den DO-State aufgenommen (persistiert;onStart-Backfill für Altzustände; inbaueState/Purge unter Kategorie „Taxonomie & Struktur", Demo-Wartungssperre nur beim Voll-Demo-Seed); Modul-KonstanteBELEGUNG_SLOTS→ Instanz-GetterbelegungSlots(bauBelegungSlots(state.arbeitsplaetze));ressourcenDTO().bays+schedulerInput()lesen aus dem State; CRUDarbeitsplatz.create|update|remove(Name + gültiger Typ Pflicht; Kapazität ≥1; Skill-/Ausstattungs-IDs gegen Bestand validiert/dedupliziert;removeräumt diebelegungdes Slots mit auf); Snapshot umarbeitsplaetze: ArbeitsplatzDTO[](Typ-Label + Parkplatz-Flag + Sperren-Zähler) + Editor-OptionenarbeitsplatzTypenAlle(inkl. Parkplatz-Typen) +ausstattungTypenerweitert. Gebaut (Client): Arbeitsplatz-Editor im Admin-Workspace/administration— Liste mit Typ/Kapazität/Status/Skill-Zähler + Anlegen/Bearbeiten-Formular (Name, Typ-Dropdown, Kapazität, Konfig-Status, Skill-Chips, Ausstattung-Chips) + Entfernen; Service-TypenArbeitsplatzDTO/ArbeitsplatzPatch+ Actions + State-Felder. Entscheidungen: (1)arbeitsplaetze(R2-Solver-Modell) persistiert, nicht das separate UI-bays-Board — letzteres ist eine eigene, bereits persistierte Repräsentation (Vereinheitlichung als Folge notiert); (2) Taxonomie der Typen bleibt Seed-basiert bis S-SEED-2 (Typ-/Ausstattungs-Auswahl liest weiter die Seed-Taxonomie — bewusst kleiner Slice); (3) Sperren dieser Iteration nur read-only Zähler (sperrenAnzahl), Sperren-Editor als Folge; (4) CRUD ungated wie die übrigen Stammdaten (employee/skill/teilschritt), erreichbar nur über die admin-gegatete/administration-Nav (echtes Rollen-Gate = OP-AUTH-1). Neuer OP-BACKUP-1 (noch auszuarbeiten): Backup & Restore möglichst Point-in-Time; Rollback-Zeitpunkt über das append-only Audit-Log (OP-AUDIT-1) bestimmen; Leitlinie: das Audit-Log bleibt unveränderlich und wird nicht mitgerollt — der Rollback selbst wird als neues Audit-Event geschrieben; offene Fragen (Snapshot vs. Event-Sourcing, Konsistenz Fachzustand↔Audit, Retention/PII, Tenant-Scope, DSGVO/EU-Residenz) in HANDOFF §4 festgehalten. Verifikation: Server-Typecheck +spike/operativ/replan/solve/test:teilplan/test:prozess+ng build(prod) + No-Hex grün. Reiner Server+Client-Pfad — kein Solver-Redeploy (das Solver-Resource-Modell ist unverändert, nur die Quelle wandert Seed→State). Doku:docs/Seed-Abloese-Plan.md(S-SEED-1 ✅), HANDOFF §4 (OP-SEED-1 aktualisiert + neu OP-BACKUP-1), CHANGELOG,docs/Timesheet.md(Session 38). - Branch
claude/seed-usage-audit-frsx52(PR folgt) — OP-SEED-1 / OP-TENANT: Seed-Audit + Datenbestand-Purge + Tenant-Vorlage-Fundament (Version 0.11.0 → 0.12.0 MINOR, Build 14 → 15). Nutzer-Auftrag: „wo werden noch Seeds verwendet?" → konkreter Ablöse-Plan + „lass mich entscheiden, welche Seeds nach einem Purge geladen werden" + „Purge-Option im Admin-Bereich" + „ergänze als OP: Mandantenfähigkeit — vestAutomotive als Tenant konfigurierbar". Audit-Befund: der statischevestAutomotiveSeed(server/src/model/seed.ts) wird nur serverseitig genutzt (kein Client-Code); im Produktivpfad (leitstand.ts) sind Mitarbeiter/Skills/Teilschritte/Leistungen bereits abgelöst (persistiert+editierbar), noch hart verdrahtet sind Buchten, Taxonomie, Schichten; die*-demo.ts/spike.ts-Skripte nutzen den Seed bewusst als Testdatensatz und bleiben. Gebaut: (1)baueState(kategorien)= einzige Stelle, an der die Tenant-Vorlagevest-automotive(TENANT_ID) zu State wird — Boot-DefaultbaueState(ALLE)ist bit-identisch zum bisherigen Voll-Seed-Boot (regressionsfrei); (2) Admin-Kommandoadmin.purge(admin-gegated über denselben Access-Owner-Gate wie Kosten, interim bis OP-AUTH-1) setzt den gesamten Datenbestand zurück und lädt einzeln wählbare Seed-Kategorien (Taxonomie & Struktur·Prozess-Katalog·Demo-Mitarbeiter·Demo-Historie) — löscht zusätzlich transiente Arbeitszustände (Vorschau/Vorschläge/Live-Tasks); (3) persistiertes FlagdemoHistorieGeseedetverhindert, dassseedDemoHistorie()nach einem Purge ohne Demo-Historie beim nächsten Cold-Boot wieder Demo-Daten nachschiebt (legacy/undefiniert = Altverhalten, rein additiv, keine Migration); (4) neuer Admin-Workspace/administration(Cluster „System", nav-/server-gegated wie Kosten) mit Gefahrenzone: Preset-Schnellwahl („Leeres Gerüst" [Default] · „Voller Demo-Seed" · „Komplett leer"), Einzel-Checkboxen je Kategorie, Ergebnis-Vorschau und Tipp-Bestätigung (LÖSCHEN) vor der destruktiven Aktion (Rot nur für Warnung/Confirm-Button, nur--tk-*-Tokens). Entscheidungen (06-26, empfohlene Defaults — interaktive Rückfrage scheiterte am Permission-Stream der Remote-Session, im Dialog/Plan überstimmbar): D1 alle vier Kategorien einzeln wählbar · D2 Purge-Default „Leeres Gerüst" (Struktur+Prozess, keine Mitarbeiter/Aufträge) · D3 Tenant-Umfang = „Fundament + OP" (eine benannte Vorlage + selektives Re-Seeding; echtes Tenant-Switching/-Isolation als spätere Slices). Ablöse-Plan (Slices, je eigene PR): S-SEED-1 Buchten persistieren+editieren · S-SEED-2 Taxonomie-Editor (G-1) · S-SEED-3 Schicht-Katalog · S-SEED-4 Vorlage nachserver/src/tenants/vest-automotive.tsextrahieren · S-SEED-5 Drizzle/Migrationen (OP-DATA-1) — danach berührt kein Produktivpfad mehr den Seed direkt (Voraussetzung für Multi-Tenancy). ⚠ Vor Produktivgang (proaktiv geflaggt): Purge ist destruktiv & irreversibel — vor Go-Live Export/Backup vor Purge (OP-EXPORT-1), Purge-Audit-Event ins D1-Audit (OP-AUDIT-1, heute nur Ops-Log-Zeile mit Actor, OP-LOG-1) und echtes Rollen-Gate (OP-AUTH-1) ergänzen. Verifikation: Server-Typecheck +operativ- &test:prozess-Smoke +ng build(prod) + No-Hex-Gate grün. Reiner Server+Client-Pfad — kein Solver-Redeploy. Doku: neudocs/Seed-Abloese-Plan.md(Audit · Entscheidungen · Slices · OP-TENANT-Zielbild), HANDOFF §4 (OP-SEED-1 + OP-TENANT), CHANGELOG,docs/Timesheet.md. - #220 — Glossar (inkl. CP-SAT) + automatische Begriffs-Sprechblasen in der gesamten Doku + Lesepfade nach Zielgruppe (OP-DOCS-10 neu; OP-DOCS-4 teil-adressiert; Doku/Doku-Site-only → kein App-Version-/Build-Bump, Präzedenz #205/#206). Aufgabe (Nutzer): „CP-SAT im Glossar erklären; alle Glossar-Begriffe in der Doku als Mouse-over/Click-Bubble erläutern (aus dem Glossar); Doku nach Zielgruppen aufbauen (Nutzer · nicht-IT-Fachleute · IT-Arch/-Dev · IT-Operations)." (1) Glossar — eine Quelle, drei Verbraucher: strukturierte Wahrheit in
docs-site/src/glossar/glossar.mjs(50 Begriffe inkl. CP-SAT, OR-Tools, Solver/Scheduler/Decoder, Makespan/Durchlaufzeit/Zielfunktion, Constraint/Pönale/G-2/G-3, Auftrag/Teilschritt/Bucht/Belegung, Durable Object/Cloudflare Worker/partyserver, Solver-Service/Fly.io/Access/D1, SBOM/Compliance/DSGVO/OTel/trace_id …) — je Eintragkurz(Sprechblasen-Text),zielgruppen,siehe. Daraus generiertnpm run glossar(Scriptscripts/gen-glossar.mjs, läuft imprebuild/prestart) die gut browsebare Seitedocs/glossar/Glossar.md(Banner „AUTO-GENERIERT — nicht handeditieren"; Muster wietokens.json → tokens.css). (2) Sprechblasen automatisch: Remark-Pluginsrc/remark/glossarTooltips.mjsumschließt in beiden Docs-Instanzen (Haupt-Docs +projekt/HANDOFF+README) je Seite die erste Fundstelle jedes Begriffs mit<span class="tk-term">; Client-Modulsrc/clientModules/glossarTooltip.jszeigt bei Mouse-over und Klick/Tap (angepinnt) die Kurz-Erklärung + „Siehe auch" + „Im Glossar öffnen →" (tastatur-zugänglich, Escape schließt). Übersprungen werden Überschriften, Links, Code (Block+inline), bereits gesetzte HTML-Knoten und die Glossar-Seite selbst; Wortgrenzen verhindern Falsch-Treffer (z. B. „Auftragsnummer" ≠ „Auftrag"); längste Oberflächenform zuerst (CP-SAT-Solver vor CP-SAT). (3) Lesepfade nach Zielgruppe:docs/zielgruppen/Lesepfade.md(Sidebar-Position 0) als nicht-invasiver Überbau — vier kuratierte Pfade (Anwender · Fach/Management · IT-Arch&Dev · IT-Operations) mit „Wer · Worauf es ankommt (True-North-Bezug) · Lesepfad · Begriffe", verlinkt nur bestehende Docs (keine Datei verschoben). Entscheidungen: (a) eine Quelle (glossar.mjs) speist Seite, Sprechblasen und Suche statt doppelter Pflege; (b) Begriffe automatisch (Remark) statt manueller Markup-Edits in jeder.md— auch HANDOFF/README profitieren; (c) erste Fundstelle je Seite (klassische Glossar-UX, kein Zukleistern); (d) Pure-CSS/Vanilla-Client-Modul ohne neue npm-Abhängigkeit; (e) kein Hex (Infima-Theme-Variablen → dark/light); (f) Zielgruppen als Überbau (OP-DOCS-4 Schritt 1) statt sofortiger Ordner-Trennung/Login-Sichtbarkeit (bleibt OP-DOCS-4/-5); (g)Glossar.mdim Ordnerglossar/⇒ Docusaurus-Index-Route/docs/glossar/(Dateiname == Ordnername) — Navbar/Client-Links darauf gesetzt. Verifikation:npm install+npm run build(Docusaurus) grün; Sprechblasen in 21 Doku-Seiten gerendert (CP-SAT auf 8 Seiten inkl. HANDOFF), Glossar-Anker (#cp-sat…) vorhanden, Client-Popover gebündelt, Remark-Logik per Standalone-Test geprüft (Heading/Link/Code übersprungen, Wortgrenze, Longest-Match). Verbleibende Broken-Link-Warnungen sind vorbestehend/dual-kontextuell (Landkarte/Lesepfade→ repo-root../HANDOFF.md/../README.mdGitHub-relativ; brechen den Build nicht,onBrokenLinks: 'warn'). Doku:docs-site/src/glossar/glossar.mjs,scripts/gen-glossar.mjs,src/remark/glossarTooltips.mjs,src/clientModules/glossarTooltip.js,src/css/custom.css,docusaurus.config.js,package.json;docs/glossar/Glossar.md(generiert) +_category_.json;docs/zielgruppen/Lesepfade.md+_category_.json;docs/README.md, HANDOFF (§2 + OP-DOCS-10), CHANGELOG, Timesheet. Kein Solver-Redeploy, kein App-Code. - Branch
claude/sync-bot-token-doc(PR folgt) — OP-PM-2 doc:SYNC_BOT_TOKEN-Setup dokumentiert + Status auf ✅ geschlossen (Doku-only → kein Version-/Build-Bump, Doku-Fast-Track). Nutzer-Wunsch (Folge zu #222): Setup-Anleitung für das optionaleSYNC_BOT_TOKENfesthalten. Gebaut:docs/konventionen/agents.md§6.6 erhält einen „SetupSYNC_BOT_TOKEN"-Block — warum (Default-GITHUB_TOKEN-Push triggert keine PR-CI, GitHub-Loop-Schutz), wie (fine-grained PAT, nurdrkv-com/taktano, Contents R/W + Pull requests R/W; alternativ GitHub-App-Token; klassischer PAT brauchtworkflow-Scope für Workflow-Dateien), wo (Settings → Secrets → Actions, odergh secret set), Compliance (OP-SEC-1/Risikoregister: Ablauf + Rotation, breite PATs meiden). Inline-Befehlspfad in §6.6 Maßnahme 5 auf Repo-Root-Formnode scripts/smooth-logs.mjsvereinheitlicht. Status: „Allow auto-merge" wurde vom Nutzer aktiviert (an #222 live verifiziert: Auto-Merge-Squash feuerte auf CI-Gate-grün) → OP-PM-2 in HANDOFF auf ✅ umgesetzt geschlossen (letzter offener Repo-Setting-Punkt erledigt). Verifikation:check-doc-consistency.shgrün;smooth-logs:checkgrün. Kein Code-/Solver-Change. Doku:docs/konventionen/agents.md(§6.6), HANDOFF (OP-PM-2), CHANGELOG, Timesheet (Session2026-06-27-concurrent-prs-merges). True North: indirekt (Governance/Audit-Bereitschaft). - #222 — OP-PM-2: Concurrent-PR-Handling — Log-Glätter + Auto-Sync-Workflow + „GitHub-kann-nicht-union-mergen"-Befund (CI/Tooling/Doku-only → kein App-Version-/Build-Bump,
APP_VERSIONbleibt 0.14.4; Build auto-gestempelt). Nutzer-Aufgabe: „we need to handle concurrent prs and merges". Die OP-PM-2-Infrastruktur (union-Merge-Logs · Auto-Build-Nummer · branch-abgeleitete Session-IDs ·check-doc-consistency.sh-Flags) war da — diese PR schließt die Lücken. (A) Log-Glätterscripts/smooth-logs.mjs(npm run smooth-logs/:check, inserver/; bzw. vom Repo-Rootnode scripts/smooth-logs.mjs): macht das bislang manuelle Glätten der union-Duplikate zum Befehl — entfernt byte-identische Duplikate verlustfrei (CHANGELOG-Eintragszeilen · Timesheet-Session-Zeilen, Zahl- und Datum-Slug-ID; erste Vorkommnis bleibt), meldet nur Mehrdeutiges (Konflikt-Marker-Reste · gleiche Session-ID mit abweichendem Inhalt), sortiert bewusst nicht um;--check= schreibfreier Dry-Run (Exit 1 bei Bedarf). EOL-erhaltend (kein CRLF→LF-Churn). Komplement zum nur-flaggendencheck-doc-consistency.sh(das jetzt darauf hinweist). (B) Befund (verifiziert): GitHubs server-seitiger Merge —Update branch-Button,update-branch-API und die Mergeability-Berechnung — wendetmerge=unionnicht an; derselbe main-Merge, der lokal sauber durchläuft, wird server-seitig mit422 merge conflictabgelehnt, log-berührende PRs bleibendirty. union greift also nur lokal. Dokumentiert in.gitattributes,agents.md§6.6 (Maßnahme 5) und HANDOFF (OP-PM-2 Pkt 7). (C) Workflow.github/workflows/sync-pr-logs.yml— macht den nötigen lokalen union-Merge +smooth-logs+ Push + PR-Kommentar per Knopfdruck (Auslöser/sync-logs-Kommentar oderworkflow_dispatch); guards Fork/nicht-offen, bricht bei echten Konflikten ab (smooth-logs-Fehler stoppt den Job, kein|| true), least-privilege; optionales SecretSYNC_BOT_TOKEN(PAT) für CI-Re-Trigger (Default-GITHUB_TOKEN-Push löst keine neue PR-CI aus). Entscheidungen: (a) nur verlustfreie Auto-Fixes (Mehrdeutiges wird gemeldet, nicht geraten); (b) kein CI-Block (Agenten-Werkzeug, warnt/fixt); (c) keine Umsortierung; (d) explizite Auslöser für den Auto-Sync (keine Push-Loops); (e)actions/checkout@v7beibehalten = Repo-Konvention (ci.yml/weekly-audit/docs-deploy/fly-deploy nutzen durchweg@v7/@v6; CodeRabbits „v7 unpublished" ist für dieses Repo/Stand ein False-Positive). Nebenbei (gleiche Session): offene PRs abgearbeitet — #221 (Owner) gemergt; #213 (upload-artifact 4→7, CI-Gate grün, SBOM-Job nutzt v7) + #214 (ortools-Floor>=9.10→>=9.15.6755, vorher lokal auf main gehoben, Solver-Selbsttest grün) squash-gemergt; #220 (Glossar) parallele Session belassen. Repo-Settings (§6.7):delete_branch_on_merge/main-Protection/Squash ✅ (per MCP); „Allow auto-merge" vom Nutzer aktiviert (war der offene OP-PM-2-Punkt). CodeRabbit-Review #222 adressiert: Befehlspfad (node scripts/…statt root-npm run),|| trueentfernt (smooth-logs-Fehler surfacen), CHANGELOG auf einen PR-Eintrag konsolidiert, EOL-Erhaltung insmooth-logs.mjs;checkout@v7begründet beibehalten. Verifikation:smooth-logs-Synthetik-/Real-Test + sauberes--check;sync-pr-logs.ymlYAML-validiert; lokaler union-Merge real auf #220 und diesem Branch (keine Log-Duplikate);check-doc-consistency.shgrün. Kein Solver-/Worker-Redeploy. Doku:scripts/smooth-logs.mjs,.github/workflows/sync-pr-logs.yml,.gitattributes,server/package.json,scripts/{check-doc-consistency,session-start-hook}.sh,docs/konventionen/agents.md(§6.6),CLAUDE.md(§Repo), HANDOFF (OP-PM-2), CHANGELOG, Timesheet (Session2026-06-27-concurrent-prs-merges). True North: indirekt (Governance — reibungsärmere, korrektere parallele Merges). - #221 — OP-DEVTOOL-1 erfasst: CodeRabbit ↔ MCP-Integration als offener Punkt (Doku, kein Code → kein Version-/Build-Bump, Präzedenz #203/#198). Nutzer-Frage 06-27: „Können wir CodeRabbit als MCP integrieren?" → recherchiert + als OP-DEVTOOL-1 geparkt (keine Umsetzung jetzt). Zwei Richtungen festgehalten: (1) CodeRabbit als MCP-Client (offiziell GA) — zieht MCP-Kontext in die PR-Reviews, konfiguriert per Dashboard + versionierter
.coderabbit.yaml, ephemeral/zero-retention, Pro-Feature, braucht gehostete Remote-MCP-URL; (2) CodeRabbit als MCP-Server (communitybradthebeeble/coderabbitai-mcp, MIT) — exponiert PR-Review-Kommentare als MCP-Tools für Claude Code, braucht GitHub-PAT. Befund Repo-Stand: CodeRabbit reviewt bereits PRs, aber keine versionierte.coderabbit.yaml(Review-Config nur im Dashboard → Everything-as-Code-Lücke). Empfehlung: (i) kleiner Schritt zuerst — versionierte.coderabbit.yaml(Vorbedingung Richtung 1); (ii) Richtung 1 = besserer Fit, falls Pro + nützlicher Kontext-Server; (iii) Richtung 2 hier nicht empfohlen (dupliziert vorhandenen GitHub-MCP + inoffizielles-Tool-mit-PAT-Risiko → Risikoregister/OP-COMPLIANCE-1/OP-SEC-1). Offene Entscheidungen (Nutzer): CodeRabbit-Plan (Pro?) + gewünschter Review-Kontext (GitHub/Cloudflare/intern). True North: Dev-Prozess-Tooling, kein direkter Auslastung/Standort/Kapazität-Beitrag → niedrige Priorität. Kein Code/Solver-Redeploy. Doku: HANDOFF (OP-DEVTOOL-1), CHANGELOG, Timesheet (Session2026-06-27-coderabbit-mcp-integration-xm9zpu). - Branch
claude/merge-churn-reduction-vo24s7(PR folgt) — Doku-Fast-Track: reine Doku-PRs überspringen die schwere CI + Auto-Merge (CI/Tooling-only → kein App-Version-/Build-Bump; Build ist seit OP-PM-2/#210 auto-gestempelt,APP_VERSIONbleibt 0.14.4 (main-Stand)). Nutzer-Wunsch: „Simple Commits (z. B. Timesheet-Fix) direkt aufmain?" → Antwort: nicht Direkt-Push (würde den Audit-/PR-Nummern-Trail und CI-Gate löchern), sondern ein dokumentierter Fast-Track über Branch+PR mit fast null Friktion. Gebaut (.github/workflows/ci.yml): (1) neuerchanges-Job (dorny/paths-filter@v3,predicate-quantifier: 'every') erkennt docs-only = jede geänderte Datei liegt unterdocs/oder ist*.md; (2) die schweren Jobs (server/client/solver-service/design-gate/sbom/security-audit) sind aufneeds: changes+if: code == 'true'gegated → bei docs-only übersprungen; (3) neuer aggregierter JobCI Gate(if: always(),needsalle schweren Jobs) = einziger Required-Check: grün, solange kein benötigter Job fehlschlägt (skipped = ok) → ein Doku-PR ist mergebar/auto-mergebar ohne die App-CI zu binden; (4)deployentfällt bei docs-only-main-Push automatisch (kein Redeploy für reine Doku). Entscheidungen: (1) Branch+PR auch für Doku (kein Direkt-Push) — lückenloser Audit-/CHANGELOG-Trail schlägt Bequemlichkeit; statt Bypass eine friktionsarme Spur; (2)CI Gateals einziger Required-Check (Aggregator-Muster) löst das „skipped Required-Check blockt Merge"-Problem sauber; (3) breite Doku-Definition (**/*.md+docs/**, nicht nur Root) — auchdesign/*.md/HANDOFF.mdetc. zählen; (4) Mergify/Tooling verworfen für heute — natives GitHub (Squash + Auto-Merge + ggf. Merge-Queue) deckt den „pr-weise"-Flow ohne neuen Auftragsverarbeiter (DSGVO Art. 28) ab; (5) komplementär zu OP-PM-2/#210 — dieses PR senkt CI-Kosten/Merge-Mechanik, #210 verhindert Log-/Build-Konflikte an der Wurzel (zwei Hälften derselben Churn-Story). Repo-Voraussetzung (Admin, nicht im Code): Branch-Protection vonmainauf nurCI Gateumstellen + „Allow auto-merge" aktivieren (sonst greift der Fast-Track technisch nicht). Verifikation:ci.ymlYAML-validiert (10 Jobs inkl.changes/ci-gate); auf den neuenmain(#210/#211) gemergt — koexistiert mitdoc-consistency, gated auchsecurity-audit, manueller Build-Bump verworfen (OP-PM-2 Auto-Stamp). Doku:agents.md§7 (Doku-Fast-Track-Regel + Footer), HANDOFF (§2), CHANGELOG, Timesheet (Session 46). Kein Solver-Redeploy. - #218 — Doku/Tooling: sprechende Session-IDs (OP-PM-2) + Zertifizierungs-/Compliance-Tracker (OP-COMPLIANCE-1) (Doku/Tooling-only → kein Version-/Build-Bump). Zwei Nutzer-Wünsche. (1) „Session-ID sprechend gestalten → weniger Konflikte": Die fortlaufende Timesheet-Session-Zahl kollidierte bei parallelen Branches (jeder griff „die nächste Nummer" → union-Merge erzeugte Duplikate → Hand-Umnummerierung, zuletzt 50→52). Umstellung auf branch-abgeleitete ID
<Datum>-<branch-slug>(z. B.2026-06-27-sprechende-session-ids): der Branch-Name ist git-weit eindeutig → die ID kann nicht kollidieren, der union-Merge konkateniert nur. Sprechend (Datum=wann, Slug=was) + chronologisch sortierbar; Alt-Sessions 0…52 behalten ihre Zahl (nicht rückwirkend umgeschrieben, CHANGELOG-Verweise bleiben gültig).scripts/check-doc-consistency.sh3b generalisiert: Dublettencheck erfasst jetzt beide ID-Formen (Zahl und Datum-Slug), Datum-only-Rückblickzeilen ausgeschlossen. (2) „Tracker bzgl. ISO-Zertifizierung / Compliance DSGVO aufnehmen":docs/betrieb/Compliance.mderhält einen At-a-glance-Tracker „Zertifizierungs-/Compliance-Tracker (lebend)" — Statustabelle C-01…C-16 (ISO/IEC 27001/ISMS · Datenschutz DSGVO/BDSG/DSG/revDSG · TÜV/Produkt- & IT-Sicherheit · E-Rechnung · Security-Audit) mit Status (☐ offen/◐ in Arbeit/☑ erfüllt) · git-nahem Beleg · nächstem Schritt · OP-Bezug; Review-Takt = je Session-/PR-Beginn, neue Themen als Zeile ergänzen. Ersetzt die bisherige Prosa-Bereitschafts-Checkliste durch die strukturierte Tabelle. SBOM-Frage des Nutzers beantwortet: SBOM ist dokumentiert (Compliance.md §SBOM + CLAUDE.md §Compliance) → im Tracker C-05 = ☑ (CycloneDX-CIsbom+ Dependabot +npm/pip-audit-Gates + CodeQL Default Setup; offen: Solver-CycloneDX + signierte Release-SBOM). Entscheidungen: (a) ID branch-abgeleitet statt Zahl (Kollisionsfreiheit by construction, kein Renumber mehr); (b) Bestand nicht rückwirkend umschreiben; (c) Tracker als kanonische Statustabelle, Detail in OPs/§SBOM. Verifikation:check-doc-consistency.shgrün (keine toten Links, ID-Dublettencheck ohne Falsch-Positive auf Datum-Zeilen). Kein Code-/Solver-Change. Doku:docs/betrieb/Timesheet.md,docs/betrieb/Compliance.md,docs/konventionen/agents.md(§6.6),CLAUDE.md,scripts/{check-doc-consistency.sh,session-start-hook.sh}, HANDOFF (OP-PM-2/OP-COMPLIANCE-1), CHANGELOG, Timesheet (Session2026-06-27-sprechende-session-ids). True North: indirekt (Governance/Audit-Bereitschaft + reibungsärmere Doku-Pflege). - #217 — Bugfix: Foto-Schutz — erneutes Markieren nach dem ersten Verpixeln ging nicht (Version 0.14.3 → 0.14.4 PATCH). Nutzer-Report (iPad): „Nachdem das erste Mal Bereiche markiert und verpixelt wurden, funktioniert das neue Markieren nicht mehr." Ursache: Das Flag
verpixeltblieb nach dem Verpixeln dauerhafttrueund wurde an drei Stellen als Guard missbraucht (boxenProzent(),syncOffeneBoxen(), der Gate-Input inanalysiere()verpixelt ? [] : …) → alle danach gezogenen Markierungen wurden ausgeblendet/ignoriert (kein Box-Overlay, kein „Verpixeln"-Button). Fix: die dreiverpixelt-Guards entfernt (sie dürfen neue Markierungen nicht blocken) und inverpixelnJetzt()nach dem Einbrennen die Boxen-Listen geleert (manuelleBoxen/autoTreffer→ leer, da ins Bild eingebrannt) → frischer Zustand für die nächste Runde.verpixeltsteuert weiterhin nur das Upload-Label „(verpixelt)" und die ehrliche-Befund-Logik (piiUngeprueft). Verifikation: echter Browser-Test (Chromium/Playwright headless): markieren → verpixeln (Button verschwindet) → erneut markieren → Verpixeln-Button und Box-Overlay wieder da. Plusng build+ No-Hex grün. Reiner Client-Pfad — kein Server-/Solver-Change (nurversion.ts). Doku: CHANGELOG, Timesheet (Session 52). True North: Bedienbarkeit des Foto-Schutzes (mehrfaches Markieren/Verpixeln pro Bild). - Branch
claude/codeql-default-setup-docs(PR folgt) — OP-SEC-1/OP-SBOM-1: CodeQL via GitHub Default Setup aktiviert + Agenten-Instruction für nicht-automatisierbare Checks (Doku/Tooling-only → kein App-Version-/Build-Bump). Nutzer: Code scanning als Default Setup aktiviert (+ Squash-only/auto-merge/auto-delete bestätigt); zusätzlich „für alle Checks, die nicht per MCP laufen, eine Agenten-Instruction zum Prüfen". Gebaut: (1) CodeQL-Status korrigiert von „blockiert" → ✅ aktiv via Default Setup (TS+Python automatisch, PR/Push, null Wartung; kein eigenercodeql.yml— advanced + default schließen sich aus) in RISK-4, Compliance, Observability §6, HANDOFF (OP-SBOM-1), Sanity-Checkliste. (2)scripts/check-security-setup.shangepasst: fehlender CodeQL-Workflow ist jetzt korrekt (ℹ️ Default Setup) statt ⚠️; echter Status weiter best-effort viagh(default-setupstate). (3) Neue verbindliche Agenten-Instructiondocs/konventionen/agents.md§6.7 „Nicht-automatisierbare Checks (nicht per MCP/Skript prüfbar)": Repo-Settings (Squash-only · allow_auto_merge · delete_branch_on_merge · Code-Scanning-Modus · Branch-Protection) + semantische Doku-Konsistenz → bei Session-Start/vor PR pergh apiODER Rückfrage beim Nutzer verifizieren, Abweichungen melden; gespiegelt als Punkt 6 in den SessionStart-Hookscripts/session-start-hook.sh. Entscheidungen: (a) Default Setup statt eigenem Workflow (Nutzer-Wahl — empfohlen, wartungsfrei, deckt TS+Python); (b) nicht-per-MCP-prüfbare Kontrollen werden Agenten-Pflicht (kein Skript ersetzt sie), verankert in agents.md + SessionStart-Hook + Sanity-Checkliste. Log-Hygiene: #215-Eintrag von „(PR folgt)" auf [#215] gezogen. Verifikation:bash -n+ lokaler Lauf voncheck-security-setup.shgrün (CodeQL jetzt ℹ️ statt ⚠️);check-doc-consistencygrün. Kein Solver-/Worker-Redeploy. Doku:docs/konventionen/agents.md(§6.7),scripts/{check-security-setup.sh,session-start-hook.sh},docs/betrieb/{Risikoregister,Compliance,Sanity-Checkliste}.md,docs/architektur/Observability.md, HANDOFF, CHANGELOG, Timesheet (Session 51). - #215 — OP-SEC-1/OP-SBOM-1/RISK-4: Wöchentlicher Security-/Setup-Sanity-Lauf (CI/Tooling+Doku-only → kein App-Version-/Build-Bump). Nutzer-Wunsch: „weekly run an audit if all is set + als Sanity-Check dokumentieren". Gebaut: (1)
.github/workflows/weekly-audit.yml— Cron Montags 06:37 UTC +workflow_dispatch(manuell); fährt die Vuln-Audits zeitgesteuert neu (npm audit --omit=dev --audit-level=highServer/Client +pip-auditSolver = blockierend; voll-Audit inkl. Dev informativ) → fängt neu bekannt gewordene Advisories auf unveränderten Deps, ohne dass ein Push/PR nötig ist (Zeit-Achse zum push/PR-Gatesecurity-audit). (2)scripts/check-security-setup.sh— Setup-Sanity „ist alles gesetzt?": prüft Dependabot-Config · CI-Jobssecurity-audit+sbom· gepinnte Actions (kein@main/@master/@latest) · CodeQL-Workflow · und best-effort viaghdie Repo-Settingsallow_auto_merge/delete_branch_on_merge/Code-Scanning-Status; warnt, blockt nicht (Exit 0,::warning::+ Markdown-Report in die Step-Summary), lokal aufrufbar. (3) Doku als Sanity-Check: neuer Abschnitt „Security-/Setup-Sanity (wöchentlich)" indocs/betrieb/Sanity-Checkliste.md(Prüf-Tabelle + bekannte offene Punkte) + Verweise in Compliance/HANDOFF. Entscheidungen: (a) GitHub-Actions-Cron statt externer Scheduler (Everything-as-Code, lebt im Repo); (b) Vuln-Audit blockierend, Setup-Sanity warnend (Konvention wiedoc-consistency); (c) least-privilegepermissions: contents:read. Verifikation:bash -n+ lokaler Lauf grün (Exit 0; flaggt korrekt die zwei realen offenen Punkte ungepinnteflyctl-actions@masterund fehlendes CodeQL/Code-Scanning);yaml.safe_loadfür den Workflow valide;check-doc-consistencygrün. Kein Solver-/Worker-Redeploy. Doku:.github/workflows/weekly-audit.yml,scripts/check-security-setup.sh,docs/betrieb/Sanity-Checkliste.md,docs/betrieb/Compliance.md, HANDOFF (OP-SBOM-1), CHANGELOG, Timesheet (Session 50). True North: indirekt (Betriebssicherheit/Compliance-Governance). - #212 — Foto-Schutz: Touch/Pencil-Markierung am iPad + ehrliche Befund-Box ohne Auto-Erkennung (Version 0.14.2 → 0.14.3 PATCH; Build-Nummer auto-gestempelt, OP-PM-2). Zwei Nutzer-Reports am echten Gerät. (1) Touch/Pencil-Markierung am iPad ging nicht: der Aufzieh-Rahmen nutzt Pointer-Events, aber ohne
touch-action: noneschluckte der Browser die Geste (Scroll/Zoom) und ohne Pointer-Capture brach das Ziehen ab, sobald der Finger das Element verließ. Fix: am Zeichen-Wrapper[style.touch-action]="zeichnend() ? 'none' : 'auto'"+setPointerCapture(pointerId)inziehStart+ev.preventDefault()(down/move) +(pointercancel)-Handler. (2) Grüne „Freigegeben — keine Beanstandung"-Box war irreführend, wenn die Auto-Erkennung NICHT lief: ein Selfie mit Gesichtern wurde als „keine Beanstandung" angezeigt, obwohl Personen/Kennzeichen mangels gehosteter Modelle gar nicht geprüft wurden. Fix: neue Anzeige-HelferanzeigeFarbe/anzeigeLabel/anzeigeMeldungen— bei Statusokund noch nicht verpixelt und kein echter PII-Detektor erfolgreich gelaufen (piiAutoGeprueft= PII-spezifisches Signal, nicht der geteilteautoStatus— ein NSFW-Fehler darf nicht „PII ungeprüft" suggerieren; CodeRabbit-Review #212) wird die Box amber „Bitte prüfen" mit Klartext „Personen/Kennzeichen wurden NICHT automatisch geprüft — bitte ggf. selbst markieren und verpixeln" (statt grün „Freigegeben"); NSFW-/Qualitäts-Blockaden unberührt, Upload bleibt erlaubt (nur Hinweis). Verifikation: echter Browser-Test (Chromium/Playwright headless): (a) Touch-PointerEvent-Drag (pointerType:'touch') erzeugt eine Markierung → „verpixeln"-Button erscheint; (b) Befund-Label bei inaktiver Erkennung = „Bitte prüfen" (nicht „Freigegeben"). Plusng build+ No-Hex grün. Reiner Client-Pfad — kein Server-/Solver-Change (nurversion.ts). Doku: CHANGELOG, Timesheet (Session 49). True North: Bedienbarkeit am Touch-Gerät + ehrliche Datenschutz-Aussage (keine falsche Entwarnung). - Branch
claude/sonarqube-sentry-snyk-eval-5eag1a(PR #211) — OP-SEC-1/OP-SBOM-1/RISK-4: Security-Quick-Wins GitHub-nativ (Dependabot · npm-audit/pip-audit-Gate; CodeQL durch Repo-Setting blockiert) (CI/Tooling-only → kein App-Version-/Build-Bump). Nutzer-Wunsch: „Quick wins direkt". Schließt die im Werkzeug-Befund (06-27) empfohlenen kostenlosen Lücken — ohne Drittanbieter/Quellcode-Export (DSGVO-arm). Gebaut: (1).github/dependabot.yml— wöchentliche Updates für npm (Server+Client), pip (Solver) und github-actions; Patch/Minor gruppiert (PR-Lärm), Major einzeln. (2) CI-Jobsecurity-audit(ci.yml): blockierender Gatenpm audit --omit=dev --audit-level=highfür Server+Client (= das ausgelieferte Risiko) +pip-auditfür den Solver; voll-Audit inkl. Dev informativ (nicht-blockierend); least-privilegepermissions: contents:read. CodeQL (3) gebaut → wieder entfernt: der CodeQL-Workflow (TS+Python,security-and-quality) scheiterte beim SARIF-Upload mitCode Security must be enabled for this repository to use code scanning— Code Scanning ist im Repo nicht aktiviert (privat = GitHub Advanced Security), eine Admin-Repo-Einstellung. Workflow entfernt; Follow-up (Admin): Code Scanning aktivieren → CodeQL re-aktivieren (1 Datei). Empirisch verifiziert (vor Push): Produktiv-Deps Server+Client sauber (high+), Solverpip-auditkeine Vulns → Gates grün;npm auditläuft ohnenpm cinur mit Lockfile (im CI bestätigt). Entscheidungen: (1) Gate auf--omit=dev— die 4 vorhandenen High-Vulns (undici/ws via Wrangler/Miniflare) sind Dev-Toolchain, werden nicht in den Worker gebündelt → dürfen CI nicht brechen; sie laufen über Dependabot-PRs ein und sind im informativen Voll-Audit sichtbar (kein silent cap). (2) GitHub-nativ statt Snyk/SonarQube (Befund 06-27: gratis, kein Code-Export). (3) Audit-Gate blockiert PR/CI, aber NICHTdeploy.needs(CodeRabbit-Review + Availability: ein nicht-patchbares Prod-Advisory soll keine main-Deploy-Sperre auslösen; neue Advisories werden via CI aufmaintrotzdem rot sichtbar). (4) kein App-Bump (reine CI/Tooling-Änderung, kein Runtime-Verhalten). CodeRabbit-Review adressiert: least-privilegepermissionsergänzt; Deploy-Deadlock-Risiko durch Entfernen ausdeploy.needsgelöst. Verifikation:yaml.safe_loadvalide; Audit-Gates lokal grün; Merge mitmain(4 zwischenzeitliche PRs) konfliktfrei aufgelöst (union-Logs, Session-Renumber 45→48). Doku:.github/{dependabot.yml,workflows/ci.yml},docs/betrieb/Compliance.md,docs/betrieb/Risikoregister.md(RISK-4 → gemindert, Score 6→4),docs/architektur/Observability.md§6, HANDOFF (OP-SBOM-1), CHANGELOG, Timesheet (Session 48). Kein Solver-/Worker-Redeploy aus diesem Commit. - Branch
claude/sonarqube-sentry-snyk-eval-5eag1a(PR folgt) — OP-OBS-1: Backend-Kandidaten bewertet + Grafana/Sentry-Vergleich festgehalten; SonarQube/Snyk-Befund (Doku-only → kein Version-/Build-Bump, Präzedenz #205/#206/#198/#203). Nutzer-Fragen 06-27: „Hilft uns SonarQube/Sentry/Snyk?" + „Wie könnte Grafana helfen?". Neue Dokudocs/architektur/Observability.md(Muster Audit-Log.md/Kosten.md) hält die offene OP-OBS-1-Backend-Wahl als bewertete Kandidaten fest: Grafana (LGTM: Loki/Tempo/Mimir/Faro/Alerting, self-host bevorzugt) ↔ Sentry (Crash-DX, EU-Region+Scrubbing) als zwei Hauptoptionen, Cloudflare-nativ nur als Worker-Ergänzung (deckt Client+Solver nicht), Honeycomb zurückgestellt (US-Residenz). Alle über OTLP code-frei austauschbar (kein Lock-in). Empfehlung: Grafana self-hosted (EU-Datenhoheit, analog Better-Auth OP-AUTH-1) oder Grafana Cloud EU; Wahl Grafana↔Sentry offen (User-Entscheidung). Scope-Leitplanke dokumentiert: technische OTel-Telemetrie ≠ Cockpit/True-North-Dashboards (gehören in die App, Selbsterklärbarkeit) ≠ Kosten-Dashboard (OP-COST-1) ≠ Audit-Log (OP-AUDIT-1). Begleit-Befund (SonarQube/Snyk): echte, aber zuerst gratis & GitHub-nativ zu schließende Lücken — Snyk → Dependabot+CodeQL+npm audit/pip-audit(RISK-4), SonarQube → ESLint+ruff/mypy+CodeQL (Lint-Gate), beide ohne Quellcode-/Dependency-Export (DSGVO-arm); externe Tools erst später als Komfort/Audit-Dashboard. Entscheidungen: (1) eigenes Architektur-Dok statt nur HANDOFF-Zeile (festgezurrte Bewertung, Musterarchitektur/); (2) Grafana self-host bevorzugt wegen EU-Residenz (Compliance + Verkaufsargument); (3) Sicherheits-Tools GitHub-nativ vor SaaS; (4) Doku-only → kein Bump. Doku:docs/architektur/Observability.md(neu), HANDOFF (OP-OBS-1),docs/README.md(Landkarte), CLAUDE.md (Tiefenquellen),docs/betrieb/Compliance.md(SBOM/Security-Befund),docs/betrieb/Risikoregister.md(RISK-4), CHANGELOG, Timesheet (Session 48). Kein Code/Solver-Redeploy. - #210 — OP-PM-2: Merge-Churn der parallelen PRs entschärfen (union-Merge · Auto-Build-Nummer · Log-Hygiene) (Tooling/Doku, kein App-Verhalten →
APP_VERSIONunverändert0.14.2). Auslöser: Beim Mergen von #207 liefmain4× weiter (#205/#206/#208/#209) → Dauer-Konflikte in den append-only Logs plus Build-/Versions-Kollisionen (jede PR bumpteversion.tsvon Hand). Nutzer: „1+2+3" + „regelmäßig Logs checken/glätten, alles dokumentieren". Gebaut: (1).gitattributesmerge=unionfürCHANGELOG.md/HANDOFF.md/docs/betrieb/Timesheet.md→ parallele PRs konkatenieren statt zu blocken. (2) Build-Nummer automatisch aus Git-Commit-Count:server/src/build-number.ts(auto-gestempelt) +scripts/stamp-build.mjs+predeploy-Hook + Deploy-Checkoutfetch-depth: 0;version.tsre-exportiertAPP_BUILDund trägt nur noch das manuelleAPP_VERSION→ keine Build-Kollision mehr (Umstellung Build 19 → Commit-Count, akt. 165). (4) Log-Hygiene verbindlich (agents.md §6.6 + §5.1, CLAUDE.md): Logs regelmäßig glätten (Session-Start + nach Merges) —scripts/check-doc-consistency.shflaggt jetzt Marker-Reste · doppelte Timesheet-Session-Nummern · doppelte CHANGELOG-PR-Zeilen (warnt, blockt nicht). (3) Offen (Repo-Setting): GitHub Merge Queue / „Allow auto-merge" aktivieren (Settings → Pull Requests) — war beim #207-Merge deaktiviert; serialisiert Merges. Entscheidungen: Build = Git-Commit-Count (deterministisch/reproduzierbar,fetch-depth:0) statt Run-Number;version.tsbewusst nicht union (SemVer-Konflikt soll sichtbar bleiben). Verifikation:stamp-build(Build 165) + Server-typecheck+check-doc-consistency(inkl. Log-Hygiene) +ng build(prod) grün. Doku:CLAUDE.md(§Repo/§Versionierung),docs/konventionen/agents.md(§5.1/§6.6),.gitattributes,scripts/, HANDOFF (OP-PM-2),docs/betrieb/Timesheet.md. Schließt zudem den Verify-Punkt OP-R9-12 (Nutzer 06-27: „ist ok"). - #207 — OP-DOCS-9: Doku-Konsistenz-Check in den Guidelines + Memory + CI (Doku/Tooling, kein App-Code → kein Version-/Build-Bump). Nutzer-Wunsch: Konsistenz-Check der Doku einbauen — in sich und gegen die Implementierung —, im Memory halten und die Guidelines anpassen (mit Rückfrage bei Unklarheiten). Gebaut: (1) Guidelines — Root-
CLAUDE.md(Repo-Guiding-Principle) +docs/konventionen/agents.md§5.1 (verbindlicher Doku-Konsistenz-Check, Achsen Doku↔Doku [IDs/Glossar/Workspace-·Phasen-Liste/Status/Version·Build/Querverweise] & Doku↔Code [Feldnamen/Enums/DTOs/Routen/Token, beschriebenes=gebautes & gebautes=beschriebenes]) + §6.5 (Workflow). (2) Memory = SessionStart-Hookscripts/session-start-hook.shin.claude/settings.json(versioniert, da kein Memory-Tool — agents.md §1). (3) CIscripts/check-doc-consistency.sh+ Jobdoc-consistency(mechanisch: tote Links/Bilder + Version/Build-Single-Source) — warnt, blockt nicht (::warning::, nicht indeploy.needs; Token read-only-scoped +persist-credentials: falseper CodeRabbit). Entscheidungen (vom Nutzer gewählt): Cadence Session-Start + je PR; Durchsetzung Guideline + nicht-blockierendes CI-Skript (semantischer Teil bleibt Agenten-Pflicht); „im Memory halten" = Repo-Guideline + SessionStart-Hook. Verifikation:bash scripts/check-doc-consistency.shlokal grün (keine toten Links, Version/Build eindeutig). Doku:CLAUDE.md,docs/konventionen/agents.md(§5.1/§6.5),HANDOFF.md(OP-DOCS-9),.github/workflows/ci.yml,scripts/, CHANGELOG,docs/betrieb/Timesheet.md. - #207 — Bugfix: linke Rail-Sidebar (Crystal-Bar) lässt sich auf dem iPad/Touch nicht mehr schließen (Version 0.14.1 → 0.14.2 PATCH, Build 18 → 19). Problem (Nutzer-Report, iPad): Die Icon-Rail (
client/.../leitstand/shell.component.ts, OP-R9-12) klappt rein per CSS über:hover/:focus-withinauf — ein Maus-Konzept. Auf Touch-Geräten gibt es kein echtes:hover(Safari emuliert es, der Zustand „klebt" bis zum Tap woanders) und:focus-withinbleibt aktiv, sobald ein Nav-Link den Fokus hält → das Panel bleibt dauerhaft offen und legt sich (perabsolute) über den Inhalt; kein Toggle, kein Backdrop → nicht schließbar. Fix (pointer-abhängiges Konzept): (1) Proximity-Reveal (:hover/:focus-within) nur noch für Feinzeiger (@media (hover: hover) and (pointer: fine)) — Desktop/Trackpad unverändert. (2) Geräteunabhängiger expliziter Aufklapp-Zustand über.railwrap.is-open, getrieben von einem neuen Signalexpanded(). (3) Touch-Toggle (☰/✕) oben in der Rail, nur auf Grobzeiger-/Touch-Geräten sichtbar (@media (hover: none), (pointer: coarse)). (4) Backdrop (.tk-railscrim, token-gefärbt, kein Hex) bei offenem Touch-Overlay → Tap schließt. (5) Auto-Einklappen beim Navigieren (Kopplung anNavigationEnd). (6) a11y: der Hintergrund-Inhalt wird bei offenem Overlayinert(Fokus bleibt in der Crystal-Bar; CodeRabbit-Review). Die schmale 84px-Icon-Rail bleibt im Ruhezustand immer sichtbar (Selbsterklärbarkeit). Entscheidungen: (a) Hover-Reveal behalten, wo es passt (Maus), expliziter Toggle, wo nötig (Touch); (b) Default-Touch = schmale Icon-Rail; (c) Schließen über Toggle, Backdrop und Navigation. Verifikation:ng build(prod) + No-Hex-Gate grün (iPad-Augenschein durch Nutzer offen — Playwright im Cloud-Env nicht installiert). Reiner Client-Pfad — kein Server-/Solver-Change (nurserver/src/version.tsbumpt). Doku: CHANGELOG, HANDOFF (OP-R9-12),docs/betrieb/Timesheet.md. True North: Bedienbarkeit des Cockpits auf dem iPad/Touch. - #207 — Doku-Nachzug zum Crystal-Bar-Fix: Begriff, Screenshots, Verify-Punkt, wöchentliche Management-Summary, Jira-OP (Doku-only, kein Code → kein Version-/Build-Bump). Nutzer-Wünsche im Anschluss an den iPad-Fix: (1) Verify-Punkt „Ist das Verhalten der Toolbar so gut?" als offener Prüfpunkt am echten iPad/Touch in HANDOFF (OP-R9-12) festgehalten (Toggle-Auffindbarkeit, Schließwege, Touch-Default, Quer-/Hochformat). (2) Begriff „Crystal-Bar" für die linke Navigations-Rail eingeführt — Glossar
docs/fachlich/Lastenheft.md§13 + ausführlicher Abschnitt indesign/WORKSPACES.md(pointer-abhängiges Verhalten Maus↔Touch). (3) Screenshots mit Einordnung der Bereiche: 3 reale Zustände (Ruhe-Icon-Rail · aufgeklappt · Touch-Overlay mit Backdrop) aus dem laufenden Client (Chromium/Playwright, Media-Emulationpointer/hover) indesign/assets/crystal-bar/, eingebettet in WORKSPACES.md mit Regionen-Legende (Logo · Cluster Überblick/Operativ/Steuerung/Qualität/Wirtschaftlichkeit · Workspace-Badges · Theme · Auf-Kurs-Ring · Live-Status · Touch-Toggle). (4) Timesheet zeigt jetzt wer gearbeitet hat (Beteiligte =MK + Claude, KI-Pair-Programming; Methodik-Bullet) + wöchentliche Management-Summary (KW-Tabelle mit Aufwand/Schwerpunkten/Versionsstand) + 2 Grafiken (Mermaidxychart-beta: Aufwand je KW und je Tag KW26 — versioniert/diff-bar, keine Binär-Charts). (5) Neuer OP-PM-1: Task-/Ticket-Pflege später mit Jira synchronisieren (Richtung/SoR/Mapping/Auth/Scope/Audit zu klären) — Vormerkung, kein MVP-Blocker. Entscheidungen: Crystal-Bar als kanonischer Name (Synonyme Icon-Rail/Rail/Sidebar bleiben gültig); Screenshots als PNG-Belege (reale UI) + Mermaid-Grafiken für die Statistik (Everything-as-Code-Prinzip „Markdown + Mermaid"). Verifikation:ng build(prod) + No-Hex grün; beide Mermaid-Charts gegen Renderer validiert. Doku:docs/fachlich/Lastenheft.md§13,design/WORKSPACES.md,design/assets/crystal-bar/, HANDOFF (OP-R9-12 + OP-PM-1),docs/betrieb/Timesheet.md, CHANGELOG. - #209 — Bugfix: Foto-Schutz zeigte das gewählte Bild nicht an (Version 0.14.0 → 0.14.1 PATCH, Build 17 → 18). Nutzer-Report: „Take photo … Foto-Auswahl öffnet, Foto ausgewählt, dann passiert nichts." Ursache: In
bild-upload-gate.component.tsgreiftonDatei()aufthis.canvas.nativeElementzu, bevor das Signalgeladenauftruegesetzt ist — das<canvas>liegt aber im@else-Zweig (@if (!geladen())) und existiert erst danach im DOM, also warthis.canvaszu dem Zeitpunktundefined→TypeError→ das Bild wurde nie gezeichnet (still verschluckt imawait). Fix: Reihenfolge umgestellt — erstgeladen.set(true)+ChangeDetectorRef.detectChanges()(rendert den@else-Zweig, ViewChildcanvas/wrapwerden verfügbar), dann zeichnen +analysiere(). Zusätzlichinput.value = ''imfinally, damit dieselbe Datei erneut wählbar ist (sonst feuertchangebeim zweiten Mal nicht). Verifikation: echter Browser-Test (Chromium/Playwright headless, statisch geserved): Datei ininput[type=file]gesetzt → Canvas rendert mit 800 px, Befund-Panel zeigt „Freigegeben"/„800×600" — vor dem Fix erschien kein Canvas. Plusng build(prod) + No-Hex grün. Reiner Client-Pfad — kein Server-/Solver-Change (nurversion.ts). Doku: CHANGELOG, Timesheet (Session 45). True North: Bedienbarkeit des Foto-Schutzes (Pre-Upload-Gate funktioniert sichtbar). - #206 — Doku-Site: Start-Seite als Produkt-Übersicht + neue Team-Seite (
docs-site/, Doku-Site-only → kein App-Version-/Build-Bump, Präzedenz Doku-PRs). Start-Seite (src/pages/index.js): von einer dünnen Doku-Verlinkung zu einer kurzen Produkt-Übersicht umgebaut — Ein-Satz-Positionierung, Herzstück (Taktung-/Reihenfolge-Optimierung Scheduler+CP-SAT, „KI schlägt vor, Mensch entscheidet"), die drei True-North-Leitfragen als Karten und die Werthebel (Effizienz/Durchsatz · Termintreue · Transparenz/Team · Qualität/Doku) als Karten, plus Buttons (Produkt & Nutzen · Lastenheft · Doku-Landkarte · Handoff). Inhaltlich gespiegelt ausdocs/produkt/Produkt-und-Marketing.md. Nebenbei behoben: die Start-Seiten-Buttons zeigten nach der OP-DOCS-8-Reorg noch auf/docs/Lastenheft&/docs/datamodel(Regression, daonBrokenLinks: 'warn'den Build nicht brach) → jetzt korrekt/docs/fachlich/…. Team-Seite (src/pages/team.js+ Navbar-Item „Team"): Kernteam mit Rolle/Schwerpunkten + Portrait-Avataren (Initialen-Platzhalter mit gewireterfoto-Slot →static/img/team/<name>.jpg, Anleitung instatic/img/team/README.md) — Dominik May (Fachmann · Gallionsfigur · Netzwerk), Mitarbeiter von Dominik (Prozess-Optimierung · Daily Challenges, Name offen), Holger Queckenstedt (Business Plan · Finance), Dr. Michael Kirchhof (IT · Betrieb); plus To-do-Sektion je Person und seitenweit (u. a. „Rollen und Titel schärfen", „Portrait-Fotos ergänzen", „Name des Mitarbeiters ergänzen"). Verifikation:npm run build(Docusaurus) grün — beide Seiten kompilieren; verbleibende Broken-Link-Warnungen sind vorbestehend/dual-kontextuell (Landkarte../HANDOFF.mdu. a. sind GitHub-relativ; HANDOFF→docs/fachlich/Flow-*im/projekt-Instanz-Kontext) und brechen den Build nicht. Entscheidungen: (1) Start-/Team-Seite als JS-Pages (wie die bestehendeindex.js) für Portrait-/Karten-Layout, Daten als editierbare Arrays am Dateikopf; (2) kein Hex (Docusaurus-Theme-CSS-Variablen → dark/light-tauglich); (3) Portraits als Platzhalter (keine echten Fotos vorhanden) + To-do statt Fake-Bilder. Doku:docs-site/src/pages/{index,team}.js,docusaurus.config.js(Navbar),static/img/team/README.md, HANDOFF (§2), CHANGELOG, Timesheet (Session 42). Kein Solver-Redeploy.
2026-06-26
-
#205 — Docs-Struktur optimiert: Doku-Landkarte + physische Unterordner-Gliederung (OP-DOCS-8 ✅; Doku/Kommentar-only → kein Version-/Build-Bump, Präzedenz #182/#185/#188). Problem:
docs/war flach (17 Dateien ohne Gruppierung), die Doku-Site-Sidebarautogenerated/alphabetisch (Master-Spec zwischenKostenundProdukt), keine Startseite/Navigation. Teil 1 — Landkarte:docs/README.mdals kategorisierter Einstieg (je „wann lesen"/OP-Bezug + Session-Start-Reihenfolge + True-North + ID-System); wirkt doppelt (GitHub-Index beimdocs/-Browsen und Docusaurus-Startseite der bisher index-losen Site). Teil 2 — physische Reorg (Nutzer-Wunsch „Ja" auf den größeren Umbau): alle 17 Dokumente pergit mv(History bewahrt) in 5 thematische Unterordner —fachlich/(Lastenheft·datamodel·operativmodell·solver·Flow-Analyse·Flow-Refactor-Plan) ·architektur/(Audit-Log·Kosten·Akademie·In-App-Assistent·Billing-Zugang) ·betrieb/(Compliance·Risikoregister·Sanity-Checkliste·Timesheet) ·konventionen/(agents) ·produkt/(Produkt-und-Marketing);docs/README.mdbleibt als Index im Root. Je Ordner ein_category_.json(Label +position) → die Docusaurus-autogenerated-Sidebar spiegelt jetzt die Gruppen statt alphabetisch zu mischen. Alle Referenzen nachgezogen: sämtliche klickbaren](…md)-Links (49 repo-weit, per Skript verifiziert → alle auflösbar) + die aktivendocs/<name>.md-Pfade in HANDOFF/CLAUDE/README/design//Code-Kommentaren (10 Code-Stellen:types.ts/seed.ts/infra.ts/github-billing.ts/insights.ts/leitstand.ts/migrations/wrangler.toml). Entscheidungen: (1) append-only Logs nicht umgeschrieben — historischedocs/<name>.md-Erwähnungen inCHANGELOG.mdund in den altenTimesheet-Einträgen bleiben als Code-Span-Prosa stehen (kein 404, beschreiben den damaligen Stand) statt revisionistischer Massen-Edits; (2)agents.md+Produkt-und-Marketing.mdin eigene 1-Datei-Ordner (Tree 1:1 zu den Landkarte-Kategorien) statt im Root zu belassen; (3) autogenerated Sidebar +_category_.jsonstatt manuellersidebars.js(selbst-pflegend) oder front-matter (verschmutzt Roh-.mdauf GitHub). Verifikation: Skript-Check „jeder](…md)-Link resolved auf eine existierende Datei" grün (49/49);_category_.jsonvalides JSON. Hinweis: der Docusaurus-Build selbst ist in der reinen Doku-Session nicht ausführbar (keinnode_modulesindocs-site/);onBrokenMarkdownLinks: 'ignore'+ die verifizierten Link-Ziele decken das ab — beim nächsten Site-Deploy (OP-DOCS-1 d, Triggerdocs/**) gegenprüfen. Folge: publizierte URLs ändern sich/docs/<name>→/docs/<ordner>/<name>(interne, Access-gegatete Site → unkritisch). Doku:docs/README.md,docs/*/_category_.json(neu), HANDOFF (§2 + OP-DOCS-8), CLAUDE.md, README.md,betrieb/Timesheet.md(Session 40). Kein Solver-Redeploy. -
Branch
claude/order-assignment-requirement-4bbw4g(PR folgt) — R7-Invariante: „Ohne Zuweisung kann ein Auftrag nicht in Arbeit sein" (Version 0.12.0 → 0.13.0 MINOR, Build 15 → 16). Nutzer-Wunsch: „ohne zuweisung kann ein auftrag nicht in arbeit sein". Zuweisung = mindestens ein produktiv zugeteilter Mitarbeiter an einem (Nicht-Annahme-)Teilschritt; Helfer/Auszubildende (helferIds) zählen nicht (sie tragen die Arbeit nicht), der nicht-solver-geplante Annahme-Doku-Schritt zählt nicht (leeremitarbeiterIds). Gebaut (Domäne, pure):hatZuweisung(auftrag)+ Guard intransition— jeder Übergang nachin_arbeit(starten/fortsetzen) verlangt eine Zuweisung, sonst wird er abgelehnt (klare Fehlermeldung);erlaubteAktionen(status, auftrag?)blendetstarten/fortsetzenohne Zuweisung aus (UI-Buttons verschwinden). Server: DTO trägthatZuweisung; derauftrag.starten-Handler lehnt ohne Zuweisung explizit ab (Doppel-Sicherung). Client (Selbsterklärbarkeit): Badge „⚠ Zuweisung nötig" im Aufträge-Detail, im geteilten Detail-Panel und im Belegungs-Wareneingang; „▶ Aufbereiten starten" ist dort deaktiviert, solange keine Zuweisung besteht. Entscheidungen: (1) Invariante am Lifecycle-Übergang erzwungen (eine Wahrheit, gilt für jeden Aufrufpfad) statt nur in der UI; (2) Guard auf Zielin_arbeit(decktstartenundfortsetzen) — der Status „in Arbeit" ist nie ohne Zuweisung erreichbar; (3) Helfer ≠ Zuweisung (sie reduzieren die Zeit nicht, sind kein produktiver Träger); (4) keinschemaVersion-Bump (rein additive Logik/Feld, keine Altdaten-Migration). Verifikation: Server-typecheck+operativ-Selbsttest (neuer Zuweisungs-Abschnitt: ohne Zuweisung →startenblockiert + Aktion ausgeblendet; mit Zuweisung →in_arbeit) +ng build(prod) + No-Hex grün. Reiner App-Pfad — kein Solver-Redeploy. Doku:docs/Lastenheft.md§5.1 (R7), HANDOFF (R7-Zeile + §3), CHANGELOG, Timesheet. -
#203 — OP-COST-4 erfasst: GitHub-Billing-Token-Aktivierung als Pre-Prod-Requirement (Doku, kein Code → kein Version-/Build-Bump). Nutzer-Wunsch: „Aktivierung des GitHub-Tokens als OP erfassen". Der GitHub-Kosten-Pull (OP-COST-2 Slice 1, #202) ist dormant, bis das Secret
GITHUB_BILLING_TOKENgesetzt ist → als eigenes OP-COST-4 = Go-Live-Vorbedingung festgehalten (HANDOFF §4, analog OP-COST-3):wrangler secret put GITHUB_BILLING_TOKEN(Billing/Plan-Read-Scope, minimaler Scope = nur Billing-Read, kein Repo-Schreibrecht;GITHUB_BILLING_ORG/GITHUB_BILLING_REPObereits als [vars]), danach „↻ GitHub ziehen" →API-Posten.docs/Kosten.md§4 querverweist OP-COST-4. Kein Solver-Redeploy. Doku: HANDOFF (OP-COST-4),docs/Kosten.md§4, CHANGELOG (#203), Timesheet (Session 38). -
#202 — OP-COST-2 Slice 1: GitHub als Infra-Kosten-Provider (projekt-bezogener Auto-Pull) (Version 0.11.0 → 0.12.0 MINOR, Build 14 → 15). Nutzer-Wunsch: „zeige auch die projekt-bezogenen Kosten von GitHub an". Erste echte OP-COST-2-Slice (automatischer Provider-Pull statt nur manuell). Gebaut: (1) Modell
InfraKostenPostenumquelle:'api'|'manuell'+quelleRef(Idempotenz-Key) — optional → kein Migrations-/schemaVersion-Bump. (2) Pureserver/src/kosten/github-billing.ts: mappt die GitHub-Enhanced-Billing-Usage-API (/organizations/<org>/settings/billing/usage,usageItems[].netAmount) je Monat auf einen „GitHub"-Posten, projekt-bezogen auf das Repo gefiltert (repositoryName), Cent/USD; Self-Test intest:kosten(Repo-Filter, Idempotenz, org-weit, null/leer). (3) DOpullGithubKosten()— dormant/deploy-sicher (No-op ohne SecretGITHUB_BILLING_TOKEN+GITHUB_BILLING_ORG/GITHUB_BILLING_REPO-[vars], wie der D1-/R2-Pfad) → fetch GitHub → Mapper → idempotenter Upsert (infraKostenUpsert, ersetzt byquelleRef); Pull = OP-AUDIT-1-Event (infraKosten.pull) + Ops-Log (OP-LOG-1). (4) Trigger interim on-demand: admin-gegatete ActioninfraKosten.pullGithub+ Client-Button „↻ GitHub ziehen" +API-Badge an automatisch gezogenen Posten. Entscheidungen: (a) GitHub als erster Provider (explizit gewünscht); (b) on-demand in Slice 1, Cron-Automatik (die „verbindliche Richtung") als Folge-Slice; (c) projekt-bezogen = Repo-Filter; (d) dormant bis Token-Secret (kein Deploy-Bruch, kein Repo-PII); (e)quelleoptional → keinschemaVersion-Bump (kollisions-arm bei schnell wanderndermain). Aktivierung:wrangler secret put GITHUB_BILLING_TOKEN(Billing/Plan-Read-Scope). Verifikation: Server-typecheck +test:kosten(erweitert) +operativ+test:prozess+ng build(prod) + No-Hex grün. Reiner App-Pfad — kein Solver-Redeploy. Doku:docs/Kosten.md§4, HANDOFF (OP-COST-2),server/wrangler.toml, CHANGELOG (#202), Timesheet (Session 37). -
Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt) — OP-R4-1: Volle Auflösung optional im Hintergrund archivieren (Version 0.10.0 → 0.11.0 MINOR, Build 13 → 14). Nutzer-Wunsch: „als Option volle Auflösung — im Hintergrund". Zweite Stufe nach der Kompression: Standard bleibt der schnelle, komprimierte Upload (Anzeige-Variante); optional (pro Browser gemerkter Toggle „Original in voller Auflösung archivieren (Hintergrund)") wird zusätzlich das unkomprimierte Original ins Archiv geladen — fire-and-forget im Hintergrund, blockiert weder UI noch das Foto-Pflicht-Gate. Zwei-Varianten-Modell:FotoAttachmentumoriginalR2Key/originalContentType/originalGroesseByteserweitert (r2Key= komprimierte Anzeige-Variante,originalR2Key= Archiv). Korrelation: Client erzeugt die Foto-ID (crypto.randomUUID()) und reicht sie infoto.registriertmit → der Hintergrund-Upload hängt die volle Auflösung per neuer Messagefoto.originalan dasselbe Foto;foto.registriertjetzt idempotent (doppelte ID ignoriert). Worker-Route:POST /api/foto/upload?variante=originallegt unter eigenem Key-Pfad…/<perspektive>/original/<uuid>ab, Limit 30 MB (komprimiert weiterhin 15 MB). Optimierung: Original-Upload entfällt, wenn die Kompression das Bild gar nicht verkleinert hat (dann ist die Anzeige-Variante schon das Original). UI: Toggle + „lädt im Hintergrund"-Toast-Hinweis + „HQ"-Badge am Thumbnail (verlinkt die volle Auflösung), sobald der Hintergrund-Upload durch ist. Entscheidungen: (1) Original opt-in (Default aus) — Bandbreiten-/Speicher-schonend by default, volle Auflösung nur wenn bewusst gewählt (Beweis-/Archiv-Qualität); (2) Hintergrund/best-effort statt blockierend — Zustands-Doku darf nicht am Original-Upload hängen; (3) Client-generierte ID für robuste Vordergrund/Hintergrund-Korrelation. Verifikation: Server-typecheck +test:prozess+operativ-Smoke +ng build(prod) + No-Hex grün; lokale Miniflare-R2-Probe (komprimiert +variante=original→foto.original→originalR2Keyim DTO + Download der vollen Auflösung) grün. Kein Solver-Redeploy. Offen (Folge): getrennte reduzierte PDF-Auflösung + asynchrones Speichern; KI-Plausibilität weiter DSGVO-geblockt (OP-AI-2). -
Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt) — OP-R4-1: Client-seitige Bild-Kompression vor dem R2-Upload (Version 0.9.0 → 0.10.0 MINOR, Build 12 → 13). Nutzer-Wunsch: „Kompression vor Upload". Annahme-Fotos kommen i. d. R. direkt von der Handy-Kamera (mehrere MB, 4000+ px Kante); das treibt Upload-Zeit (Werkstatt-WLAN/Mobilfunk), R2-Speicher und R2-Egress beim Anzeigen unnötig hoch. Gebaut: neuer Helferclient/src/app/leitstand/foto-kompression.ts→komprimiereFoto(file): dekodiert viacreateImageBitmap(EXIF-Orientierungfrom-image), skaliert auf längste Kante 1600 px herunter (kein Hochskalieren), re-encodiert als JPEG q=0.82 über ein<canvas>. Robust/best-effort: Nicht-Bilder, Dekodier-Fehler (z. B. HEIC ohne Browser-Support), fehlendes Canvas oder kein Größenvorteil → Originaldatei wird unverändert hochgeladen (nie ein Fehler). Eingehängt inLeitstandService.uploadFotovor demPOST /api/foto/upload(Body + Content-Type = komprimiertes File); der Server liefert die tatsächlichegroesseByteszurück → DO-Metadaten stimmen. Entscheidungen: (1) Kompression im Service (eine Stelle, gilt für alle Aufrufer) statt in der Komponente; (2) Parameter (1600 px / q0.82) als bewusste Fix-Defaults (Detail/Größe-Kompromiss für Zustands-Doku), nicht admin-editierbar; (3) immer Fallback aufs Original statt Upload zu blockieren — Zustands-Doku darf nicht an einem Decoder scheitern. Verifikation:ng build(prod) + No-Hex-Gate grün. Reiner Client-Pfad — kein Server-/Solver-Change (nurversion.tsbumpt). Offen (Folge): Server-seitige Größen-/Format-Validierung bleibt unverändert (15 MB /image/*); KI-Plausibilität weiter DSGVO-geblockt (OP-AI-2). -
Branch
claude/op-r4-3-foto-perspektiven(PR folgt) — OP-R4-3 R2-Bucket aktiviert (Config). R2-Buckettaktano-fotosvom Nutzer in EU-Jurisdiction (--jurisdiction eu, DSGVO-Residenz) angelegt; das[[r2_buckets]]-Binding inserver/wrangler.tomlaktiviert mitjurisdiction = "eu"(Pflicht — EU-Buckets liegen in separatem Namespace; ohne den Zusatz findet der Worker den Bucket nicht). Damit ist der Foto-Upload-/Download-Pfad live, sobald deployed. ⚠️ Vorbedingung Merge→main: der CI-CLOUDFLARE_API_TOKENbraucht R2-Edit-Recht, sonst brichtwrangler deploy(eigener Scope, analog D1 §7.4). Kein Code-Change. -
Branch
claude/op-r4-3-foto-perspektiven(PR folgt) — OP-R4-3 Foto-Upload (R2) + Foto-Gate (Build 10 → 11, Version bleibt 0.8.0 — selbe Feature-PR). Zweite Stufe nach dem Konfig-Modell: echter Foto-Upload + Pflicht-Gate. Attachment-Modell:FotoAttachment(§4.10, polymorphe Ziel-Ref Auftrag+Teilschritt-Instanz + Perspektive; Bytes in R2, Metadaten im DO-Statefotos[]) + HelferfotoPflichtErfuellt. Worker-Routen (hinter Access):POST /api/foto/upload(Bild → R2, max 15 MB, nurimage/*, Keyfotos/<auftrag>/<instanz>/<perspektive>/<uuid>) +GET /api/foto?key=(Stream aus R2). Deploy-sicher/dormant wie der D1-Pfad:Env.FOTOS?: R2Bucketoptional, kein[[r2_buckets]]-Binding committed → ohne Bucket antworten die Routen 503 (kein Deploy-Bruch); Aktivierung dokumentiert inwrangler.toml(Bucketweuranlegen + Binding einkommentieren). DO: Messagesfoto.registriert(nach Upload, Metadaten persistieren) /foto.entfernen;TeilschrittDTOumfotos[]+fotoPflichtErfuellt; Erledigen-Gate verlangt jetzt zusätzlich erfüllte Foto-Pflicht.schemaVersion14 → 15 (Foto-Metadaten leer init, idempotent). Client: im Detail-Panel je geforderter Perspektive Aufnahme-Button (<input capture>) + Thumbnails + Zählern/Soll; „Fertig" blockiert, bis Kommentar und Pflicht-Fotos da sind.uploadFoto/fotoUrl/entferneFotoim Service. Test:test:prozessAbschnitt 9 (fotoPflichtErfuellt). Lokal verifiziert (wrangler dev + Miniflare-R2): Upload→R2, Download,foto.registriert, Gate 5/5→erfüllt — Probe grün. Entscheidungen: (1) deploy-sicher dormant (R2-Provisionierung = bewusste Folge-Aktion); (2) Bilder in R2 (nicht DO-Blob); (3) KI-Plausibilität weiter offen — ⚠️ DSGVO (Bilder an externe API). typecheck + alle Self-Tests +ng build+ No-Hex grün. Kein Solver-Redeploy. -
Branch
claude/op-r4-3-foto-perspektiven(PR folgt) — OP-R4-3 Foto-Perspektiven-Pflicht: Konfig-Modell + Anzeige (Version 0.7.0 → 0.8.0 MINOR, Build 9 → 10). Erste, infra-freie Stufe des Foto-/KI-Ausbaus (Anschluss an PR7-Doku-Gate). Datenmodell:Teilschritt.fotoPflicht?: FotoAnforderung[](F15,{perspektive, anzahl}) + HelferfotoAnforderungen()(Normalisierung: Anzahl ≥1, leere/doppelte Perspektiven raus) + VorschlagslisteFOTO_PERSPEKTIVEN(G-1: freier String bleibt erlaubt) inserver/src/model/types.ts. Seed:ts-annahmefordert die Rundum-Zustandsdoku (Front/Heck/Seite L/R/Innen ×1). Editierbar:TeilschrittFelderPatchumfotoPflicht(+dokuPflicht) erweitert (setzeTeilschrittFelder, Handlerteilschritt.update). DTO:fotoPflichtanTeilschrittDTO(Anzeige) +ProzessSchrittDTO(Editor) inkl.phase/dokuPflicht. Client: Anzeige der geforderten Perspektiven am Schritt im Auftrags-Detail-Panel („📷 erforderlich: Front ×1 …"). Test:test:prozessAbschnitt 9 (Seed-Annahme, Normalisierung, Patch). Bewusst NICHT in diesem Slice (Folge-Slices, je eigene Entscheidung): echter Foto-Upload (Attachment-Modell §4.10 + Cloudflare-R2 + presigned, OP-R4-1) und KI-Plausibilität (Vision-LLM, OP-AI-2) — Letzteres DSGVO-relevant (Fahrzeugfotos/Kennzeichen an externe API → Datenschutz/Provider/Residenz zu klären, proaktiv geflaggt). Editor-Oberfläche fürfotoPflicht+ Standalone-Standard-Schritte (Annahme ist nicht Teil einer Leistung → erscheint nicht im Leistungs-Katalog) als Folge. typecheck + alle Self-Tests +ng build+ No-Hex grün. Kein Solver-Redeploy. -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2: Auto-Erkennung — sichtbare Fehler-Warnung + tfjs-Slim-Improvement festgehalten (Version 0.9.4 → 0.9.5 PATCH; Build 16 → 17). Nutzer-Wunsch 06-27: wenn das Rating fehlschlägt oder nicht einkommentiert ist, soll gewarnt werden (statt still auf manuell zurückzufallen). Gebaut: (1)detektoren.tsliefert jetztAutoStatus(aus/aktiv/fehler) statt nuraktiv-Bool:aus= dormant (MODELLE_BASIS_URL leer, kein Hinweis nötig) ·aktiv= Adapter geladen ·fehler= konfiguriert, aber Adapter-/Modell-Load schlägt fehl (z. B. Binding nicht einkommentiert →/models404). (2)bild-upload-gate.component.tszeigt den Status: ● aktiv · ○ inaktiv · ⚠ amber Warn-Banner im Fehlerfall mit Aufforderung zur manuellen Markierung/Prüfung (+ Detailtext); zur Laufzeit setzt die Komponente den Status bei Detektor-Fehlern auffehler(einmalfehlerbleibt sichtbar, Stubs „heilen" nicht). Detektor-Fehler blockieren nie (manuelle Markierung bleibt nutzbar). (3) Demo-Seite reichtinitialerAutoStatusdurch (eigenes Badge entfernt, jetzt in der Komponente). Improvement festgehalten (kein Bau): schlankeres tfjs-Backend / kleineres nsfwjs-Bundle (heute ~40 MB, da nsfwjs ganz TF.js bündelt → künftig@tensorflow/tfjs-core+tfjs-backend-wasm/-webgl, nur nötige Ops; kein akuter Blocker, lazy+Cache) — als Folge-Punkt in OP-QS-2 (docs/Bildbewertung.md§7 + HANDOFF). Tests:ng build·test:bildgate· No-Hex · Server-typecheckgrün. Reiner Client — kein Server-/Solver-Change (nurversion.ts). Doku:docs/Bildbewertung.md(§7 Status/Warnung + Improvement), HANDOFF, CHANGELOG, Timesheet (Session 35). -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2: Modell-Upload-Skript + nsfwjs-Adapter auf eingebautes Modell (Version 0.9.3 → 0.9.4 PATCH; Build 15 → 16). Liefert den letzten Aktivierungs-Baustein:scripts/upload-models.shbereitet die On-Device-Modelle auf und lädt sie in den privaten EU-Buckettaktano-models. Empirisch verifiziert (06-27, Scratch-Install): (1) MediaPipe@mediapipe/tasks-visionliefertvision_bundle.mjs(self-contained ESM) +wasm/(6 Dateien:vision_wasm_internal/_module_internal/_nosimd_internalje.js+.wasm); (2).tflite(blaze_face_short_range) vonstorage.googleapis.com/mediapipe-models/…erreichbar (HTTP 200); (3) nsfwjs bündelt sich via esbuild zu einem self-contained ESM (tfjs + eingebautes MobileNetV2-Modell, ~40 MB) —load()ohne URL nutzt das eingebaute Modell. Folge-Korrektur:nsfw-nsfwjs.adapter.tslädt nun ein Bundlensfwjs/nsfwjs.bundle.mjs+load()(statt separater tfjs-Datei + Modell-URL — das hätte nicht funktioniert, da die nsfwjs-Modelle als JS-Module ins Paket gebündelt sind, nicht alsmodel.json+.bin). Skript: Temp-npm i→ esbuild-Bundle →.tflite-Download →wrangler r2 object put … --jurisdiction eu --remotemit korrekten Content-Types (.wasm→application/wasm,.mjs→text/javascript); Bucket bleibt privat (Hinweis aufs CI-Privacy-Gate). Asset-Set reduziert: kein separatestfjs/…und keinnsfwjs/model/…mehr nötig (im Bundle enthalten). Entscheidungen: (a) nsfwjs als ein Bundle mit eingebautem Modell statt URL-geladenem Modell — robust, da das Paket die Modelle als JS-Module shipped; (b) ~40 MB lazy akzeptiert (nur bei aktiver Auto-Erkennung, danach Browser-Cache); (c) Upload bleibt Operator-Schritt (brauchtwrangler-Auth aufs EU-Konto). Tests:bash -n(Skript-Syntax) ·ng build(Adapter weiter winzige Lazy-Chunks, Libs runtime-geladen) ·test:bildgate/No-Hex/Server-typecheckgrün. NICHT hier ausführbar: der tatsächliche Upload (wrangler-Auth) + Browser-Laufzeit. Doku:docs/Bildbewertung.md(§7b Schritt 2: verifizierte Asset-Liste + Skript), HANDOFF, CHANGELOG, Timesheet (Session 35). Reiner Client/Tooling — kein Server-/Solver-Change (nurversion.ts). -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2: Modelle privat ausliefern (R2-Binding, kein öffentlicher Bucket) + CI-Privacy-Gate (Version 0.9.2 → 0.9.3 PATCH; Build 14 → 15; deploybare Worker-Änderung). Nutzer-Entscheidung 06-27:taktano-modelssoll nicht öffentlich sein → Architektur von „öffentliche Custom-Domain" auf privat, Worker-served umgestellt + ein Pipeline-Check, der Öffentlichkeit verhindert. Gebaut: (1) Privates R2-Serving im Worker (server/party/leitstand.ts):Env.MODELLE_BUCKET?: R2Bucket+serveModellAssetliefernGET /models/*aus dem privaten Bucket same-origin (Access-geschützt, kein CORS; Content-Type je Endung inkl.application/wasm/text/javascript,..-Schutz, 404 ohne Binding/Objekt).[[r2_buckets]]-Binding (jurisdiction = "eu") inwrangler.tomlauskommentiert = dormant/deploy-sicher (Muster D1 #184).MODELLE_BASIS_URLzeigt nun auf/models(same-origin) statt einer öffentlichen Domain. (2) CI-Privacy-Gatescripts/check-r2-private.mjs— prüft via CF-REST-API (/r2/buckets/{b}/domains/managed+/domains/custom, Headercf-r2-jurisdiction: eu), dasstaktano-modelsUNDtaktano-fotosnicht öffentlich sind (kein r2.dev Public Dev URL, keine aktive Custom-Domain); läuft im Deploy-Job vorwrangler deployund blockiert ihn bei Öffentlichkeit. Fail-soft: fehlende Creds / Token ohne R2-Leserecht → Warnung + Skip (kein False-Positive-Deploybruch; für ein wirksames Gate braucht das Token R2-Read). Entscheidungen: (a) privat + Worker-served statt öffentlicher Domain — strenger, kein CORS, alles hinter Access; (b) Binding auskommentiert/dormant (deploy-sicher bis Bucket+Assets bereit); (c) Gate schützt beide Buckets (auch den Foto-Speichertaktano-fotos/OP-R4-3). Bucket-Trennung dokumentiert:taktano-fotos(EU, privat) = Fotos;taktano-models(EU, privat) = Modelle. Cloudflare-MCP-Grenze festgehalten: keine EU-Jurisdiktions-Sicht/-Anlage (empirisch:r2_bucket_get404 für den EU-Bucket) → EU-R2-Ops viawrangler/Dashboard. Tests: Server-typecheck(R2Bucket/HTMLRewriter typisiert) · Gate-Dry-Run (ohne Creds → Skip/Exit 0) ·ng build/test:bildgate/No-Hex grün. NICHT hier verifizierbar: echte CF-API-Antwort des Gates + Laufzeit-Auslieferung (Deploy/Browser). Doku:docs/Bildbewertung.md(§7a Verschärfung + §7b Runbook neu: privat/Worker-served + Gate), HANDOFF (OP-QS-2), CHANGELOG, Timesheet (Session 35). Worker-Redeploy: ja (beim Merge; verhaltensgleich solange Binding/Var dormant). -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2: Worker-Injection der Modell-URL (env-gesteuert) — Aktivierung per 1 Variable (Version 0.9.1 → 0.9.2 PATCH; Build 13 → 14; deploybare Worker-Änderung). Schließt das Wiring ab: die Auto-Erkennung wird künftig allein über eine Worker-Variable scharfgeschaltet — kein Angular-Rebuild, kein index.html-Edit. Gebaut: (1)Env.MODELLE_BASIS_URL?+[vars] MODELLE_BASIS_URL = ""inserver/wrangler.toml(leer = dormant; öffentliche URL → kein Secret). (2) Im Worker-fetch(server/party/leitstand.ts): nachenv.ASSETS.fetchwird bei gesetzter Var undtext/html-Antwort perHTMLRewriter‹script›window.__TAKTANO_MODELLE_URL__=…‹/script›in den SPA-<head>vorangestellt (greift den schon verdrahteten Client-Runtime-Override aus #v0.9.1). Sicherheit: der Wert ist env-/operator-gesetzt (keine Nutzereingabe) und wirdJSON.stringify+<→<-escaped (kein</script>-Ausbruch). Leer/ungesetzt ⇒ nichts injiziert, exakt bisheriges Verhalten (dormant, deploy-sicher). Aktivierung jetzt: inwrangler.tomlMODELLE_BASIS_URLauf die R2-Custom-Domain setzen +wrangler deploy(Runbook §7b Schritt 4 entsprechend auf den Worker-Weg umgestellt). Tests: Server-typecheckgrün (HTMLRewritertypisiert) ·ng build/test:bildgate/No-Hex (Client unverändert) grün. Doku:docs/Bildbewertung.md(§7b Schritt 4), HANDOFF (OP-QS-2), CHANGELOG, Timesheet (Session 35). Solver-Redeploy: nein; Worker-Redeploy: ja (beim Merge aufmain, verhaltensgleich solange Var leer). -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2: Auto-Erkennungs-Aktivierung vorbereitet —MODELLE_BASIS_URL-Wiring + R2-Runbook (Version 0.9.0 → 0.9.1 PATCH — Config-Tweak; Build 12 → 13). Macht die dormante Auto-Erkennung (Phase 1b) aktivierbar ohne Code-Umbau. Gebaut: (1) Runtime-Override inbild/modelle.config.ts—MODELLE_BASIS_URLliest vorrangigwindow.__TAKTANO_MODELLE_URL__(vor dem Bootstrap, z. B. Worker-injiziertes Inline-Script je Umgebung), sonst den Build-Default → Auto-Erkennung pro Umgebung schaltbar ohne Angular-Rebuild. (2) Aktivierungs-Runbookdocs/Bildbewertung.md§7b: R2-Buckettaktano-models(EU) · Asset-Pfade exakt wie die Adapter lesen (mediapipe/vision_bundle.mjs+wasm/+blaze_face_short_range.tflite·tfjs/tf.esm.js·nsfwjs/nsfwjs.esm.js+model/) · Custom-Domainmodels.taktano.com+ CORS (GET von app.taktano.com) · Override setzen · Browser-Verifikation (/bild-schutz→ „aktiv", Gesicht→Box, NSFW→gesperrt, Fetches first-party). ⚠ Compliance-Entscheidung (proaktiv geflaggt): R2-Bucket bewusst NICHT per MCP angelegt —r2_bucket_createkann keine EU-Jurisdiktion setzen, die aber bei Erstellung fix ist (DSGVO-Residenz, nachträglich nicht änderbar); daher Operator-Schrittwrangler r2 bucket create taktano-models --jurisdiction eu. Stand 06-26 verifiziert: das per MCP verbundene Konto ist erreichbar und hat 0 Buckets (kein Namenskonflikt); Konto-Match-Vorbehalt wie #185. Tests:test:bildgate·ng build(prod) · No-Hex grün. Reiner Client — kein Server-/Solver-Change (nurversion.ts). Doku:docs/Bildbewertung.md(§7b Runbook), HANDOFF (OP-QS-2), CHANGELOG, Timesheet (Session 35). Offen: Operator-Aktivierung (Bucket+Assets+Domain) → dann Browser-Verifikation. -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2 Phase 1b: Auto-Erkennungs-Adapter gebaut (dormant) — Entscheidung ①+Ⓐ (Version 0.8.0 → 0.9.0 MINOR — additive Auto-Erkennungs-Capability; Build 11 → 12). Füllt diePiiDetektor/NsfwKlassifikator-Naht aus Phase 1a mit echten Adaptern, deploy-sicher dormant (PR-184-Muster). Nutzer-Entscheidung 06-26 ①+Ⓐ: Hosting self-host first-party (R2/Pages, EU, lazy); Scope Gesichter (MediaPipe) + NSFW (nsfwjs) jetzt, Kennzeichen manuell; ⊘ Auto-Kennzeichen Ⓑ = offene Frage (zurückgestellt). Gebaut (reiner Client): (1)bild/modelle.config.ts—MODELLE_BASIS_URL(first-party, leer = Auto-Erkennung aus) +ladeModul(dynamischer Import einer absoluten URL, bewusst vor dem Bundler verborgen viaFunction('u','return import(u)')→ keine npm-Dep, kein Bundle-Wachstum, kein Public-CDN/Drittland-Fetch). (2)bild/pii-mediapipe.adapter.ts(MediaPipe Vision-Tasks Face Detector — nur Lokalisieren/Box, keine Biometrie) +bild/nsfw-nsfwjs.adapter.ts(nsfwjs, Klassen porn/hentai/sexy →unangemessen+Score; Schwelle/Block viaentscheideGate), beide laden Lib+Gewichte zur Laufzeit vonMODELLE_BASIS_URL. (3)bild/detektoren.ts-Factory: bei aktiver Config Adapter als eigene Lazy-Chunks (769/707 B — Libs nicht gebundelt) laden, sonst Stubs;try/catch→ Fallback auf manuell. (4) Demo-Seite zeigt Aktiv/Inaktiv-Status; Komponente fängt Detektor-Fehler ab (manuelle Markierung bleibt immer nutzbar). Entscheidungen: (a) Runtime-Self-Host statt npm-Bundle — hält Build sicher, Basis-Bundle schlank, Repo frei von Modell-Blobs, Privacy/Drittland gewahrt. (b) Dormant/deploy-sicher (PR-184-Präzedenz): aktiv erst nach Asset-Hosting +MODELLE_BASIS_URL. (c) Version MINOR (additive Capability). Aktivierung (Deploy/Infra, offen): MediaPipe-WASM+.tflite· TF.js+nsfwjs-ESM · nsfwjs-Modell auf R2/Pages (EU) ablegen,MODELLE_BASIS_URLsetzen → live. Tests:test:bildgate(14 Asserts) ·ng build(prod, Adapter als 769/707-B-Lazy-Chunks, Initial-Bundle unverändert) · No-Hex grün. NICHT hier verifizierbar: Laufzeit-Inferenz + Asset-Hosting (Browser-Augenschein beim Deploy). Reiner Client — kein Server-/Solver-Change (nurversion.ts). Doku:docs/Bildbewertung.md(§ Status + §7 Phase 1b + §7a Entscheidung), HANDOFF (OP-QS-2 ✅ Phase 1b + ⊘ Ⓑ), CHANGELOG, Timesheet (Session 35). -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2: Auto-Erkennungs-Slice — Optionen aufbereitet (Doku, kein Code → kein Version-/Build-Bump).docs/Bildbewertung.md§7a: drei Entscheidungs-Achsen für die Modell-gestützte B-3/B-4-Auto-Erkennung. (A) Modelle: Gesichter via MediaPipetasks-vision(empfohlen, kein voller TF.js) vs. BlazeFace/TF.js vs. nativer FaceDetector (verworfen); Kennzeichen via YOLO-nano/ONNX bzw. OpenCV.js — vorerst manuell (schwächster/teuerster Teil); NSFW viansfwjs; TF.js-Backend WASM vs WebGL. (B) Gewichte-Hosting (Kern-Dependency-Entscheidung): self-host first-party (R2/Pages, EU, lazy — empfohlen) vs. In-App-Bundle (+MB/Repo-Bloat) vs. Public-CDN (Drittland/Verfügbarkeit → abgeraten). (C) Integration: Lazy-Load nur bei Foto-Upload (Basis-Bundle unberührt), Adapter über die Naht aus §7, Modell nicht in CI laden. Empfehlung: MediaPipe + nsfwjs, Gewichte self-hosted first-party, lazy, WASM; Auto-Kennzeichen späterer Slice. Entscheidung offen (Hosting-Weg + Scope). Doku:docs/Bildbewertung.md(§7a), HANDOFF (OP-QS-2), CHANGELOG, Timesheet (Session 35). Kein Code/Solver-Redeploy. -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2 Phase 1a gebaut: On-Device-Pre-Upload-Schutz (B-1 Qualität · B-3 Verpixelung · B-4 NSFW-Gate) (Version 0.7.1 → 0.8.0 MINOR — neues, rückwärtskompatibles Feature; Build 10 → 11). Erster Bau nach der Optionen-Doku (docs/Bildbewertung.md). Gebaut (reiner Client): (1) DOM-freier Kernclient/src/app/leitstand/bild/upload-gate.ts— rechnet auf rohen RGBA-Pixeln (RGBAImage), in Node selbst-testbar: B-1bildstatistik(mittlere Luma + Laplace-Varianz/Schärfe in einem Durchlauf) +bewerteQualitaet(zu_klein/unscharf/zu_dunkel/zu_hell, Schwellen konfigurierbarSTANDARD_QUALITAET); B-3verpixele(img, boxen, block)— Mosaik je Box auf einer Kopie (Original unberührt); B-4 + Gesamt-EntscheidungentscheideGate(Priorität NSFW > Qualität > PII > ok, Schwellwert konfigurierbar); Detektor-NahtPiiDetektor/NsfwKlassifikator(Default-StubsKeinPiiDetektor/UnkritischerNsfw) → BlazeFace/Plate/NSFWJS dockt ohne Umbau an. (2) Angular-Standalone-Komponentebild/bild-upload-gate.component.ts(Canvas-Glue + UX, OnPush, Signals): Bild wählen → Canvas →getImageData→ Kern; Befund-Panel (Status ok/Achtung/Gesperrt + Statistik); Bereiche manuell markieren (Pointer-Ziehen, Box-Overlay in %) + Verpixeln; Upload-Button nur bei nicht-blockiert; das Original verlässt die Komponente nie — nur der (ggf. verpixelte)image/jpeg-Blob wird via(freigegeben)emittiert. (3) Demo-/Vorschau-Seitepages/bild-schutz.component.tsunter Deep-Link/bild-schutz— bewusst nicht im Workspace-Rail (kein fertiges Feature vortäuschen, bis das reale R4-Upload-Feld existiert). (4) Self-Testnpm run test:bildgate(upload-gate.demo.ts, synthetische RGBA-Bilder: Schärfe/Helligkeit/Größe, Verpixel-Invarianz [Block eingeebnet, Original/Außenbereich unverändert], Entscheidungs-Priorität) + CI (Client-Job vorng build);tsxals Client-devDep. Entscheidungen: (a) Heavy ML-Deps (TF.js/NSFWJS/BlazeFace) bewusst NICHT gezogen — Bundle-/Modell-Hosting-/Verifizierbarkeits-Kosten; stattdessen Detektor-Naht + reale manuelle Markierung/Verpixelung (B-3 trägt heute), Auto-Erkennung = eigener Slice mit Dep-Entscheidung. (b) On-device, Original bleibt lokal (Privacy-by-Design, §4a/§4b) — nur der redigierte Blob geht raus. (c) Version = MINOR (additives Feature, kein Breaking). (d) Demo-Route ohne Rail-Eintrag statt halbfertigem Workspace. Offen: Auto-Erkennung (BlazeFace/Plate/NSFWJS), EXIF-Stripping, „blockiert"-Override (rollen-gegated OP-AUTH-1 + OP-AUDIT-1-Event), Anbindung an R4-Upload (OP-R4-3). Tests:test:bildgate(14 Asserts grün) ·ng build(prod) grün (Bundle-Budget-Warnung vorbestehend) · No-Hex-Gate grün (alle Farben--tk-*/color-mix). Reiner Client-Pfad — kein Server-/Solver-Verhaltens-Change (nurserver/src/version.tsbumpt). Doku:docs/Bildbewertung.md(§ Status + §7 Umsetzung), HANDOFF (OP-QS-2 ✅ Phase 1a), CHANGELOG, Timesheet (Session 35). True North: indirekt (QS-/Doku-Qualität + Datenschutz/Governance). -
Branch
claude/auto-image-rating-options-4upp3q(PR folgt bei Bedarf) — OP-QS-2: Optionen für automatische Bildbewertung festgehalten (Optionen-/Design-Doku, kein Code → kein Version-/Build-Bump, Präzedenz #182/#187/#188). Neue lebende Dokudocs/Bildbewertung.md(Nutzer-Frage 06-26 „welche Optionen für eine automatische Bildbewertung?"). Zwei getrennte Ziele festgehalten: B-1 Foto-technische Qualität (Upload-Gate an jedem R4-Foto-Feld) und B-2 fachliche Bewertung (QS-Endkontrolle/Mangel-Doku/Anlieferung). Abgrenzung zu OP-AI-2/OP-AI-3 (Upload-Plausibilität ≠ Gewerk-Qualität); Bezug OP-QS-1 (Mangel-Foto). Optionen A–F bewertet: A Vision-LLM (Claude Vision, liegt bereits im Stack A-4-KI-Layer/A-5-Pragma) · B generische Cloud-Vision (nur OCR/Grob-Labels) · C eigenes CNN (später, datenintensiv) · D klassische Bildverarbeitung (deterministisches Gate) · E on-device/Edge · F Hybrid = Empfehlung (D/E-Gate → A für B-2, gestuft; „KI schlägt vor, QS entscheidet"). ⚠ Compliance proaktiv geflaggt (DE/AT/CH): Fahrzeugfotos personenbezogen (Kennzeichen/Personen/EXIF) → A/B = Drittland/AVV; EXIF strippen + Schwärzung + R2-Retention (OP-AUDIT-1) vor Bau klären —docs/Compliance.md/RISK-10-Bezug. Entscheidung: Optionen empfohlen (Hybrid F), Umsetzung noch nicht beschlossen. Nachtrag (gleiche Session, Nutzer-Wunsch): B-3 PII-Schutz vor Upload — beim Foto-Upload on-device auf Personen/Kennzeichen scannen, warnen und Verpixeln von Gesichtern/Kennzeichen anbieten (Privacy-by-Design DSGVO Art. 25). B-3-Entscheidungen: Erkennung+Verpixelung on-device, vor Upload (Option E; nur redigierte Kopie geht hoch, Server-Blur zu spät) · Gesichter MediaPipe/BlazeFace, Kennzeichen leichtes Objektmodell/OpenCV-Heuristik — nur lokalisieren, kein OCR/Biometrie · Erkennung ≠ perfekt → manuelle Box-Korrektur Pflicht-Fallback · „anbieten" (opt-in), aber Cloud-Pfad A/B → Redaktion default/erzwungen (sonst PII an US-Dienst; „ohne Verpixeln" begründet/rollen-gegated + OP-AUDIT-1) · B-3 = Voraussetzung für A/B; entschärft das §4-Compliance-Risiko an der Quelle.docs/Bildbewertung.md§1 (Ziel B-3) + §4a (UX/Detektion/Entscheidungen) + §5 (Phase 1 erweitert). Nachtrag 2 (gleiche Session, Nutzer-Wunsch): B-4 Inhalts-/NSFW-Check — beim Foto-Upload on-device prüfen, ob das Bild unangemessen (NSFW) ist → warnen + Upload blocken (anders als B-3 nicht redigierbar). B-4-Entscheidungen: on-device via NSFWJS (TF.js, gleicher Pre-Upload-Pass wie B-1/B-3; kein Bild-Leak; Cloud-Moderation nur optional nach Upload + Drittland) · Reaktion = blockieren, Override nur begründet + rollen-gegated (OP-AUTH-1) + OP-AUDIT-1-Event · Schwellwert/Strenge konfigurierbar (G-1) · Abgrenzung Content-Moderation ≠ B-2/B-3.docs/Bildbewertung.md§1 (Ziel B-4) + §4b + §5 (Phase 1 = ein on-device-Pass B-1+B-3+B-4). Doku:docs/Bildbewertung.md(neu), HANDOFF (OP-QS-2 inkl. B-3/B-4), CHANGELOG, Timesheet (Session 35). Kein Code/Solver-Redeploy. True North: indirekt (QS-Beschleunigung/Qualitätssicherung + Datenschutz + Governance, nicht direkt Auslastung/Standort/Kapazität). -
#200 — Infra-Kosten-Änderungen werden protokolliert (OP-COST-1 · OP-AUDIT-1 · OP-LOG-1) (Version 0.8.0 → 0.9.0 MINOR, Build 11 → 12). Nutzer-Wunsch: „im Log festhalten, wenn die Infra-Kosten aktualisiert wurden". Gebaut: jede
infraKosten.hinzufuegen|aktualisieren|entfernen-Aktion schreibt (1) eine Ops-Log-Zeile (interimconsole, wie die Boot-Zeile, inkl. Version/Build, ohne Klartext-PII) und (2) ein dauerhaftes Audit-Event ins D1-Audit-Log (audit_entries:event_type=infraKosten.*,resource_type=infra_kosten,summary+delta_jsonmit Dienst/Monat/Betrag/Währung,tsin ms) — best-effort/No-op ohne D1-Binding. Actor = die verifizierte Access-E-Mail der Verbindung (neu je Verbindung gehalten), sonstunbekannt, solange das Owner-Gate nicht scharf ist (OP-COST-3). Entscheidung: „Beides" — durables Audit (Historie/Compliance) plus Ops-Zeile (sofortige Sicht, funktioniert auch ohne D1-Binding); schließt den indocs/Kosten.md§11 offenen Punkt „Audit der Posten-Änderungen = OP-AUDIT-1" (der Actor folgt vollständig mit OP-COST-3). Reiner Server-Pfad — kein Solver-Redeploy. Verifikation: Server-Typecheck +test:kosten+operativ-Smoke grün. Doku:docs/Audit-Log.md§3 (Event-Typ-Katalog),docs/Kosten.md§11, HANDOFF (OP-COST-1), CHANGELOG (#200), Timesheet (Session 35). -
#198 — OP-COST-3: Kosten interim für alle freigeschaltet; Owner-only-Scharfschaltung als Pre-Prod-Requirement (Doku/Konfig, kein Code → kein Version-/Build-Bump). Nutzer-Entscheidung 06-26: Das Owner-only-Gate (Sicht B) wird nicht jetzt scharf geschaltet — die Infra-Kosten bleiben für alle Access-authentifizierten Nutzer sichtbar (
ACCESS_TEAM_DOMAIN/ACCESS_AUDinserver/wrangler.tomlbleiben leer →kostenAdminFuer=true; der Zugang selbst bleibt durch Cloudflare Access am Edge geschützt). Das Scharfschalten ist als neues OP-COST-3 = Pre-Prod/Go-Live-Requirement festgehalten: HANDOFF §4 (OP-COST-3 mit Lockout-Warnung),docs/Risikoregister.md(RISK-12 „mitigiert" → „offen (interim akzeptiert)", W 1→2),docs/Kosten.md§12 (Status-Callout + bereitliegende drkv-com-WerteACCESS_TEAM_DOMAIN/ACCESS_AUDfür die spätere 1-Schritt-Aktivierung). Entscheidung/Begründung: interim ok, da aktuell nur Infra-/Cloud-Spend exponiert ist (Sicht A Marge/Sätze noch nicht gebaut) und der Edge-Access bereits authentifiziert; echtes Owner-only wird vor Produktivgang scharf, endgültig per OP-AUTH-1. Kein Code/Solver-Redeploy (ACCESS_*unverändert leer; nur Doku +wrangler.toml-Kommentar). Doku: HANDOFF (OP-COST-3),docs/Risikoregister.md(RISK-12),docs/Kosten.md§12,server/wrangler.toml, Timesheet (Session 34). -
#196 — OP-COST-1 Follow-up (Doku/Konfig, kein Code → kein Version-/Build-Bump): Prod-Gate-Runbook · Sicht-A-Stundensatz-Design · OP-COST-2 · OP-EXPORT-1. Erfasst die Nutzer-Entscheidungen vom 06-26: (1) Sicht A (Arbeitskosten je Auftrag) — Stundensatz je Abteilung + Override je Mitarbeiter, jeder Satz mit Von-Bis-Gültigkeit (historisiert, nie überschrieben); die Berechnung (istMin × zum Leistungs-Zeitpunkt gültiger Satz) entsteht nur im Report (D-2, nie persistiert) —
docs/Kosten.md§3.1/§3.2. (2) OP-COST-2: Infra-Kosten via Provider-APIs — automatischer Pull je Dienst (Cloudflare/Fly/Anthropic/Registrar-APIs, Cron-Worker) als verbindliche Richtung; manuelle Erfassung bleibt Fallback; Datenmodellquelle:'api'|'manuell'+ Idempotenz-Key, API-Keys als Secrets — §4. (3) OP-EXPORT-1: Reports immer mit Diagramm + Export (PDF + CSV + Excel) für alle Reports — §13. (4) Prod-Gate-Aktivierungs-Runbook (docs/Kosten.md§12) +server/wrangler.toml-Cleanup:KOSTEN_ADMIN_EMAILSaus[vars]entfernt (PII → Secretwrangler secret put, vermeidet Var/Secret-Clash), ACCESS-Kommentare + Lockout-Warnung geschärft. Kein Code/Solver-Redeploy. Doku:docs/Kosten.md(§3/§4/§11–§13), HANDOFF (OP-COST-1 + OP-COST-2 + OP-EXPORT-1),server/wrangler.toml, Timesheet (Session 33). -
Direkt auf
main(reine Way-of-Working-Doku, via GitHub-API committet — Commits087b59a/dbbd62b): GitHub-Operationen über die GitHub-API/MCP statt lokalesgit/ghfür Remote-Writes (PR/Merge/Kommentar/Commit/Push; CI/Mergeability viapull_request_read) — indocs/agents.md§7 +CLAUDE.mdverankert (Nutzer-Anweisung; Grund: lokalegit-Pushes sind in der Remote-Session unzuverlässig). -
#197 — Bugfix: linke Rail-Sidebar scrollt bei niedrigem Fenster (Version 0.7.0 → 0.7.1 PATCH, Build 9 → 10). Problem (Nutzer-Report): die Icon-Rail (
client/.../leitstand/shell.component.ts, OP-R9-12) füllt mith-screen+overflow-hiddenexakt die Viewport-Höhe; bei zu niedrigem Fenster liefen die Nav-Items (und der untere Auf-Kurs-/Status-/Theme-Block) über und wurden abgeschnitten — ohne Scrollmöglichkeit (im aufgeklappten Zustand verschärft, weil die Cluster-Titel zusätzliche Höhe einnehmen). Fix: der<nav>-Block wird zur scrollbaren Zone (flex-1 min-h-0 overflow-y-auto;overflow-x-hiddenerhält das Label-Clipping beim Ein-/Ausklappen), Logo (oben) und Status/Theme (unten) bleiben fixiert (shrink-0stattmt-auto); dezenter, token-gefärbter Scrollbalken (--tk-line, kein Hex). Entscheidung: nur die Nav scrollt (Logo + Status bleiben sichtbar) statt das ganze Panel — beste Erreichbarkeit;min-h-0ist der Schlüssel, damit das Flex-Item unter seine Inhaltshöhe schrumpfen darf. Verifikation:ng build(prod) + No-Hex-Gate grün (Browser-Augenschein offen — Playwright im Cloud-Env nicht installiert). Reiner Client-Pfad — kein Server-/Solver-Change (nurserver/src/version.tsbumpt). Doku: CHANGELOG (#197), HANDOFF (OP-R9-12), Timesheet (Session 32). True North: Bedienbarkeit des Cockpits auf kleinen/geteilten Fenstern (Navigation bleibt erreichbar). -
#195 — Timesheet-Nachtrag: Session 31 (Wrap-up der Gantt-OPs) (kein Code → kein Version-/Build-Bump, Präzedenz #168). Bucht die nach dem Build (#193) folgende Merge-Orchestrierung (update-from-main inkl. Auflösung der Versions-Kollision mit der parallelen OP-COST-1-B1-PR #192, PR #193 + Squash-Merge, Deploy-Verifikation) als eigene Session 31 (~0.5 h) — getrennt von Session 28 (Build) wegen des >1 h-Gaps (Gap-Regel). Summe → ~85.2 h (inkl. der parallel via #194 gemergten Flow-Sessions 29/30), Stand 06-26 ~13:00. Hintergrund (Repo-Hygiene): Remote-Branch-Löschung gemergter Feature-Branches ist in der Cloud-Session blockiert (
git push --delete→ 403, kein MCP-Branch-Delete) → empfohlen, im Repo „Automatically delete head branches" zu aktivieren. Doku:docs/Timesheet.md(Session 31 + Summe), CHANGELOG (#195). Kein Code/Solver-Redeploy. -
Flow-Refactor (OP-R3-1) — PR-Bündel +
main-Abgleich (#194, Version 0.6.0 → 0.7.0 MINOR, Build 8 → 9). Fasst den Branchclaude/workflow-reservation-pickup-6m2q37(Analyse + Flow-Refactor-Plan + PR 1–7, Einträge unten 2026-06-24/25) zum Pull Request gegen den aktuellenmainzusammen. Inhalt: fachliche Phase first-class (Achse 2) durchgängig Daten→DTO→UI · Annahme als nicht-solver-geplanter Doku-Schritt · QS/Abholung/Nachkontrolle entzerrt · Klärfälle (abbrechen/abgebrochen+ Klärfall-Kontext + Skill „Klärung") · Pflicht-Doku-Gate je Schrittabschluss. Zweimain-Abgleiche eingepflegt (zuletzt #192/#193/Way-of-Working) — Konflikte gelöst (Importe inkl.ConnectionContext;SCHEMA_VERSION— main 11/12/13 [Infra-Kosten] → Phase-Migration v14; CHANGELOG/Timesheet beide behalten). Verifikation: Server-typecheck + alle Self-Tests (inkl. main'sfairness/progression) grün ·ng build(prod) + No-Hex grün · Laufzeit-Probe gegen lokalen PartyServer (neuer Auftrag → phase=annahme + Annahme-Schritt + Doku-Pflicht; Klärfall melden; Abbruch → abgebrochen/reservierung keine). Kein Solver-Redeploy. -
#193 — Gantt: Zeit-Zoom (OP-R8-18) + Heute-Linie/Echtzeit-Überfälligkeit (OP-R8-17) (Version 0.5.0 → 0.6.0 MINOR, Build 7 → 8). Baut die beiden am 06-25 erfassten Gantt-OPs (Nutzer-Wahl „Gantt: Heute-Linie + Zoom"). OP-R8-18 (Zeit-Zoom): der bisher fixe
SCALE(0.6 px/min) wird einscale-Signal und durchzieht die gesamte Zeit-Geometrie (Blöcke, Zeitachse, JETZT-Linie, Pins/Drag, Auslastungs-Heatmap); Bedienung über Presets Std/Tag/Woche/Monat + Feinzoom −/+ (geclippt [0.012, 6] px/min); Zoom-Anker = Viewport-Mitte (die Zeit unter der Mitte bleibt beim Zoomen stehen). Adaptive Achsen-Dichte je Zoom — Gitterlinien, Tages-/Wochen-Labels, Intraday-Zeit-Labels und Heatmap-Zellen wählen ihre Schrittweite aus Leitern, damit die Achse nie zu dicht/spärlich wird (adressiert zugleich den Performance-Punkt teilweise: keine DOM-Flut beim Auszoomen; volle Virtualisierung bleibt offen). OP-R8-17 (Heute-Linie): Befund — die vertikale JETZT-Linie (cyan, Glow, 30-s-Live-Tick, „Jetzt"-Badge) existierte bereits über alle Zeilen (Dark-Cockpit,jetztLeft); gebaut wurde die fehlende „was-ist-überfällig"-Hälfte: noch nicht begonnene (geplant) Teilschritte, deren geplanter Start links der JETZT-Linie liegt, bekommen einen dezenten Amber-Ring „⏰ läuft spät" (in Hell und Dunkel, wie der bestehende rote Termin-Konflikt-Ring; Priorität Sprung-Highlight > Konflikt > spät) — plus die Linie ist jetzt zoom-fest. Entscheidungen: (1) Heute-Linie nicht neu gebaut (existierte) — stattdessen die Echtzeit-Überfälligkeit ergänzt + zoom-fest gemacht; kein Doppelbau. (2) Linie bleibt Dark-Cockpit-gegated wie die übrigen Overlays (⚑ Wunsch-Abholung, Heatmap) — eine Hell-Modus-Variante ist als optionaler Folge-Schritt notiert (Kontrast-Tokens), statt die bestehende Design-Entscheidung still aufzubrechen. (3) Überfälligkeit = Amber, nicht Rot — Rot bleibt dem harten Termin-Konflikt vorbehalten (Design-Regel „Rot nur für Warnungen"; zwei Rot-Bedeutungen vermieden). (4) Zoom-Anker Mitte als robustester Default (Cursor-/Heute-Anker + Strg-Scroll bleiben mögliche Folge). Tests:ng build(prod) grün · No-Hex-Gate grün (alle neuen Farben über--tk-*/color-mix, inkl. Zoom-Buttons) · Server-Typecheck grün. Reiner Client-Pfad — kein Server-/Solver-Verhaltens-Change (nurserver/src/version.tsbumpt). Doku: HANDOFF (OP-R8-17/18 → gebaut), CHANGELOG (#193), Timesheet (Session 28). True North: beantwortet Frage 2 („was läuft jetzt / was ist überfällig") direkter und macht Frage 1/3 (Auslastung/Kapazität) über Stunden ↔ Monate schneller ablesbar.
2026-06-25
- Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt bei Bedarf) — Flow-Refactor PR 7: Pflicht-Doku-Gate je Schrittabschluss (OP-R4-3) — schließt den Flow-Refactor-Plan ab (PR 1–7). Server: MasterTeilschritt.dokuPflicht?(F14; Default pflichtig,falseschaltet ab) + HelferdokuPflichtig; InstanzTeilschrittInstanz.kommentar?;erledige(…, kommentar?)speichert die Abschluss-Doku;teilschritt.aktion erledigenträgtkommentarund lehnt ohne Kommentar ab, wenn der Schritt doku-pflichtig ist (Gate); Kommentar landet zusätzlich in der Chronik.TeilschrittDTOumdokuPflicht/kommentarerweitert (viadokuPflichtByTsim Snapshot). Client: per-Schritt „✓ Fertig (mit Doku)" im Detail-Panel mit Pflicht-Kommentar-Eingabe (verdrahtet die zuvor ungenutzteteilschrittAktion), erfasster Kommentar wird am erledigten Schritt angezeigt. Test:test:prozessAbschnitt 8 (dokuPflichtig-Default/Override;erledigespeichert Kommentar). Entscheidungen: (1) Doku-Pflicht Default an (OP-R4-3 „gilt immer"), per Schritt abschaltbar; (2) Gate am per-Schritt-Abschluss (der reguläre Doku-Punkt); Bulk-fertigstellenbleibt bewusst Operator-Override ohne Gate; (3) Foto-Perspektiven + KI-Plausibilität + Diktat (restliche OP-R4-3/OP-AI-2/3) als Folge-Ausbau. typecheck + alle Self-Tests grün,ng build+ No-Hex grün. Kein Solver-Redeploy. ➡ Flow-Refactor (OP-R3-1) komplett: Phase first-class (Daten→DTO→UI), Annahme-Doku-Schritt, QS/Abholung/Nachkontrolle entzerrt, Klärfälle/Abbruch, Doku-Gates. - Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt bei Bedarf) — Flow-Refactor PR 6: Klärfälle — Abbruch + Klärfall-Kontext + Skill (OP-R3-1; Server + Client). Lifecycle (S-6): neue Aktionabbrechen+ terminaler Statusabgebrochen, erlaubt ausgeplant/angeliefert/in_arbeit/pausiert(Unterbrechung an jeder Stelle → Abbruch);reservierungsmodus('abgebrochen')='keine';abgebrochenals inaktiv/terminal eingestuft (InsightsABGESCHLOSSEN, ClientaktiveAuftraegeraus → Archiv-Sicht, Flow-Band aus dem Fluss). Klärfall-Kontext (Auftrag.klaerfall?: {grund,eskaliert,seit}, OP-R3-1): pure HelfersetzeKlaerfall/loeseKlaerfall(Grund pflicht, orthogonal zum Status), Server-Messageauftrag.klaerfall(melden/lösen, mit Protokoll-Eintrag), imAuftragDTO. Skill „Klärung" (skill-klaerung) geseedet. Client: Status-/Aktions-Labels fürabgebrochen/abbrechen; Klärfall-Badge (⚠, eskaliert) im Detail-Panel + Orders; Klärfall melden (Grund-Pflichtfeld + Eskalieren-Checkbox) / lösen im Aktions-Hub; „Abbrechen" erscheint viaerlaubteAktionen. Test:operativ-Selbsttest (Klärfall setzen/lösen, Grund-Pflicht, Abbruch aus pausiert/geplant → terminal, Reservierung keine). Entscheidungen: (1) keinSCHEMA_VERSION-Bump — neuer Enum-Wert + optionales Feld sind rein additiv, kein Remap von Altdaten nötig; (2) Klärfall orthogonal zum Lifecycle (ändert Status nicht) statt eigener Status; (3) Re-Entry-Routing (zurück/Sprung-zu-QS/anderer-Schritt) über die bestehenden Teilschritt-Aktionen, kein neuer Mechanismus (volle Klärungs-Workflow-Engine bleibt Folge-OP). Server-typecheck + alle Self-Tests grün,ng build+ No-Hex grün. Kein Solver-Redeploy. Offen: PR 7 (Pflicht-Doku-Gates, OP-R4-3). - Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt bei Bedarf) — Flow-Refactor PR 5: QS-Freigabe vs. Abholung vs. Nachkontrolle entzerrt (OP-R3-1; reiner Client). Befund (Analyse): „Freigeben (zur Abholung) →" rief direktabholen(→abgeschlossen= abgeholt) und vermengte so QS-Freigabe und tatsächliche Abholung;kontrolliert(Nachkontrolle) war faktisch verwaist. Entscheidung (Nutzer-Frage scheiterte technisch → empfohlene Minimal-Variante gewählt, ohne neuen Lifecycle-Status/Migration; Alternative „neuer Statusabholbereit" bleibt nachrüstbar): QS-Seite ist die Endkontrolle/Abnahme vor der Übergabe — Primär-Button ehrlich umbenannt zu „✓ Abnahme bestanden — Fahrzeug übergeben →" (macht weiterhinabholen, nun klar als Handover/Abholung benannt, Toast „Übergeben · abgeholt"). Neu: Nachkontrolle-Sektion unter der Prüfung listet abgeschlossene (abgeholte) Aufträge mit „Nachkontrolle erledigt ✓" →kontrollieren(→kontrolliert) — macht den zuvor verwaisten Schritt sichtbar/erreichbar und stellt End- (vor) vs. Nachkontrolle (nach Abholung) klar. Service:nachkontrolleAuftraege(Statusabgeschlossen). Entscheidungen: (1) keine Auto-Fallback-Aktion mehr (abholennur wenn erlaubt, statterlaubteAktionen[0]); (2) QS-Checkliste bleibt client-seitig/ephemer (kein QS-Pass-Persistieren) — daher kein neuer Status nötig.ng build(prod) grün, No-Hex-Gate grün. Offen: PR 6 (Klärfälle:abbrechen/abgebrochen+ Skill „Klärung"), PR 7 (Doku-Gates, OP-R4-3). - Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt bei Bedarf) — Flow-Refactor PR 4: UI liest First-Class-Phase (Flow-Sprache) (OP-R3-1; reiner Client, nutzt PR 3). Flow-Band (flow-band.component.ts) ordnet Stationen jetzt ausAuftragDTO.phasezu — die fragile Aufbereitung/Produktion-Heuristik entfällt;kontrolliert↔Abholung-Bug korrigiert:fertiggestellt(Prozess inkl. QS fertig) = Station Abholung,abgeschlossen/kontrolliert(Nachkontrolle nach Abholung)/archiviert= aus dem Fluss. Gemeinsame Flow-Sprache neu inclient/.../leitstand/phase.ts(PHASE_LABEL/PHASE_COLOR/phaseLabel()/phaseColor(), Farben = Flow-Band-Stationen, nur--tk-*): Flow-Band-Defs, Orders-Liste und Detail-Panel zeigen denselben Phasen-Chip (annahme→qs, plus „Abholung" fürfertiggestellt) — getrennt vom Status- und Terminklasse-Badge (Achsen sichtbar entkoppelt). Client-DTO umphase: Phase|null+Phase-Typ erweitert. Entscheidung: Phase first-class aus dem DTO statt Status-Heuristik; eine TS-Helfer-Quelle statt dupliziertem Mapping je Komponente.ng build(prod) grün, No-Hex-Gate grün. Offen (Folge): „▶ Aufbereiten starten" auch im Flow-Band/Detail (heute nur Belegung); Gantt-Legende auf Phase; PR 5 (QS-Freigabe/Nachkontrolle). - Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt bei Bedarf) — Flow-Refactor PR 2: Annahme als Standard-Doku-Schritt (OP-R3-1; QS war mit PR 1 bereits first-class viats-qm/Phaseqs). Entscheidung (Nutzer): Annahme = getrackter Doku-Schritt, NICHT solver-geplant (belegt Parkplatz statt Bucht; G-3 <15 Min). Umsetzung: Seed-Skillskill-annahme+ Stammschrittts-annahme(Phaseannahme, 10 Min, keine Bucht-Bindung) — bewusst nicht in den Leistung-Prozessen, daher vom Solver nie instanziiert.materialisiereAuftragstellt beimeta.mitAnnahmeeine Annahme-Instanz voran (FactoryannahmeInstanz,bayId:'', keine Mitarbeiter); nur der reguläre Anlage-Pfad (auftrag.create) setzt das Flag → Demos unberührt. Schlüssel-Invariante:istPlanbarerSchrittschließtts-annahmeglobal aus → Annahme leakt nie in den Optimierer und verschiebt nicht die positionsweise Zuordnung Solver-Schritt↔Instanz (toAuftragInput/applyPlanung/Vorschau-Diff). Test:test:prozessAbschnitt 7 (genau +1 Schritt, an erster Stelle, nicht planbar, currentBays unverändert, frischer Auftrag → Phaseannahme). Entscheidungen: (1) Annahme imteilschritte[]-Array (sichtbar in Timeline/Flow, Phase ableitbar) statt separater Entität; (2) kein Backfill bestehender Aufträge (nur neue erhalten Annahme) — risikoarm; (3) historische §5.1-Vereinfachung „Annahme/Endausgabe keine Teilschritte" damit teil-abgelöst. Additiv; alle CI-Self-Tests + typecheck grün. Kein Solver-Redeploy. Offen: PR 4 (Flow-Band/UI liestAuftragDTO.phase). - Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt bei Bedarf) — Flow-Refactor PR 3: Phase abgeleitet + imAuftragDTO(OP-R3-1; nutzt PR 1). Reiner HelferaktuellePhase(auftrag, phaseByTs)inserver/src/operativ/auftrag.ts— abgeleitet aus demphase-Tag der Teilschritte: maßgeblich der laufende, sonst pausierte, sonst nächste offene Schritt (analogbearbeitungsphase);null= keine offenen Schritte → Lifecycle trägt die Sicht (z. B. Abholung).AuftragDTO.phase: Phase|nullergänzt;toAuftragDTO/snapshotbauenphaseByTsaus den persistierten Teilschritten (phaseEffektiv) und liefern die Phase live mit — kein Derived State gespeichert (D-2). Test:test:prozess(CI) um Abschnitt 6 erweitert (laufend>pausiert>nächster; nur-QM→qs; alles erledigt→null). Entscheidung: die fragile Flow-Band-Heuristik wird damit serverseitig ersetzt; der Client liest die Phase künftig aus dem DTO (PR 4). Additiv (Feld neu, Producer-seitig), Client unverändert. typecheck + test:prozess/test:teilplan/test:insights/operativ/spike/replan/solve grün. Kein Solver-Redeploy. Offen: PR 2 (Annahme/QS als echte Standard-Teilschritte), PR 4 (Flow-Band/UI liest DTO-Phase). - Branch
claude/workflow-reservation-pickup-6m2q37(PR folgt bei Bedarf) — Flow-Refactor PR 1:Phaseals Teilschritt-Tag (Achse 2 first-class, OP-R3-1; erster Schritt ausdocs/Flow-Refactor-Plan.md). Datenmodell (additiv): neues EnumPhase='annahme|aufbereitung|produktion|qs'+ FeldTeilschritt.phase?(F13, G-1-Ausnahme: logik-tragend) + HelferphaseEffektiv()/PHASE_RANGinserver/src/model/types.ts. Seed explizit getaggt (ts-wash=aufbereitung,ts-qm=qs [Endkontrolle vor Abholung, ≠ Nachkontrollekontrolliert], Folie/Keramik/Super=produktion). MigrationSCHEMA_VERSION10→11 inserver/party/leitstand.ts: idempotenter Remap taggt untaggte persistierte Teilschritte über dieselbephaseEffektiv-Ableitungsregel (Id/Name → Defaultproduktion). Test:test:prozess(CI) um Abschnitt 5 erweitert (Seed-Tags · Altdaten-Ableitung · expliziter Tag schlägt Heuristik). Entscheidungen: (1) Phase als Tag am Teilschritt-Master, aktuelle Auftrags-Phase bleibt abgeleitet (kein Derived State gespeichert); (2) eine einzige Ableitungsregel (phaseEffektiv) für Seed-Default + Migration; (3) „Abholung" ist KEINE Arbeits-Phase, sondern Lifecyclefertiggestellt→abgeschlossen. Abwärtskompatibel (Feld optional, Solver unberührt). typecheck + test:prozess/test:teilplan/operativ/spike/replan/solve grün. Kein Solver-Redeploy. Folge: PR 2 (Annahme/QS als echte Standard-Teilschritte), PR 3 (Ableitung+DTO). - Branch
claude/workflow-reservation-pickup-6m2q37(reine Doku/Plan; PR folgt bei Bedarf) — Flow-Refactor-Plan zum Zielbild „Phasen first-class" (docs/Flow-Refactor-Plan.md, verlinkt ausdocs/Flow-Analyse.md). Setzt die Analyse-Empfehlung in einen inkrementellen 7-PR-Plan um. Leitentscheidung: Achse 1 (Lifecycle/Reservierung) bleibt unverändert; Achse 2 „fachliche Phase" wird First-Class als EnumPhase='annahme|aufbereitung|produktion|qs'— Tag am Teilschritt-Master (server/src/model/types.ts:188), aktuelle Phase abgeleitet (Erweiterungbearbeitungsphase()insights.ts:120, kein Derived State gespeichert) → die fragile Flow-Band-Heuristik entfällt. Anlieferung ≠ Annahme:angeliefert= physisch da (Lifecycle), Annahme wird echter erster Teilschritt (Doku-Pflicht). QS-Doppelmodellierung aufgelöst: Endkontrolle = Teilschritt Phaseqs(vor Abholung), Nachkontrolle = Lifecyclekontrolliert(nach Abholung); Flow-Band-Mappingkontrolliert↔Abholungkorrigiert. Plan-Reihenfolge: PR1 Phase-Tag (additiv) · PR2 Annahme/QS als Standard-Teilschritte · PR3 einheitliche Ableitung+DTO · PR4 konsistente UI-Flow-Sprache (geteilte Primitives) · PR5 QS-Freigabe/Nachkontrolle entkoppeln · PR6 Klärfälle (abbrechen/abgebrochen+ Klärfall-Kontext, Skill „Klärung") · PR7 Pflicht-Doku-Gates (OP-R4-3). Jeder schemaverändernde PR bumptSCHEMA_VERSIONmit idempotentem Remap (Musterleitstand.ts:753-801). Schärft OP-R3-1/OP-R4-3; Umsetzung noch nicht beschlossen. Keine Code-Änderung (kein Build/Solver betroffen). - #192 — OP-COST-1 Slice B1: Infra-/Cloud-Kosten (Sicht B) gebaut (Version 0.4.0 → 0.5.0 MINOR — neues, rückwärtskompatibles Feature; Build 6 → 7). Erster Bau auf dem Design #187 (
docs/Kosten.md): Kosten-Workspace mit Tab Infra (Sicht B — Cloud-/Betriebs-Spend; Tab Betrieb/Sicht A vorgemerkt). Gebaut: (1) pureserver/src/kosten/infra.ts— gespeicherte FaktenInfraKostenPosten(Dienst × Monat, Beträge in Cent) + abgeleiteteinfraKostenAuswertung(Summe gesamt · je Dienst + Anteil · je Monat · Monats-Trend [kalendarischer Vormonat, Lücke = kein Trend] · größte Posten · Mehrwährungs-Flag) — nie persistiert (D-2), Self-Testtest:kosten(+ CI). (2) DO-Verdrahtung (server/party/leitstand.ts):infraKostenPostenim State,schemaVersion12 → 13 (idempotent leer initialisiert), ActionsinfraKosten.hinzufuegen|aktualisieren|entfernen. (3) Per-Connection-Rollen-Gate (kein Broadcast-Leak): der Worker verifiziert das Access-JWT, extrahiert dieemail-Claim und injiziert sie vertrauenswürdig als HeaderX-Taktano-User(client-gesetzte Kopie wird zuvor gestrippt — Anti-Spoofing); der DO bestimmt je VerbindungkostenAdminüber die AllowlistKOSTEN_ADMIN_EMAILSund filtert die Infra-Kosten je Verbindung aus dem Broadcast (Nicht-Berechtigte erhalten das Feld nie; Schreib-Actions ebenso gegated). (4) Client: Service-Typen/Selektoren/Actions + Workspacepages/costs.component.ts(KPI-Kacheln · Spend je Dienst · Monats-Verlauf · größte Posten · CRUD-Erfassung; Mono, nur--tk-*) + Route/costs+ nur fürkostenAdminsichtbarer Nav-Eintrag. (5) Token--tk-ws-costs(#84cc16/ Light#4d7c0f, provisorische Signaturfarbe). Entscheidungen: (a) Gate = Access-E-Mail-Allowlist, per-Connection (Empfehlung ggü. „alle Access-Nutzer sehen es") — design-treu (§6 „kein Leak"), geringstes Bedauern, bereitet OP-AUTH-1 vor; fail-closed in Prod sobaldACCESS_*+KOSTEN_ADMIN_EMAILSgesetzt sind (sonst interim für alle Access-Nutzer sichtbar — s. HANDOFF/PR-Flag), lokal ohne Access sichtbar (demobar). (b) Version = MINOR (0.5.0) — additives Feature, State migriert idempotent. (c) Cent statt Float; Mehrwährung ehrlich gespeichert, aber ungewichtete Summe + Hinweis (FX = future, OP-I18N-1). (d)dienstals freier String + Vorschlagsliste (G-1). (e) interim manuelle Erfassung — Provider-Billing-API-Pull später (OP-OBS-1). Mergemain: parallele PRs #189/#190 (OP-R1-3) + #191 (Gantt-OPs) eingepflegt (Version → 0.5.0/Build 7,schemaVersion→ 13 entkoppelt). Tests: Server-Typecheck ·test:kosten·test:progression·ng build(prod) · No-Hex · tokens-Staleness ·operativ-Smoke · WS-Upgrade-Live-Check (wrangler dev: 101 + Live-State + Gate) grün; CI auf PR #192 grün. Kein Solver-Redeploy. Doku:docs/Kosten.md(§11 Stand + Status), HANDOFF (§2 + OP-COST-1),design/WORKSPACES.md(§10) +design/DESIGN_TOKENS.md,docs/Risikoregister.md(RISK-12 → mitigiert),docs/Compliance.md,server/wrangler.toml, Timesheet (Session 27). True North: schärft Frage 1 „Auslastung" um die Wirtschaftlichkeit (Infra-Spend-Transparenz). - #191 — OPs erfasst: Heute-Linie (OP-R8-17) + Zoom (OP-R8-18) im Gantt (Backlog, kein Code → kein Version-/Build-Bump). Zwei Nutzer-OPs (06-25) zur Gantt-Navigation/Lesbarkeit: OP-R8-17 vertikale „Jetzt"-Linie über alle Zeilen (was läuft jetzt / überfällig); OP-R8-18 Zeit-Zoom (Stunden↔Tage↔Wochen, Tag/Woche/Monat-Presets). Offene Klärungen je OP (Live-Tick/Styling bzw. Zoom-Stufen/Anker/Performance) in HANDOFF §4. Doku: HANDOFF (OP-R8-17/18). Kein Code/Solver-Redeploy. (Hinweis: parallel zur unmergten OP-R1-3-Slice-2-PR #190 erfasst; Timesheet wird beim Merge nachgezogen.)
- #190 — OP-R1-3 Slice 2: begründungspflichtige Beförderung + Audit-Historie (Version 0.3.0 → 0.4.0 MINOR, Build 5 → 6). Macht jede Skill-Niveau-Erhöhung begründungspflichtig und revisionssicher. Gebaut: (1)
employee.setSkillNiveauträgt jetzt einen Grund (grundKategorieexterner_lehrgang/xp_basiert/manager + optionalergrundText); der „Anheben"-Button auf der MA-Karte öffnet einen Begründungs-Dialog (Pflicht), bevor befördert wird. (2) Neue append-onlybefoerderungsHistorie(BefoerderungEintrag: wer · wann · von→auf · Grund · Akteur) — beim Niveau-Anstieg schreibtprotokolliereBefoerderungeinen unveränderlichen Eintrag (Muster wie die Abwesenheits-Historie #183; Akteur interim'system'bis OP-AUTH-1). (3) Die jüngsten Beförderungen je Mitarbeiter erscheinen als Audit-Spur auf der Karte (Employee.befoerderungen, server-abgeleitet). Entscheidungen: (1) Audit interim im DO-Blob (wie #183) — der D1-Umzug (durable, abfragbar) folgt mit der OP-AUDIT-1-D1-Migration. (2) Manager-Aktionen vertagen/verwerfen + Übersichts-Liste = Slice 3 (Dismiss-State + Vorschlags-Filter) — Slice 2 fokussiert die Begründungspflicht + Nachweis-Spur (das Headline-Requirement von OP-R1-3). Tests: Server-Typecheck +test:progression/test:leistung(unverändert grün) +ng build(prod). Kein Solver-Redeploy. Doku:docs/Akademie.md(Status), HANDOFF (OP-R1-3 Slice 2), Timesheet (Session 25). True North + OP-COMPLIANCE-1: die Beförderungs-Historie = lückenloser Kompetenz-/Zertifizierungs-Nachweis. - #189 — OP-R1-3 Slice 1: Skill-Niveau-Progression — niveau-gezielte Ausbildungsziele + XP-gegatete Aufstiegs-Vorschläge (Version 0.2.2 → 0.3.0 MINOR, Build 4 → 5). Erster Bau nach dem Design (#188,
docs/Akademie.md). Gebaut: (1)Mitarbeiter.ausbildungsZiele: string[]→{skillId, zielNiveau}[](neuer TypAusbildungsziel, Migration v12: Alt-Skill-IDs → Ziel-Niveau = aktuelles+1, sonst 2); Editor mit ★-Ziel-Auswahl, Anzeigeaktuell→Ziel, nur noch nicht erreichte Ziele (niveau < zielNiveau, server-gefiltert). (2) per-Skill-XPerfahrungspunkteProSkill(gleiche Gewichtung wieerfahrungspunkte, gefiltert auf den Skill) + XP-SchwellenXP_SCHWELLE_NIVEAU {2:60, 3:150}(dokumentierte Konstanten; admin-editierbare Stammdaten G-1 = Folge-Slice). (3)niveauVorschlaegeXP-gegatet — Aufstieg nur bei XP ≥ Schwelle und bestehenden Qualitäts-Gates (Nacharbeit/Bewertung); der Vorschlag trägtxp/schwelle, die MA-Karte zeigt den XP-Fortschritt („N/M XP"). Entscheidungen: (1) Reuse statt Parallelpfad — der bestehendeniveauVorschlaege-/Karten-Pfad wird XP-verfeinert statt einer zweiten „beförderungsreif"-Engine. (2) XP-Schwellen als Konstanten in Slice 1 (Stammdaten-Editor = Slice 2), um Migrations-/DTO-Fläche klein zu halten. (3) Begründungspflichtige Beförderung + Audit + Übersicht = Slice 2 (heute bleibtsetSkillNiveauEin-Klick). Tests: Server-Typecheck + neuertest:progression(per-Skill-XP; XP-Gate blockt bei 50/öffnet bei 70; niveau-gezielte Ausbildungsziele) +test:leistung(unverändert grün) +ng build(prod) + CI-Step ergänzt. Kein Solver-Redeploy. Doku:docs/Akademie.md(Status), HANDOFF (OP-R1-3 Slice 1), Timesheet (Session 24). True North: genauere Eignungs-/Kompetenzdaten → bessere Taktung. - #188 — OP-R1-3 erfasst + Design festgezurrt →
docs/Akademie.md: Skill-Niveau-Progression (niveau-gezielte Ausbildungsziele · begründete Beförderung · XP-Todo · Akademie-Vorbereitung) (Design-PR, kein Code → kein Version-/Build-Bump). Neuer OP (Nutzer 06-25), erweitert OP-R1-2: (1) Ausbildungsziele zielen auf eine Stern-Stufe (z. B. Keramik ★★) —Mitarbeiter.ausbildungsZiele: string[]→{skillId, zielNiveau}[]; nur noch nicht erreichte Ziele anbieten. (2) XP-Schwellen je Niveau (G-1; heute Heuristik inniveauVorschlaege), XP künftig je Skill. (3) Beförderung begründungspflichtig (externer Lehrgang/Manager/XP) → OP-AUDIT-1-Event (= Zertifikats-Nachweis). (4) Gesammelte XP als „beförderungsreif"-Todo (MA-Karte + Übersicht; derived D-2, propose-not-execute). Bereitet Akademie/Zertifizierungen vor (evtl. OP-ACADEMY-1). Offene Frage (anstehende Beförderung „zählt nicht"/„weitere XP erforderlich") mit Vorschlag erfasst: Manager-Aktionen bestätigen/vertagen/verwerfen am Todo. Design (docs/Akademie.md): Datenmodell (ausbildungsZiele→{skillId, zielNiveau}, XP-Schwellen je Niveau G-1, Beförderungs-Historie append-only als OP-AUDIT-1-Event), per-Skill-XP-Ableitung (XP-Schwelle + Qualitäts-Gate kombiniert), Beförderungs-Flow bestätigen/vertagen/verwerfen (= Antwort auf die offene Frage; XP nie genullt), Rollen (Manager/OP-AUTH-1), Slices, Akademie/Zertifizierungs-Vision (evtl. OP-ACADEMY-1). Doku:docs/Akademie.md(neu), HANDOFF (OP-R1-3),CLAUDE.md(Tiefenquellen), Timesheet (Session 23). Kein Code/Solver-Redeploy. - #187 — OP-COST-1: Kosten-Dashboard-Architektur festgezurrt (Design-PR, kein Code → kein Version-/Build-Bump, Präzedenz #182). Neue lebende Doku
docs/Kosten.mdpinnt das Design der Kostenkontrolle in der App. Scope-Entscheidung (Nutzer-Wahl 06-25): zwei getrennte Sichten — A betriebswirtschaftlich (Arbeits- + Materialkosten + Marge je Auftrag/Leistung, Soll-Ist; Management-Sicht) · B Infra-/Cloud-Kosten (Cloudflare/Fly/D1/LLM-Spend; Ops-Sicht) — getrennte Datenquellen/Rollen, kein Misch-KPI. Design-Entscheidungen: (1) Arbeitskosten abgeleitet aus den vorhandenenLeistungsnachweise.istMin(OP-R1-2) × Stundensatz-Stammdaten je Abteilung (abteilungId/TaxonomyValue, neu, admin-editierbar G-1; Mitarbeiter-/Skill-Override später — Freitext-roleals Schlüssel ungeeignet). (2) Materialkosten konsumieren OP-R10-1 (strukturierte Materialerfassung Menge/Charge/Verschnitt) × Materialpreise — nicht dupliziert. (3) Umsatz/Marge aus OP-R7-6 (Preismodell/Auftragswert) bzw. SevDesk (OP-BILLING-1). (4) Derived nie speichern (D-2) — wieleistung.ts(Fakten gespeichert, Sichten abgeleitet). (5) Rollen/Sichtbarkeit: Kosten = sensibel → Management/Owner-Gate, hängt an OP-AUTH-1 (interim server-seitiges Admin-Flag, kein Broadcast-Leak, OP-SEC-1 #6); Stundensatz-/Preis-Änderungen als OP-AUDIT-1-Event. (6) Abgrenzung: ≠ Rechnungsstellung (SevDesk/OP-BILLING-1), ≠ SaaS-Paygate (OP-PAY-1), ≠ Betriebs-Logs (OP-LOG-1). Build-Slices: A1 Arbeitskosten je Auftrag = baubar JETZT (keine neue Abhängigkeit, nur Stundensatz-Stammdaten + Ableitung,test:kosten) · A2 Materialkosten (gated OP-R10-1) · A3 Marge+Dashboard (gated OP-R7-6/SevDesk) · B1 Infra-Kosten (manuell→Provider-APIs, OP-OBS-1). Split (Nutzer-Wahl „split"): auf eigenem Branchclaude/op-cost-1-design, getrennt von der parallelen Audit-Binding-PR #186 (claude/loving-lovelace-x0cht6). Doku:docs/Kosten.md(neu), HANDOFF (OP-COST-1),CLAUDE.md(Tiefenquellen),docs/Risikoregister.md(RISK-11 Garbage-in-Stammdaten, RISK-12 Sichtbarkeit vor Rollenmodell), Timesheet (Session 22). Kein Code / kein Solver-Redeploy. True North: schärft „Auslastung" um Wirtschaftlichkeit/Marge (Frage 1). - #186 — OP-AUDIT-1: D1-Audit-Binding gesetzt — Dual-Write live (Version 0.2.1 → 0.2.2 PATCH, Build 3 → 4). Aktiviert den seit #184 dormant gebauten D1-Schreibpfad:
[[d1_databases]]-Binding (binding = "DB"→taktano-audit,database_id 6a080ffd-…,migrations_dir = "migrations") inserver/wrangler.tomlergänzt. Beim Merge aufmaindeployt der strikte CD-Job (ci.yml) den Worker mit DB-Binding →env.DBist gesetzt → der guarded Dual-Write (protokolliereAbwesenheit→ Blob + D1, fire-and-forget) und der Boot-Backfill (d1BackfillFromBlob) werden live; ohne Binding waren beide No-ops (exakt bisheriges Verhalten). Vorbedingungen — beide nutzerseitig bestätigt, bevor das Binding gesetzt wurde (docs/Audit-Log.md§7.4): (a) das per Cloudflare-MCP verbundene Konto (in demtaktano-auditliegt) ist das Deploy-Konto (CLOUDFLARE_ACCOUNT_ID) →database_idlöst beim Deploy auf; (b) der CI-CLOUDFLARE_API_TOKENhat D1-Bearbeitungsrechte →wrangler deploymit Binding läuft durch (sonst strikter CD-Job →mainrot). Entscheidungen: (1) Version = PATCH (0.2.2) — diese PR ergänzt nur das Binding (Config); die Dual-Write-/Backfill-Logik kam bereits in #184 (selbst PATCH), kein neuer Code-/Feature-Surface, rückwärtskompatibel (additiv, Blob bleibt synchrone Fairness-Quelle). Build +1 (→ 4) je harter Regel (deploybare Verhaltensänderung). (2) Kein Doppel-Apply-Risiko — Migration0001ist remote bereits angewandt (#185) und idempotent (CREATE … IF NOT EXISTS);wrangler deploywendet ohnehin keine D1-Migrationen an. (3) Hybrid unverändert — DO-Blob bleibt Quelle der synchronen Fairness, D1 ist der durable append-only Sink; Lese-Umstellung auf D1 (async+Cache) + Slice 2/3 (breite Erfassung · Panel/Rollen/Suche) bleiben offen. Kein Solver-Redeploy. Doku:docs/Audit-Log.md(§7 Schreibpfad + D1-Aktivierung [Schritte 1–4 ✅]), HANDOFF (OP-AUDIT-1),docs/Compliance.md(ISO-27001-Checkliste: Audit-Log-EU-Persistenz aktiv), Timesheet (Session 21). True North: stützt OP-OPT-7 (durable Fairness-Historie) + OP-COMPLIANCE-1 (EU-Residenz/Audit-Bereitschaft jetzt persistent). Go-Live: beim Merge aufmain. - #185 — OP-AUDIT-1: D1-Audit-DB provisioniert + migriert (Binding bewusst zurückgestellt) (Nutzer-Wahl „DB anlegen, Binding später"; kein Code → kein Version-/Build-Bump, Präzedenz #182). Aktiviert die Infra für den in #184 dormant gebauten D1-Pfad ohne Deploy-Risiko: D1-DB
taktano-auditin EU-Regionweur(DSGVO-Residenz) via MCPd1_database_createangelegt (database_id 6a080ffd-9cad-4c8e-80df-314beebdab9b) + Migration0001_audit_entries.sqlangewandt (audit_entriesINSERT-only + 4 Indizes; Remote persqlite_master-Query verifiziert: Tabelle +ix_audit_tenant_ts|_type_ts|_res_ts|_actor_ts). Entscheidungen: (1) Binding NICHT gesetzt —server/wrangler.tomlbleibt unangetastet,env.DBweiter undefined → exakt bisheriges Laufzeit-/Deploy-Verhalten, null Risiko (deploy-sicher wie #184). (2) Zwei harte Aktivierungs-Vorbedingungen festgehalten (docs/Audit-Log.md§7), beide nutzerseitig zu bestätigen, bevor das Binding gemergt wird: (a) das per MCP verbundene CF-Konto muss das Deploy-Konto sein (sonst löst diedatabase_idbeim Deploy nicht auf), (b) der CI-CLOUDFLARE_API_TOKENbraucht D1-Rechte (sonst brichtwrangler deploy). (3) Konto-Vorbehalt dokumentiert — die DB liegt im aktuell verbundenen Konto; Identität mit dem Deploy-Konto noch zu verifizieren. Kein Solver-Redeploy, kein Worker-Verhaltens-/Deploy-Risiko (dormant). Doku:docs/Audit-Log.md(Status + §7-Aktivierung [Schritte 1+2 ✅, 3+4 ⛔] + §8), HANDOFF (OP-AUDIT-1), Timesheet (Session 20 + Summe-Rollup 18–20 nachgezogen). Offen (Go-Live): Konto-Match + Token-D1-Rechte bestätigen → Binding mergen → Dual-Write live. True North: stützt OP-OPT-7 (Fairness-Historie) + OP-COMPLIANCE-1 (EU-Residenz/Audit-Bereitschaft). - #184 — OP-AUDIT-1: D1-Verdrahtung (deploy-sicher, dormant) + OP-COST-1 erfasst (Version 0.2.0 → 0.2.1, Build 3). Bringt das im Design (#182) entschiedene D1-Audit-Log code-seitig an, ohne den Produktiv-Deploy zu gefährden. Gebaut: (1) Schema-Migration
server/migrations/0001_audit_entries.sql(audit_entriesINSERT-only + 4 Indizes; Spalteausloeserstatt SQLite-Keywordtrigger); (2)Env.DB?: D1Databaseoptional; (3) guarded Dual-Write —protokolliereAbwesenheitschreibt jeden Abwesenheits-Historien-Eintrag zusätzlich fire-and-forget nach D1 (d1InsertAudit,INSERT OR IGNORE, Fehler blocken den Broadcast nie), nur wenn dasDB-Binding existiert (sonst No-op); (4) idempotenter Backfill der Interim-Blob-Historie nach D1 beim Boot (d1BackfillFromBlob, nur wenn D1 leer). Entscheidungen: (1) Kein[[d1_databases]]-Binding inwrangler.tomlin dieser PR —wrangler deployvalidiert D1-Bindings, eine fehlende/nicht erreichbare DB würde den Deploy-on-Merge brechen; daher bleibt der D1-Pfad dormant (Binding fehlt →env.DBundefined → exakt bisheriges Verhalten, kein Risiko) und wird erst aktiviert, wenn die DB provisioniert und der CI-CLOUDFLARE_API_TOKEND1-Rechte hat (Aktivierungs-Checkliste:docs/Audit-Log.md§7). (2) Hybrid beibehalten: der DO-Blob bleibt in diesem Slice die Quelle der synchronen Fairness (snapshot()); D1 ist der durable append-only Sink — die Lese-Umstellung der Fairness auf D1 (async + Cache) ist ein Folge-Slice. (3) Best-effort Dual-Write (Blob maßgeblich) — Retry/Pufferung bei D1-Ausfall folgt. Zusätzlich neuer OP OP-COST-1 erfasst (Nutzer-Wunsch): Kostenkontrolle / Kosten-Dashboard in der App — Arbeits-/Material-Kosten + Marge je Auftrag/Leistung (Basis: Leistungsnachweise/Ist-Zeit), Scope (betriebswirtschaftlich vs. Infra-/Cloud-Kosten) + Datenquellen/Rollen zu klären (HANDOFF §4). Tests: Server-Typecheck (D1-Typen) +test:fairness+ Smoke (spike/operativ) + No-Hex grün. Kein Solver-Redeploy; kein Worker-Verhaltens-/Deploy-Risiko (dormant). Doku:docs/Audit-Log.md(§7 Integration + D1-Aktivierung, §8, Status), HANDOFF (OP-AUDIT-1 + OP-COST-1), Timesheet (Session 19). Offen (Aktivierung): D1-DB provisionieren (EUweur) + Binding +migrations apply+ CI-Token-D1-Rechte bestätigen → dann geht der Dual-Write live.
2026-06-24
-
Branch
claude/workflow-reservation-pickup-6m2q37(reine Doku/Analyse; PR folgt bei Bedarf) — Flow-Analyse Auftrags-Flow (Reservierung → Anlieferung → Annahme → Aufbereitung → Produktion → QS → Abholung). Auf Nutzer-Eindruck „nicht intuitiv" geprüft aus Daten-, Prozess- und UX-Sicht; neues Dokumentdocs/Flow-Analyse.md. Befund: drei nicht deckungsgleiche „Flows" (8-Status-Lifecycle vs. 5-Phasen-Standard-Prozess vs. 5-Stationen-UI-Flow-Band); der gefühlte 7-Schritt-Flow vermischt zwei orthogonale Achsen (Lifecycle/Reservierung vs. fachliche Phase); Anlieferung ≠ Annahme auf einen Statusangeliefert; QS doppelt modelliert + End-/Nachkontrolle vermengt. Entscheidung: Zielbild „Phasen first-class" → schärft OP-R3-1 (umgesetzt in PR 1–7, siehe 2026-06-25). Keine Code-Änderung. -
#183 — OP-AUDIT-1 Slice 1: Abwesenheits-/Wunschfrei-Historie → OP-OPT-7-Fairness (erster Bau nach dem Design #182; Version 0.1.0 → 0.2.0, Build 1 → 2). Problem: Eine entfernte Abwesenheit verschwand spurlos aus
Mitarbeiter.abwesenheiten— die Fairness-Frage „wer hatte in den letzten Monaten wie viel Wunschfrei" (OP-OPT-7, Design-Entscheidung #173) war damit unbeantwortbar. Bau: neue append-onlyAbwesenheitHistorieEintrag[]im DO-State (server/src/model/types.ts); jedes Hinzufügen/Entfernen einer Abwesenheit hängt überprotokolliereAbwesenheiteinen unveränderlichen Eintrag an (Entfernen = zweiter Eintragaktion='entfernt', nie Löschen).schemaVersion10 → 11 mit idempotentem Backfill aus den aktuellen Abwesenheiten (Erfassungszeit unbekannt → Stand-invon), damit die Fairness sofort einen Stand zeigt. Abgeleitet (D-2, nie gespeichert): pure, selbst-getestetefairnessAusHistorie(server/src/operativ/fairness.ts) zählt je Mitarbeiter die im gleitenden 90-Tage-Fenster gewährten Wunschfrei-Blöcke (FairnessDTOanEmployee) — inkl. später entfernter (die Fairness gilt der Gewährung, nicht dem Bestand); in der Mitarbeiter-Karte als „Wunschfrei 90 T: N · M genehmigt" sichtbar (staff.component.ts, nur--tk-*-Tokens). Entscheidungen: (1) Interim im DO-Blob statt sofort D1 — niedrig-volumig, kleinster nutzbarer Schritt; bewusst als Interim markiert, wandert mit der D1-Verdrahtung (OP-DATA-1) um (Designdocs/Audit-Log.md§8-Hinweis). (2) Scope = nur Abwesenheits-Historie:bereitschaft.geoeffnet(on-call gezogen) undzugang.stufe/override(OP-ACCESS-1) bleiben offen, weil ihre Quell-Events noch nicht existieren → sauber als Slice-1-Rest dokumentiert statt Platzhalter zu bauen. (3) Fairness zählt die Gewährung (Erfassung im Fenster), nicht netto-effektive Tage — robust gegen Entfernen und genau die zuvor verlorene Spur; netto-Tage bleiben einem späteren Slice vorbehalten. (4) Akteur interim'system'(kein Identitäts-Plumbing bis OP-AUTH-1). (5) Derivation als pure Funktion (Repo-Konvention) →npm run test:fairness(CI) beweist die Kern-Eigenschaft „Gewährung überlebt Entfernen" + Härtegrad/Fenster/Mitarbeiter-Isolation/genehmigt-Teilmenge. Tests: Server-Typecheck +test:fairness+ Smoke (spike/operativ/replan) +ng build(prod) + No-Hex-Gate grün. Kein Solver-Redeploy (reine DO-/Client-/Ableitungs-Änderung; Optimierer-Verhalten unverändert — Wunschfrei-Pönale steckt bereits in #179/#180). Doku:docs/Audit-Log.md(Status + §8 Slice-1-Stand), HANDOFF (OP-AUDIT-1), CHANGELOG, Timesheet (Session 18). True North: stützt OP-OPT-7 (fairere/vertrauenswürdigere Kapazitäts-/Bereitschafts-Entscheidungen, Frage 3) + OP-COMPLIANCE-1 (Audit-Bereitschaft). -
#182 — OP-AUDIT-1: Audit-Log-Architektur festgezurrt (Design-PR, kein Code; User-Wahl „erst Architektur festzurren"). Neue lebende Doku
docs/Audit-Log.mdpinnt: Speicher-Entscheidung D1 (Cloudflare SQLite, EU) statt DO-Blob (abfragbar · append-only · skalierbar · EU-Residenz; Hybrid — der DO behält die Live-Geschäftsfakten, D1 nur das Audit-Log; folgt OP-DATA-1/Drizzle); D1-Schema-Entwurf (audit_entries+ Indizes, INSERT-only, Korrektur = kompensierender Eintrag); Event-Katalog (typisiert, Akteur Mensch/system+ Auslöser-Kausalkette); „nicht reverse-engineerbar"-Sicht-/Suchmodell (rollenbasiert; kein Oracle über Existenz/Inhalt/Anzahl/Timing verborgener Einträge — uniforme Leerantwort, Counts/Pagination nur über autorisierte Teilmenge; Bezug OP-SEC-1); Retention + PII-Scrubbing (DSGVO DE/AT/CH, EU-D1); DO→D1-Schreibpfad (fire-and-forget, blockt den Broadcast nie); Build-Slices (1 Abwesenheits-/Bereitschafts-Historie → entsperrt OP-OPT-7-Fairness + OP-ACCESS-1-Nachweis; 2 breite Event-Erfassung; 3 read-only Panel + Rollen + Suche). Abgrenzung: Audit-Log ≠ Betriebs-Logs (OP-LOG-1) ≠ Auftrags-Protokoll. Doku: HANDOFF (OP-AUDIT-1 §4-Eintrag), CLAUDE.md (Tiefenquellen),docs/Audit-Log.md, Timesheet (Session 17). Kein Code / kein Solver-Redeploy. -
#181 — Projekt-Konventionen & Governance: Versionierung (SemVer) + Build-Nummer · SBOM · Compliance/Zertifizierung · Risikoregister · Log-Handling. Mehrere stehende Konventionen in
CLAUDE.mdverankert + die konkrete Version/Build-Anzeige gebaut.- Versionierung (SemVer, bewusst hochgezählt): erstes Ziel MVP = 1.0.0 (Vor-MVP bleibt 0.x); MINOR = Optimierungen/Features (1.0.0→1.1.0), PATCH = Bugfixes/Tweaks (1.1.0→1.1.1), MAJOR = Meilenstein/Breaking. Build-Nummer parallel, monoton, +1 je PR. Single Source
server/src/version.ts(APP_VERSION='0.1.0',APP_BUILD=1) → über den State an den Client; sichtbar in der UI (Cockpit-Toolbar neben dem Solver-Build) und in den Logs (DO-Boot-Zeile). - SBOM immer pflegen (OP-SBOM-1): CycloneDX via
npm run sbom(Server+Client) + CI-Jobsbom(Artefakt je Lauf → immer aktuell); Python-Solver-SBOM offen. - Compliance/Zertifizierung (OP-COMPLIANCE-1): lebende
docs/Compliance.md(TÜV/ISO 27001/Security-Audit-Bereitschaft · Zielmärkte DE/AT/CH · Rahmen DSGVO/E-Rechnung/Arbeitszeit) + proaktives Flagging kritischer/regulatorischer Themen mit Optionen. - Risikoregister
docs/Risikoregister.md: 10 Risiken geseedet (DO-Blob-Wachstum, fehlende Wunschfrei-Historie, PII/DSGVO, Supply-Chain, Mandanten-Isolation …), Review je Session/PR. - Log-Handling (OP-LOG-1): Logger-Wrapper (strukturiert, Version/Build +
trace_id, keine roheconsoleim Laufzeitpfad, PII-Scrubbing) als OP erfasst; Transport via OP-OBS-1; heute interimconsole(Boot-Zeile). - Entscheidung: Vor-MVP-Version =
0.1.0(passt zur bestehendenpackage.json-Version beider Pakete);1.0.0markiert das fertige MVP. Server-Typecheck +ng build(prod) + alle Self-Tests + No-Hex grün. Kein Solver-Redeploy. Doku:CLAUDE.md(§Versionierung, §Compliance, Tiefenquellen), HANDOFF (OP-LOG-1/OP-SBOM-1/OP-COMPLIANCE-1),docs/Compliance.md,docs/Risikoregister.md, Timesheet (Session 16).
- Versionierung (SemVer, bewusst hochgezählt): erstes Ziel MVP = 1.0.0 (Vor-MVP bleibt 0.x); MINOR = Optimierungen/Features (1.0.0→1.1.0), PATCH = Bugfixes/Tweaks (1.1.0→1.1.1), MAJOR = Meilenstein/Breaking. Build-Nummer parallel, monoton, +1 je PR. Single Source
2026-06-23
- #180 — OP-OPT-7 Slice 2: Bereitschaft/Überlauf als Hybrid-Vorschlag (baut auf #179). Kern-Korrektur („nie still"): Überlauf-/Bereitschafts-Schichten (
Schicht.art='ueberlauf') zählten bisher wie reguläre Schichten zur Verfügbarkeit — der Optimierer konnte sie still belegen.mitarbeiterAvailabilityblendet sie jetzt standardmäßig aus (neuerincludeUeberlauf-Schalter); Bereitschaft ist damit aus dem Normalbetrieb heraus. Hybrid-Vorschlag (Entscheidung #173): der Optimierer rechnet zusätzlich eine Variante, die die Bereitschaft öffnet (berechnePlaene(…, bereitschaft=true)→buildProblem/scheduleLeistungschaltenueberlaufviaueberlaufFensterfrei), und vergleicht sie mit dem besten normalen (flow) Plan. Nutzt die Variante die Bereitschaft und lohnt sie sich, entsteht ein bestätigungspflichtiger Eintrag im Vorschläge-Feed (VorschlagAktionbereitschaft) mit konkreter Wirkung: welche Termine gehalten/gerettet (per-AuftragdeltaMin/termin) und wer aus dem On-Call gezogen würde (bereitschaftGezogen). Übernehmen = den Bereitschafts-Plan einmal rechnen + schreiben; nie automatisch. Auslöser (Nutzer-Wahl „auch bei Zeitgewinn"): Vorschlag, sobald Bereitschaft einen Termin rettet oder Aufträge früher fertig macht. Pönale-Ordnung (Slice-1-softBlockswiederverwendet): geöffnete Bereitschaft wird als Soft-Block mitBEREITSCHAFT_POENALE_PRO_MIN=5belegt — teurer als ein einfacher Wunschfrei (2 → „erst Wunschfrei, dann Bereitschaft"), aber billiger als ein genehmigter (200 → eine zugesagte freie Schicht ist stärker geschützt als On-Call): 2 < 5 < 200; im TS-Greedy viasoftBlockRang(frei → Wunsch → genehmigt → Bereitschaft, zuletzt). Keinmodel.py/Solver-Redeploy: Bereitschaft ist nur ein weiteres gewichtetessoftBlock-Fenster — die CP-SAT-Pönale aus #179 trägt es bereits; nur der Worker (Verfügbarkeit/buildProblem) + DO + Client ändern sich. Client: der bestehende Vorschläge-Feed (recommendations.component) rendert + übernimmt/verwirft den Bereitschafts-Vorschlag generisch (nurVorschlagAktion-Typ gespiegelt). Entscheidungen: (1) Auslöser „auch bei Zeitgewinn" (Termin-Rettung ODER früher fertig); (2) Vorschlag im manuellen „Optimierung vorschlagen"-Lauf (optimierenVorschau) — hält den Auto-Feed latenzarm (Auto-Bereitschaft = möglicher Folge-Schritt); (3) Vorschlag nur, wenn die Variante die Bereitschaft wirklich belegt (bereitschaftGezogennicht leer) — kein irreführender Bereitschafts-Vorschlag bei reiner Solver-Streuung. Tests:test:bereitschaft(Überlauf zählt nicht zur Default-Verfügbarkeit;includeUeberlauf/ueberlaufFensterschalten frei; Status-Gate) + CI; Server-Typecheck + alle Self-Tests +ng build(prod) + No-Hex grün. Damit OP-OPT-7 Slice 1+2 fertig (Wunschfrei-Pönale + Bereitschaft-Hybrid); offen bleibt nur die Verteilung/Fairness-Historie (Block-Füllen + Wunschfrei-/Bereitschafts-Historie) — hängt an OP-AUDIT-1. Folge-Ideen aufgenommen (User): (e) konfigurierbarer Bereitschafts-Vorlauf (Mindest-Ankündigung), (f) verschiedene Bereitschafts-Arten (mehrere On-Call-Typen, Taxonomie-artig), (g) Bereitschafts-Dienstplanung (Roster: wer wann Bereitschaft hat) — s. HANDOFF OP-OPT-7. Doku: HANDOFF OP-OPT-7, Lastenheft §4.4a/F05, Timesheet (Session 15). True North: genauere, vertrauenswürdigere Planung (Frage 1/3) — Bereitschaft wird nie verdeckt verplant, sondern als transparenter Vorschlag mit Wirkung gezeigt. - #179 — OP-OPT-7 Slice 1: Wunschfrei-Pönale im Optimierer (Solver-Anbindung der weichen Soft-Blocks aus #173). Weiche „Wunschfrei"-Blöcke (
Abwesenheit.hart=false) reduzieren die Verfügbarkeit weiterhin nicht, werden vom Optimierer jetzt aber gewichtet gemieden — in beiden Solvern (Parität wie OP-OPT-5): CP-SAT (solver-service/model.py) pönalisiert je zugewiesenem Schritt die Überlapp-Minuten mit den Soft-Block-Fenstern des Mitarbeiters (add_max/min_equalityfür den Überlapp + „nur wenn zugewiesen"-Gate viaonly_enforce_if(on), additiv zuextras); TS-Fallback misstwunschfreiMininobjective.ts(Tie-Break inistBesserdirekt nach Durchsatz) und der Greedy reiht inschedule.tsdie Kandidaten frei → Wunsch → genehmigt (pickCrewnimmt die ersten passenden). Abstufung (Design-Entscheidung 3): neues FeldAbwesenheit.genehmigt— einfacher Wunsch (Faktor 1) vs. vorgesetzten-genehmigt = „quasi-hart" (WUNSCHFREI_GENEHMIGT_FAKTOR=100); Editor-Toggle im Mitarbeiter-Raum (nur im Wunschfrei-Modus) + „✓ genehmigt"-Marker in der Liste. Geteilter HelperweicheBloecke(availability.ts) speist Solver-Payload (problem.ts→employees[].softBlocksmitgewicht/min) und Fallback aus einer Quelle. Gewichte (WUNSCHFREI_POENALE_PRO_MIN=2) als Konstanten, kalibriert unter Reserve/Termintreue: ein einfacher Wunsch beugt sich Deadlines/Reserve, schlägt aber marginalen Flow; genehmigt (×100) ist faktisch quasi-hart, nur von Eil/Garantiert/Termintreue zu brechen. Entscheidungen: (1) Slice 1 = nur Wunschfrei — Bereitschaft/Überlauf (Schicht.art='ueberlauf') folgt als Slice 2, weil das per Design „Hybrid" ist (Optimierer rechnet, übernimmt aber nie still → bestätigungspflichtiger Vorschlag mit Effekt-Vorschau) — eine Vorschlags-UX, kein reiner Penalty; (2) deploy-sicher: das neuesoftBlocks-Feld liest der Solver mit.get→ der aktuell deployte Solver ignoriert es (kein Bruch), der TS-Fallback honoriert es sofort; (3)genehmigtoptional (Reader defaulten) → keinschemaVersion-Bump (Parität zu #173). Tests:python model.pyum den Wunschfrei-Fall erweitert (gleich geeigneter, unblockierter MA wird gewählt; ohne Alternative bleibt der Block belegbar → genehmigt ist weich, nicht hart) ·test:ausfallumweicheBloecke/bewerte/istBesser(Pönale-Minuten, genehmigt-Faktor ×100, Tie-Break). Deploy: diesolver-service/**-Änderung triggert beim Merge aufmainautomatischfly-deploy.yml(Fly-Auto-Deploy, vorab vompython model.py-Gate geschützt) → die CP-SAT-Pönale geht ohne manuellen Schritt live (flyctl/Token hier nicht verfügbar). Server-Typecheck + alle Self-Tests (CP-SAT + TS) grün ·ng build(prod) + No-Hex grün. Doku: HANDOFF OP-OPT-7 (Slice-1-Stand) + OP-R8-11, Lastenheft §4.4a/F05, Timesheet (Session 14). True North: genauere, vertrauenswürdigere Planung (Frage 1/3) — der Plan respektiert reale Wunschfrei-Wünsche, statt sie zu ignorieren. - #178 — Eingriffsregeln am Preemption-Hebel durchgesetzt (OP-R3-3, server-seitig — User-Wahl „kein Solver-Redeploy"; schließt OP-R3-3 ab). Architektur-Befund: Der Optimierer splittet/preemptet Schritte nie (atomare Single-Crew-Intervalle in TS-Scheduler + CP-SAT), Preemption ist ein manueller Hebel, und das Resume behält die Crew (
starteTeilschritt). Es gibt also nichts im Solver zu pönalisieren — die Regeln greifen dort, wo der Eingriff real entschieden wird: am Konflikt-/Preemption-Hebel.unterbrechung: vermeiden: Kandidaten werden „erlaubt vor vermeiden" gereiht + tragen einen ⚠-Soft-Hinweis („sollte möglichst nicht unterbrochen werden");verbotenbleibt ganz aus der Kandidatenliste (istUnterbrechbar).uebernahme: am Hebel sichtbar —verboten→ „nur der ursprüngliche Mitarbeiter darf fortsetzen, bei Ausfall blockiert der Schritt",vermeiden→ „möglichst derselbe Mitarbeiter"; da das Resume die Crew unverändert lässt, istuebernahme: verbotenim normalen Ablauf gewahrt. Pure LogikpreemptionHinweis/preemptionUnterbrechungsRang(operativ/preemption.ts) +test:preemptionerweitert;HebelDTO.warnung(server+client); Anzeige am Hebel inconflicts.component.ts(var(--tk-amber)). Entscheidungen: (1) server-seitig statt CP-SAT (User-Wahl) — eine in den Solver integrierte Pönale hätte heute keine Wirkung (keine Auto-Preemption / kein Step-Splitting) und bräuchte Redeploy → als Zukunfts-Option dokumentiert; (2)uebernahme: verbotennicht als hartes Block des Hebels (Preempten bleibt erlaubt — derselbe MA setzt fort), sondern als Warnung; (3) kein neuer Crew-Reassign-Pfad nötig (es existiert keiner; Resume behält die Crew). Server-Typecheck +test:preemption/test:prozess/spikegrün ·ng build(prod) grün · No-Hex grün. Kein Solver-Redeploy. Damit ist OP-R3-3 server-seitig abgeschlossen (Editor #175–#177 + Eingriffsregeln #178); eine CP-SAT-integrierte Pönale bleibt optionale Zukunft (erst bei Step-Splitting). - #177 — Leistungs-Prozess-Editor (R3a; schließt den OP-R3-3-Editor ab, baut auf #175/#176). Je Leistung admin-editierbar: Stammfelder (Name · Standzeit · Status aktiv/inaktiv) und die Prozess-Komposition — Schritt-Reihenfolge (↑/↓), Teilschritt je Schritt (Picker), Abhängigkeit (
nach_vorherigem/parallel/frei), Dauer-Override (sonst Standarddauer), Schritte hinzufügen/entfernen. Persistenz:leistungenjetzt im DO persistiert (Voll-Persist wie OP-R1-1;structuredClone+onStart-Backfill +SCHEMA_VERSION9→10);schedulerInput()speist sie ein undbuildProzessKatalogliest sie → Edits wirken auf neue Aufträge (Komposition/Standzeit/Dauer fließen in Taktung). Server: puresetzeLeistungFelder+setzeLeistungProzess(ersetzt die Komposition atomar; unbekannte Teilschritte / ungültige Abhängigkeiten / Override <1 werden verworfen) + Handlerleistung.update/leistung.setProzess.ProzessDTOumstatus,ProzessSchrittDTOumdauerOverrideMinerweitert. Client: „Prozesse"-Workspace mit Tab-Umschalter (Teilschritte ↔ Leistungen); Leistungen-Tab = Karte je Leistung mit Stammfeld-Inputs + Kompositions-Editor (Reorder/Picker/Abhängigkeit-Segmente/Override/+−), ServiceupdateLeistung/setLeistungProzess. Self-Testtest:prozessum Leistungs-Stammfelder + Komposition (Reihenfolge/Filter/Override) erweitert. Entscheidungen: (1)leistung.setProzessersetzt die ganze prozess-Liste (ein Pfad für Reorder/Add/Remove/Edit) statt feingranularer Schritt-Messages — einfacher, atomar; (2) Scope = Editieren bestehender Leistungen (Anlegen/Löschen ganzer Leistungen als kleiner Folgepunkt offen); (3) bestehende Aufträge bleiben unverändert (Komposition wird bei Materialisierung gesnapshottet) → Edits gelten für neue Aufträge. Damit ist der OP-R3-3-Editor komplett; offen bleibt nur die Optimierer-Wirkung (Soft-Penaltyvermeiden+ Übernahme-Durchsetzung, Solver + Redeploy). Server-Typecheck +test:prozess/operativ/spike/solve/eligibilitygrün ·ng build(prod) grün · No-Hex grün. Kein Solver-Redeploy. - #176 — Prozessschritt-Eigenschaften editierbar (R3b; weitere OP-R3-3-Auflösung, baut auf #175 auf). Neben der Skill-Anforderung sind je Teilschritt jetzt auch die Schritt-Eigenschaften admin-editierbar: Dauer (F02) · Cool-down + Indoor-Pflicht (F07/F07a) · optional (F05) · parallel möglich (F04) · mehrtägig erlaubt (F06) · Bucht-Typen (F10) · Unterbrechung/Übernahme-Regel (F15/F16,
erlaubt/vermeiden/verboten). Server: puresetzeTeilschrittFelder(Patch-Semantik; Dauer ≥1 / Cool-down ≥0 normalisiert, Bucht-Typen gegen diearbeitsplatz_typ-Taxonomie gefiltert+dedupliziert, Regel-Enum validiert) + Handlerteilschritt.update. Da nun Bucht-Typen/optional/Unterbrechung editierbar sind, lesen die restlichen seed-statischen Teilschritt-Maps den persistierten Stand:TS_REQUIRED_TYPESentfällt (→toAuftragDTO(reqTypesByTs)-Parameter), dieoptional-Map der Auftrags-Materialisierung und die Preemption-tsById(füristUnterbrechbar) kommen austhis.state.teilschritte.ProzessSchrittDTOumstandarddauerMin/parallelMoeglich/mehrtaegigErlaubt/arbeitsplatzTypIdserweitert; neue Taxonomie-ListeARBEITSPLATZ_TYPEN(Parkplatz-Typen via/parkplatz/iausgeblendet) im State/Broadcast. Client: „Prozesse"-Workspace um den Block Schritt-Eigenschaften erweitert (Zahl-Inputs, Toggle-Pills, Bucht-Typ-Checkboxen, 3-Wege-Regel-Segmente); ServiceupdateTeilschritt(patch)+arbeitsplatzTypen-Accessor. Self-Testtest:prozessum Feld-Normalisierung/-Validierung erweitert. Entscheidungen: (1) Patch-Handler (teilschritt.updatemit partiellem Patch) statt Voll-Payload — erweiterbar, weniger Daten je Edit; (2) Abhängigkeit/Dauer-Override bleiben außen vor (per-Leistung, nicht per-Teilschritt → eigener „Leistungs-Prozess-Editor", OP-R3-3); (3) Parkplatz-Typen als Bucht-Anforderung ausgeblendet (Label-Heuristik wie im Scheduler), serverseitig jede gültigearbeitsplatz_typ-ID akzeptiert; (4) Soft-Penaltyvermeiden+ Übernahme-Durchsetzung im Optimierer weiter OP-R3-3 (reine Stammdaten-Pflege hier, kein Solver-Verhalten geändert). Server-Typecheck +test:prozess/operativ/replan/eligibilitygrün ·ng build(prod) grün · No-Hex grün. Kein Solver-Redeploy. - #175 — Prozessschritt-Skill-Anforderungen editierbar (R3b; Teil-Auflösung OP-R3-3). Der geforderte Skill · das Mindest-Niveau · die Personenzahl je Teilschritt (F11/F11a/F12) sind jetzt admin-editierbar statt read-only aus dem Seed. Persistenz (User-Wahl: Voll-Persist wie OP-R1-1):
Teilschritt[]in den DO-State geklont (structuredClone),onStart-Backfill (saved.teilschritte ?? Seed),SCHEMA_VERSION8→9;schedulerInput()speist die persistierten Teilschritte ein → Edits wirken hart auf Eignung/Machbarkeit (identischer Pfad wie die OP-R1-1-Skills: CP-SATbuildProblem.eligible+ TS-Scheduler). Die zuvor seed-statischen Maps (TS_SKILL,tsByIdinbuildProzessKatalog/engpassSkills) lesen jetzt den persistierten Stand (neue MethodeteilschrittSkill). Pure Logikserver/src/operativ/prozess.ts(setzeSkillAnforderung: genau ein Skill, Niveau 1–3 geklemmt, Personen ≥1) + Self-Testnpm run test:prozess(CI): Validierung + End-to-End-Beweis, dass ein Edit dieeligible-Menge ändert (Folie-Niveau 1 wird für Super-Premium geeignet, nachdem das Mindest-Niveau 3→1 gesenkt wird). Client: neuer Workspace „Prozesse" (pages/processes.component.ts+ Route + Rail) — je eindeutigem Teilschritt (geteilter Baustein) Skill-Picker · ★-Niveau · Personen-Stepper;ProzessSchrittDTOumteilschrittId+benoetigteSkillIderweitert; ServicesetProzessSkillAnforderung. Design: 9. Workspace-Signaturfarbe--tk-ws-processes(orange#fb923c/ light#ea580c) intokens.json→tokens.cssregeneriert (+build.mjsNAME-Map);WORKSPACES.md(§6, „Eight→Nine") +DESIGN_TOKENS.md-Tabelle gepflegt. Entscheidungen: (1) Voll-Persist (Konsistenz mit Skills/Mitarbeiter) statt Override-Layer — Nachteil „persistierter Stand überschattet künftige Seed-Verbesserungen am ganzen Schritt" bewusst akzeptiert; (2) Scope strikt = die 3 Skill-Felder (Dauer/Cool-down/Abhängigkeit bleiben OP-R3-3); (3) nurteilschrittepersistiert (nichtleistungen— nicht editiert, lösen gegen persistierte Teilschritte auf); (4) eigener Workspace statt Unterbringung in bestehender Seite (es gab bislang keine Katalog-UI — die HANDOFF-Notiz „read-only inleitstand.component.ts" war veraltet); (5) Teilschritte als geteilte Bausteine dedupliziert (ein Editor je Teilschritt, Edit wirkt auf alle verwendenden Leistungen). Server-Typecheck +test:prozess/test:eligibility/spike/solve grün ·ng build(prod) grün · No-Hex grün · tokens.css-Staleness grün. Kein Solver-Redeploy. - #174 — Skill-Katalog: Beschreibung (F02) editierbar (rundet den OP-R1-1-Phase-C-Editor ab). Der „Skill-Katalog"-Dialog auf der Mitarbeiter-Seite konnte bisher nur Name + aktiv/inaktiv, obwohl
Skill.beschreibungim Datenmodell steht undskill.create/skill.updatesie server- und service-seitig (inkl.SkillDTO+ Snapshot-Broadcast) längst durchreichen. Ergänzt im UI (pages/staff.component.ts): je Katalog-Eintrag ein Beschreibungs-Feld (neuer HandlersetzeSkillBeschreibung,change-getriggert, getrimmt; leerer Text löscht die Beschreibung) + ein Beschreibungs-Feld im Anlege-Formular (createSkill(name, beschreibung)statt nurname). Entscheidungen: (1) reiner Client-Pfad — keine Server-/Service-/DTO-Änderung nötig (Feld war end-to-end schon vorhanden, nur ohne Oberfläche); (2)change+ Trim konsistent mit dem vorhandenen Umbenennen (benenneSkillUm); leerer Text räumt das Feld (Server:beschreibung.trim() || undefined); (3) kein Hard-Delete unverändert (Deaktivieren statt Löschen, Verlaufsdaten bleiben gültig).ng build(prod) grün, No-Hex-Gate grün (nur--tk-*-Tokens); kein Solver-Redeploy. - #173 — Abwesenheiten/Soft-Blocks + Schicht-Art (R1-S2/S3; erfüllt OP-R8-11 Mitarbeiter-Teil, neuer Folge-OP OP-OPT-7). Abwesenheits-Editor neu gebaut: Härtegrad (feste Abwesenheit Urlaub/Krank ↔ Wunschfrei/Soft-Block) × Reichweite (ganzer Tag ↔ bestimmte Schichten) mit Von/Bis-Datum. Datenmodell:
AbwesenheitumganzerTag/schichtIds/harterweitert,SchichtKatalogumart(regulaer/standard/ueberlauf= Bereitschaft). Derived: harte Abwesenheiten reduzieren die Verfügbarkeit schicht-granular (neuer HelperabwesenheitIntervalle, geteilt vonavailability.ts+ausfall.ts); Soft-Blocks reduzieren nicht, erscheinen als eigenes „Wunschfrei"-Gantt-Band (cyan). Schicht-Art als Badge in der Zuweisung. Self-Testtest:ausfallum Schicht-granular + Wunschfrei erweitert (CI). Entscheidungen: (1) Scope = Erfassen + Sichtbar jetzt, Solver-Pönale (Soft-Block meiden, Überlauf nur bei Bedarf) + Bereitschafts-UX als Folge-OP OP-OPT-7 (User-Wahl); (2) Soft-Block defaultet die Verfügbarkeit nicht herunter (nur Band/Pönale-Kandidat); (3)ganzerTag(Default) blockt exakt [von,bis] → abwärtskompatibel zu Alt-Abwesenheiten (kein Schema-Bump nötig, Reader defaulten). Reiner Server-/Client-Pfad, kein Solver-Redeploy. Way-of-Working: neue Guideline „Feature-Branches regelmäßig gegenmainaktualisieren" (CLAUDE.md + agents.md §7). Design-Entscheidungen OP-OPT-7 geklärt (23.06., Bau folgt): (1) Bereitschaft = Hybrid (Optimierer rechnet, übernimmt aber nie still → bestätigungspflichtiger Vorschlag mit Effekt-Vorschau); (2) Pönale-Reihenfolge erst Wunschfrei, dann Bereitschaft (Bereitschaft = letzte Reserve); (3) Wunschfrei abgestuft (einfacher Wunsch vs. vorgesetzten-genehmigt = quasi-hart); (4) Verteilung „Block erst vollmachen", beim Block-Anbruch Verteil-Optionen zur Nutzer-Wahl mit Wunschfrei-Historie der letzten 3 Monate (Zeitraum konfigurierbar; Historie hängt an OP-AUDIT-1). - #172 — Detail-Fly-in workspace-übergreifend geteilt + auf der Aufträge-Fortschritts-Leiste verdrahtet (Folge zu #171, OP-R8-16): Die Komponente
gantt-task-panel.component.ts→auftrag-detail-panel.component.tsumbenannt (Selectorapp-auftrag-detail-panel, KlasseAuftragDetailPanelComponent) — sie ist kein Gantt-Widget mehr, sondern eine geteilte Auftrags-Detail-Fläche. Im Aufträge-Detail wird die Fortschritts-Leiste klickbar: Klick auf einen Schritt öffnet dasselbe rechts einschwebende Panel, fokussiert auf diesen Teilschritt (cyan-Ring), inkl. Aktions-Hub. Entscheidungen: (1) Umbenennen statt Wiederverwenden unter Gantt-Namen — „Selbsterklärbarkeit" (das Panel ist workspace-übergreifend;<app-gantt-task-panel>im Aufträge-Raum wäre irreführend); aktiv geteilte Komponente → keine ungefragte Fremd-Refaktorisierung. (2) Ein Signal (panelInstanzId) steuert Öffnen+Fokus; Panel bindetsel()(live) → schließt automatisch, wenn der Auftrag den aktiven Set verlässt. (3) Schritt-Dots werden echte<button>(Tastatur/A11y) mit Hover-Affordanz; das Inline-Detail bleibt, das Fly-in ergänzt fokussierte Schritt-Sicht + Hebel. Nur--tk-*-Tokens (No-Hex grün),ng builddev+prod grün. Reiner Client-Pfad, kein Server-/Solver-Change. Docs:COMPONENTS.md+WORKSPACES.md(Aufträge §4) + HANDOFF. - #171 — Gantt-Task Tooltip + Detail-Fly-in (OP-R8-16): Hover über einen Gantt-Block zeigt einen Schnell-Tooltip (Auftragsnr. · Schritt · Status · Zeit + Cool-down), der Termin-Konflikte hervorhebt (quantifizierter Verzug via
formatDauer, Wunsch- vs. geplante Zeit); Klick/Enter öffnet ein rechts einschwebendes Detail-Panel (client/.../gantt-task-panel.component.ts) mit vollen Details (Status-/Terminklasse-Badges, Konflikt-Banner + „Konflikt lösen →"/conflicts, Fakten-Grid Fertigstellung/Wunsch-Abholung/Reserve/Standort, alle Teilschritte mit Zeit/Bucht/MA — der angeklickte cyan hervorgehoben) plus einem Aktions-Hub (in-place Hebel): Lifecycle-Aktionen (erlaubteAktionen,starten→ Belegung für Bucht-Wahl), „✦ Vorziehen vorschlagen" (geplant → Vorschlag), „⏱ Verzögerung melden" (Inline-Preset-Picker +15 min … +4 h + Grund →meldeVerzoegerung— war bislang ohne UI im Service), „📍 Umparken" (globales Umpark-Modal), „Im Hofplan zeigen →". Entscheidungen: (1) Hover-Tooltip + Klick-Fly-in statt nur nativemtitle; dertitlebleibt alsaria-label, Block wirdrole=button/tabindex=0+ Enter (A11y). (2) Panel self-contained im Gantt (rendert<app-gantt-task-panel>, bindet den live-Auftrag → bleibt aktuell, schließt automatisch, wenn der Auftrag den Plan verlässt) statt Output an die Planungs-Seite. (3) Aktions-Hub statt read-only (auf Wunsch): „propose-not-execute" gewahrt — Plan-Änderungen nur als Vorschlag (Vorziehen) oder expliziter operativer Fakt (Verzögerung/Lifecycle/Umparken), jede Aktion quittiert per Toast; Aktionen spiegeln die kanonische Aufträge-Detail-Leiste + reaktivieren das verwaiste „Verzögerung melden". (4) Im Entwurfs-/Drag-Modus (✎ Plan ändern) unterdrückt — der Block ist dort nur Zieh-Griff; Touch zeigt keinen Hover (direkt Klick). (5) Slide-in via komponenten-lokalem@keyframes(translateX 100%→0,--tk-ease) über Fog-Scrim,prefers-reduced-motionrespektiert. Nur--tk-*-Tokens (No-Hex-Gate grün). Scope:app-ganttwird nur auf der Planung verwendet (kein Mini-Gantt im aktuellen Code) → Feature wirkt dort. Reiner Client-Pfad, kein Server-/Solver-Change;ng buildgrün. Docs:COMPONENTS.md+WORKSPACES.md+ HANDOFF-Gantt-Zeile + Timesheet (Session 7). - #170 — Helfer-Vorschlag: echte Verfügbarkeitsprüfung zur Schritt-Zeit (OP-R1-2 #6). Die Ausbildungs-Helfer-Vorschläge prüfen jetzt nicht mehr nur das Stammdatum (aktiv + nicht beschäftigt), sondern auch, ob der Auszubildende zum geplanten Schritt-Beginn tatsächlich verfügbar ist (Schicht aktiv + keine Abwesenheit) — über den bestehenden
mitarbeiterAvailability(D-2, nichts gespeichert).ausbildungsVorschlaegebekommt dafür einen optionalenverfuegbarBei(mitarbeiterId, start)-Callback (server-seitig verdrahtet);test:leistungum diesen Fall erweitert. Entscheidung: Prüfung am Schritt-Beginn (Näherung; Schicht-Wechsel mitten im Schritt wird nicht zerlegt) — bewusst einfach, Vorschlag bleibt unverbindlich. Reiner Server-Pfad, DTO unverändert → kein Client-Change, kein Solver-Redeploy. Weiter auf diesem Branch (OP-R1-2 + neue OP-R3-3): (1) Güteklassen-gewichtete XP — schwerere Fahrzeuge zählen mehr (Faktor 1/1,25/1,5 für Güteklasse 1/2/3);Leistungsnachweis.gueteklasse. (2) Anteilige Helfer-XP — ein Helfer-Einsatz, der unterbrochen wird oder verspätet beginnt, gibt nur anteilige Erfahrung (lernanteil; Verspätung mindert ab Toleranz proportional, Unterbrechung halbiert); produktive Einsätze unverändert. DafürTeilschrittInstanz.unterbrochen(beim Pausieren/Preempten gesetzt). (3) Niveau-Aufstieg-Vorschlag — genug produktive, fehlerarme Praxis (≥5 Ausführungen, niedrige Nacharbeit, hohe Bewertung) → Vorschlag „Skill-Niveau anheben" auf der Karte (niveauVorschlaege, Ein-Klick). (4) Neue OP-R3-3 — Unterbrechung/Übernahme in der Prozessdefinition:Teilschritt.unterbrechung+uebernahmejeerlaubt/vermeiden/verboten(§4.6 F15/F16);verboten-Unterbrechung wirkt hart auf die Preemption (istUnterbrechbar/unterbrechungsRegel), Katalog-DTO zeigt beide Regeln. Entscheidungen: XP-Parameter konfigurierbar (Güteklasse-Faktor, Verspätungs-Toleranz 15 min, Unterbrochen-Faktor 0,5) · proportionale Minderung nur für Helfer (Ausbildungswert) · Soft-Goalvermeidenim Optimierer + Übernahme-Enforcement + Prozess-Editor-UI geparkt als OP-R3-3 · Team-/Zeitraum-Vergleich bleibt offener OP-R1-2-Punkt.test:leistungum Anteil/Güteklasse/Niveau erweitert. Kein Solver-Redeploy. - #169 — Neuer geparkter OP OP-SEC-1: autorisierte Penetration-/Sicherheitstests vor produktivem Mehr-Mandanten-/Kunden-Betrieb (Auth/Mandanten-Isolation · Audit-Log-„nicht-reverse-engineerbar" · Assistenten-Berechtigung/Prompt-Injection · zahlungs-gesteuerter Zugang server-seitig · API/WS/DO · Solver · PII/DSGVO · Secrets/Supply-Chain · Client). Findings git-nah, automatisiert+manuell. Reine Doku.
- #168 — Wrap-up: Timesheet Session 5 (06-23, ~3.3 h; Σ ~59.5 h) — parallele Vorarbeit (#152–#158/#161) im Wall-Clock paralleler Sessions nicht doppelt gezählt (Untergrenze) — + HANDOFF §4 „Aktueller Stand" auf 06-23/#167 aktualisiert (Verweis auf CHANGELOG als chronologische Quelle). Reine Doku.
- #167 — Way-of-Working (
agents.md§7) geschärft: Branch laufend aufmainaktuell halten — zu Beginn (vor inhaltlichen Änderungen), in Abständen, vor PR und vor Merge. Entscheidung: früh + regelmäßig statt nur am Ende → Divergenz/Konflikte bleiben klein und lokal. Erweitert #166. Reine Doku. - #166 — Way-of-Working (
agents.md§7): Branch vor PR auf aktuellenmainaktualisieren (fetch + rebase/merge origin/main). Entscheidung: behebt die wiederholten „base branch was modified"/Merge-Konflikte durch parallele Merges — Konflikte entstehen lokal beim Autor statt im PR. Reine Doku. - #165 — Sequenzierung: SevDesk-Integration zurückgestellt (kommt später, nicht nächste Iteration) — damit auch der abhängige zahlungs-gesteuerte Zugang (OP-ACCESS-1). Entscheidungen aus #164 bleiben gültig, nur der Bau wartet. Reine Doku.
- #164 — Strategie-Session festgehalten (Markteintritt EU, reines B2B):
docs/Billing-Zugang.md+ OP-AUTH-1/2 erweitert + OP-BILLING-1 · OP-ACCESS-1 · OP-I18N-1. Entscheidungen: Rechnung+Mahnwesen = SevDesk (SoR, erfüllt DE-E-Rechnung XRechnung/ZUGFeRD); keine eigene Abo-Plattform (Stripe Billing/Clerk Billing/RevenueCat/MoR verworfen) · PSP optional · B2B-Reverse-Charge/VIES; Auth = Better Auth (self-host, EU-D1; Clerk/WorkOS Fallback); zahlungs-gesteuerter Zugang Stufenmodell Banner→eingeschränkt→gesperrt, server-seitig, fail-open, Admin-Override, Audit. Reine Doku. - #163 — Mitarbeiter-Leistung & Erfahrung + Ausbildung als Helfer-Leistung + QS-Mangelerfassung (OP-R1-2, OP-QS-1). Fakten-Modell: neuer Leistungsnachweis je Schritt-Ausführung (persistiert: Auftrag/Teilschritt/Skill, produktiv vs. Helfer, Vorgabe- vs. Ist-Dauer aus tatsächlichen Start/Ende-Stempeln) + Mangel am Auftrag (worauf bezogen = Teilschritt-Instanz → Skill + ausführende MA; Kategorie/Schwere/Beschreibung; Nacharbeit-Aufwand in min; §4.9.1). Abgeleitet (nie gespeichert, D-2): Mitarbeiter-Statistik je Teilschritt/Skill (Anzahl, Helfer-Anteil, Dauer min/avg/median/max, Ø-Abweichung von der Vorgabe, Nacharbeit-Quote + Ø-Aufwand, Bewertung 0–100) + Erfahrungspunkte. Ausbildung: Helfer/Auszubildende je Schritt (
helferIds) — reduzieren die Zeit NICHT (rein operativ, nicht im Solver), sammeln beim Abschluss aber Erfahrung. UI: Mitarbeiter-Karte zeigt ⚡ XP + aufklappbare Statistik; Aufträge-Detail weist Helfer je Schritt zu; QS erfasst Mängel (Bezug + Aufwand) statt nur Client-Marker. Reines Moduloperativ/leistung.ts+ Self-Testtest:leistung(CI). Entscheidungen: Leistungsnachweise/Mängel = gespeicherte Fakten, Statistik/XP immer abgeleitet (CLAUDE.md „Derived State nie speichern") · Helfer ohne Scheduling-Effekt (Ausbildung ≠ Kapazität) · produktive Zuteilung gewinnt über Helfer (kein Doppel-Nachweis) · XP konfigurierbar (produktiv 10 / Helfer 5 / im-Plan +2 / Nacharbeit-Malus 6×Schwere) · Mangel-Kategorien v1 als feste Liste (G-1: künftig admin-editierbar) · Demo-Leistungshistorie nur, wenn leer (sofort sichtbare Karte). Kein Solver-Redeploy. Nachtrag (gleicher Branch): Ausbildungsziele je Mitarbeiter (Mitarbeiter.ausbildungsZiele, Editor in der Karte) → abgeleitete Helfer-Vorschläge (ausbildungsVorschlaege): freie/verfügbare Auszubildende werden auf passende offene Schritte mit dem Ziel-Skill als Helfer vorgeschlagen (Karte „+ Helfer" Ein-Klick · 🎓-Markierung in der Auftrags-Helferauswahl). Penaltyfreies Abziehen (G-2-Ausnahme): Helfer-/Ausbildungs-Tätigkeit ist kein produktiver Kontext → jederzeitiges Abziehen für echte Aufträge ohne Wechsel-Pönale (dokumentiert in §6.4.1 + G-2; Helfer sind nicht im Solver). Seed: Marco→Keramik, Tom→Vollfolierung als Demo-Ziele. Self-Testtest:leistungum die Vorschlags-Logik erweitert. - #162 — Doku-Nachtrag + neue OP: OP-REPORT-1 (tägliche Management-Zusammenfassung DE in zwei Fassungen — nicht-technisch + technisch — per Mail + WhatsApp; geparkt mit offenen Designfragen, u. a. WhatsApp-„Status" nicht via offizieller API) · CHANGELOG-Eintrag für #160 nachgetragen · Timesheet Session 3 (~1.3 h aktiv, Leerlauf exkl.; Σ ~55.0 h). Reine Doku.
- #160 — Mitarbeiter- & Skills-CRUD + Modell-Zusammenführung (OP-R1-1, Phasen A–E + Schicht-/Abwesenheits-Editor):
Mitarbeiterwird kanonische Single Source für UI und Solver (persistiert statt Seed;schedulerInput()); Karten viatoEmployeeDTOabgeleitet,currentTask/recommendationtransient. Voller CRUD: Identität, Abteilung + Freitext-Rolle, editierbare Verfügbarkeit→abgeleiteter Status, Skill-Qualifikationsmatrix (skillId+Niveau), Skill-Katalog (G-1 Soft-Deaktivieren), Schicht-Zuweisung + Abwesenheits-Editor. Self-Testtest:eligibility(CI) + live verifiziert (Skill-Edit kippt Auftrags-Feasibility). Entscheidungen: Mitarbeiter kanonisch, Karten abgeleitet (die zwei Demo-Datensätze waren disjunkt) · Abteilung-Taxonomie + Freitext-Rolle · Verfügbarkeit editieren, „Frei"/„Aktiv" ableiten · Phase C fokussiert (Schichten/Abwesenheiten als Folge-Slice, jetzt enthalten). Reiner Server-/Client-Pfad, kein Solver-Redeploy. Merge-Konflikte mit der parallel gemergten Insights-Arbeit (#157) aufgelöst (mitarbeiterGesamtauf persistierten State umgestellt).
2026-06-22
- #159 — Light/Dark-Mode (OP-R9-9): Cockpit jederzeit zwischen Hell/Dunkel/System umschaltbar. Zweites Token-Set (Light) wird aus
tokens.jsongeneriert (Hell-Wert je theme-abhängigem Token unter$extensions.taktano.light;build.mjs→:root[data-theme="light"]+@media (prefers-color-scheme: light)für „System").ThemeService(Signalmode,isLight/isDark) setztdata-themeam<html>, persistiert je Gerät (localStorage), folgt bei „System" live der OS-Wahl; No-Flash-Inline-Skript inindex.html; Toggle im Sidebar-Fuß (Ein-Klick-Zyklus System→Hell→Dunkel). Entscheidungen: Tokens bleiben einzige Farbquelle → Light als generierter Override statt zweiter Hand-Palette; Defaultsystem; Komponenten-Restetext-white/bg-white/x→ Tokens (text-tk-heading/bg-tk-soft/hover:bg-tk-hover), damit sie mitschalten; Gantt über vorhandenen[dark]-Pfad antheme.isDark()gebunden; Token-Staleness-Check block-bewusst (Dark- und Light-Wert getrennt geprüft). Folgepunkte OP-DESIGN-2 (A11y-Kontrast Hellmodus) + OP-DESIGN-3 (Gantt-Light auf--tk-*). - #158 — Icon-Rail leichter verständlich (OP-R9-12): klappt bei Maus-Nähe/Tastatur-Fokus auf und zeigt Labels neben allen Icons; Workspaces in Cluster gruppiert (Überblick·Operativ·Steuerung·Qualität). Entscheidung: Overlay statt Push (kein Reflow); ein Aufklapp-Reveal ersetzt die per-Icon-Tooltips. (Ersetzt das beim Stack-Merge versehentlich geschlossene #154 — gleicher Inhalt/Branch.)
- #157 — In-App-Assistent (OP-AI-4) Slices 1–3 + Way-of-Working. Assistent: erweitert die Chatbot-Idee (OP-DOCS-2) zu drei Säulen — Doku-Q&A · App-Feedback · Insights (True-North-nah); gebaut: Insights-Engine (read-only) → DO-Broadcast → Angular-Panel „Lage auf einen Blick". Way-of-Working: Branch nach Merge löschen (
agents.md§7/CLAUDE.md) + Doku-Pflicht (HANDOFF/Timesheet) je PR. Entscheidung: Assistent ist vorschlagend, nicht ausführend (simuliert Konsequenzen, führt nicht aus). - #156 — 30-s-Solver-Status-Ping bricht eine laufende Optimierung nicht mehr ab: neuer server-seitiger
rechenStempel(+1 nur bei echten Läufen), der Client beendet „Optimierung läuft…" erst bei dessen Vorrücken (Routine-Broadcasts lassen ihn unverändert). Entscheidung: Ursache behoben statt den Ping leiser zu machen → fixt die ganze Klasse (Ping · onConnect · Mehrbenutzer);test:optimizingin CI. - #155 — „Plan ändern"-Fokus-Modus (OP-R8-15): im Entwurfs-Modus liegt ein Nebel über den übrigen Bedienelementen (fängt Klicks ab = deaktiviert), die relevanten (Toggle·Entwurf·Gantt) bleiben darüber; Klick auf den Nebel/Escape beendet — bei offenen Pins mit Rückfrage „Entwurf verwerfen?". Entscheidung: region-basierter Scrim statt per-Button-disabled (robust + Nebel + Außerhalb-Klick in einem); Rückfrage nur bei offenen Pins.
- #153 — Audit-Trail etabliert:
CHANGELOG.md(je-PR-Eintrag, Backfill #122–#151) + Audit-Trail als Repo-Prinzip (CLAUDE.md/agents.md) + OP-R9-12 (Sidebar verständlicher) & OP-R8-15 („Plan ändern"-Fokus-Modus) festgehalten. Entscheidung: Changelog je PR (nicht je Commit); ältere Stände bleiben in HANDOFF/Git, ab hier je PR; die zwei UX-OPs nur dokumentiert, nicht gebaut (Optionen zuerst). - #152 — Konflikt-Navigation auf der Planung (OP-R8-14 Slice 1): Toolbar-Chip „⚡ N Konflikte" zeigt, dass es Konflikte gibt, und springt per Klick zum nächsten ⚡ im Gantt (scrollt hin + hebt kurz hervor). Entscheidung: Sprung-Reihenfolge nach Gantt-Position (links→rechts), eine Stelle je Auftrag; der Konflikte-Workspace bleibt die systematische Triage (Slice 1 = nur sichtbar/anspringbar).
- #151 — OP-R8-14 festgehalten (Konflikte auf der Planung: auffindbar · springen · in-place lösen). Entscheidung: Hybrid — in-place lösen am ⚡-Balken, der Konflikte-Raum bleibt die systematische Triage-Queue (nicht auflösen).
- #150 — Docusaurus-Build-Log aufgeräumt:
onBrokenMarkdownLinks→markdown.hooks, Search-docsDirgesetzt, 1 broken link/anchor gefixt. Entscheidung:onBrokenLinks/onBrokenAnchorsbleibenwarn(echte Brüche weiter melden). - #149 — OpenTelemetry-Logging als Prinzip (CLAUDE.md/agents.md) + OP-OBS-1. Entscheidung: Logs via OTel-SDK je Laufzeit, kein rohes
console.log/printim Produktivpfad (CLI-Demos/Tests ausgenommen). - #148 — CP-SAT-Status aktualisiert sich automatisch (30-s-
/health-Ping + onConnect) + „· vor X s"-Stempel. Behebt den zwischen Optimierungen festhängenden Hinweis. - #147 — Docs-Deploy triggert jetzt auch bei
docs/**(die Haupt-Docs werden gerendert, waren aber nicht im Trigger → Timesheet-Push deployte die Site nicht neu). - #146 — Szenario-Konvergenz geprüft (kein Bug — identische Profile = eindeutiges Optimum bei knappen Ressourcen) + Banner „Alle Profile ergeben denselben Plan" + Tests (
plaeneIdentisch,profile-distinct). Entscheidung: Vergleich auf echter Zuweisung, nicht gerundeten Zahlen. - #145 — Timesheet: Session 1 (06-22) abgeschlossen, ~11.8 h.
- #144 — CP-SAT: Folierbucht-als-Überlauf-Parkplatz (OP-OPT-5 Slice 2) — Park-Intervalle teilen die Bucht-No-Overlap. Bewusst offen: Präferenz „dedizierte vor Überlauf" als Pönale.
- #143 — CP-SAT: Indoor-Trocknung-Pflicht (F07a, OP-OPT-5 Slice 1) —
allowedBays-Verengung, Parität zum TS-Scheduler. - #142 — OP-OPT-4 festgehalten: neuer Auftrag joint-optimal einlasten (Default-Strategie konfigurierbar).
- #141 — 3. Zielprofil „Termintreue" (OP-OPT-1 P5): minimiert die Anzahl gerissener Termine. Entscheidung: zählt gegen den Wunsch-Abholtermin (
ziel); garantiert ist schon hart. - #140 — Pin-Konflikt-Feedback korrigiert (OP-R8-13): kein falscher „Erfolg" mehr; gestempelter
pinErgebnis-Kanal stattsolverInfo. - #139 — Solver-Version/Build-Zeit + Fallback-Anzeige im Cockpit (OP-DEPLOY-2).
- #138 — Solver-Auto-Deploy auf Fly.io (OP-DEPLOY-1). Entscheidung: strikt, fehlt
FLY_API_TOKEN→ expliziter Guard bricht rot ab (kein stiller Skip). - #137 — Gantt-Ausfallzeiten markiert (Pause/Geschlossen/Krank/Urlaub/Wartung), abgeleitet, nichts gespeichert.
- #136 — CI-Action-Versionen auf Node-24-Majors (Node-20-Deprecation behoben).
- #135 — App-CD live + Token verifiziert (HANDOFF-Korrektur).
- #134 — App-Worker-Deploy bei push-to-main (CD).
- #133 — Entscheidung: Doku-Plattform = Docusaurus statt GitBook (mit Re-Eval-Triggern) + OP-DOCS-7.
- #132 — Doku-Footer-SHA aus
github.sha(robuster Build). - #131 — Doku-Deploy strikt: Build/Deploy-Fehler bricht die Action ab.
- #130 — Version + Build-Zeit im Doku-Footer (OP-DOCS-6).
- #129 — Doku-Auto-Deploy + OP-DOCS-2..5 geparkt (Chatbot/MCP/Anwender-Doku/Login-Sichtbarkeit).
- #128 — Gantt-Drag-UI (3b-2b): Direktverschiebung per Drag → Pin.
- #127 — Timesheet in den Doku-Index aufgenommen.
- #126 — OPs geparkt (STANDORT-2 · R9-11 · KIOSK-1) + R9-10 ergänzt.
- #125 — Pin-Vorschlag + Orchestrierung (3b-2a).
- #124 — Pin-Constraint im Solver-Backend (3b-1); mehrere Pins pro Durchgang.
- #123 — Timesheet (Repo-Spiegel) + Way-of-Working in
agents.md. - #122 — Zahlen-/Dauer-Konsistenz (Slice A): Dauer in W+T+h+min, Singular/Plural automatisch, Termin-Überzug.
Ältere Stände (vor 06-22) sind in
HANDOFF.md§2/§4 und der Git-History dokumentiert; der Changelog wird ab hier je PR weitergeführt.