Zum Hauptinhalt springen

Operatives Modell — Auftrag (R7) + Teilschritt-Instanz

Kernaussage. Ein Auftrag durchläuft den Lifecycle geplant → angeliefert → in_arbeit ⇄ pausiert → fertiggestellt → abgeschlossen → kontrolliert → archiviert; aus jedem Arbeitsstatus vor der Fertigstellung führt abbrechen in den terminalen Status abgebrochen, und nacharbeiten führt bei einem QS-Mangel von fertiggestellt zurück nach angeliefert. Bis zur Fahrzeugannahme ist die Reservierung weich (der Optimierer darf umplanen), ab „Fahrzeug angeliefert" hart — nach der Fertigstellung bindet der Auftrag keine Zukunfts-Ressourcen mehr. Die Auftragsnummer hat das Format #000.KW00.JJJJ (laufende Nummer in der Kalenderwoche · KW · Jahr).

Zielgruppe: IT-Dev/Architektur · Customer Service (Vokabular)

Bezug: Lastenheft.md §5.1 (R7, fachliche Quelle), §6.3 (Reservierung) · Code: server/src/operativ/auftrag.ts · Demos: cd server && npm run operativ / npm run replan

Während datamodel.md die Eingabe des Solvers beschreibt (Stammdaten), ist dies die Ausgabe: ein konkreter Auftrag mit geplanten Teilschritt-Instanzen, der aus einem ScheduleResult (Angebotsmodus) materialisiert wird. Das schließt den Bogen von UC-A: Verfügbarkeit prüfen → Auftrag mit zugesagtem Termin anlegen.


1. Vom Angebot zum Auftrag

materialisiereAuftrag(result, meta) wandelt die steps des Plans in Teilschritt-Instanzen (Status geplant, mit Planung: Bucht, Zeit, Mitarbeiter) und legt den Auftrag im Status geplant an (weiche Reservierung). geplanteFertigstellung (R7-F13) = ScheduleResult.completion (derived, nicht doppelt gepflegt).

Auftragsnummer (R7-F01): Format #000.KW00.JJJJ000 = laufende Nummer in der Kalenderwoche der Anlage, KW00 = Kalenderwoche, JJJJ = Jahr (z. B. #003.KW25.2026). Nur wenn die Kalenderwoche unbekannt ist (Alt-Daten), fällt der Code auf das frühere Format #JJJJ-NNN zurück.

2. Lifecycle (R7-F02, S-6)

Drei fachliche Abschnitte — Anlieferung (geplant → angeliefert) · Produktion (in_arbeit/pausiert → fertiggestellt) · Abholung (abgeschlossen → kontrolliert → archiviert):

Status (Key)UI-LabelBedeutungReservierung (§6.3)
geplantgeplanteingeplant (früheste/späteste Anlieferung), Fahrzeug noch nicht daweich
angeliefertFahrzeug angeliefertFahrzeug per Check-in angenommen, Produktion noch nicht begonnenhart
in_arbeitin ArbeitProzess läufthart
pausiertpausiertProzess unterbrochen (Pause, Klärfall, Preemption)hart
fertiggestelltfertiggestelltProzess inkl. Quality-Check abgeschlossen, Fahrzeug noch nicht abgeholtkeine
abgeschlossenabgeschlossenFahrzeug abgeholtkeine
kontrolliertkontrolliertNachkontrolle durchgeführtkeine
archiviertarchiviertnach 7 Tagen (ab Abholung) automatisch oder manuellkeine
abgebrochenabgebrochenAbbruch/Storno (Klärfall) — vorzeitig beendet, terminalkeine

