Operative Durchgängigkeit & Werker-Sicht (OP-UX-1)
Status: gebaut — OP-UX-1 (U1–U7, ✅ Stand 06-28; U9 ✅ v0.58.0) · OP-UX-2 (U8 Klärfälle-Workspace) · OP-UX-3 (Nacharbeit live im Gantt) · OP-QS-GATE · OP-QS-4/-5 (✅ v0.46.0); E-UX-1…3 entschieden · Bezug: OP-UX-1 (Owning-OP) · OP-UX-2/-3 · OP-QS-GATE · OP-QS-4/-5 · Zielgruppe: IT-Dev/Architektur (Slices + Datenfluss) · Anwender · Business/Management (§2 „warum das den Alltag trägt") · True North: direkt — die durchgängige Auftragszeile (U1) ist die direkteste Antwort auf Frage 2 (Wo stehen die Fahrzeuge?); §2 belegt den Bezug zu allen drei Leitfragen.
Kernaussage. Den operativen Flow — „ein Auto kommt, was passiert dann?" — durchgängig und intuitiv machen. Der Flow-Audit (06-27) ergab: das Cockpit ist auf hohem Niveau, aber der Alltag bricht an drei Stellen — es fehlt eine durchgängige Auftragszeile (Status · Mitarbeiter · Bucht · Standort · Fortschritt verteilt auf vier Seiten), eine Werker-Sicht (der Mitarbeiter sieht „seine" Schritte nicht) und eine echte Annahme-Maske (Auftrag anlegen geht heute nur per Demo-Button). Dieses Dokument zurrt die Politik fest und schneidet die Umsetzung in Slices — inzwischen gebaut (s. Status): der Flow ist von der Vordertür (Annahme) über Tafel + Meine Arbeit bis zur Abholung durchgängig.
1. Ausgangsbefund & Lösungsschnitt (Flow-Audit 06-27)
Die folgende Problem-Analyse beschreibt den Ausgangsbefund (Flow-Audit 06-27).
- Taktano war ein exzellentes Leitstand-Cockpit mit fehlender Vordertür und ohne Hand-Sicht. Die Steuerung eines bereits erfassten Auftrags war nahe am Meisterwerk; die Erfassung selbst und die Werker-Bedienung fehlten (jetzt geschlossen, s. o.).
- Drei Lücken, drei Slices (Priorität in dieser Reihenfolge):
- U1 — Durchgängige Auftragszeile („Werkstatt-Tafel"). Eine Zeile je Auftrag mit allen Alltags-Fakten auf einen Blick: Auftragsnummer · Status · fachliche Phase · aktueller Schritt · wer · welche Bucht · Standort · Fortschritt · Reserve · Warn-Flags. Heute sind diese Fakten über Aufträge · Planung-Gantt · Belegung verstreut.
- U2 — Werker-/Mitarbeiter-Sicht. Ein Mitarbeiter sieht „meine Schritte", startet/pausiert selbst, dokumentiert (Kommentar/Foto) — heute ist alles eine Leitstand-Sicht, keine Hand-Sicht.
- U3 — Annahme-Maske. Auftrag regulär anlegen (Kunde · Leistung · Güteklasse · Wunschtermin);
der Server-Handler
auftrag.createexistiert bereits — es fehlt nur die UI.
- Kein neues Datenmodell, keine Solver-Änderung für U1. Die Auftragszeile ist eine reine
Projektion des Live-States (
AuftragDTO+RessourcenDTO) — Derived-State-Prinzip (S-2), nichts wird zusätzlich gespeichert. U2/U3 brauchen UI + bestehende Handler, kein neues Schema.
2. Warum das den Alltag trägt (True-North-Bezug)
Jedes Feature muss ≥1 der drei True-North-Fragen direkter/schneller/genauer beantworten:
| Frage | Heute | Mit OP-UX-1 |
|---|---|---|
| Wo stehen die Fahrzeuge? (physisch und in Bearbeitung) | Standort in Belegung, Bearbeitungs-Status in Aufträge, Mitarbeiter nur im Detail-Panel → drei Seiten | Eine Zeile zeigt Standort + aktueller Schritt + Mitarbeiter + Bucht (U1) |
| Wie hoch ist die Auslastung? | Cockpit-KPIs (gut) | Tafel zeigt die laufende Belegung pro Auftrag in Kontext (U1) |
| Wann sind die nächsten freien Kapazitäten? | nur indirekt | U2 macht die Auslastung pro Werker greifbar (Folge-Slice) |
Die durchgängige Auftragszeile ist damit die direkteste Antwort auf True-North-Frage 2 — sie verdient ihren Platz.
3. Befund aus dem Flow-Audit (06-27)
Walkthrough „ein Auto kommt": geplant → angeliefert → in_arbeit ⇄ pausiert → fertiggestellt → abgeschlossen → (kontrolliert) → archiviert. Stärken und Reibungen, mit Belegstellen:
Stärken (bleiben unangetastet):
- Gantt (
gantt.component.ts) — Zoom-Presets, Heatmap, Ausfall-Schraffur, Bottleneck-Puls, Konflikt-Marker. Hohe Dichte, lesbar. - Doku-/Foto-Pflicht-Gate (OP-R4-3,
auftrag-detail-panel.component.ts) — „✓ Fertig" bleibt gesperrt bis Kommentar + Pflicht-Fotos da; Server validiert doppelt. - Farb-Semantik konsistent (Rot=Warnung, Grün=bestanden, Blau=aktiv, Amber=Achtung),
Mono-Font für alle Daten, ARIA +
prefers-reduced-motion.
Reibungen → die drei Slices:
- U1: Status in
orders.component.ts, Mitarbeiter nur im Detail-Panel (auftrag-detail-panel.component.ts), Bucht nur im Gantt-Zeilenlabel, Standort nur inoccupancy.component.ts. Für „wer macht gerade was, wo?" ⇒ drei Seiten öffnen. - U2: Keine Werker-Sicht — der Mitarbeiter kann nicht sehen „das sind meine Schritte". Das ganze System ist Leitstand, nicht Hand.
- U3: Auftrag anlegen nur über Demo-Buttons (
planning.component.ts, „Testdaten"-Schalter); der reale Server-Handlerauftrag.create(server/party/leitstand.ts) wird von keiner UI gefüttert.
Kleinere Reibungen (Backlog): inkonsistente Leere-Zustände (✅ app-empty-state) ·
zwei rote Warnsysteme (Klärfall ⚠ ≠ Termin-Konflikt ⚡) (✅ entwirrt, U7) · Nacharbeit nach
QS-Mangel nicht live im Gantt (✅ OP-UX-3) · Administration-Seite zu technisch für Werkstatt-Rollen ·
kein Onboarding/Tour.
4. Slices
U1 — Durchgängige Auftragszeile / „Werkstatt-Tafel" (dieser PR, Start)
- Neuer Workspace „Tafel" (Cluster Überblick, Signaturfarbe
--tk-ws-tafel, Glyph▤). - Eine Zeile je aktivem Auftrag, rein abgeleitet (keine Persistenz, S-2):
Auftragsnummer (★ Güteklasse) · Status-Pill · Phase-Pill · aktueller Schritt (in_arbeit, sonst
nächster geplanter) mit Mitarbeiter-Namen + Bucht-Name · 📍 Standort · Fortschritt
(erledigt/gesamt + Balken) · Reserve · Warn-Flags (
⚠ Zuweisung nötig,⏱ verzögert,⚡ überfällig,⚠ Klärfall). - Sortierung nach operativer Dringlichkeit (in_arbeit → angeliefert → pausiert → geplant →
fertig); Klick auf die Zeile öffnet das geteilte Detail-Panel (
auftrag-detail-panel). - Quelle:
aktiveAuftraege()+ressourcen()+employees()— alles vorhanden. - ✅ in diesem PR.
U2 — Werker-/Mitarbeiter-Sicht „Meine Arbeit" (✅ gebaut)
- Eigener Workspace „Meine Arbeit" (Cluster Operativ, Signaturfarbe
--tk-ws-werker, Glyph ⬣, Route/meine-arbeit). - Schichtterminal-Picker oben (Mitarbeiter wählen — kein Per-Mitarbeiter-Login nötig;
R1-QR/Login ist Future) → darunter nur seine offenen/laufenden Schritte über alle aktiven
Aufträge (produktiv aus
mitarbeiterIds, zusätzlich als 🎓 Helfer aushelferIds), laufend zuerst sortiert, Badge mit Offen-Anzahl je Person. - Große, touch-taugliche Aktionen je Schritt: ⏸ Pause / ▶ Weiter (kein Gate, direkt über
teilschrittAktion) und ✓ Fertig. Braucht der Abschluss Doku/Foto (OP-R4-3), führt „Fertig" ins geteilte Detail-Panel (dort lebt das Gate + Foto-Upload — kein zweites Gate); sonst wird direkt erledigt. Inline-Hinweis nennt, was zum Abschluss fehlt. - Reine Projektion des Live-States (kein neues Schema, keine Server-/Solver-Änderung).
- ✅ gebaut.
U3 — Annahme / „Auto kommt → Auftrag anlegen" (✅ gebaut)
- Eigener Workspace „Annahme" (Cluster Operativ, erster Eintrag = Start des Flows,
Signaturfarbe
--tk-ws-annahme, Glyph ⊕, Route/annahme). - Ein Formular (Single-Modal-Geist, S-1): Kunde (Name + CRM-Link, R5-v1) · Leistung (Picker
aus dem aktiven Prozess-Katalog) · Güteklasse + Anspruch · Anlieferung +
Wunsch-Abholung (datetime-local, UTC) · Termin-Härte → bestehender
auftrag.create-Handler. Der Server prüft Machbarkeit (Angebotsmodus) und legt nur einen machbaren Auftrag an; der erscheint live in Tafel + Aufträge. - Kunde v1 neu im Modell (war dokumentiert, aber nicht gebaut):
Auftrag.kunde = { name, crmLink? }(R5-v1 = nur Name + CRM-Link am Auftrag; Voll-Modell = FR-1). Optionales Feld, keine Migration nötig. - ✅ gebaut.
U3b — Machbarkeits-Rückmeldung der Annahme (✅ gebaut)
auftrag.createantwortet jetzt der anlegenden Verbindung (neueServerMsg-Varianteauftrag.create.result) — vorher fire-and-forget (bei nicht machbarem Plan kein Feedback).- Abgelehnt (
ok:false) mit konkretem Grund aus dem fehlgeschlagenen Schritt (ScheduleResult.reason, z. B. kein qualifizierter Mitarbeiter/keine passende Bucht für die Güteklasse) bzw. „Abholung muss nach Anlieferung liegen" / „ungültige Zeitangaben". - Angenommen (
ok:true) mit Auftragsnummer; Termin-Warnung, wenn der Auftrag planbar ist, aber frühestens nach der Wunsch-Abholung fertig wird (earliest.abholbereit > abholtermin). - Client:
LeitstandService.auftragCreateResult-Signal → der Annahme-Workspace zeigt einen Spinner („prüft …"), bei Erfolg Toast + Formular-Reset (+ ggf. Termin-Warn-Toast), bei Ablehnung den Grund inline + Toast (Formular bleibt zum Korrigieren stehen). 8-s-Sicherheitsnetz gegen hängenden Spinner.
U4 — Vorschau mit Preis & Reserve + „Wirklich anlegen?"-Bestätigung (✅ gebaut)
- Weil bei der Annahme ein kostenpflichtiger Auftrag entsteht, ist „annehmen" jetzt zweistufig:
„Prüfen & anlegen" ruft erst die neue Dry-Run-Message
auftrag.pruefen(Antwortauftrag.pruefen.result, Muster wie U3b) → läuftangebot()(TS-Scheduler), leitet Machbarkeit, Reserve (floor((abholtermin − earliest.completion)/1440)) und Preis ab — ohne anzulegen. - Bei Machbarkeit öffnet ein Bestätigungs-Dialog (Kunde · Leistung · Termine · Reserve grün/rot ·
Preis · ggf. Termin-Warnung) mit „Abbrechen" / „✓ Wirklich anlegen (kostenpflichtig)"; erst die
Bestätigung ruft
auftrag.create. Nicht machbar → Grund inline (kein Dialog). - Preismodell (OP-R7-6, erster Schnitt):
Leistung.grundpreisCent(Seed + Picker zeigt „ab X €"), pure Summen-FunktionauftragspreisCent(server/src/operativ/preis.ts, Self-Testtest:preis), Preis-SnapshotAuftrag.preisCentbei Anlage. Güteklasse-/Anspruch-Zuschläge bleiben OP-R7-6-Folge (dokumentiert). - Solver-Frage beantwortet: die Annahme-Prüfung läuft den TS-Scheduler (
angebot, synchron im DO) — schnelle Einzelauftrags-Machbarkeit; der CP-SAT macht die globale Mehrauftrags-Optimierung (separat). U6 stößt nach Anlage zusätzlich eine globale CP-SAT-Reopt an.
U5 — „Zuletzt angenommen"-Panel + Kunde/CRM nachtragen (✅ gebaut)
- Der Annahme-Workspace ist jetzt zweispaltig (
grid lg:grid-cols-[minmax(0,1fr)_340px], stapelt mobil): links das Formular, rechts ein „Zuletzt angenommen"-Panel mit den letzten ~6 aktiven Aufträgen, neueste zuerst (sortiert über die Anlage-Reihenfolge aus der idAU-<seq>— es gibt keincreatedAt). - Je Zeile Auftragsnummer · Status · Kunde; Inline-„✎ nachtragen" editiert Kunde-Name + CRM-Link
→ neue Server-Message
auftrag.update({ id, kunde }) — ändert nur die R5-v1-Kunde-Felder eines bestehenden Auftrags (Name bleibt Pflicht), schreibt ein Audit-Event (auftrag.aktualisiert, OP-AUDIT-1) + Chronik-Eintrag und broadcastet. Kein Leistung-/Termine-Edit (bewusst eng gehalten).
U6 — Reopt bei Annahme (✅ gebaut)
auftrag.createist jetzt einREOPT_EVENT: nach erfolgreichem Anlegen läuft — wie bei den Lifecycle-Eventsliefern/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, CP-SAT-Global-Reopt nach Anlage (als Vorschlag).
U7 — Zwei rote Warnsysteme entwirrt (Störung-Achse ⚠ vs. Termin-Achse) (✅ gebaut)
- Befund (Flow-Audit, §3-Backlog): Auf der Werkstatt-Tafel kollidierten zwei rote Signale mit
gleicher Optik (
var(--tk-red)/danger-bg), obwohl sie Verschiedenes meinen — eine Zeile konnte−3T über(rote Reserve-Pille) und⚡ überfällig(rotes Flag) und⚠ Klärfall(rotes Flag) zeigen: drei rote Pillen, zwei davon für dieselbe Termin-Bedingung. - Entwirrt in zwei klar getrennte Achsen:
- Störung-Achse — Klärfall ⚠ (rot): das einzige rote Flag; bedeutet „Prozess-Störung, Mensch muss eingreifen" (von Hand gesetzt/gelöst, zeit-unabhängig, OP-R3-1).
- Termin-Achse — Reserve-/Verzug-Pille mit Schweregrad: Puffer/Verzug quantifiziert (
+2T Reserve…−5T über) statt als zweites rotes Icon. Farbe nach Schweregrad statt binär:≥0grün ·−1…−3 Tamber (Achtung) ·≤−4 T**rot (Warnung). Die 4-Tage-Schwelle spiegelt die **Konflikte-Triage** (conflicts.component`) → eine Termin-Logik über beide Sichten.
- Effekt: Das redundante
⚡ überfällig-Flag auf der Tafel entfällt (die Reserve-Pille trägt die Termin-Achse, mit Zahl). Rot auf einer Zeile heißt jetzt entweder Klärfall (Eingriff) oder ein ernster Terminverzug (≤−4 T) — nicht mehr jeder kleine Verzug. Achse-Doku als Pattern indesign/COMPONENTS.md(„Warn-Achsen"). Design-Regel gewahrt: Amber = Achtung, Rot = Warnung. - Folge-Idee → umgesetzt als OP-UX-2 (U8): die symmetrische Klärfall-Sicht/-Zähler (Störung-Achse) ist gebaut — siehe unten.
U9 — Termin-Vorschlag (frühestmögliche Abholung) + Sonderwünsche in der Annahme (✅ gebaut, v0.58.0)
- Termin-Vorschlag (Nutzer-Wunsch 07-03): Die Annahme bietet den frühestmöglichen Abholtermin
basierend auf der gewählten Leistung direkt an — statt dass der Erfasser einen Wunschtermin rät und
erst beim Prüfen erfährt, ob er machbar ist. Sobald Leistung (+ Anlieferung/Güteklasse) feststeht,
fragt das Formular entprellt den neuen Dry-Run
auftrag.terminvorschlagan ({ leistungId, anlieferung, gueteklasse }; ohne Anlieferung rechnet der Client ab „jetzt"); der Server antwortet der Verbindung mitauftrag.terminvorschlag.result=fruehesteAbholungausscheduleLeistung(...).abholbereit(TS-Scheduler, inkl. Standzeit — dieselbe Größe, an der auchauftrag.create/pruefendie Wunschtermin-Warnung messen) bzw. dem konkreten Nicht-machbar-Grund. Kein State-Change/Broadcast (wieauftrag.pruefen, kein Reopt). - Direkt angeboten: ein leeres (oder zuvor automatisch befülltes) Wunsch-Abholung-Feld wird mit dem Vorschlag sofort vorbefüllt; ein von Hand gesetzter Termin bleibt unangetastet — dann zeigt eine Zeile unter dem Feld „Frühestmöglich: …" mit „Übernehmen". Nicht machbar ⇒ dezenter Amber-Hinweis mit Grund (das harte Gate bleibt der Prüfen-Schritt).
- Sonderwünsche (R7-F10, Nutzer-Wunsch 07-03): neues optionales Freitext-Feld im Annahme-Formular →
auftrag.create.sonderwuensche→Auftrag.sonderwuensche(additiv, keine Migration) → sichtbar im Bestätigungs-Dialog und im Aufträge-Detail (Fakten-Grid, volle Breite). Abgrenzung: Freitext am Auftrag — 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.
OP-UX-2 — Klärfälle-Workspace (Störung-Achse bekommt Sicht + Zähler) (✅ gebaut)
U8 — Klärfälle-Workspace
- Warum: U7 entwirrte die zwei roten Warn-Achsen. Die Termin-Achse hatte mit dem
Konflikte-Workspace (
/conflicts) + Nav-Badge bereits ein Zuhause; die Störung-Achse (Klärfall) erschien nur inline (Tafel-Flag, Detail-Panel-Badge) — keine Sammelsicht, kein Zähler. Diese Asymmetrie ist jetzt geschlossen: jede Achse hat Liste + Badge. - Neuer Workspace „Klärfälle" (Cluster Steuerung, direkt nach Konflikte; Signaturfarbe
--tk-ws-klaerfaelle= Amber/Gold#f59e0b, Glyph ⚠, Route/klaerfaelle). Rot bleibt der Termin-Achse (Konflikte) vorbehalten — die Workspace-Identität der Störung-Achse ist amber/gold, die inline-Klärfall-Pille bleibt rot (OP-R3-1). - Inhalt (reine Projektion, kein Schema/Server): alle Aufträge mit aktivem
klaerfall(svc.klaerfaelle()), Dringlichkeits-sortiert — eskaliert zuerst, dann am längsten ungeklärt (kleinstesklaerfall.seit) zuerst. Je Zeile: Auftragsnummer · ★ Güteklasse ·⚠ eskaliert-Pille (wenn eskaliert) · Grund · „seit … · X offen". Klick öffnet das geteilteauftrag-detail-panel— dort lebt das geroutete „✓ Klärfall lösen …" (nichts dupliziert). - Zähler:
svc.klaerfaelleCount()als Nav-Badge (analogkonflikteCount). - Lösen (seit v0.74.0, OP-R3-1-Folge „Klärungs-Engine"): geroutet über das geteilte
Formular
app-klaerfall-loesen(auftrag.klaerfall {loesen, route, kommentar, ziel…}) — Routenzurueck·qs(Klärungs-Skip offener Nicht-QS-Schritte) ·schritt(ab-hier-weiter oder Katalog-Einschub via zusatzSchritt/Einzelplan) ·abbruch(Storno); Lösungs-Kommentar Pflicht, Chronik + D1-Audit (klaerfall.gemeldet/klaerfall.geloest), Reopt-Trigger. Das Melden pausiert laufende Schritte (echte Unterbrechung, §5.1) und erfasst den auslösenden Schritt (klaerfall.teilschrittInstanzId, aus „Meine Arbeit" mitgesendet). Melden geschieht weiter kontextuell aus Detail-Panel/„Meine Arbeit". Kapazitätstragende Klärung (v0.75.0): „⏱ Klärung einplanen" (geteiltesapp-klaerung-einplanen, Presets 15/30/60 min →auftrag.klaerungEinplanen) plant die Klärungsarbeit als echten Schritt (Katalog-Templatets-klaerung, Skill „Klärung", Migration v19) — Klärzeit zählt als Auslastung, max. eine offene Klärung je Klärfall, Auditklaerung.eingeplant. Pattern indesign/COMPONENTS.md(„Warn-Achsen": beide Achsen haben Liste + Badge), Screen indesign/WORKSPACES.md.
OP-UX-3 — Nacharbeit nach QS-Mangel live im Gantt (✅ gebaut)
Problem (Flow-Audit-Backlog): Ein in der Endkontrolle erfasster Mangel mit Behebungs-Aufwand
(nacharbeitAufwandMin) war nur eine Kennzahl — kein geplanter Schritt: keine Kapazität, kein
Gantt-Block, keine Verschiebung von geplanteFertigstellung/Reserve. Das Cockpit beantwortete
Auslastung & „wann fertig/frei?" falsch, solange Nacharbeit ausstand.
Lösung — Nacharbeit als echter, voll solver-integrierter Schritt:
- Auslösung (Sign-off „erst bestätigen"): Mangel wird wie bisher erfasst; in der Qualität-Sicht
öffnet ein expliziter Button „⚠ Nacharbeit einplanen" (sichtbar bei offenen Aufwands-Mängeln) die
neue Aktion
auftrag.nacharbeitEinplanen. - Server: pro offenem Aufwands-Mangel eine Nacharbeits-
TeilschrittInstanz(status:'geplant',nacharbeitMin = Aufwand,teilschrittId= betroffener Schritt → Skill/Bucht-Typ). Auftrag geht über die neue Transitionnacharbeiten: fertiggestellt → angeliefertzurück in die Planung; ein Einzel-Plan wird sofort gerechnet (konkrete Bucht/Zeit/Crew → live im Gantt), die globale CP-SAT-Reopt (REOPT_EVENTS) schiebt Optimierungen als Vorschlag nach. Auditnacharbeit.eingeplant. - Scheduler-Kern (Sign-off „voll solver-integriert"): dynamische
zusatzSchritteimAuftragInputwerden inscheduleLeistung(TS) undbuildProblem(CP-SAT) nach dem Skip-Filter an den statischenLeistung.prozessangehängt (Wiederverwendung vondauerOverrideMin+abhaengigkeit);applyPlanungbleibt index-stabil (nach Reopen sind die statischen Schritte erledigt/geskippt → einziger planbarer Schritt ist die Nacharbeit). - Besetzung (Sign-off „Solver wählt frei"): Skill + Dauer fix (vom Mangel-Schritt), Bucht +
Mitarbeiter optimal vom Solver. Reserve/Konflikt aktualisieren sich automatisch über
geplanteFertigstellung(kein Client-Extra). Self-Testtest:nacharbeit(blockierender CI-Gate). - Mangel-Abschluss (Nachzug, 0.33.1): der Nacharbeits-Schritt trägt eine Verknüpfung zum
auslösenden Mangel (
TeilschrittInstanz.mangelId). Wird der Schritt erledigt, setzterledigeden verknüpftenAuftrag.maengel-Eintrag automatisch aufbehoben(+ Protokoll + Auditmangel.behoben). Damit schließt sich der QS-Kreis: Mangel → Nacharbeit → behoben.
OP-QS-GATE — QS-Vollständigkeits-Gate vor der Abholung + Nacharbeit als QS-Schritt (✅ gebaut)
Problem: Die QS-Freigabe war ein reines Client-Gate (eine hartcodierte 4-Punkte-Sichtliste,
losgelöst von den echten Teilschritten); der Server akzeptierte abholen blind (Transition
fertiggestellt → abgeschlossen ohne Prüfung). Ein Fahrzeug konnte übergeben werden, obwohl
Prozessschritte unerledigt/undokumentiert waren oder noch ein Mangel offen war.
Lösung — Nacharbeit dokumentiert sich im QS, und das Gate erzwingt Vollständigkeit server-seitig:
- Nacharbeit = QS-Phasen-Schritt: neues optionales
TeilschrittInstanz.phase(Per-Instanz- Override der Template-Phase).nacharbeitInstanzsetztphase: 'qs'→ die Nacharbeit erscheint als QS-Schritt und dokumentiert dass Nacharbeit nötig war (statt die Produktions-Phase des Original-Templates zu erben).aktuellePhaseund das Teilschritt-DTO bevorzugen die Instanz-Phase. Der bestehendenacharbeitEinplanen-Mechanismus (Solver-Replan, Lifecycle-Rücklauf) bleibt unverändert — kein separater Lifecycle-Statusnacharbeit. - Server-hartes Gate (
abholen): pureistAbnahmebereit(auftrag, dokuPflichtByTs, fotoAnfByTs, fotosByInstanz) → { ok, offen[] }. Bedingung je nicht übersprungenem Teilschritt: erledigt- (falls pflichtig) Doku-Kommentar + Foto-Pflicht erfüllt; zusätzlich kein QS-Mangel offen.
Der
auftrag.aktion-Handler lehntabholenbei!okab (kein Übergang), schicktauftrag.aktion.result(mitoffen[]) an die Verbindung + Auditauftrag.abnahme.abgelehnt(OP-AUDIT-1).
- (falls pflichtig) Doku-Kommentar + Foto-Pflicht erfüllt; zusätzlich kein QS-Mangel offen.
Der
- Client (Qualität-Sicht): Prozess-Vollständigkeits-Tafel aus den echten Teilschritten (erledigt?/Doku?/Foto? + offene Mängel) spiegelt das Server-Gate; „Übergeben" ist daran gebunden; Server-Ablehnung erscheint als Toast. Die manuelle Sicht-Checkliste startet frisch je QS-Runde (Schlüssel inkl. Nacharbeit-Schritt-Anzahl → kein veraltetes „Bestanden" nach Nacharbeit).
Entscheidungen: (a) Nacharbeit als QS-Phasen-Schritt statt neuem Lifecycle-Status; (b) Gate
server-seitig hart (auditierbar/manipulationssicher), Client spiegelt nur; (c) Sonderwünsche
vertagt (eigener PR) — istAbnahmebereit ist als Erweiterungspunkt vorbereitet.
Bewusst NICHT (Folge-Schritte):
transition()→fertiggestelltsetzt offene Schritte weiterhin auferledigt; das Gate fängt undokumentierte Schritte ab (erledigt ohne Kommentar ⇒ blockiert), aber das Auto-Erledigen selbst könnte später eingeschränkt werden.- Pflichten-Snapshot:
istAbnahmebereitliest die Doku-/Foto-Pflichten aus dem lebenden Template-Katalog (state.teilschritte) — wie schon das bestehende Per-Schritt-Gate beim Erledigen (teilschritt.aktion). Eine nachträgliche Template-Änderung wirkt damit rückwirkend auf bereits erledigte Arbeit. Sauberer wäre, die Pflichten zum Abschluss-Zeitpunkt auf der Instanz zu snapshotten (Persistenz-Frage, OP-DATA-1) — bewusst vertagt (betrifft nicht nur das QS-Gate, sondern die ganze Pflicht-Mechanik) und kein Regress dieses PRs.
Verifikation: test:abnahme (7 Fälle, blockierender CI-Gate) · test:do-migrations (v0→v16) ·
test:nacharbeit · ng build. Migration: SCHEMA_VERSION 15 → 16 (additiv, kein Transform).
OP-QS-4 — QS-Nacharbeit direkt als zuweisbarer Prozessschritt + Leistungs-Schwellwerte (✅ gebaut, v0.46.0)
Kernaussage: Die QS-Nacharbeit wird direkt in der Endkontrolle als Prozessschritt erfasst (statt zweistufig Mangel→Einplanen), lässt sich manuell oder automatisch einem Mitarbeiter zuweisen, und pro Leistung definierte Minuten-Schwellwerte markieren Aufträge mit auffällig viel Nacharbeit. Der Auftrag ist erst abschließbar, wenn alle QS-Schritte erledigt sind — jetzt server-seitig lückenlos.
Was neu ist (baut auf OP-QS-GATE/OP-UX-3 auf):
- Einstufige Erfassung — Message
qs.nacharbeitErfassen(auftragId,teilschrittInstanzId?= Ursprungsschritt, Kategorie/Schwere/Beschreibung,nacharbeitAufwandMin= überschreibbare Zeit, optionalmitarbeiterIds). Der Server legt den Mangel automatisch im Hintergrund an (Bezug →teilschrittId/skillId/betroffeneMitarbeiterIds, speist die Qualitätsbewertung unverändert), erzeugt einen Nacharbeits-Schritt (nacharbeitInstanz,phase:'qs'), reopnet (nacharbeiten) und plant sofort ein (einzelplan). Die alten Messages (qs.mangelErfassen/auftrag.nacharbeitEinplanen) bleiben als interne Bausteine; letztere überspringt jetzt Mängel mit bereits vorhandenem Schritt (keine Doppel-Einplanung). - Manuelle Zuweisung — Message
teilschritt.zuweisen+ FeldTeilschrittInstanz.manuellZugewiesen.applyPlanungbehält die Hand-Crew (überschreibt sie nicht bei der Re-Optimierung); der Solver plant weiterhin Zeit/Bucht drumherum. Ohne manuelle Zuweisung besetzt der Solver frei (Default). - Abschluss-Gate gehärtet —
transition(→fertiggestellt)erledigt Nacharbeits-Schritte nicht mehr automatisch (nacharbeitMin != nullausgenommen). Damit blockiert ein offener Nacharbeits-Schrittabholenüber das bestehendeistAbnahmebereit— das in OP-QS-GATE bewusst vertagte Auto-Erledigen ist hiermit geschlossen. - Leistungs-Schwellwerte + Marker —
Leistung.nacharbeitSchwelleGesteigertMin/ExtremMin(Minuten, optional, admin-editierbar über den Prozess-Katalog, G-1). Reine FnnacharbeitStufe(summeMin, gesteigertMin, extremMin).AuftragDTOträgt (abgeleitet, D-2)nacharbeitStufeaus dem Maximum von geplanter und tatsächlicher Nacharbeit-Summe gegen die (über die Auftrags-Leistungen summierten) Schwellwerte, plusnacharbeitGeplantMin/nacharbeitIstMin. Client-Badge in den Auftragskarten (normal ⇒ kein Badge · gesteigert amber · extrem rot).
Entscheidungen (Sign-off): (a) Schritt direkt erfassen, Mangel automatisch (Bewertungs-Pipeline
unverändert); (b) Schwellwerte absolute Minuten; (c) erfassbar ab fertiggestellt; (d) Gate
server-hart. Bewusst NICHT: Nacharbeit während laufender Produktion (vor fertiggestellt) und ein
voller Solver-seitiger Crew-Pin (heute Preservation in applyPlanung, Timing bleibt solver-optimiert).
Verifikation: test:qs-nacharbeit (Stufen-Schwellwerte · Auto-Erledigen-Härtung · Abnahme-Gate ·
fixe Hand-Zuweisung; blockierender CI-Gate) · test:abnahme/test:nacharbeit unverändert grün ·
ng build. Keine Migration (alle neuen Felder optional/nested → additiv).
OP-QS-5 — Mangel/Nacharbeitsschritt: Schritt = Single Source der Dauer (✅ gebaut, v0.46.0)
Kernaussage: Der Mangel bleibt ein eigenständiges Objekt (Fehler-Fakt + eigener Lifecycle, künftig
OP-QS-3-Kette), aber die Nacharbeit-Dauer wird nicht mehr doppelt geführt: maßgeblich ist die Dauer des
Nacharbeitsschritts (TeilschrittInstanz.nacharbeitMin); der am Mangel erfasste nacharbeitAufwandMin
ist nur noch Ersterfassung/Intent (bis ein Schritt existiert bzw. für den Zwei-Stufen-Altpfad und
Fehler ohne Schritt).
Umsetzung (read-authoritativ, kein Feld-Löschen): Beim Aufbau von alleMaengel für Statistik/Bewertung
(leitstand.ts) wird pro Mangel mit verknüpftem Schritt (mangelId) der Aufwand mit dessen nacharbeitMin
überschrieben (Fallback: erfasster Mangel-Wert, wenn kein Schritt existiert). Damit beziehen
statistikFuer/bewertungScore/erfahrungspunkte/niveauVorschlaege (pure, Signatur unverändert) die
Schritt-Dauer, und es gibt keine Sync-Pflicht mehr zwischen Mangel und Schritt. Der DTO-Marker
(nacharbeitStufe, OP-QS-4) las die Schritte ohnehin.
Warum eigenständig statt ableiten? Ein Fehler kann ohne Nacharbeitsschritt existieren (Sofort-Fix, reine Doku, akzeptierter/gewaiveter Mangel), trägt einen eigenen Lifecycle (offen→behoben; künftig Ersatzteil-Kette OP-QS-3) und ankert die Qualitätsbewertung dauerhaft (überlebt Re-Planung der Schritte). Er ist damit ein primärer Fakt, kein Derivat (D-2 spricht nicht dagegen).
Verifikation: test:qs-nacharbeit (5) — Schritt-Dauer gewinnt über den erfassten Wert; ohne Schritt
Fallback. test:leistung unverändert grün. Keine Migration.
5. Entscheidungen
| ID | Frage | Status |
|---|---|---|
| E-UX-1 | U1 als eigener Workspace „Tafel" (eigene Signaturfarbe, Cluster Überblick) statt Umbau von Aufträge/Überblick | ✅ (06-27) eigener Workspace — hält die bestehenden Seiten unverändert, gibt der Durchgängigkeit einen klaren Ort |
| E-UX-2 | Werker-Sicht als eigener touch-Workspace vs. Filter der Tafel | ✅ (06-28) eigener Workspace „Meine Arbeit"; Identität via Mitarbeiter-Picker (Schichtterminal) für den ersten Slice — echtes QR/Login (R1) später |
| E-UX-3 | Annahme-Maske: „+ Auftrag"-Button vs. eigener Workspace | ✅ (06-28) eigener Workspace „Annahme" (erster Operativ-Eintrag); Kunde v1 (Name + CRM-Link) neu am Auftrag |
6. Bezug
OP-R3-1 (Phasen first-class / Flow) · OP-R4-3 (Doku-/Foto-Pflicht) · OP-KIOSK-1 (Werkstatt-Tablet) ·
OP-R9-3 (Mitarbeiter-Ansicht-Detail) · R7 (Auftrag/Lifecycle) · R2 (Belegung) · S-1 (Single-Modal) ·
S-2 (Derived-State) · design/WORKSPACES.md (Workspace-Verhalten).
↩ Zurück zur Doku-Landkarte · Lesepfade · Register (alle OPs)