Seed-Ablöse-Plan & Mandantenfähigkeit (OP-SEED-1 / OP-TENANT)
Status: Seed-Ablösung abgeschlossen — S-SEED-1…4 ✅ (Stand 0.16.0: kein Produktiv-Codepfad berührt den Seed mehr, s. §4); S-SEED-5 = Persistenz-Hygiene → OP-DATA-1 (
docs/architektur/Persistenz.md), OP-TENANT-Slices (mehrere Vorlagen · Room=Tenant · Isolation · Registry) offen · Bezug: OP-SEED-1 (Owning-OP) / OP-TENANT · S-SEED-1…5 · OP-DATA-1 · G-1 · Zielgruppe: IT-Dev/Architektur · True North: nur indirekt — echte, editierbare Stammdaten (Buchten · Taxonomie · Schichten) statt Demo-Seed machen die Antworten auf Auslastung/Standort/Kapazität für den realen Betrieb korrekt.
Kernaussage. Konkreter Plan, wie der statische Beispiel-Seed (
vestAutomotiveSeed) schrittweise aus dem Laufzeitpfad gelöst wird, und wievest-automotivezur konfigurierbaren Tenant-Vorlage wird. Begleitend: die Purge-Funktion im Admin-Bereich (Datenbestand zurücksetzen + Vorlage laden). Audit-Hintergrund: Branchclaude/seed-usage-audit-frsx52. Tiefe je Thema:HANDOFF.md§4.
Verhältnis zu Mandantenfähigkeit: dort die Zielarchitektur der Tenant-Isolation; hier der konkrete Migrationsweg (Seed → Vorlage). Beide teilen OP-TENANT.
1. Audit-Befund — wo Seeds noch verwendet werden (Stand 0.12.0)
Alle Fundstellen gehen auf einen Datensatz zurück: vestAutomotiveSeed in server/src/model/seed.ts.
Kein Client-Code nutzt Seeds direkt. Zwei Gruppen:
1a. Produktiv-/Laufzeitpfad — server/party/leitstand.ts
| Daten | Bezug zum Seed | Status |
|---|---|---|
| Mitarbeiter, Skills, Teilschritte, Leistungen | beim ersten Boot aus dem Seed geklont in den DO-State | abgelöst — persistiert + editierbar (OP-R1-1 Phase B, OP-R3-3) |
Buchten/Arbeitsplätze (arbeitsplaetze/bays) | seed()-Buchten + read-only vestAutomotiveSeed.arbeitsplaetze (Belegung, Ausfall) | noch am Seed — nicht editierbar |
| Taxonomie (Abteilungen, Arbeitsplatz-Typen, Abwesenheits-/Sperre-Typen, Ausstattung) | read-only direkt aus vestAutomotiveSeed.taxonomy (Modul-Konstanten) | noch am Seed — nicht editierbar (G-1: taxonomie-artig = admin-editierbar vorgesehen) |
Schichten (SCHICHTEN, SCHICHT_DTOS) | read-only aus vestAutomotiveSeed.schichten | noch am Seed — nicht editierbar |
Solver-Eingabe schedulerInput() | Stammdaten-Rest weiter ...vestAutomotiveSeed, Mitarbeiter/Skills/Teilschritte/Leistungen aus dem State | teil-abgelöst |
Demo-Historie seedDemoHistorie() | Beispiel-Aufträge/Leistungsnachweise je Boot | Demo-Daten (kein Stammdatum) |
1b. Demo-/Self-Test-/Spike-Skripte (CLI, nicht Laufzeit) — unkritisch
scheduler/spike.ts, solver/{demo,cpsat-demo,eligibility-demo,overflow-demo,pin-demo}.ts,
operativ/{demo,replan-demo,teilplan-demo,prozess-demo}.ts, insights/insights-demo.ts.
Diese importieren den Seed bewusst als Testdatensatz (npm run spike|solve|replan|…) und bleiben —
sie sind kein Produktivpfad. Ablösung betrifft nur 1a.
2. Getroffene Entscheidungen (06-26)
Die interaktive Rückfrage scheiterte technisch (Permission-Stream, Remote-Session); umgesetzt wurden die empfohlenen Defaults — jederzeit über den Purge-Dialog (Laufzeit) bzw. hier (Plan) überstimmbar.
- D1 — Purge-Kategorien: Alle vier Seed-Kategorien sind im Purge-Dialog einzeln wählbar:
Taxonomie & Struktur·Prozess-Katalog·Demo-Mitarbeiter·Demo-Historie & Aufträge. - D2 — Purge-Default (Schnellwahl): „Leeres Gerüst" = Taxonomie+Struktur+Prozess-Katalog laden, keine Mitarbeiter/Aufträge/Historie (sauberer Produktiv-Start). Alternativ ein Klick: „Voller Demo-Seed" (wie heute) oder „Komplett leer".
- D3 — Tenant-Umfang dieser PR: „Fundament + OP" — Seed → benannte Tenant-Vorlage
vest-automotive, Purge lädt die gewählten Kategorien daraus; echtes Tenant-Switching/-Isolation als spätere Slices (OP-TENANT, hängt an OP-AUTH-2 + OP-DATA-1).
3. Was in dieser PR gebaut wurde (0.12.0, Build 15)
- Tenant-Vorlage als einzige Seeding-Stelle —
baueState(kategorien)inleitstand.tsist die einzige Stelle, an der die Vorlagevest-automotive(TENANT_ID) zu State wird. Boot-Default =baueState(ALLE)→ bit-identisch zum bisherigen Voll-Seed-Boot (Regressionsfreiheit). - Purge-Kommando
admin.purge(admin-gegated über denselben Access-Owner-Gate wie Kosten, interim bis OP-AUTH-1): baut den State aus den gewählten Kategorien neu, löscht alle Aufträge/Historien/Fotos/ Kosten + transiente Arbeitszustände (Vorschau/Vorschläge/Live-Tasks), setztschemaVersionaktuell. - Demo-Historie-Unterdrückung — neues persistiertes Flag
demoHistorieGeseedetverhindert, dassseedDemoHistorie()nach einem Purge ohne Demo-Historie beim nächsten Cold-Boot wieder Demo-Daten nachschiebt. Legacy/undefiniert = altes Verhalten (kein Migrationsbedarf, rein additiv). - Admin-Bereich (neu) — Workspace
/administration(Cluster „System", nav-gegated wie Kosten): aktiver Mandant + Gefahrenzone mit Preset-Schnellwahl, Einzel-Checkboxen je Kategorie, Ergebnis-Vorschau und Tipp-Bestätigung (LÖSCHEN) vor der destruktiven Aktion. Rot nur für die Warnung/den Bestätigungs-Button (Design-Regel), nur--tk-*-Tokens.
4. Ablöse-Plan für den Rest-Seed (Slices, je eigene PR/Entscheidung)
Ziel: die noch hart verdrahteten Stammdaten (Buchten, Taxonomie, Schichten) genauso aus dem Laufzeitpfad lösen, wie es für Mitarbeiter/Skills/Teilschritte/Leistungen bereits geschah — persistiert, editierbar, je Mandant aus der Vorlage initialisiert. Reihenfolge nach Risiko/Nutzen:
- S-SEED-1 · Buchten/Arbeitsplätze persistieren & editieren — ✅ gebaut (0.13.0).
arbeitsplaetze(ArbeitsplatzR2) ist jetzt im DO-State (persistiert +onStart-Backfill für Altzustände + inbaueState/Purge unter „Taxonomie & Struktur"). Die Modul-KonstanteBELEGUNG_SLOTSwurde zum Instanz-GetterbelegungSlots(leitet ausstate.arbeitsplaetzeab);ressourcenDTO().baysundschedulerInput()lesen ebenfalls aus dem State statt aus dem Seed. CRUD:arbeitsplatz.create/update/remove(validiert gegen Typ-/Skill-/Ausstattungs-IDs;removeräumt die Belegung des Slots mit auf) + neuer Editor in/administration(Name, Typ, Kapazität, Konfig-Status, Skills, Ausstattung). True North: direkter Treffer auf „Wo stehen die Fahrzeuge / wann ist frei" (Frage 2/3) — der Betrieb pflegt seine echten Buchten. Offen (Folge): Sperren-Editor (heute nur read-only ZählersperrenAnzahl);state.bays(UI-Board) undarbeitsplaetzeperspektivisch vereinheitlichen (zwei parallele Repräsentationen); Taxonomie der Typen bleibt bis S-SEED-2 Seed-basiert. - S-SEED-2 · Taxonomie-Editor (G-1) — ✅ gebaut (0.14.0).
taxonomy: TaxonomyValue[]ist jetzt im DO-State (persistiert +onStart-Backfill + inbaueState/Purge unter „Taxonomie & Struktur"). Alle bisher statischen Modul-Konstanten (ABTEILUNGEN,TYP_LABEL,ARBEITSPLATZ_TYPEN,AUSSTATTUNG_TYPEN,ABWESENHEIT_TYPEN, … + die Validierungs-Sets) wurden zu Instanz-Gettern überstate.taxonomy; die Modul-FunktionentoAuftragDTO,buildProzessKatalog,bauBelegungSlotsbekommen die Taxonomie/Label-Map als Parameter;schedulerInput()reichttaxonomy: state.taxonomyan Scheduler/CP-SAT. CRUD:taxonomie.create|update|remove(Label +aktiv-Soft-Deaktivierung; Anlegen reaktiviert gleichnamige deaktivierte Werte; hartes Löschen nur unreferenziert —taxonomieInUseprüft Mitarbeiter/Arbeitsplätze/Teilschritte/Leistungen/Sperren) + generischer Taxonomie-Editor in/administration(Art-Auswahl × Werte mit Umbenennen/Aktiv/Löschen). Logik-tragend bleibt fix (G-1): die Label-Regex-Konventionen im Scheduler — Parkplatz/parkplatz/i, Indoor/indoor|folierbucht/i— der Editor warnt, solche Typen nicht umzubenennen. Offen: die Mangel-Kategorien (§4.9.1,MANGEL_KATEGORIEN) sind eine separate feste Liste (nicht Teil der Stamm-Taxonomie) und bleiben vorerst hart;kind-Flag statt Label-Regex für Parkplatz/Indoor als robustere Folge. - S-SEED-3 · Schicht-Katalog persistieren & editieren — ✅ gebaut (0.15.0).
schichten: SchichtKatalog[]ist jetzt im DO-State (persistiert +onStart-Backfill + inbaueState/Purge unter „Taxonomie & Struktur"). Die Modul-KonstantenSCHICHTEN/SCHICHT_DTOS/SCHICHT_IDSwurden zu Instanz-Gettern (schichtenMap/schichtDtos/schichtIds) überstate.schichten;schedulerInput()reichtschichtenan Scheduler/CP-SAT (Verfügbarkeit/Ausfall). CRUD:schicht.create/update/remove(Name + Wochentage + Zeit-SlotsHH:mmvalidiert [start<ende],artregulär/standard/überlauf,aktiv-Soft-Deaktivierung; hartes Löschen nur unzugewiesen viaschichtInUseüber Mitarbeiter-Schichten und Abwesenheits-Schichtbezug) + Schicht-Editor in/administration(Wochentag-Picker, variable Zeit-Slots mittype=time, Art, Aktiv). Mitarbeiter-Schicht-Zuweisung + Abwesenheits-Schichtbezug referenzieren die persistierten Schichten. Logik-tragend bleibt fix: Wochentage/Zeitfenster steuern die Solver-Verfügbarkeit — Werte editierbar, dasHH:mm-Format ist validiert/fix. - S-SEED-4 · Vorlage extrahieren — ✅ gebaut (0.16.0).
Die Stammdaten sind aus
server/src/model/seed.tsnachserver/src/tenants/vest-automotive.tsumgezogen (git mv, Historie erhalten) und als benannte Tenant-Vorlage gewrappt:vestAutomotive: TenantVorlage = { id: 'vest-automotive', name: 'Vest Automotive GmbH', daten: <SchedulerInput> }(TenantVorlage-Typ intenants/types.ts). Eine Registrytenants/index.ts(TENANT_VORLAGEN,tenantVorlage(id),DEFAULT_TENANT_ID,aktiveTenantVorlage()) ist die einzige Bezugsquelle;leitstand.tszieht die Vorlage überaktiveTenantVorlage()(→TENANT_ID+ internevestAutomotiveSeed-Referenz).model/seed.tsbleibt als dünner Re-Export-Shim (export { vestAutomotiveSeed } from '../tenants/vest-automotive'), damit die Demo-/Spike-Skripte (1b) ihren Import unverändert behalten. Damit ist der Seed kein impliziter Laufzeit-Default mehr, sondern eine explizit benannte Vorlage — das Code-Fundament für Multi-Tenancy (OP-TENANT). Offen: Demo-Imports später direkt auftenants/umstellen + Shim entfernen; mehrere Vorlagen + Room=Tenant (OP-TENANT). - S-SEED-5 (OP-DATA-1) — Design ausgearbeitet 06-27 →
docs/architektur/Persistenz.md. Persistenz-Konvention vereinheitlichen: Drizzle-Schema als Single Source, generierte Migrationen + CI-Gate statt handgepflegteronStart-Remaps. Kern: Heimat der Daten (DO-Blob · DO-SQLite · D1) — ⮕ Entscheidung E-DATA-1. Slices D5-1…D5-4. Kein Teil der Seed-Ablösung mehr (die ist mit S-SEED-4 abgeschlossen) — reine Persistenz-/Migrations-Hygiene.
Stand 0.16.0: S-SEED-1..4 ✅ — kein Produktiv-Codepfad berührt mehr den Seed direkt; der DO bezieht die
Stammdaten ausschließlich über die benannte Tenant-Vorlage (aktiveTenantVorlage() → baueState). Damit ist
das Code-Fundament für echtes Multi-Tenancy (OP-TENANT) gelegt; offen bleibt S-SEED-5 (Drizzle/Migrationen,
OP-DATA-1) sowie die OP-TENANT-Slices (mehrere Vorlagen, Room=Tenant, Isolation, Registry in D1/KV).
5. Mandantenfähigkeit — OP-TENANT (Zielbild)
vest-automotive ist der erste Mandant, nicht der einzige. Zielbild (mehrere Slices, hängt an
OP-AUTH-2 „Mandanten-/Cross-Tenant-Trennung" und OP-DATA-1):
- Tenant-Identität je DO-Room (heute fix
leitstand-vest) → Room = Tenant;TENANT_IDaus der Room-/Access-Identität statt Konstante. Datenisolation strikt je Tenant (kein Cross-Read). - Tenant-Registry (welche Mandanten existieren, welche Vorlage/welcher Plan) — D1/KV, EU-Residenz.
- Provisionierung: neuen Mandanten anlegen = neuen Room +
baueState(gewählte Kategorien)der passenden Vorlage; Self-Service-Onboarding folgt dem Billing-/Access-Pfad (docs/Billing-Zugang.md, OP-BILLING-1/OP-ACCESS-1). - Owner-Gate scharf (OP-AUTH-1/OP-COST-3): der heutige interim-
kostenAdmin-Gate wird durch echte Rollen ersetzt; Purge/Tenant-Admin sind dann owner-/admin-rollen-gebunden.
Abgrenzung: Diese PR liefert das Fundament (eine benannte Vorlage + selektives (Re-)Seeding via Purge). Tenant-Switching, -Isolation und -Registry sind nicht enthalten und bleiben OP-TENANT.
6. Risiken & Sicherheit
- Destruktiv & irreversibel: Purge löscht den Datenbestand ohne Backup. Schutz heute:
Admin-Gate + Tipp-Bestätigung. Vor Produktivgang: echtes Rollen-Gate (OP-AUTH-1), zusätzlich
Export/Backup vor Purge (Bezug OP-EXPORT-1 + OP-BACKUP-1 — Point-in-Time-Restore, Rollback-Punkt
über das Audit-Log, Umgang mit dem Audit-Log beim Rollback; noch auszuarbeiten) und ein Audit-Event
je Purge ins D1-Audit (OP-AUDIT-1) — heute nur Ops-Log-Zeile (
console, OP-LOG-1) mit Actor. - Mehrbenutzer-Live: Purge broadcastet sofort den neuen (leeren) State an alle Verbindungen — bewusst, da der ganze Mandant zurückgesetzt wird.
- DSGVO/Residenz: Tenant-Daten + -Registry in EU (D1
weur/eu), konsistent mit OP-AUDIT-1/OP-AUTH-1.
7. Verweise
HANDOFF.md §4 (OP-SEED-1, OP-TENANT, OP-AUTH-1/2, OP-DATA-1, OP-AUDIT-1, OP-EXPORT-1) ·
docs/Lastenheft.md (G-1) · server/party/leitstand.ts (baueState, admin.purge) ·
server/src/model/seed.ts · client/.../pages/administration.component.ts.
↩ Zurück zur Doku-Landkarte · Lesepfade · Register (alle OPs)