Die UI-Labels kommen aus einer Quelle (client/src/app/leitstand/labels.ts); die technischen Keys bleiben stabil (Selbsterklärbarkeit: Label „Fahrzeug angeliefert", Key angeliefert).

transition(auftrag, aktion) setzt die Übergangstabelle durch und wirft bei unzulässigen Aktionen (z. B. archiviert --starten-->). Die Übergänge sind logik-tragend und systemfest (G-1-Ausnahme). Wichtige Guards:

  • Zuweisungs-Invariante (R7): starten/fortsetzen (→ in_arbeit) setzen mindestens einen zugeteilten Mitarbeiter voraus (hatZuweisung) — ohne Zuweisung kann ein Auftrag nicht in Arbeit sein.
  • QS-Abnahme-Gate: abholen ist erst zulässig, wenn istAbnahmebereit grün ist — jeder nicht übersprungene Schritt erledigt + dokumentiert (Kommentar, Foto-Pflicht) und kein QS-Mangel offen.
  • nacharbeiten: bei einem QS-Mangel geht der Auftrag von fertiggestellt zurück nach angeliefert; der Mangel wird als dynamische Nacharbeits-Teilschritt-Instanz eingeplant (nacharbeitInstanz, Solver plant sie über zusatzSchritte ein).
  • abbrechen/Storno: aus geplant/angeliefert/in_arbeit/pausiert möglich, Grund ist Pflicht (stornieren); offene Schritte werden mit Begründung übersprungen, damit der Auftrag keine Ressourcen mehr einplant.

erlaubteAktionen(status, auftrag?) liefert die im aktuellen Status erlaubten Aktionen für UI-Buttons (und filtert starten/fortsetzen ohne Zuweisung heraus).

Zweite Achse — fachliche Phase: Orthogonal zum Lifecycle-Status läuft die Phase des Standard-Prozesses: annahme/aufbereitung/produktion/qs mit den sprechenden Labels Annahme · Vorbereitung · Produktion · Quality-Check (client/src/app/leitstand/phase.ts). Sie wird aus den Teilschritten abgeleitet (aktuellePhase, nie gespeichert); sind keine Schritte mehr offen, trägt der Lifecycle die Sicht (z. B. fertiggestellt → „Abholung").

3. Reservierungsmodi (§6.3)

reservierungsmodus(status) leitet den Modus aus dem Status ab (kein gespeicherter Wert):

StatusReservierung
geplantweich — eingeplant, darf vom Optimierer umgeplant/verdrängt werden
angeliefert, in_arbeit, pausierthart — Fahrzeug vor Ort, Ressourcen fix
fertiggestellt, abgeschlossen, kontrolliert, archiviert, abgebrochenkeine — keine Zukunfts-Ressourcen

Jeder Auftrag startet weich; die Fahrzeugannahme (Check-in) macht die Reservierung hart: fahrzeugAnnahme erledigt den Standard-Annahme-Schritt mit Pflicht-Zustandskommentar (Car-Check), verlangt die FIN und stellt den Auftrag per liefern auf angeliefert (stempelt tatsaechlicheAnlieferung).

Zusätzlich gilt eine schritt-granulare Reservierung: bereits gestartete/pausierte/erledigte Schritte sind fix (istFixerSchritt) und werden bei einer Re-Optimierung nie verschoben; nur noch geplante Schritte sind (re-)planbar (istPlanbarerSchritt).

4. Teilschritt-Instanz

Aus dem Plan materialisiert; trackbar je Schritt entlang geplant → in_arbeit ⇄ pausiert → erledigt (uebersprungen aus geplant):

Status (Key)UI-LabelÜbergang
geplantwartetAusgangsstatus; einziger (re-)planbarer Status
in_arbeitläuftstarteTeilschritt (stempelt tatsaechlichStart)
pausiertpausiertpausiereTeilschritt/Preemption (setzt unterbrochen)
erledigterledigterledige (stempelt tatsaechlichEnde; Doku-Kommentar ist bei pflichtigen Schritten Pflicht)
uebersprungenübersprungenueberspringe — nur optionale Teilschritte (R3b-F05), nur mit Pflicht-Begründung; die Klärfall-Lösung darf per ueberspringeFuerKlaerung auch Pflicht-Schritte überspringen (Grund pflicht)

Neben den statischen Prozess-Schritten gibt es dynamische Instanzen: den nicht solver-geplanten Standard-Annahme-Schritt (Doku-Schritt beim Check-in), Nacharbeits-Schritte aus QS-Mängeln und Klärungs-Arbeitsschritte (Skill „Klärung", kapazitätstragend) — beide letzteren tragen ihre Vorgabe-Dauer in nacharbeitMin und werden vom Solver eingeplant.

5. Re-Planung bei Eilauftrag (replan.ts)

Verzahnt den Scheduler mit dem Lifecycle nach der Reservierungsregel §6.3: harte Reservierungen (Auftrag angeliefert/in_arbeit/pausiert) gewinnen und bleiben unverändert; weiche (geplant) dürfen vom Eilauftrag verdrängt und danach neu geplant werden. npm run replan zeigt es.

replanMitEil(input, bestehende, eil):

  1. WorkshopState mit den Belegungen aller harten Aufträge vorbelegen (belegeWorkshop aus Bucht-/Mitarbeiter-Bookings + In-Bay-Stays der Teilschritt-Instanzen; bei fixen Schritten schritt-granular).
  2. Eilauftrag in die so reservierte Werkstatt einplanen — er bekommt damit ggf. Slots, die zuvor nur weich gehalten wurden.
  3. Jeden weichen Auftrag neu einplanen (gegen harte + Eil) — er rutscht ggf. nach hinten (verschoben).

Vereinfachung: Parkplatz-Belegung wird beim Vorbelegen ignoriert (knappe Ressourcen für die Re-Planung sind Buchten + Mitarbeiter). → A-5: ein globaler Solver nimmt harte Constraints als Fixpunkte und re-optimiert alles Verschiebbare gemeinsam statt sequenziell — das leistet heute die globale Re-Optimierung im Leitstand (berechnePlaene).

6. Persistenz + Leitstand-Anbindung (R9)

Der Live-Leitstand (server/party/leitstand.ts, Cloudflare Durable Object) ist die Source of Truth und persistiert seinen Zustand in DO-Storage. Aufträge sind Teil dieses Zustands:

  • Persistenz: PersistedState.auftraege: Auftrag[] (+ auftragSeq) wird wie der übrige State gespeichert und überlebt DO-Neustarts/Redeploys. Ältere persistierte Zustände werden beim Start idempotent migriert (server/src/persistence/do-state-migrations.ts) — dort werden u. a. die abgelösten Spike-Status (unbestaetigt/aktiv/blockiert) auf das heutige Modell remappt.
  • Erzeugen: Wire-Message auftrag.create rechnet im DO den Angebotsmodus, materialisiert den frühest-machbaren Plan als geplant und legt ihn ab.
  • Check-in: Wire-Message auftrag.checkin führt die Fahrzeugannahme aus (fahrzeugAnnahme: Car-Check-Kommentar + FIN Pflicht → angeliefert, Reservierung hart).
  • Lifecycle: Wire-Message auftrag.aktion führt einen S-6-Übergang (transition) aus; abholen läuft durch das QS-Abnahme-Gate, unzulässige Aktionen werden mit Begründung abgelehnt.
  • Broadcast: LeitstandState.auftraege: AuftragDTO[] (anzeigefreundlich, inkl. erlaubteAktionen) geht per WebSocket an alle verbundenen Clients; mehrere Tabs sehen Änderungen live.

Leistungsnachweise, QS-Mängel und Ausbildung als Helfer-Leistung setzen auf denselben Teilschritt-Instanzen auf (server/src/operativ/leistung.ts, npm run test:leistung); fachlich: Lastenheft.md §6.4.1.

7. Historie (Spike-Stand) & Abgrenzung

Historie (Spike-Stand): Der ursprüngliche Operativ-Spike modellierte den Lifecycle als unbestaetigt → aktiv → pausiert/blockiert → abgeschlossen → archiviert mit Auftragsnummern im Format #JJJJ-NNN. Beides ist abgelöst — der heutige Lifecycle (oben, §2) ist die verbindliche Wahrheit; persistierte Alt-Status werden automatisch migriert (do-state-migrations.ts), das Alt-Nummernformat existiert nur noch als Fallback ohne Kalenderwoche.

Bewusst (noch) nicht enthalten:

  • Mehrmandantenfähigkeit — Konzept in Mandantenfaehigkeit.md.
  • Workflow-Engine — bewusst leichtgewichtige State-Machine statt Camunda/Temporal (A-2/A-5).

↩ Zurück zur Doku-Landkarte · Lesepfade · Register (alle OPs)