Track HiveGrid Cloud planning reference

This commit is contained in:
david committed 2026-06-26 20:48:01 +02:00
1 parent b3d5ea6764
commit e341c5938a
5784 files changed
+1104929 -3

No files matched your search

@@ -0,0 +1,88 @@
# M001 — Audit-Log default
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.6 — Audit-Log als Default
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/03-architektur.md` Sektion A.6
## Ziel
Eine Schreib-Aktion durch ein beliebiges Modul erzeugt automatisch einen Audit-Eintrag — ohne dass das Modul den Audit-Service aktiv aufrufen muss.
## Pflichtenheft-Bezug
- A.6.1 — Jede schreibende Aktion (Anlegen, Ändern, Löschen, Status-Wechsel) wird mit Wer/Wann/Was/Vor-Nach-Wert protokolliert
- A.6.2 — Auch Aktionen durch Automatisierungen oder externe Sync-Vorgänge; Auslöser wird mit-protokolliert
## Abhängigkeiten
- **Vorbedingung:** EU-Sterilisation + RR7-Migration der Boilerplate abgeschlossen
- **Wird benötigt von:** M004, M005, M006, M075-M082 (Automation), M151-M152 (Audit-UI/Export), alle schreibenden Module
## Out of Scope
- Audit-Anzeige-UI → M151
- Audit-Export für Compliance → M152
## Erfolgskriterium
Test-Modul ruft `kontakt.create({...})` → ohne expliziten Audit-Code-Aufruf erscheint ein Eintrag in `audit_events` mit korrektem actor, tenant, before/after, timestamp.
## Hinweise für Slice-Planung
- Schema-Design separat von Hook-Implementierung
- Akteur-Resolution unterscheidet User / Auto / Sync / System
- Performance: Bulk-Update von 1000 Datensätzen darf nicht > 2x normale Latenz erzeugen
- Audit-Writes sind unveränderlich (keine UPDATE/DELETE-Pfade)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,90 @@
# M002 — Klartext-Diagnostik
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.1 — Klartext-Diagnostik in jedem Feature
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/03-architektur.md` Sektion A.1
## Ziel
Jeder erkennbare Fehler-Zustand in HiveGrid hat einen vorformulierten Klartext-Text und (wo sinnvoll) einen Lösungs-Knopf — kein nackter HTTP-Code, kein kryptisches Log.
## Pflichtenheft-Bezug
- A.1.1 — Fester Klartext-Text + optional Lösungs-Knopf pro Fehler-Zustand
- A.1.2 — Keine KI-on-the-fly-Übersetzung in Phase 1; Texte sind redaktionell vorgefertigt
- A.1.3 — Kein Feature-Release ohne definierte Klartext-Texte
## Abhängigkeiten
- **Wird benötigt von:** allen folgenden Modulen
- **Hängt zusammen mit:** M003 (i18n), weil Klartext mehrsprach-fähig sein muss
## Out of Scope
- KI-Live-Übersetzung von Fehlern (Phase 2)
- Auto-Generierung von Texten
## Erfolgskriterium
Geworfener Catalog-Fehler erscheint als deutscher Klartext-Hinweis im UI mit korrektem Lösungs-Knopf-Verhalten; ESLint-Rule lehnt nackte `throw new Error("...")` außerhalb des Catalogs ab.
## Hinweise für Slice-Planung
- Catalog-Format als TypeScript-Modul + i18n-Keys
- Error-Boundary (RR7-kompatibel)
- Logger-Bridge zu Pino
- Migrations-Lint für bestehende Boilerplate-Fehler
- Klartext-Beispiele aus Pflichtenheft-Modulen übernehmen (z.B. M27.15)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,89 @@
# M003 — i18n-Pflicht-Wiring
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.4 — Mehrsprachigkeit von Anfang an sauber vorbereitet
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/03-architektur.md` Sektion A.4
## Ziel
Kein einziger UI-Text wird hartkodiert. Build schlägt fehl, wenn ein nicht-erlaubter harter Text gefunden wird.
## Pflichtenheft-Bezug
- A.4.1 — Alle Texte aus Sprach-Dateien (Locale-Files), keine Hardcoding
- A.4.2 — DE Phase 1 befüllt; EN/TR/PL als Ziel-Sprachen vorbereitet, nicht befüllt
- A.4.3 — Sprach-Wechsel pro Nutzer (siehe M028, M029)
## Abhängigkeiten
- **Wird benötigt von:** allen folgenden Modulen mit UI
- **Verwendet:** Boilerplate-`packages/i18n` (i18next + remix-i18next)
## Out of Scope
- DeepL-Pipeline für DE → EN/TR/PL (Phase 2)
- Sprach-Pflege-UI für Mandanten (gibt es nicht — Mandanten-Inhalte sind 1-sprachig)
## Erfolgskriterium
Hartcodierter String im UI-Code (`packages/ui-hivegrid/**`) → Build schlägt fehl mit Klartext-Verstoß-Meldung. Pluralisierung (DE-Form) und Datums/Zahlen-Format funktionieren.
## Hinweise für Slice-Planung
- i18next-Setup als Querschnitt-Service, einzig DE als Quelle
- ESLint-Rule gegen JSX-Text-Nodes ohne `t()`
- CI-Wiring (`pnpm verify:i18n` im baseline)
- Pluralisierung: ICU MessageFormat (Polnisch hat 3 Formen — Phase 2 nicht brechen)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,87 @@
# M004 — Tenant-Scope-Wrapper + Owner-Check
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.5 Teil 1 — Berechtigungs-Logik als Standard
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/03-architektur.md` Sektion A.5
## Ziel
Jede Liste, Suche, Detail-Ansicht filtert automatisch nach Mandant + Berechtigungen. Owner-Check für „eigene Daten" zentral implementiert.
## Pflichtenheft-Bezug
- A.5.1 — Auto-Filter nach angemeldetem Nutzer; ohne Recht: nicht im Menü, nicht aufrufbar, nicht in Suche
- A.5.2 — Owner-Check zentral, nicht pro Modul nachgebaut
- A.5.3 — Keine versteckten URL-Tricks zum Umgehen
## Abhängigkeiten
- **Vorbedingung:** M001 (Permission-Verstöße werden geauditet)
- **Wird benötigt von:** allen Modulen, die Daten anzeigen
## Out of Scope
- URL-Tampering-Probes + Mass-Action-Hardening → M005
## Erfolgskriterium
Test-Modul vergisst den Filter → Wrapper greift trotzdem; Cross-Tenant-ID-Lookup liefert 404 (nicht 403).
## Hinweise für Slice-Planung
- Wrapper für Prisma-Queries (`withTenantScope`, `withPermission`, `withOwnerCheck`)
- Permission-Definition als Feingranular (siehe M27.6.2 — Stufen pro Funktionsbereich)
- Test-Suite mit Cross-Tenant-Probe + Negative-Path
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,87 @@
# M005 — URL-Tampering Hardening + Mass-Action-Schutz
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.5 Teil 2
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/03-architektur.md` Sektion A.5.3 + 27.2
## Ziel
URL-Manipulation, Bulk-Operationen, kreative Query-Strings können Mandanten-Trennung nicht umgehen.
## Pflichtenheft-Bezug
- A.5.3 — Keine versteckten URL-Tricks
- 27.2.1 — System verhindert durchgehend Cross-Tenant-Datenzugriff
- 27.2.3 — Auch Hintergrund-Prozesse setzen Mandanten-Bezug explizit
## Abhängigkeiten
- **Vorbedingung:** M004 (Wrapper steht)
- **Wird benötigt von:** allen Modulen mit ID-basierten Routen
## Out of Scope
- Cache/CDN-Layer Probes (separat falls relevant)
## Erfolgskriterium
Pen-Test-Suite mit URL-Tampering-Probes (fremde IDs, Cross-Tenant-Slug, Mass-DELETE-Versuche) liefert konsistent 404; Audit-Log erfasst alle Probe-Versuche.
## Hinweise für Slice-Planung
- Probe-Test-Suite als CI-Pflicht (Playwright)
- Mass-Action-Validation (Bulk-Updates müssen IDs einzeln gegen Tenant prüfen)
- Background-Job-Wrapper (BullMQ-Jobs setzen Tenant explizit)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,90 @@
# M006 — Feature-Flag-Engine (Code-Layer)
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.7 — Feature-Flags als Standard-Einführungs-Hülle
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/03-architektur.md` Sektion A.7 + Modul 32
## Ziel
Flag-Auswertung mit korrekter Priorität (direkte Ausnahme → Filter → Default). Code-Layer steht; Admin-UI später (M031-M033).
## Pflichtenheft-Bezug
- A.7.1 — Neue Features hinter Flag, intern → ausgewählte → breit
- A.7.2 — Plattform-Admin schaltet ohne Deploy
- 32.4 — Auswertungs-Reihenfolge
## Abhängigkeiten
- **Vorbedingung:** M001 (Flag-Änderungen werden geauditet)
- **Wird benötigt von:** allen folgenden Modulen mit gestaffeltem Roll-out
## Out of Scope
- Admin-UI für Flag-Verwaltung → M031-M033
- Mandanten-Selbstbedienungs-Flags (Phase 2)
- Prozentualer Roll-out (Phase 2)
- A/B-/C-Tests (Phase 2)
## Erfolgskriterium
`featureFlag('foo', tenant)` returns korrekten Wert nach Priorität; Test-Mode mit forced overrides; im Code referenzierter aber nicht definierter Flag → Klartext-Build-Warnung.
## Hinweise für Slice-Planung
- Flag-Schema mit Lifecycle (Beta/Roll-out/GA/Abgekündigt)
- Resolver mit Caching
- Test-Mode für CI (forced overrides)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,86 @@
# M007 — Idempotenz-Wrapper für BullMQ-Steps
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.8 — Idempotenz pro Automatisierungs-Aktion
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/03-architektur.md` Sektion A.8
## Ziel
Jeder BullMQ-Step hat einen Idempotenz-Schlüssel; bei Re-Run wird die Aktion nicht doppelt ausgeführt.
## Pflichtenheft-Bezug
- A.8.1 — Idempotenz-Schlüssel pro Step
- A.8.2 — Konkret: keine doppelten Mails, Datensätze, KWP-Push-Operationen
## Abhängigkeiten
- **Vorbedingung:** M001 (Idempotenz-Skip wird geauditet), M004
- **Wird benötigt von:** M075-M082 (Automation), M089-M095 (KWP-Sync), Mail-/Notification-Worker
## Out of Scope
- Distributed-Lock-Service (BullMQ atomic ops reichen)
## Erfolgskriterium
Job zweimal mit gleichem Key gequeued → läuft einmal, zweite Ausführung schreibt Audit-Skip-Eintrag.
## Hinweise für Slice-Planung
- Idempotency-Key-Store mit TTL
- BullMQ-Wrapper als Higher-Order-Function
- Replay-Tests mit Job-Crash-Szenarien
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,90 @@
# M008 — Apps-Engine: Adapter-Interface + State-Machine
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.2 Teil 1 — Adapter-Schicht für jede Integration
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/03-architektur.md` A.2 + Modul 33a (Block 4)
## Ziel
Abstrakte Adapter-Klasse + 5-Status-State-Machine (wartet/aktiv/eingeschränkt/defekt/getrennt). Eine Dummy-App zum Beweis.
## Pflichtenheft-Bezug
- A.2.1 — Externe Systeme nur über Apps-Engine
- A.2.2 — Adapter-Interface so gebaut, dass weitere Implementierungen ohne Engine-Umbau dazu kommen
- 33a.3 — 5-Status mit Klartext-Hinweis pro Status
## Abhängigkeiten
- **Vorbedingung:** M002, M001
- **Wird benötigt von:** M009, M010 (Apps-Engine), alle Module mit externer Integration (M19, M9, M12, M25, M125, M131, M153)
## Out of Scope
- Konkrete Adapter (KWP, Gmail, AirCall, Stripe, PandaDoc, Calendar) — eigene Module
- Setup-Wizard → M009
- Probe-Scheduler → M010
- Drittanbieter-Marketplace (Phase 2)
## Erfolgskriterium
Dummy-App durchläuft Lifecycle (wartet → aktiv → eingeschränkt → defekt → getrennt), Klartext-Hinweis pro Übergang sichtbar im Test-UI.
## Hinweise für Slice-Planung
- Adapter-Interface als TypeScript-Interface mit klaren Hooks (connect, probe, sync, disconnect)
- State-Machine als XState oder einfache Enum-Transitions mit Audit-Eintrag pro Wechsel
- Dummy-App als Referenz-Implementation
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,88 @@
# M009 — Apps-Engine: Setup-Wizard + Sync-Log
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.2 Teil 2
**Pflichtenheft-Quelle:** Modul 33a Sektionen 33a.2, 33a.4, 33a.7
## Ziel
Generischer Setup-Wizard pro Anbindungs-Art (OAuth, API-Key, Username/PW, Local-Sync-Programm). Sync-Verlauf als Liste mit Klartext-Zusammenfassung pro Vorgang.
## Pflichtenheft-Bezug
- 33a.2 — Setup-Wizard-Reihenfolge: Voraussetzungs-Check → Zugangsdaten → Probe → optional Initial-Sync
- 33a.4 — Vier Sync-Arten (Pull, Push, Webhook, manuell), Verlauf mit Filter
- 33a.7 — Verwaltungs-Bereich „Integrationen" mit Re-Sync, Token-Refresh, Trennen
## Abhängigkeiten
- **Vorbedingung:** M008, M013-M015 (UI-Layer)
- **Wird benötigt von:** alle konkreten Adapter
## Out of Scope
- Probe-Scheduler + Webhook-Schutz → M010
- Konkrete Adapter
## Erfolgskriterium
Dummy-App via Wizard verbinden in <60 Sek; Sync-Verlauf zeigt 5 letzte Vorgänge mit Klartext (z.B. „Sync mit X, 14 Datensätze gepullt, 2 fehlgeschlagen").
## Hinweise für Slice-Planung
- Wizard-Form-Generator aus Adapter-Definition
- Sync-Log mit Filter (Status/Operation/Datum) + Detail-Schublade
- Connect/Disconnect mit Mehrfach-Bestätigung + Audit
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,91 @@
# M010 — Apps-Engine: Probe-Scheduler + Webhook-Sturm-Schutz
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** A.2 Teil 3 + A.16 — Rate-Limit + Anomalie-Erkennung
**Pflichtenheft-Quelle:** Modul 33a Sektionen 33a.3, 33a.5, 33a.6 + A.16
## Ziel
Auto-Probe alle 5/15/30 Min je nach Status. Hard-Limit für Webhook-Events pro Stunde. Anomalie-Erkennung pausiert bei 10x normalem Volumen.
## Pflichtenheft-Bezug
- 33a.3.4 — Probe-Frequenz pro Status (aktiv: 5min, eingeschränkt: 1min, defekt: 15min)
- 33a.5 — Webhook-Sturm-Schutz + Anomalie-Erkennung
- 33a.6 — Schema-Drift-Schutz (für Apps allgemein, KWP-spezifisch in M092)
- A.16.1 — Hartes Limit pro Mandant (Standard 1000 Trigger/h)
- A.16.2 — Anomalie-Erkennung mit 10x-Schwelle
## Abhängigkeiten
- **Vorbedingung:** M008, M009, M011 (Notifications)
- **Wird benötigt von:** alle Adapter, M075-M082 (Automation)
## Out of Scope
- Konkrete Adapter
- Schema-Drift-Sentinel KWP-spezifisch → M092
## Erfolgskriterium
Test-App bei 1500 Webhook-Events/h → 500 verworfen mit Klartext-Notification; bei 10x normalem Volumen pausiert Anomalie-Erkennung mit Klartext-Hinweis.
## Hinweise für Slice-Planung
- Probe-Scheduler als BullMQ-Cron mit Status-Adaption
- Webhook-Receiver mit Rate-Limit pro Mandant + pro Endpoint
- Anomalie-Detector als Rolling-Window-Average + Threshold
- Klartext-Texte aus Pflichtenheft 33a.10 + Modul 17.8 übernehmen
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,88 @@
# M011 — Notification-Service-Layer
**Block:** Querschnitt-Hülle Teil 1 (Bauprinzipien)
**Bauprinzip:** — (Service-Layer für M22 Notifications-Modul)
**Pflichtenheft-Quelle:** Modul 22 (Block 5)
## Ziel
Service-API für In-App, Email, Push als Querschnitt — jeder Modul-Code ruft `notify({channel, recipient, template, payload})`. UI/Settings/Kategorien später (M115-M117).
## Pflichtenheft-Bezug
- Modul 22 als Pflicht-Service für viele Module (Lead-Routing, Mandanten-Lifecycle, Apps-Engine-Status, Automation)
## Abhängigkeiten
- **Vorbedingung:** M001, M002 (Klartext-Templates), M003 (i18n)
- **Wird benötigt von:** ~30+ Modulen
## Out of Scope
- Notification-Center-UI → M115
- User-Settings (Kanäle, Stille Stunden) → M116
- Kategorien + Bündelung → M117
## Erfolgskriterium
Test-Modul ruft `notify({channel: 'push', recipient: userId, template: 'lead_received', payload: {...}})` → Push-Mock erhält korrekt formatierte Nachricht (DE-Klartext).
## Hinweise für Slice-Planung
- Service-Interface + Channel-Adapter (In-App, Email via packages/mail, Push via Capacitor/FCM)
- Template-Registry mit i18n-Keys
- Idempotenz pro Notification (verwendet M007)
- BullMQ-Queue für asynchronen Versand
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,91 @@
# M012 — Workspace-Topologie
**Block:** Querschnitt-Hülle Teil 2 (UI-Hot-Swap-Architektur)
**Architektur-Entscheidung:** Layer-Trennung lint-erzwungen
## Ziel
Drei neue pnpm-Workspaces: `packages/view-models`, `packages/ui-hivegrid`, `packages/ui-subframe`. ESLint-Boundary-Rules verhindern Cross-Layer-Imports.
## Architektur-Bezug
Aus Party-Mode-Diskussion (Sally + Winston + Amelia, 2026-05-10):
- `app/routes/**` → Loaders/Actions, baut View-Models, importiert `packages/ui-hivegrid`
- `app/domain/**` → Domain-Logik, Prisma, BullMQ — KEIN React, KEIN UI
- `packages/view-models/**` → pure Funktionen (domain → VM); KEIN React, KEIN Prisma
- `packages/ui-hivegrid/**` → Library-Adapter; KEIN Prisma, KEIN Auth
- `packages/ui-subframe/**` → Subframe-Output unangefasst; NIE direkt von Routes importiert
## Abhängigkeiten
- **Vorbedingung:** EU-Sterilisation + RR7-Migration der Boilerplate
- **Wird benötigt von:** M013-M017, alle Module mit UI
## Out of Scope
- View-Model-Konvention (Naming, Schemas) → M013
- Subframe-Adapter-Layer → M015
## Erfolgskriterium
`pnpm typecheck` grün; ESLint blockiert Import von `~/db` in `packages/ui-hivegrid/**` als Build-Fehler.
## Hinweise für Slice-Planung
- pnpm-workspace.yaml Anpassung
- TypeScript Project-References zwischen den Paketen
- ESLint-Boundary-Plugin (`eslint-plugin-import-boundaries` oder Custom-Rules)
- Skeleton-Files in jedem Paket damit der Workspace direkt baut
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M013 — View-Model-Konvention
**Block:** Querschnitt-Hülle Teil 2 (UI-Hot-Swap-Architektur)
**Architektur-Entscheidung:** Synchron im Loader, Zod-validiert
## Ziel
Naming-Pattern für View-Models, Discriminated-Unions für Loading/Error, Zod-Schema pro VM, ESLint-Rule gegen React-Imports im VM-Paket.
## Architektur-Bezug
Server bereitet VM einmal vor (synchron im Loader), UI rendert nur — kein client-seitiges Re-Compute.
## Abhängigkeiten
- **Vorbedingung:** M012
- **Wird benötigt von:** M014, M015, alle Module mit UI
## Out of Scope
- Action-Callbacks → M014
## Erfolgskriterium
Beispiel-VM (`KontaktDetailVM`) durchläuft kompletten Pfad: Loader baut, Zod validiert, UI rendert; React-Import in `packages/view-models/**` → Build-Fehler.
## Hinweise für Slice-Planung
- Naming-Konvention: `<Domain><Use>VM` (z.B. `KontaktListVM`, `KontaktDetailVM`)
- Discriminated-Union für Loading/Error/Success (`{state: 'loaded', data: ...}`)
- Zod-Schema neben Type für Runtime-Validierung
- Pure Functions: `toKontaktDetailVM(entity, ctx) → KontaktDetailVM`
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M014 — Action-Callback-Contract
**Block:** Querschnitt-Hülle Teil 2 (UI-Hot-Swap-Architektur)
**Architektur-Entscheidung:** Components erhalten Actions als Callback-Props, kein RR7-Hook intern
## Ziel
Standard-Shape `{ onX: (input) => Promise<Result> | void }` für alle UI-Aktionen. UI-Components rufen Hooks wie `useFetcher` NIE selbst auf — Routes injizieren die Callbacks.
## Architektur-Bezug
Aus den drei Anti-Patterns: kein `useLoaderData`/`useFetcher` in `packages/ui-hivegrid/**`.
## Abhängigkeiten
- **Vorbedingung:** M012, M013
- **Wird benötigt von:** alle interaktiven UI-Components
## Out of Scope
- Konkrete Modul-Actions (jedes Modul definiert eigene)
## Erfolgskriterium
Beispiel: `KontaktDetailPage` empfängt `actions={{onEdit, onArchive}}` als Prop. Test mit `vi.fn()`-Spies bestätigt Callback-Shape; ESLint blockiert `useFetcher` in `packages/ui-hivegrid/**`.
## Hinweise für Slice-Planung
- Callback-Type-Pattern als Conventions-Doku
- Test-Helper für Action-Spy-Setup
- Migrations-Lint (alte Boilerplate-Fetcher-Nutzung in UI flagged)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M015 — Subframe-Adapter-Layer
**Block:** Querschnitt-Hülle Teil 2 (UI-Hot-Swap-Architektur)
**Architektur-Entscheidung:** Brücke `packages/ui-subframe` → `packages/ui-hivegrid`
## Ziel
Mapping-Komponenten in `packages/ui-hivegrid/src/adapters/*` binden Subframe-Primitives an View-Model-Slots. Subframe-Output bleibt unangetastet, Adapter macht die Übersetzung.
## Architektur-Bezug
Designer baut in Subframe, exportiert Code, AI-Agent integriert. Adapter ist die Schnittstelle.
## Abhängigkeiten
- **Vorbedingung:** M012-M014
- **Wird benötigt von:** alle Module mit UI
## Out of Scope
- Konkrete Modul-Pages (jedes Modul nutzt das Pattern)
## Erfolgskriterium
Beispiel-Adapter: Subframe-Komponente `<DataTable>` wird via Adapter zu HiveGrid-`<KontaktList vm={...} actions={...}>` — Replace der Subframe-Komponente erfordert nur Adapter-Update, nicht Routes.
## Hinweise für Slice-Planung
- Adapter-Pattern als Type-Bridge (Subframe-Props ↔ HiveGrid-VM)
- AI-Agent-Briefing in `AGENTS.md` mit Adapter-Beispielen
- Test: Adapter-Snapshot pro Subframe-Component
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,83 @@
# M016 — Visual-Regression-Gate
**Block:** Querschnitt-Hülle Teil 2 (UI-Hot-Swap-Architektur)
**Architektur-Entscheidung:** Playwright Screenshot-Diff in CI (kein separates Storybook)
## Ziel
Vor jedem Merge fotografiert Playwright alle Kern-Pages mit Fixture-VMs und vergleicht mit Baseline. Diff > Threshold → CI bricht mit Klartext-Liste der betroffenen Screens.
## Abhängigkeiten
- **Vorbedingung:** M012-M015
- **Wird benötigt von:** alle Module mit UI (laufendes Gate)
## Out of Scope
- E2E-Flow-Tests mit Login (separat)
- Storybook-Build (entfällt — Subframe ist Catalog)
## Erfolgskriterium
Trivialer Style-Change in `packages/ui-subframe` → CI listet 23 betroffene Pages mit Diff-Bildern. Bewusster Update → Approve-Workflow setzt neue Baseline.
## Hinweise für Slice-Planung
- Playwright Component-Testing-Setup
- Fixture-VM-Repository in `packages/view-models/**/__fixtures__/*.ts`
- CI-Pipeline mit Diff-Artefakt-Upload (für PR-Review)
- Threshold-Konfiguration (Pixel-Diff-Tolerance)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M017 — Hot-Swap-Drill
**Block:** Querschnitt-Hülle Teil 2 (UI-Hot-Swap-Architektur)
**Architektur-Entscheidung:** Synthetischer UI-Lib-Tausch in CI
## Ziel
CI-Job tauscht `packages/ui-hivegrid` gegen `packages/ui-mock` (Minimal-Komponenten ohne Styles), führt Smoke-E2E aus. Wenn die App noch funktioniert (Routen laden, Actions feuern, Loader liefern Daten), ist Hot-Swap real.
## Abhängigkeiten
- **Vorbedingung:** M012-M016
- **Wird benötigt von:** Sicherheitsnetz für M015 + alle UI-Module
## Out of Scope
- Visuelle Regression (separat in M016)
## Erfolgskriterium
`packages/ui-mock` als Drop-in-Replacement: Smoke-E2E grün ohne Code-Änderung außerhalb von `packages/ui-mock`. Versteckte Kopplung in irgendeinem Modul → Drill bricht mit konkreter Datei-Referenz.
## Hinweise für Slice-Planung
- `packages/ui-mock` als Skelett-Lib mit gleicher Component-Signatur, aber `<div>{children}</div>`-Implementations
- CI-Job-Variante: `pnpm test:hot-swap`
- Smoke-E2E-Suite als Pflicht-Pfad pro Route
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,93 @@
# M018 — Mandanten-Anlage
**Block:** Block 1 — Plattform-Fundament · Modul 27 (Anmeldung/Mandanten/Rollen)
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/blocks/block1.md` Abschnitt 27.1
## Ziel
Eine Handwerksfirma kann sich selbst als neuer Mandant registrieren oder wird manuell durch Plattform-Admin angelegt. Eindeutiger Slug, Branche, AGB/AVV-Zustimmung.
## Pflichtenheft-Bezug
- 27.1.1 — Zwei Wege: Self-Service oder manuell durch HiveGrid
- 27.1.2 — Pflichtangaben: Email, Passwort, Firmenname, Vor-/Nachname, Branche, Firmengröße, AGB/Datenschutz/AVV
- 27.1.3 — Optional: Telefon, USt-IdNr.
- 27.1.4 — Slug auto-generiert, vom User änderbar
- 27.1.5 — Live-Eindeutigkeitsprüfung mit Vorschlag bei Konflikt
- 27.1.6 — Slug nach Anlage nicht änderbar (außer durch HiveGrid-Support)
- 27.1.7 — Phase 1: nur SHK aktiv, andere als „Demnächst"
## Abhängigkeiten
- **Vorbedingung:** M001 (Audit), M002 (Klartext), M003 (i18n), M012-M015 (UI-Layer)
- **Wird benötigt von:** M019, M020, M026, M157 (Onboarding), M036 (Plattform-Admin)
## Out of Scope
- Massen-Einladung CSV (Phase 2)
- Eigene Domain pro Mandant (Phase 2, Enterprise)
- Konkrete Daten-Provisionierung → M158
## Erfolgskriterium
Self-Service-Anmeldung: Geerkens-Test-Mandant in <3 Min angelegt, Slug eindeutig, AGB-Zustimmung dokumentiert, Bestätigungs-Email versendet.
## Hinweise für Slice-Planung
- Slug-Generator + Live-Uniqueness-Probe
- Branche-Whitelist (Phase 1: nur SHK aktiv)
- AGB/AVV-Versionierung (siehe M37.16.2)
- Audit-Log-Eintrag pro Mandanten-Anlage
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,89 @@
# M019 — Mandanten-Trennung Hardening
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitt 27.2
## Ziel
Strikte Mandanten-Trennung durchgesetzt — keine Cross-Tenant-Sichtbarkeit, auch nicht in Hintergrund-Jobs, nicht über URL-Manipulation, nicht in zwischengespeicherten Daten oder Dateien.
## Pflichtenheft-Bezug
- 27.2.1 — Durchgehende Verhinderung Cross-Tenant Lese/Schreib/Löschen
- 27.2.2 — Trennung gilt für Dateien + Cache
- 27.2.3 — Hintergrund-Prozesse setzen Mandanten-Bezug explizit
- 27.2.4 — Mehrfach-Mandanten-Mitgliedschaft + Wechsel-Funktion
- 27.2.5 — Mandanten-Auswahl beim Login
## Abhängigkeiten
- **Vorbedingung:** M001, M004, M005, M018
- **Wird benötigt von:** ALLE folgenden Module
## Out of Scope
- URL-Tampering-Probes generisch → M005
## Erfolgskriterium
Pen-Test-Suite mit Cross-Tenant-Probes (Cache-Spillover, BullMQ-Job ohne Tenant, Datei-Cross-Read) liefert konsistent 404 oder Klartext-Block; Mandanten-Wechsel-UI durchgehend erreichbar.
## Hinweise für Slice-Planung
- BullMQ-Job-Wrapper: jeder Job MUSS tenant_id im Payload haben
- Cache-Keys mit tenant_id präfixiert
- Datei-Storage Bucket-Strategie (Scaleway S3 Pro-Tenant-Pfad)
- Mandanten-Switcher in der App-Shell
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,90 @@
# M020 — Email/Passwort-Auth + HIBP + Brute-Force
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitt 27.3
## Ziel
Standard-Login per Email+Passwort. Mindestens 12 Zeichen, HIBP-Leak-Check, Brute-Force-Schutz, 3+-Versuche → Captcha, 5/15-Min Account-Lock.
## Pflichtenheft-Bezug
- 27.3.1 — Email + Passwort als Standard
- 27.3.2 — ≥12 Zeichen, keine Sonderzeichen-Zwang, HIBP-Check mit Klartext-Hinweis
- 27.3.5 — 5/15-Min Account-Lock, Captcha ab 3. Fehlversuch
- 27.3.6 — Passwort-Reset beendet alle Sessions
## Abhängigkeiten
- **Vorbedingung:** M002 (Klartext), M003 (i18n), M001 (Audit), M018, EU-Sterilisation (TOTP/Magic-Link statt remix-auth-google)
- **Wird benötigt von:** M021, M022, alle Module mit Auth-Pflicht
## Out of Scope
- Magic-Link → M021
- TOTP → M022
- Microsoft-Anmeldung (Phase 2)
- Apple/Google-Login (Anti-Liste)
## Erfolgskriterium
Login mit korrektem PW grün, mit falschem PW Klartext-Hinweis + Counter, nach 5 Fehl-Versuchen 15-Min-Lock; HIBP-API-Probe blockiert geleaktes Passwort beim Setzen.
## Hinweise für Slice-Planung
- HIBP via k-Anonymity-API (`https://api.pwnedpasswords.com/range/`)
- Captcha-Integration (Google reCAPTCHA Phase 2 prüfen — alternativ hCaptcha EU)
- Klartext-Texte aus Pflichtenheft 27.15
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,88 @@
# M021 — Magic-Link + Sitzungs-Verwaltung
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitte 27.3.3, 27.5
## Ziel
Magic-Link als alternativer Login (15 Min, einmal nutzbar). Session-Mgmt: 30 Tage default, 4h-Inaktivitäts-Refresh, sichtbare aktive Sessions mit Beend-Funktion.
## Pflichtenheft-Bezug
- 27.3.3 — Magic-Link 15 Min gültig, single-use
- 27.5.1 — 30-Tage Sliding-Session, Admin-konfigurierbar
- 27.5.2 — 4h-Inaktivitäts-Soft-Refresh
- 27.5.3 — Sichtbare aktive Sessions: Gerät, Browser, Standort, letzte Aktivität, Beenden
- 27.5.4 — Auto-Beendigung bei PW/Email/2FA/Deaktivierung
## Abhängigkeiten
- **Vorbedingung:** M020, M011 (Notifications für Email-Versand)
- **Wird benötigt von:** M022, M026
## Out of Scope
- TOTP → M022
## Erfolgskriterium
Magic-Link-Email zugestellt, Klick loggt ein, zweiter Klick liefert Klartext „bereits genutzt"; Session-Liste zeigt aktive Geräte; Session-Beenden funktioniert sofort.
## Hinweise für Slice-Planung
- Single-use Token mit DB-Lookup (kein JWT-only)
- Session-Liste mit Geo-IP-Lookup (lokal, nicht SaaS) für Standort
- Klartext aus 27.15.3
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,89 @@
# M022 — TOTP-2FA + Notfall-Codes
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitt 27.4
## Ziel
TOTP-Authenticator-App als zweiter Faktor (kein SMS). 10 Notfall-Codes, „Gerät 30 Tage merken"-Option mit Widerruf. Pflicht für Admins, optional für Mitarbeiter; Admin kann mandantenweit Pflicht aktivieren.
## Pflichtenheft-Bezug
- 27.4.1 — Nur Authenticator-App, keine SMS
- 27.4.2 — 10 einmalige Notfall-Codes
- 27.4.3 — Pflicht für Mandanten-Admin, optional für andere; Mandanten-weit Pflicht möglich
- 27.4.4 — „30 Tage merken" pro Gerät, einzeln widerrufbar
- 27.4.5 — 2FA-Reset durch Mandanten-Admin (mit Audit) bzw. HiveGrid-Support
## Abhängigkeiten
- **Vorbedingung:** M020, M021
- **Wird benötigt von:** M026 (Lifecycle), M034 (Plattform-Admin-Auth)
## Out of Scope
- Hardware-Keys (FIDO2/WebAuthn) — Phase 2
- SMS — explizit ausgeschlossen
## Erfolgskriterium
TOTP-Setup mit QR-Code in <2 Min; Login mit korrektem Code grün; Notfall-Codes als Download/Druck; „30 Tage merken" persistiert; Admin-Reset im Audit-Log.
## Hinweise für Slice-Planung
- `otpauth`-Library oder vergleichbare EU-neutrale TOTP-Lib
- Notfall-Codes hashed in DB (bcrypt oder argon2)
- QR-Code-Generierung clientside (qrcode.react bereits in Boilerplate)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,87 @@
# M023 — Rollen-Engine + 6 SHK-Standard-Rollen + Gruppen
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitte 27.6, 27.7, 27.8
## Ziel
Rollen-Engine mit Stufen pro Funktionsbereich. Neuer SHK-Mandant erhält 6 Standard-Rollen [N1] (Partner-Liste 19.06.: Geschäftsführer, Projektleiter, Verwaltung, Vertriebler, Kundensupporter, Monteur). Gruppen für Filter ohne Rechte-Wirkung.
## Pflichtenheft-Bezug
- 27.6 — Rollen-Modell mit Stufen + Mehrfach-Rolle
- 27.7 — 6 SHK-Standard-Rollen-Tabelle [N1, 09.05.2026]
- 27.8 — Gruppen für Massen-Aktionen, Filter, Notifications
## Abhängigkeiten
- **Vorbedingung:** M004 (Permission-Wrapper), M018 (Mandant)
- **Wird benötigt von:** M024, alle folgenden Module mit Permission-Bedarf
## Out of Scope
- Schalter pro einzelnem Nutzer (Phase 2)
## Erfolgskriterium
Neuer SHK-Mandant: 10 Rollen automatisch angelegt, Mandanten-Admin kann Rollen umbenennen/anpassen; Gruppen-Anlage + Mitglieder-Zuordnung; Mehrfach-Rolle pro User addiert Rechte korrekt.
## Hinweise für Slice-Planung
- Permission-Definition als TypeScript-Konst + Stufen pro Bereich
- Rollen-Templates als Konfigurations-Datei (Bauprinzip A.3)
- UI für Rollen-Verwaltung in Mandanten-Admin
- 27.6.6 (Büro-/Baustellen-Oberfläche-Default pro Rolle)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,88 @@
# M024 — Mitarbeiter-Einladung / Deaktivierung / Umverteilung
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitt 27.9
## Ziel
Mandanten-Admin lädt Mitarbeiter per Email ein (7-Tage-Link), kann deaktivieren oder entfernen. Vor Entfernung Pflicht-Prüfung auf zugeordnete Aufgaben/Vertrieb/Projekte mit Massen-/Einzel-Umverteilungs-Funktion.
## Pflichtenheft-Bezug
- 27.9.1-27.9.3 — Einladungs-Flow
- 27.9.4 — Deaktivieren (reversibel) vs. Entfernen (irreversibel)
- 27.9.5 — Pflicht-Daten-Umverteilung vor Entfernung
- 27.9.6 — Letzter Admin nicht entfernbar
## Abhängigkeiten
- **Vorbedingung:** M020, M021, M023, M011 (Notifications)
- **Wird benötigt von:** M025 (Lösch-Flow), M036 (Plattform-Admin)
## Out of Scope
- Massen-Einladung CSV (Phase 2)
- Microsoft-SSO (Phase 2)
## Erfolgskriterium
Einladung verschickt + Link funktioniert; Mitarbeiter mit 12 offenen Aufgaben kann erst nach Umverteilung entfernt werden; Deaktivierung sofortige Session-Beendigung.
## Hinweise für Slice-Planung
- Einladungs-Token mit DB-Lookup, 7-Tage-TTL
- Daten-Umverteilungs-UI mit Konflikt-Anzeige (27.15.6)
- Bei bestehendem Account: direkter Mandanten-Beitritt
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,86 @@
# M025 — Konto-Löschung (User + Admin)
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitt 27.10 [N2, 09.05.2026]
## Ziel
DSGVO- + Apple-konformer Lösch-Flow: mehrstufig (Erklärung, Identitäts-Bestätigung, Sonderfall-Prüfung, finale 3-Sek-Wartezeit). 24h Restore-Fenster. Admin-initiierte Löschung mit Audit + Email-Mitteilung.
## Pflichtenheft-Bezug
- 27.10.1-27.10.4 — User-Self-Lösch-Flow + 24h-Restore
- 27.10.5 — Admin-Notification bei Self-Löschung [N2]
- 27.10.6 — Admin-initiierte Löschung mit Pflicht-Begründung [N2]
## Abhängigkeiten
- **Vorbedingung:** M020, M022, M001 (Audit), M011, M024 (Daten-Umverteilung)
- **Wird benötigt von:** M164 (DSGVO-Export), M165 (Lösch-Workflow plattformweit)
## Out of Scope
- Mandanten-Komplett-Löschung → M026
## Erfolgskriterium
User-Self-Löschung: 4-Stufen-Flow erfolgreich, Daten anonymisiert (Name/Email/Avatar weg, „ehemaliger Mitarbeiter" in Verknüpfungen); Admin sieht Notification; Admin-Lösch-Flow gleicher Schutz.
## Hinweise für Slice-Planung
- Anonymisierungs-Strategie: identifizierende Felder weg, Verknüpfungen bleiben
- 24h-Restore-Job (BullMQ delayed)
- Sonderfall: einziger Admin → blockiert (27.10.2 + 27.15.7)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,89 @@
# M026 — Mandanten-Lebenszyklus
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitt 27.11
## Ziel
Mandant durchläuft Zustände (Test, Bezahlend, Zahlung gescheitert, Pausiert, Gesperrt, Kündigung läuft, Gelöscht). Pro Zustand Klartext-Banner und nächste-Handlung. Read-only-Modus bei Zahlungs-Fail.
## Pflichtenheft-Bezug
- 27.11.1 — 7 Zustände
- 27.11.2 — Zahlungs-Fail → Read-only nach 30 Tagen → Kündigung
- 27.11.3 — Freiwillige Pausierung mit reduzierter Gebühr
- 27.11.4 — 30-Tage-Karenz vor finaler Löschung
- 27.11.5 — Klartext-Banner pro Zustand
## Abhängigkeiten
- **Vorbedingung:** M002, M001, M153 (Stripe), M011 (Notifications)
- **Wird benötigt von:** M155 (Trial), M036 (Plattform-Admin)
## Out of Scope
- Stripe-Integration konkret → M153
- Trial+Read-Only-Downgrade-Flow → M155
## Erfolgskriterium
State-Machine durchläuft alle 7 Zustände in Test-Szenarien; Zahlungs-Fail simuliert → Read-only nach 30 Tagen + Klartext-Banner; freiwillige Pause + Reaktivierung funktionieren.
## Hinweise für Slice-Planung
- Lifecycle-State-Machine (XState oder einfache Enum)
- Banner-Component mit Klartext-Text + Lösungs-Knopf pro State
- Stripe-Webhook-Empfänger (delegiert an M153)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,86 @@
# M027 — API-Keys + Tarif-Feature-Gates
**Block:** Block 1 · Modul 27
**Pflichtenheft-Quelle:** block1.md Abschnitte 27.12, 27.13
## Ziel
Mandanten-API-Keys mit Scope, 365-Tage-Rotation, Last-100-Requests-Log. Tarif-Feature-Gates: Funktion in tieferem Tarif → Klartext + Pricing-Link.
## Pflichtenheft-Bezug
- 27.12 — API-Keys (Name, Scope, Rotation, Rate-Limit, Last-100-Requests)
- 27.13 — Tarif-Gates: Klartext + Link zu hivegrid.de/pricing (Apple-Compliance)
## Abhängigkeiten
- **Vorbedingung:** M001 (Audit), M006 (Feature-Flag-Engine)
- **Wird benötigt von:** M161-M163 (Public-API), M153 (Subscriptions)
## Out of Scope
- OAuth2-für-Drittanbieter (Phase 2, Anti-Liste)
- Schreibendes Public-API (Phase 2, Anti-Liste)
## Erfolgskriterium
API-Key-Anlage einmal sichtbar (Sicherheits-Standard); Rate-Limit greift bei >1000 Req/h; Tarif-Gate führt auf Pricing-Link statt In-App-Checkout (Apple-Vorgabe).
## Hinweise für Slice-Planung
- Hashed-Storage (nur Hash in DB, Plain einmal beim Anlegen)
- Last-100-Requests-Ringbuffer pro Key
- Pricing-Link in `t()` (kein Hardcoded-URL)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,88 @@
# M028 — User/Tenant Sprach-Settings + Auflösungs-Reihenfolge
**Block:** Block 1 · Modul 30
**Pflichtenheft-Quelle:** block1.md Abschnitte 30.1-30.3
## Ziel
Pro-User Sprach-Setting + Mandanten-Default. Auflösungs-Reihenfolge: User > Mandant > Browser > DE. Outgoing: Empfänger-Sprache > Kontakt-Sprache > Mandanten-Default > DE. ICU-Pluralisierung.
## Pflichtenheft-Bezug
- 30.1.1-30.1.6 — Grundprinzip (kein Hardcoding, Ganzsatz-Übersetzung, ICU-Plural, Format-Lokalisierung)
- 30.2 — User-/Mandant-/Kontakt-Sprache
- 30.3 — Plattform-Text vs. Mandanten-Inhalte (1-sprachig in Phase 1)
## Abhängigkeiten
- **Vorbedingung:** M003 (i18n-Pflicht-Wiring)
- **Wird benötigt von:** M029, M092 (Email-Versand), alle UI-Module
## Out of Scope
- DeepL-Pipeline → Phase 2
- Mehrsprachige Mandanten-Inhalte → Phase 2
- Auto-Chat-Übersetzung → Phase 2
## Erfolgskriterium
DE-Mitarbeiter und (Phase-2-Mock) PL-Mitarbeiter im selben Mandanten sehen unterschiedliche UI-Sprachen; Email an Kontakt mit Sprach-Setting nutzt Empfänger-Sprache.
## Hinweise für Slice-Planung
- Resolver-Funktion `resolveLocale(user, tenant, browser, default)`
- ICU-MessageFormat (i18next-icu-plugin)
- Format-Helper für Datum/Zahl pro Locale
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M029 — Sprach-Wechsler + Fallback-Hinweise
**Block:** Block 1 · Modul 30
**Pflichtenheft-Quelle:** block1.md Abschnitte 30.4, 30.6
## Ziel
Sofortiger Sprach-Wechsel ohne Reload. Public-Pages (Hilfe, Booking, Forms) mit Cookie-merkendem Sprach-Wähler. Klartext-Hinweise bei unvollständig-befüllter Sprache.
## Pflichtenheft-Bezug
- 30.4.1 — Live-Wechsel ohne Reload
- 30.4.2 — Cookie-merkender Wähler auf Public-Pages
- 30.6 — Klartext bei Fallback (Sprache nicht vollständig befüllt)
## Abhängigkeiten
- **Vorbedingung:** M028, M015 (UI-Layer)
- **Wird benötigt von:** alle UI-Module
## Out of Scope
- Mehrsprachiges Hilfe-Center → Phase 2
## Erfolgskriterium
Sprach-Wechsel im Settings live wirksam; Public-Booking-Page mit Cookie-Persistenz; Test-Modul mit unvollständigem Locale → User sieht 30.6.1-Hinweis.
## Hinweise für Slice-Planung
- Locale-Switcher als reusable Component in `packages/ui-hivegrid`
- Cookie-Strategy für Public-Pages (httpOnly: false, samesite: lax)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M030 — Hell/Dunkel-Modus + Capacitor-Status-Bar
**Block:** Block 1 · Modul 31 (Phase 1)
**Pflichtenheft-Quelle:** block1.md Abschnitt 31.1
## Ziel
Pro-User „System / Hell / Dunkel" mit Live-Wechsel ohne Reload, kein Aufblitzen, Capacitor-Status-Bar respektiert Modus.
## Pflichtenheft-Bezug
- 31.1.1-31.1.6 — Drei Modi, System-Default, Live-Sync, No-Flash via Cookie, Capacitor-Status-Bar
## Abhängigkeiten
- **Vorbedingung:** M015 (UI-Layer), M167 (Capacitor-Setup, dependency-soft — Mobile-Status-Bar erst mit M168)
- **Wird benötigt von:** alle UI
## Out of Scope
- Logo-Upload, Custom-Farben, White-Label → Phase 2 (siehe 31.2-31.4)
## Erfolgskriterium
Mode-Switch live ohne Reload; Mac-Auto-Wechsel auf Dunkel zur Abendzeit greift in offener Session; iOS/Android-Splash respektiert Modus.
## Hinweise für Slice-Planung
- `next-themes` bereits in Boilerplate-Deps
- SSR-Cookie für No-Flash
- Tailwind `dark:`-Variant einheitlich angewendet
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M031 — Feature-Flag Schalter-Definition + Lifecycle
**Block:** Block 1 · Modul 32
**Pflichtenheft-Quelle:** block1.md Abschnitte 32.1, 32.2
## Ziel
Plattform-Admin-UI: Schalter mit Lifecycle (Beta/Roll-out/GA/Abgekündigt), Verantwortlicher, Modul-Tag, Beschreibung, Standard-Wert.
## Pflichtenheft-Bezug
- 32.1 — Definition + Mandanten sehen keine Eigen-Verwaltung in Phase 1
- 32.2 — Pflicht-Stammdaten + Lifecycle-Stufen
## Abhängigkeiten
- **Vorbedingung:** M006 (Feature-Flag-Engine), M034 (Plattform-Admin-Auth)
- **Wird benötigt von:** M032, M033
## Out of Scope
- Filter/Ausnahme-Editoren → M032
- Massen-/Statistik → M033
## Erfolgskriterium
Plattform-Admin legt Schalter „beta-foo" an, sieht ihn in Liste mit Stufe „Beta"; Lifecycle-Wechsel mit Bestätigungs-Dialog.
## Hinweise für Slice-Planung
- Liste mit Filter (Stufe, Modul, Verantwortlicher)
- Detail-Ansicht mit Verlauf
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,86 @@
# M032 — Feature-Flag Filter-Editor + Einzel-Ausnahme-Editor
**Block:** Block 1 · Modul 32
**Pflichtenheft-Quelle:** block1.md Abschnitt 32.3, 32.4, 32.5
## Ziel
Filter-Editor mit Live-Vorschau („12 Mandanten betroffen"). Einzel-Ausnahme mit optionalem Ablaufdatum. Auswertungs-Reihenfolge sichtbar.
## Pflichtenheft-Bezug
- 32.3 — Drei Setz-Wege (Default, Filter, Ausnahme)
- 32.4 — Auswertungs-Reihenfolge (Ausnahme > Filter > Default)
- 32.5 — Verwaltungs-Oberfläche
## Abhängigkeiten
- **Vorbedingung:** M031, M006
- **Wird benötigt von:** M033
## Out of Scope
- Prozentualer Roll-out → Phase 2
- Zeitgesteuerte Aktivierung → Phase 2
## Erfolgskriterium
Filter „SHK-Mandanten >50 MA" → Live-Vorschau zeigt Treffer-Anzahl; Einzel-Ausnahme „Geerkens-Pilot" überstimmt Filter.
## Hinweise für Slice-Planung
- Filter-DSL als JSON mit Mandanten-Properties
- Resolver-Test mit Edge-Cases (32.4)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M033 — Feature-Flag Massen-Funktionen + Statistik + Audit-Historie
**Block:** Block 1 · Modul 32
**Pflichtenheft-Quelle:** block1.md Abschnitte 32.5.6-32.5.8, 32.7, 32.9
## Ziel
Massen-Setzen für 12 Mandanten gleichzeitig. Wirkungs-Statistik („X aktiv, Y nicht"). Änderungs-Historie + Klartext-Hinweise (Filter wirkungslos, Ablaufdatum vergangen).
## Pflichtenheft-Bezug
- 32.5.6-32.5.8 — Massen + Lifecycle-Wechsel + Archiv
- 32.7 — Audit-Protokoll
- 32.9 — Klartext-Hinweise
## Abhängigkeiten
- **Vorbedingung:** M032, M001 (Audit)
- **Wird benötigt von:** Plattform-Admin-Workflow
## Out of Scope
- Nutzungs-Telemetrie → Phase 2
## Erfolgskriterium
Massen-Aktivierung für 12 Mandanten in 1 Aktion; Statistik-Kachel zeigt Live-Trefferzahl; archivierter Schalter bleibt sichtbar mit „Archiv"-Tag.
## Hinweise für Slice-Planung
- Bulk-Action mit Confirmation + Audit
- Klartext aus 32.9 übernehmen
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M034 — Plattform-Admin-Auth (admin.<domain>)
**Block:** Block 1 · Modul 37
**Pflichtenheft-Quelle:** block1.md Abschnitte 37.1, 37.2
## Ziel
Strikt getrennte Plattform-Admin-Welt auf eigener Subdomain (`admin.hivegrid.de`). Eigene Konten, eigene Sessions (8h, 1h Inaktivitäts-Timeout), 2FA Pflicht, IP-Wechsel löst Re-Auth aus.
## Pflichtenheft-Bezug
- 37.1 — Strikte Trennung (Subdomain, Cookies, kein Generalschlüssel)
- 37.2 — Auth-Spezifika (kein Magic-Link, 2FA Pflicht, 5/15 Lock, 10/24h Konto-Sperre, IP-Wechsel = Re-Auth)
## Abhängigkeiten
- **Vorbedingung:** M020, M022, M001
- **Wird benötigt von:** M035-M041
## Out of Scope
- Hardware-Keys → Phase 2
## Erfolgskriterium
admin.hivegrid.de erreichbar, Cookies getrennt von app.hivegrid.de; 2FA-Pflicht beim Anlegen; IP-Wechsel mid-Session → Re-Auth-Prompt.
## Hinweise für Slice-Planung
- Subdomain-Routing in RR7
- Separate Session-Cookies (Pfad/Domain-Lock)
- Erst-Admin per Skript (37.2.8)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,83 @@
# M035 — Plattform-Admin-Dashboard
**Block:** Block 1 · Modul 37
**Pflichtenheft-Quelle:** block1.md Abschnitt 37.5
## Ziel
Live-Dashboard mit Mandanten-Status-Verteilung, MRR-Trend, neue/verlorene Umsätze, System-Status (grün/gelb/rot), Aktivität, Lead-Pipeline-Volumen, Support-Status.
## Pflichtenheft-Bezug
- 37.5 — alle Dashboard-Kacheln + Zeitraum-Wechsler + Click-Through
## Abhängigkeiten
- **Vorbedingung:** M034, M147 (Dashboard-Widget-Engine — Reuse)
- **Wird benötigt von:** Plattform-Operations
## Out of Scope
- Cohort-Analyse → Phase 2
## Erfolgskriterium
Dashboard lädt in <2 Sek; alle Kacheln zeigen Live-Daten; Zeitraum-Wechsler (24h/7d/30d/12mo) funktioniert.
## Hinweise für Slice-Planung
- Recharts (bereits in Boilerplate)
- Caching pro Kachel mit TTL
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M036 — Mandanten-Verwaltung (Plattform-Admin)
**Block:** Block 1 · Modul 37
**Pflichtenheft-Quelle:** block1.md Abschnitt 37.6, 37.14
## Ziel
Liste + Detail aller Mandanten mit Status-Wechsel (mit Pflicht-Begründung), Notizen, Test-Phase-Verlängerung, Sonder-Konditionen, manuelle Mandanten-Anlage, Lösch-Anstoß im Auftrag.
## Pflichtenheft-Bezug
- 37.6 — Liste + Detail + Aktionen
- 37.14 — Manuelle Mandanten-Anlage + Test-Phase-Verlängerung
## Abhängigkeiten
- **Vorbedingung:** M034, M026, M153 (Stripe — für Sonder-Tarife)
- **Wird benötigt von:** Plattform-Operations
## Out of Scope
- Stellvertreter-Anmeldung → M037
- Mandanten-Mitarbeiter-Verwaltung → M038
## Erfolgskriterium
Plattform-Admin sperrt Mandant mit Begründung „Test-Account", Banner erscheint bei nächstem Login des Mandant-Admins; Manuelle Anlage funktioniert; Email-an-Admin verschickt.
## Hinweise für Slice-Planung
- Pflicht-Begründungs-Texte → Audit (37.18.1)
- Lösch-Workflow im Auftrag (Mandanten-Admin bestätigt per Email-Link)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M037 — Stellvertreter-Anmeldung („Login as")
**Block:** Block 1 · Modul 37
**Pflichtenheft-Quelle:** block1.md Abschnitt 37.7
## Ziel
Plattform-Admin mit spezieller Berechtigung kann sich kurzzeitig als Mandanten-Mitarbeiter einloggen (Begründungs-Pflicht, max 30 Min Session, sichtbares Banner für andere Mandanten-Mitarbeiter, voller Audit-Eintrag).
## Pflichtenheft-Bezug
- 37.7 — alle Punkte
## Abhängigkeiten
- **Vorbedingung:** M034, M001 (Audit), M036
- **Wird benötigt von:** Support-Workflow
## Out of Scope
- Allgemeines Schreiben in Mandanten-Daten ohne Stellvertreter-Session bleibt verboten
## Erfolgskriterium
Plattform-Admin loggt mit Begründung „Bug-Reproduktion Ticket 123" als Geerkens-Mitarbeiter ein; Banner sichtbar; nach 30 Min Auto-Logout; Audit-Eintrag dauerhaft mit Begründung.
## Hinweise für Slice-Planung
- Token-basierter Switch (kein Passwort-Sharing)
- Banner in App-Shell mit Klartext (37.7.4)
- Audit mit Pflicht-Begründungs-Feld (37.18.2)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M038 — Mandanten-Mitarbeiter-Verwaltung (Plattform-Admin)
**Block:** Block 1 · Modul 37
**Pflichtenheft-Quelle:** block1.md Abschnitt 37.8
## Ziel
Liste aller Mitarbeiter aller Mandanten. Aktionen: 2FA-Reset, Sessions beenden, Email ändern, Deaktivieren/Reaktivieren, Konto-Löschung im Auftrag, Wiederherstellung in 24h-Karenz.
## Pflichtenheft-Bezug
- 37.8 — alle Punkte
## Abhängigkeiten
- **Vorbedingung:** M034, M022, M025
- **Wird benötigt von:** Support-Workflow
## Erfolgskriterium
Plattform-Admin findet User per Email-Suche, resettet 2FA mit Begründung; Audit-Eintrag korrekt; 24h-Wiederherstellung im Lösch-Workflow funktioniert.
## Hinweise für Slice-Planung
- Volltext-Suche über alle Mandanten
- Aktionen mit Begründungs-Pflicht
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M039 — Plattform-Admin-Konten + Rollen
**Block:** Block 1 · Modul 37
**Pflichtenheft-Quelle:** block1.md Abschnitte 37.3, 37.9
## Ziel
Plattform-Admin-Konten verwalten (Standard-Rollen: Super-Admin, Support, Vertrieb, Engineering, Betrachter). Anlegen mit Pflicht-2FA-Setup-Link. 2FA-Reset durch anderen Super-Admin. Letzter Super-Admin nicht entfernbar.
## Pflichtenheft-Bezug
- 37.3 — Rollen-Modell intern
- 37.9 — Konto-Verwaltung
## Abhängigkeiten
- **Vorbedingung:** M034, M023 (Rollen-Engine wiederverwendet)
- **Wird benötigt von:** Plattform-Operations
## Erfolgskriterium
Super-Admin lädt neuen Plattform-Admin ein; Eingeladener muss bei Setup 2FA aktivieren; 2FA-Reset durch zweiten Super-Admin im Audit; letzter Super-Admin: Self-Demote blockiert (37.18.5).
## Hinweise für Slice-Planung
- Eigene Rollen-Definition für Plattform-Admins (unabhängig von Mandanten-Rollen)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,83 @@
# M040 — Interne Lead-Pipeline (HiveGrid-Verkäufe)
**Block:** Block 1 · Modul 37
**Pflichtenheft-Quelle:** block1.md Abschnitt 37.13
## Ziel
HiveGrid-eigene Lead-Liste (von Vertriebs-Pipeline der Mandanten strikt getrennt). Lead-Eingang über Webformular/Demo-Buchung/Email/Empfehlung/Manuell. Kanban mit Stufen Erstgespräch→Demo→Angebot→Verhandlung→Gewonnen→Verloren. „Promote-to-Tenant"-Funktion.
## Pflichtenheft-Bezug
- 37.13 — alle Punkte
## Abhängigkeiten
- **Vorbedingung:** M034, M036, M147 (Dashboard-Reuse)
- **Wird benötigt von:** Plattform-Vertrieb
## Out of Scope
- Marketing-Automatisierung für Trial-Konversion → Phase 2
## Erfolgskriterium
Lead aus Marketing-Form landet in Liste; Kanban-Drag funktioniert; „Gewonnen → Promote-to-Tenant" führt zu manueller Mandanten-Anlage mit Verknüpfung.
## Hinweise für Slice-Planung
- Strikt getrennte DB-Tabellen (kein Cross-Reference zu Mandanten-Vertrieb)
- Lead-Source-Adapter (Re-Use Apps-Engine?)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,93 @@
# M041 — System-Health + Audit-Anzeige + Datenschutz + Support
**Block:** Block 1 · Modul 37
**Pflichtenheft-Quelle:** block1.md Abschnitte 37.10, 37.11, 37.12, 37.15, 37.16
## Ziel
- System-Health: Service-Status + Hintergrund-Aufgaben + KWP-Sync pro Mandant + Top-10-Fehler
- Audit: plattformweite Sicht auf Plattform-Admin- + Mandanten-Audit-Logs
- Datenschutz: Auftragsverarbeiter-Liste + AVV-Versionen mit Re-Akzeptanz-Aufforderung
- Support: Ticket-Eingang + Antworten + interne Notizen
- Abo-Verwaltung (37.10)
## Pflichtenheft-Bezug
- 37.10 — Abo-Verwaltung mit Stripe-Sync-Vergleich
- 37.11 — System-Health
- 37.12 — Plattform-weites Audit
- 37.15 — Support
- 37.16 — Datenschutz-Verwaltung
## Abhängigkeiten
- **Vorbedingung:** M034, M001, M151 (Audit-Anzeige Wiederverwendung), M153 (Stripe), M174 (Help-Desk)
- **Wird benötigt von:** Plattform-Operations
## Out of Scope
- Vollständiger Helpdesk-Workflow mit SLA → Phase 2
- Cohorten-Analyse → Phase 2
## Erfolgskriterium
Health-Dashboard zeigt KWP-Heartbeat-Status pro Mandant; Audit-Volltext-Suche funktioniert; Support-Ticket per Email→automatisch zugeordnet; AVV-V2-Upload löst Re-Akzeptanz-Email an alle Mandanten-Admins aus.
## Hinweise für Slice-Planung
- Stripe-Diff-View (Klartext-Vergleich bei Abweichung — 37.18.8)
- Aufbewahrungs-Frist 24 Monate (37.12.6)
- Massen-Email an Mandanten-Admins mit Pre-Send-Pflicht (37.18.10)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,89 @@
# M042 — Kontakt-Stammdaten
**Block:** Block 2 — Stammdaten · Modul 1 (CRM-Kern)
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/blocks/block2.md` Abschnitt 1.1, 1.5
## Ziel
Personen-CRUD: Anrede, Titel, Name, Mehrfach-Email/Telefon mit Typ, Adresse, Geburtstag, Sprache, Verantwortlicher, Quelle, Privatkunde/Geschäft. Inline-Edit, Quick-Actions (Anruf, Mail, Termin, Aufgabe).
## Pflichtenheft-Bezug
- 1.1 — alle Stammdaten + Pflichtfelder + Mehrfach-Werte
- 1.5 — Detail-Ansicht mit Inline-Edit und Quick-Actions
- 1.10 — Permission-Stufen (Eigene/Alle, Bearbeiten, Admin)
- 1.13 — Klartext-Fehlertexte
## Abhängigkeiten
- **Vorbedingung:** M001, M004 (Permissions), M013 (View-Models), M015 (UI-Layer)
- **Wird benötigt von:** M043, M044, alle Module mit Kontakt-Verknüpfung
## Out of Scope
- Firma → M043
- Schlagwörter/Custom-Felder → M044
- Listen-Ansicht → M046
## Erfolgskriterium
Kontakt mit Pflichtfeldern angelegt, Inline-Edit funktioniert, 404 statt 403 bei fremdem Zugriff (1.10.1), Endgültig-Löschen mit Verknüpfungs-Auflistung.
## Hinweise für Slice-Planung
- Mehrfach-Email/Telefon-Schema mit Primär-Markierung
- Multi-Firma-Verknüpfung mit Rolle (1.1.3)
- Archivieren vs. Löschen Pattern (1.1.6)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M043 — Firma-Stammdaten + Hierarchie
**Block:** Block 2 · Modul 1
**Pflichtenheft-Quelle:** block2.md Abschnitt 1.2, 1.6
## Ziel
Firma-CRUD: Name, Rechtsform, USt-IdNr, Branche, Webseite, Standort. Verknüpfte Kontakte mit Rolle, primärer Ansprechpartner. Aktivitäts-Verlauf zeigt auch Aktivitäten der Kontakte.
## Pflichtenheft-Bezug
- 1.2 — Firma-Stammdaten
- 1.6 — Detail-Ansicht (kontakte verwalten, Aktivitäts-Aggregation)
## Abhängigkeiten
- **Vorbedingung:** M042
- **Wird benötigt von:** M044, M053 (Sales-Pipeline-Verknüpfung), M060 (Auftrag)
## Erfolgskriterium
Firma anlegen, mehrere Kontakte verknüpfen, Rolle pro Kontakt; Aktivitäts-Verlauf zeigt Activity-Summe der verknüpften Kontakte.
## Hinweise für Slice-Planung
- Mutter-Tochter-Hierarchie als optionales Feld
- Primär-Ansprechpartner-Logik
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,88 @@
# M044 — Schlagwörter + Custom-Felder + Datenherkunft
**Block:** Block 2 · Modul 1
**Pflichtenheft-Quelle:** block2.md Abschnitte 1.3, 1.9, 1.5.4 (Notizen)
## Ziel
Tags mit 8 Standard-Farben, ad-hoc + verwaltet. Custom-Felder pro Workspace (Text, Zahl, Datum, Auswahl, Mehrfach, Bool, URL, Email) für Kontakte/Firmen/Leads getrennt konfigurierbar. SHK-Standard-Custom-Felder beim neuen Mandanten (1.1.5).
## Pflichtenheft-Bezug
- 1.3 — Custom-Felder pro Workspace
- 1.9 — Tags
- 1.5.4 — Notizen Markdown
## Abhängigkeiten
- **Vorbedingung:** M042, M043
- **Wird benötigt von:** alle Module mit Tag/Custom-Feld-Verknüpfung
## Out of Scope
- Custom-Felder als Automation-Trigger → Phase 2 (1.12.3)
- Erweiterte Validierung → Phase 2 (1.12.4)
- Feld-spezifische Permissions → Phase 2 (1.12.5)
## Erfolgskriterium
Tag „VIP" ad-hoc per Eingabe + Vorschlag-Knopf angelegt; Custom-Feld „Heizungsanlage Hersteller" als Pflicht setzbar; Tag-Merge-Funktion vereinigt Verwendungen.
## Hinweise für Slice-Planung
- Tag-Schema mit Color-Constraint (8 Farben)
- Custom-Field-Definition als JSON-Schema
- SHK-Standard-Felder als Konfigurations-Datei (Bauprinzip A.3)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M045 — Aktivitäts-Stream
**Block:** Block 2 · Modul 1
**Pflichtenheft-Quelle:** block2.md Abschnitt 1.7
## Ziel
Chronologischer Verlauf an Kontakten/Firmen/Leads/Verkaufsfällen/Projekten. Erfasst automatisch: Anrufe, Emails, Notizen, Tag-Wechsel, Verantwortlichen-Wechsel, Stage-Wechsel, Datei-Uploads, Forms, Aufgaben, Termine, Lead-Übernahmen, Won/Lost, Automationen, KI-Aktionen.
## Pflichtenheft-Bezug
- 1.7.1-1.7.7 — alle Punkte
## Abhängigkeiten
- **Vorbedingung:** M042, M001 (Audit als Datenquelle), M004 (Permission-aware)
- **Wird benötigt von:** M046, alle „Detail-Ansichten" anderer Entitäten
## Erfolgskriterium
Aktivitäts-Eintrag pro System-Event automatisch erstellt; Filter nach Typ/Mitarbeiter/Zeitraum; Gruppierung „heute/gestern/diese Woche/älter"; Lese-Schutz bei verbotenem Cross-Tenant-Zugriff (1.7.7).
## Hinweise für Slice-Planung
- Activity-Stream als unveränderlicher Append-only Log
- Re-use Audit-Daten wo möglich (M001)
- Volltext-Such-Index (re-use M056)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,87 @@
# M046 — Listen + Segmente + DSGVO-Felder
**Block:** Block 2 · Modul 1
**Pflichtenheft-Quelle:** block2.md Abschnitte 1.4, 1.5.8, 1.8
## Ziel
Listen-Ansichten mit Filtern, Sortierung, Spalten-Konfiguration, Sammel-Aktionen, „Mehr laden" für 10K+. Duplikat-Erkennung mit Klartext-Hinweis + Merge-Tool. DSGVO-Export pro Kontakt als ZIP.
## Pflichtenheft-Bezug
- 1.4 — Listen-Ansichten + Filter + Sammel-Aktionen
- 1.5.7-1.5.8 — Lösch-Bestätigung + DSGVO-Export
- 1.8 — Suche + Duplikat-Erkennung mit Merge
## Abhängigkeiten
- **Vorbedingung:** M042-M045, M056 (Suche)
- **Wird benötigt von:** Lead-Liste, alle „Listen-Module"
## Out of Scope
- KI-Smart-Match → Phase 2 (1.12.1)
- Auto-Merge-Regeln → Phase 2 (1.12.2)
## Erfolgskriterium
Liste mit 10K+ Einträgen läuft flüssig (Mehr-Laden); Sammel-Tag-Setzen für 200 Kontakte; Duplikat-Tool zeigt Treffer-Paar nebeneinander mit Aktivitäten-Anzahl.
## Hinweise für Slice-Planung
- Cursor-Pagination für große Listen
- Filter-DSL kombinierbar (UND/ODER mit Klammer)
- Merge-UI mit Field-by-Field-Wahl (1.8.5)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,86 @@
# M047 — Lead-Inbox + Quellen-Adapter
**Block:** Block 2 · Modul 2
**Pflichtenheft-Quelle:** block2.md Abschnitte 2.1, 2.2
## Ziel
Lead-Schema mit Quellen-Adaptern (Form, Email, Telefon, Manuell, Apps-Engine). Pro Quelle Standard-Verantwortlicher + Standard-Tags. Live-Aktualisierung der Inbox.
## Pflichtenheft-Bezug
- 2.1 — Lead-Definition + Quellen
- 2.2 — Auto-Anlage pro Quelle (Form, Email, Anruf, Manuell, Apps-Engine)
## Abhängigkeiten
- **Vorbedingung:** M008-M010 (Apps-Engine), M042 (Kontakt für Match)
- **Wird benötigt von:** M048-M051
## Out of Scope
- WhatsApp → Phase 2
- CSV/JSON-Import → Phase 2 (2.12.1)
## Erfolgskriterium
Form-Submit erzeugt Lead live in Inbox; Email an Mailbox von unbekanntem Absender wird Lead; Telefon-Anruf von unbekannter Nummer wird Lead mit Aufzeichnungs-Link.
## Hinweise für Slice-Planung
- Quellen-Adapter via Apps-Engine (M008)
- Kontakt-Match-Probe beim Eingang
- Real-Time-Updates (websocket via packages/realtime)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M048 — Lead-Routing pro Quelle [N4]
**Block:** Block 2 · Modul 2
**Pflichtenheft-Quelle:** block2.md Abschnitt 2.11 [N4, 09.05.2026]
## Ziel
Mandanten-konfigurierbares Routing pro Quelle: Status-Default, Verantwortlicher (Person/Round-Robin), Tags, Auto-Verkaufsfall mit Pipeline-Wahl + Bedingungen.
## Pflichtenheft-Bezug
- 2.11.1-2.11.6 — alles [N4]
## Abhängigkeiten
- **Vorbedingung:** M047, M053 (Sales-Pipeline für Auto-Verkaufsfall)
- **Wird benötigt von:** M049
## Erfolgskriterium
Beispiel Geerkens (2.11.4): Form „Kontaktformular Webseite" → Status „Neu", Round-Robin Vertriebs-Team, Tag „Webseite", Auto-Verkaufsfall in „Anlagen-Verkauf" Pipeline; Routing-Aktionen im Lead-Activity-Log mit Klartext.
## Hinweise für Slice-Planung
- Routing-Regel-DSL mit Bedingungs-Kombinatoren
- Reihenfolge-Auswertung (erste Treffer-Regel)
- Round-Robin-State pro Gruppe
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,82 @@
# M049 — Auto-Verkaufsfall-Anlage
**Block:** Block 2 · Modul 2 + Modul 3
**Pflichtenheft-Quelle:** block2.md 2.11.2 + block3.md Modul 3.7
## Ziel
Aus qualifiziertem Lead automatisch Verkaufsfall in Ziel-Pipeline anlegen mit vorausgefüllten Daten. Routing-Regeln (M048) entscheiden Pipeline + Stufe.
## Pflichtenheft-Bezug
- 2.5 — Übernahme-Modal (manuell)
- 2.11.2 — Auto-Anlage durch Routing
- 3.7 — Quellen-Liste für Verkaufsfall (inkl. Lead, Form, Email, Anruf, Automation)
## Abhängigkeiten
- **Vorbedingung:** M047, M048, M060 (Verkaufsfall-CRUD)
- **Wird benötigt von:** Geerkens-Workflow
## Erfolgskriterium
Form-Submit „PV-Konfigurator" mit Volumen-Feld → Auto-Verkaufsfall in Premium-Pipeline mit Volumen vorausgefüllt + Activity-Log-Eintrag.
## Hinweise für Slice-Planung
- Auto-Anlage als Routing-Action in M048
- Daten-Mapping pro Form-Feld konfigurierbar
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M050 — Spam/Duplikat-Erkennung
**Block:** Block 2 · Modul 2
**Pflichtenheft-Quelle:** block2.md Abschnitte 2.7, 2.8
## Ziel
Spam-Schutz pro Quelle (Stundenlimit, IP-Limit, Anomalie 10x). Optionale Heuristiken (IP-Blocklist, Wegwerf-Mail, Honeypot, zu schnelle Submission). Auto-Lösch-Job nach 30 Tagen für Spam, 90 Tage für Verloren.
## Pflichtenheft-Bezug
- 2.7 — DSGVO-Auto-Löschung
- 2.8 — Spam-Schutz mit konfigurierbaren Heuristiken
## Abhängigkeiten
- **Vorbedingung:** M047, M010 (Apps-Engine Webhook-Schutz analog)
- **Wird benötigt von:** stabile Lead-Inbox
## Out of Scope
- KI-Smart-Match → Phase 2
## Erfolgskriterium
Form-Flut mit 247 Submissions/5 Min → Quelle pausiert + Klartext-Notification (2.8.3); Spam-Lead nach 30 Tagen Auto-gelöscht mit anonymisiertem Activity-Eintrag.
## Hinweise für Slice-Planung
- Per-Source Rate-Limit + IP-Limit
- Anomalie-Detector wiederverwendbar (re-use M010)
- BullMQ-cron für Auto-Lösch-Job
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,86 @@
# M051 — Lead-Status-Pipeline + Verlust-Gründe + Notifications
**Block:** Block 2 · Modul 2
**Pflichtenheft-Quelle:** block2.md Abschnitte 2.3-2.6, 2.9, 2.10
## Ziel
Status-Verlauf (Neu→Qualifiziert→Übernommen / Verloren / Spam). Listen-Detail-UI mit Quick-Actions, Sammel-Aktionen mit gemischten-Rechte-Hinweis. Statistik-Seite + CSV-Export.
## Pflichtenheft-Bezug
- 2.3 — Listen-Ansicht
- 2.4 — Detail mit Quick-Actions
- 2.5 — Übernahme zu Kontakt
- 2.6 — Status-Übergänge mit Begründungs-Pflicht
- 2.9 — Lead-Statistiken
- 2.10 — Permissions
## Abhängigkeiten
- **Vorbedingung:** M047-M050, M042 (Kontakt für Übernahme)
- **Wird benötigt von:** Geerkens-Lead-Workflow
## Erfolgskriterium
Lead durchläuft alle Status-Übergänge; Übernahme-Modal legt Kontakt + ggf. Firma + ggf. Verkaufsfall in einem Schritt an; Statistiken mit Aufschlüsselungen pro Quelle/Vertriebler.
## Hinweise für Slice-Planung
- Status-State-Machine mit Begründungs-Pflichten
- Übernahme-Modal mit Sub-Forms (Kontakt, Firma, Verkaufsfall)
- Sammel-Aktionen mit Pre-Check (2.10.1)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M052 — Datei-Upload (Anti-Virus + Format-Whitelist)
**Block:** Block 2 · Modul 23
**Pflichtenheft-Quelle:** block2.md Modul 23 (Block 2 zweite Hälfte — wird beim TC-Plan vor Ort gelesen)
## Ziel
Datei-Upload mit Anti-Virus-Scan (ClamAV-EU oder vergleichbar), Format-Whitelist, Max-Size-Limit, Foto-Auto-Compression.
## Pflichtenheft-Bezug
- Modul 23 Sektionen 23.1-23.4 (Upload-Pfad, Validierung)
## Abhängigkeiten
- **Vorbedingung:** M001, M004
- **Wird benötigt von:** M053-M055, M095 (KWP-Archiv-Sync), M137 (Customer-Portal-Upload), M092 (Email-Anhänge)
## Erfolgskriterium
Upload mit Standard-Format funktioniert; .exe abgelehnt mit Klartext; Foto >10MB auto-compressed.
## Hinweise für Slice-Planung
- Browser-Image-Compression (`browser-image-compression` ist in Boilerplate-Deps)
- Anti-Virus über externes EU-Service oder ClamAV-Self-Hosted
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,82 @@
# M053 — Speicher-Backend (S3 auf Scaleway)
**Block:** Block 2 · Modul 23
**Pflichtenheft-Quelle:** block2.md Modul 23 + Bauprinzip A.12
## Ziel
S3-kompatibler Storage auf Scaleway (EU). Pro-Tenant-Bucket-Pfad. Signed-URLs für temporären Read-Zugriff.
## Pflichtenheft-Bezug
- A.12.1 — Hosting Scaleway
- 27.2.2 — Mandanten-Trennung gilt für Dateien
## Abhängigkeiten
- **Vorbedingung:** M052
- **Wird benötigt von:** M054, M055
## Erfolgskriterium
Datei landet in `s3://bucket/tenant_<id>/<file-id>`; Signed-URL läuft nach Konfiguration ab; Cross-Tenant-Read-Versuch blockiert.
## Hinweise für Slice-Planung
- `packages/storage` (bereits in Boilerplate)
- Scaleway Object-Storage (S3-kompatibel)
- Pre-signed-URL TTL konfigurierbar
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M054 — Datei: Permissions + Sharing + Versionierung
**Block:** Block 2 · Modul 23
**Pflichtenheft-Quelle:** block2.md Modul 23
## Ziel
Pro-Datei-Permissions (sichtbar für Rollen/Personen). Sharing-Link mit Ablaufdatum. Versionierung (frühere Versionen aufbewahren).
## Pflichtenheft-Bezug
- Modul 23 Sektionen Permissions + Versionierung
## Abhängigkeiten
- **Vorbedingung:** M052, M053, M004 (Permission-Wrapper)
- **Wird benötigt von:** M055, alle Module mit Datei-Verknüpfung
## Erfolgskriterium
Datei mit Permission „nur Projekt-Mitglieder" sichtbar nur für diese; Share-Link läuft am gewählten Datum ab; vorherige Version restorebar.
## Hinweise für Slice-Planung
- Permission-Layer auf Datei-Ebene
- Version-Snapshots mit Diff-Anzeige
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M055 — Datei: Suche + Tagging + Archivierung
**Block:** Block 2 · Modul 23
**Pflichtenheft-Quelle:** block2.md Modul 23
## Ziel
Volltext-Suche in Dateien (PDF/Office), Tagging, Archivierungs-Workflow.
## Pflichtenheft-Bezug
- Modul 23 Sektionen Suche + Archiv
## Abhängigkeiten
- **Vorbedingung:** M052-M054, M056 (Suche)
- **Wird benötigt von:** M058 (Such-UI), Geerkens-Datei-Workflow
## Erfolgskriterium
PDF mit OCR-Text findbar in Such-Dialog; Archivierung blendet aus aktiver Sicht aus.
## Hinweise für Slice-Planung
- OCR-Pipeline (Phase 1 evtl. Tesseract; Phase 2 EU-OCR-API)
- Tag-Re-use (M044)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M056 — Globale Suche: Such-Index
**Block:** Block 2 · Modul 24
**Pflichtenheft-Quelle:** block2.md Modul 24
## Ziel
Such-Index über Kontakte, Firmen, Leads, Verkaufsfälle, Aufträge, Aufgaben, Dateien, Notizen. Postgres FTS oder Meilisearch.
## Pflichtenheft-Bezug
- Modul 24 Sektionen Index + Volltext
## Abhängigkeiten
- **Vorbedingung:** M042-M046
- **Wird benötigt von:** M057, M058
## Erfolgskriterium
Index-Refresh bei Datensatz-Änderung; <500ms für 100K+ Datensätze.
## Hinweise für Slice-Planung
- Postgres FTS bevorzugen (kein Extra-Service)
- Update-Trigger via Prisma-Middleware (re-use M001)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M057 — Globale Suche: Permission-aware
**Block:** Block 2 · Modul 24
**Pflichtenheft-Quelle:** block2.md Modul 24 + A.5
## Ziel
Suche zeigt nur Treffer, die der User sehen darf — kein Leak via Snippet/Highlight.
## Pflichtenheft-Bezug
- A.5.1 — auch in Suche darf nur sichtbar werden, was Recht hat
## Abhängigkeiten
- **Vorbedingung:** M056, M004
- **Wird benötigt von:** M058
## Erfolgskriterium
Vertriebler ohne CRM-Recht: Such-Treffer für Kontakt erscheint nicht; Volume-Feld in Verkaufsfall: Snippet ohne Volume-Wert für unberechtigten User (3.11.4).
## Hinweise für Slice-Planung
- Filter im SQL-Query, nicht erst im Result
- Field-Level-Redact für Snippets
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M058 — Globale Suche: UI + Saved-Searches
**Block:** Block 2 · Modul 24
**Pflichtenheft-Quelle:** block2.md Modul 24
## Ziel
Cmd-K-Suche-Overlay (kbar). Filter pro Entität. Bis 5 Saved-Searches pro User. Such-Verlauf.
## Pflichtenheft-Bezug
- Modul 24 Such-UI
## Abhängigkeiten
- **Vorbedingung:** M056, M057, M015 (UI-Layer)
- **Wird benötigt von:** Geerkens-Daily-Workflow
## Erfolgskriterium
Cmd-K öffnet Suche; Treffer kategorisiert (Kontakte, Verkaufsfälle, Aufträge); Saved-Search „Meine offenen Leads" persistiert.
## Hinweise für Slice-Planung
- `kbar` ist in Boilerplate-Deps
- Saved-Search-Schema pro User
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M059 — Sales-Pipeline: Konfiguration + SHK-Standard-Pipeline
**Block:** Block 3 · Modul 3
**Pflichtenheft-Quelle:** block3.md Abschnitt 3.2
## Ziel
Pipeline-CRUD mit Stufen, Stufen-Typen (offen/gewonnen/verloren), Wahrscheinlichkeit, Stuck-Schwelle, Farbe. Drag-&-Drop für Reihenfolge. SHK-Standard-Pipelines beim neuen Mandanten.
## Pflichtenheft-Bezug
- 3.2.1-3.2.9 — alle Punkte
- 3.13.1-3.13.3 — Klartext-Fehlertexte (keine Gewonnen-Stufe etc.)
## Abhängigkeiten
- **Vorbedingung:** M001, M004, M158 (SHK-Provisionierung)
- **Wird benötigt von:** M060-M064
## Erfolgskriterium
Mandant kann „Anlagen-Verkauf" + „Wartungsverträge" Pipelines parallel führen; Stufe ohne Gewonnen-Typ → Klartext-Block; Drag-&-Drop sortiert Stufen.
## Hinweise für Slice-Planung
- Pipeline-Schema in Prisma
- Standard-Pipeline-Definition als Konfigurations-Datei (Bauprinzip A.3)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,83 @@
# M060 — Verkaufsfall-CRUD + Pflichtfeld Vertriebler [N6]
**Block:** Block 3 · Modul 3
**Pflichtenheft-Quelle:** block3.md Abschnitte 3.1, 3.5, 3.7, 3.9
## Ziel
Verkaufsfall mit eindeutiger Nummer (D-2026-0042), Titel, Pipeline/Stufe, Volumen, Termin, Pflichtfeld-Vertriebler [N6], verknüpfter Kontakt + optional Firma. Anlage manuell + aus Lead/Form/Email/Anruf/Automation. Stufen-Übergänge mit Begründungs-Pflicht (Verloren) + 24h-Undo (Gewonnen/Verloren).
## Pflichtenheft-Bezug
- 3.1 — Stammdaten + Vertriebler-Pflicht [N6]
- 3.5 — Stufen-Übergänge + 24h-Undo
- 3.7 — Quellen
- 3.9.4 — Klartext-Banner pro Zustand
## Abhängigkeiten
- **Vorbedingung:** M042, M043, M059
- **Wird benötigt von:** M061-M064
## Erfolgskriterium
Verkaufsfall mit Pflichtfeldern angelegt, Vertriebler-Default aus Routing (M048); Stufen-Wechsel mit Begründungs-Pflicht + 24h-Undo funktioniert.
## Hinweise für Slice-Planung
- Sequenz-Generator für Verkaufsfall-Nummer
- Quick-Action „Termin anlegen mit Daten-Übergabe" (3.9.5 [N17])
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,82 @@
# M061 — Sales-Pipeline: Kanban-UI + Drag&Drop
**Block:** Block 3 · Modul 3
**Pflichtenheft-Quelle:** block3.md Abschnitt 3.4, 3.11
## Ziel
Kanban-Spalten pro Stufe mit Live-Aktualisierung, Drag-&-Drop, Karten-Inhalt (Titel, Volumen falls Recht, Verantwortlicher, Tags, Stuck-Indikator). Tabellen-Ansicht alternativ. Cross-Pipeline-Sicht. Suche + Filter + Sammel-Aktionen + CSV-Export.
## Pflichtenheft-Bezug
- 3.4.1-3.4.11 — alle Punkte
- 3.11.1-3.11.6 — Permission-Stufen mit Volumen-Sonderregel
## Abhängigkeiten
- **Vorbedingung:** M060, M015 (UI), M057 (Permission-aware Search)
- **Wird benötigt von:** Geerkens-Daily-Workflow
## Erfolgskriterium
Kanban zeigt 200 Verkaufsfälle flüssig; Drag-&-Drop zwischen Stufen; Bauleiter sieht Karten OHNE Volumen (3.11.4); Live-Updates wenn anderer User Karte verschiebt.
## Hinweise für Slice-Planung
- `react-beautiful-dnd` oder `react-dnd` (in Boilerplate-Deps)
- Field-Level-Redact für Volumen
- WebSocket via packages/realtime
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M062 — Sales-Pipeline: Verlust/Gewinn-Gründe [N8]
**Block:** Block 3 · Modul 3
**Pflichtenheft-Quelle:** block3.md Abschnitt 3.3 [N8, 09.05.2026]
## Ziel
Mandanten-pflegbare Verlust- und Gewinn-Gründe (Pflicht/Optional pro Mandant einstellbar). 5 SHK-Standard-Gründe je Liste beim neuen Mandanten. Auswertungs-Aggregation pro Grund.
## Pflichtenheft-Bezug
- 3.3.1-3.3.5 — alle Punkte [N8]
## Abhängigkeiten
- **Vorbedingung:** M060, M158 (SHK-Provisionierung)
- **Wird benötigt von:** M064 (Reporting)
## Erfolgskriterium
Mandanten-Admin pflegt Gründe; Verloren-Markierung verlangt Grund (oder optional je Mandanten-Setting); Auswertung „Top-3-Verlust-Gründe pro Vertriebler" zeigt Häufigkeiten.
## Hinweise für Slice-Planung
- Archivierbar, nicht hart löschbar (sonst Auswertungen brechen)
- Konfigurations-Toggle „Pflicht/Optional" pro Liste
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M063 — Auto-Auftragsprojekt [N7] + Setter-Closer [N17]
**Block:** Block 3 · Modul 3
**Pflichtenheft-Quelle:** block3.md Abschnitte 3.6, 3.9.5 [N7, N17, N9]
## Ziel
Won-Handoff zur Auftragspipeline mit Pipeline/Stufen-Wahl. Mandanten-Konfiguration: Projekt-Anlage bei Gewonnen ODER bei Verkaufsfall-Anlage [N7]. Setter-Closer-Termin direkt aus Verkaufsfall mit Auto-Daten-Übernahme [N17]. Wartung/Service explizit kein Projekt [N9].
## Pflichtenheft-Bezug
- 3.6.1-3.6.7 — Won-Handoff + Mandanten-Konfiguration [N7] + Wartung/Service-Hinweis [N9]
- 3.9.5 — Setter-Closer-Workflow [N17]
## Abhängigkeiten
- **Vorbedingung:** M060, M065 (Auftragspipeline-Konfig), M119 (Calendar-Sync)
- **Wird benötigt von:** M064
## Out of Scope
- Service-Modul → Phase 2 [N9]
## Erfolgskriterium
Won-Verkaufsfall → Modal mit „Projekt anlegen?" → Auftragspipeline-Wahl + Anlage in einem Schritt; Setter klickt im Verkaufsfall „Termin für Closer" → Termin mit Adresse/Volumen/Fotos vorausgefüllt im Closer-Kalender.
## Hinweise für Slice-Planung
- Mandant-Konfig „Option A vs. B" (3.6.7)
- Field-Mapping pro Sales-Pipeline → Termin-Layout (3.9.5)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M064 — Sales-Pipeline: Reporting + KWP-Sync
**Block:** Block 3 · Modul 3
**Pflichtenheft-Quelle:** block3.md Abschnitte 3.8, 3.10
## Ziel
Forecast (gewichtetes Volumen pro Stufe), realisierter Umsatz, Vertriebler-Kennzahlen, Stufen-Übergangs-Quoten, Verlust-Gründe-Verteilung. Stuck-Erkennung + Auto-Archivierung. Optional KWP-Sync für gewonnene Verkaufsfälle (Wartungs-Verträge ausgenommen [N9]).
## Pflichtenheft-Bezug
- 3.8 — Stuck + Auto-Archivierung
- 3.10 — Forecast + KPIs
## Abhängigkeiten
- **Vorbedingung:** M060, M062, M063, M147 (Dashboard für Widgets)
- **Wird benötigt von:** GF-Dashboard, KWP-Anbindung
## Erfolgskriterium
Forecast-Berechnung über alle Pipelines stimmt; Stuck-Verkaufsfälle als Liste; Verloren-Verkaufsfälle nach 90d auto-archiviert.
## Hinweise für Slice-Planung
- Tägliche Stuck-/Archiv-Jobs (BullMQ-cron)
- Forecast-Aggregation als View oder berechnete Spalte
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M065 — Auftragspipeline: Konfiguration
**Block:** Block 3 · Modul 4
**Pflichtenheft-Quelle:** block3.md Abschnitt 4.2, 4.3
## Ziel
Auftrags-Pipelines mit Stufen + Abnahme-Pflicht-Stufe (4.2.3-4.2.4). SHK-Standard: Anlagen-Installation, Wartungseinsatz, Notfall-Reparatur. Projekt-Vorlagen (Default-Pipeline, Mitarbeiter-Rollen, Aufgaben, Plantafel-Einträge, Custom-Felder).
## Pflichtenheft-Bezug
- 4.2 — Pipeline-Konfig + Abnahme-Pflicht
- 4.3 — Projekt-Vorlagen
## Abhängigkeiten
- **Vorbedingung:** M001, M004, M059 (Pipeline-Engine reuse)
- **Wird benötigt von:** M066-M070
## Erfolgskriterium
Mandant kann 3 SHK-Standard-Pipelines mit korrekten Stufen + Abnahme-Pflicht setzen; Vorlage „Standard-Anlagen-Installation" füllt neue Projekte mit 3 Mitarbeiter-Rollen + 6 Default-Tasks.
## Hinweise für Slice-Planung
- Stufen-Typ „erfordert Abnahme" als Flag
- Vorlagen als Konfigurations-Daten (A.3)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,86 @@
# M066 — Auftrag-CRUD + KWP-Dokumenten-Archiv [N5]
**Block:** Block 3 · Modul 4
**Pflichtenheft-Quelle:** block3.md Abschnitte 4.1, 4.4, 4.5, 4.8, 4.9, 4.12
## Ziel
Auftragsprojekt mit eindeutiger Nummer (P-2026-0042), Pipeline/Stufe, Volumen, Geplanter/Tatsächlicher End-Termin, Baustellen-Adresse, Projektleiter, Mitarbeiter-Liste, Ursprung-Verkaufsfall (optional), Stornierungs-Grund. Anlage manuell + aus Won-Handoff + Form + Booking + Notfall-Anruf + Automation. Detail-Ansicht mit Sales-Verlauf-Sektion read-only. Hard-Delete-Block bei Abnahme-Protokollen.
## Pflichtenheft-Bezug
- 4.1 — Stammdaten
- 4.4 — Quellen
- 4.5 — Spalten/Tabellen-Ansicht mit Drag-&-Drop
- 4.8 — Detail-Ansicht inkl. Sales-Verlauf-Sektion read-only mit Volumen-Permission-Schutz
- 4.9 — Lifecycle (Vor/Rück-Wechsel, Storno-Grund-Pflicht, Hard-Delete-Block bei Aufbewahrung)
- 4.12 — Modul-Integration (CRM, Sales, Forms, Booking, Email, Telefonie, Chat, HR, Customer-Portal, Automation, KWP, Notifications, Dateien, Calendar, Aufgaben)
## Abhängigkeiten
- **Vorbedingung:** M042, M043, M060 (Verkaufsfall), M065, M095 (KWP-Archiv-Sync), M052-M055 (Dateien)
- **Wird benötigt von:** M067-M070
## Erfolgskriterium
Won-Handoff legt Projekt + automatischen Chat-Channel an (4.12.7); Sales-Verlauf-Sektion read-only mit Volumen-Schutz für Bauleiter (4.8.4.4); Hard-Delete bei aufbewahrungspflichtigen Daten Klartext-blockiert.
## Hinweise für Slice-Planung
- Sequenz-Generator P-YYYY-NNNN
- Sales-Verlauf-Sektion via View-Model-Composition
- Mängel→Aufgaben-Auto-Erzeugung (4.12.15)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,82 @@
# M067 — Plantafel mit Tagen-Granularität [N10]
**Block:** Block 3 · Modul 4
**Pflichtenheft-Quelle:** block3.md Abschnitt 4.6 [N10, 09.05.2026]
## Ziel
Wochenkalender-Plantafel (Tag/Woche/Monat) mit Mitarbeiter-Achse und Drag-&-Drop. Konflikt-Erkennung (Doppel-Belegung, Urlaub, Krankheit, außerhalb Verfügbarkeit). Verfügbarkeits-Regeln pro Mitarbeiter. Status-Verlauf pro Eintrag. Kalender-Sync, Mobile-Sicht „Meine Termine heute".
## Pflichtenheft-Bezug
- 4.6.1-4.6.13 — Desktop-Plantafel + Konflikt-Erkennung + Verfügbarkeit + Mobile-Sicht
- KWP-Sync (4.6.14) → M094
## Abhängigkeiten
- **Vorbedingung:** M066, M129 (Krankmeldung), M135 (Urlaub), M119 (Calendar-Sync)
- **Wird benötigt von:** M068, M094 (KWP-Plantafel-Sync)
## Erfolgskriterium
Drag-Move erkennt Doppel-Belegung mit Klartext-Confirm; Krankmeldungs-Konflikt blockiert; Mobile-Sicht zeigt heutige Einsätze mit Karten-Link + Status-Wechsel-Knopf.
## Hinweise für Slice-Planung
- xyflow oder eigene Calendar-Grid-Component
- Konflikt-Detector mit allen Regeln aus 4.6.9
- Push bei neuer Zuweisung (4.6.13.5)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M068 — Auftrag: Mitglieder-Mgmt + Rollen pro Auftrag
**Block:** Block 3 · Modul 4
**Pflichtenheft-Quelle:** block3.md Abschnitt 4.10
## Ziel
Mitarbeiter pro Projekt zuweisen mit Rolle (Projektleiter, Bauleiter, Monteur, Lehrling, frei beschriftbar). Gruppen-Add-Funktion. Auto-Add zum Projekt-Team-Chat (M104). Klartext-Hinweis bei leerem Team.
## Pflichtenheft-Bezug
- 4.10.1-4.10.4
## Abhängigkeiten
- **Vorbedingung:** M066, M104 (Channel-Modell)
- **Wird benötigt von:** M067 (Plantafel braucht Mitglieder), M069
## Erfolgskriterium
Gruppen-Add „Team Süd" fügt 5 Monteure hinzu + erstellt Projekt-Channel mit allen; leeres Team zeigt Klartext + Add-Knopf.
## Hinweise für Slice-Planung
- Rollen pro Projekt sind frei textuell (nicht globale Rolle)
- Chat-Channel-Lifecycle bei Projekt-Abschluss → archivieren
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,82 @@
# M069 — Auftrag: Abnahme-Workflow + Mängel-Liste
**Block:** Block 3 · Modul 4
**Pflichtenheft-Quelle:** block3.md Abschnitt 4.7
## Ziel
Mobile-first Abnahme-Protokoll mit Datum/Anwesende, technischen Werten, übergebenen Dokumenten, Mängel-Liste mit Foto, Touch-Unterschriften (Kunde + Monteur), Auto-PDF-Generierung, Auto-Email an Kunde. Mängel-Klassifizierung (kritisch/klein/kosmetisch) bestimmt Folge-Aktionen. Mehrere Abnahmen pro Projekt möglich (Teilabnahmen). Rechtliche Aufbewahrung 6 Jahre (kein Löschen).
## Pflichtenheft-Bezug
- 4.7.1-4.7.7 — alle Punkte
- 4.14.1, 4.14.3, 4.14.5 — Klartext-Texte
## Abhängigkeiten
- **Vorbedingung:** M066, M052-M055 (Dateien für Fotos), M121 (Form-Builder für Vorlage), M092 (Email-Versand), M158 (SHK-Standard-Formular), M073 (Aufgaben für Mängel-Auto-Erzeugung)
- **Wird benötigt von:** Geerkens-Auftrags-Abschluss
## Erfolgskriterium
Monteur füllt mobile Abnahme aus, Kunde unterschreibt per Touch, PDF generiert + per Email gesendet; Mit-Vorbehalt-Mängel werden auto-Aufgaben mit Frist; Hard-Delete blockiert (rechtliche Aufbewahrung).
## Hinweise für Slice-Planung
- `signature_pad` ist in Boilerplate-Deps
- @react-pdf/renderer für PDF (in Boilerplate-Deps)
- IP+Zeitstempel als Beweissicherung (4.7.3.3, 4.7.7.4)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M070 — Auftrag: Material-Listen + Lager-Anbindung
**Block:** Block 3 · Modul 4
**Pflichtenheft-Quelle:** block3.md (Material/Lager via 4.13.3 + Modul-Integrationen)
## Ziel
Material-Listen pro Auftrag (Position, Menge, Status). Lager-Anbindung über Apps-Engine (Phase 1: KWP). Lagerist-Rolle (M023.1) sieht Material-Ausgang.
## Pflichtenheft-Bezug
- 4.13.3 — Detaillierte Material-Bestell-Verwaltung Phase 2 falls KWP nicht reicht — Phase 1 via KWP-Sync (M095)
- M27.7 — Lagerist-Rolle [N1]
## Abhängigkeiten
- **Vorbedingung:** M066, M095 (KWP-Material-Daten)
- **Wird benötigt von:** Geerkens-Material-Workflow
## Out of Scope
- Eigenes Material-Bestell-Modul → Phase 2 (4.13.3)
## Erfolgskriterium
Lagerist sieht zugeordnete Material-Lieferungen pro Auftrag; Material-Ausgang dokumentierbar.
## Hinweise für Slice-Planung
- Lagerist-Permission-Cluster (M023.1)
- KWP-Daten via M095 read-only
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,83 @@
# M071 — Aufgaben-CRUD + Zuweisung
**Block:** Block 3 · Modul 26
**Pflichtenheft-Quelle:** block3.md Abschnitte 26.1, 26.2, 26.4, 26.8
## Ziel
Aufgabe mit Titel/Beschreibung/Verantwortlicher (Person ODER Gruppe — eines Pflicht), Frist, Priorität (niedrig/normal/hoch/dringend), Status (offen/in Arbeit/erledigt), Verknüpfung zur Haupt-Entität, Quelle, Beobachter-Liste. Listen-Ansichten (Meine/Von mir erstellt/Alle) mit Filter, Schnell-Aktionen, Sammel-Aktionen.
## Pflichtenheft-Bezug
- 26.1 — Stammdaten + Verantwortlicher-Pflicht
- 26.2 — Listen-Ansichten + Filter
- 26.4 — Detail-Ansicht
- 26.8 — Permissions
## Abhängigkeiten
- **Vorbedingung:** M001, M004, M013-M015 (UI), M042 (Kontakt für Verknüpfung)
- **Wird benötigt von:** M072-M074
## Erfolgskriterium
Aufgabe ohne Verantwortlichen blockiert (oder Default = Ersteller laut 26.11.3); Sammel-Aktion „Status erledigt" für 50 Aufgaben; 404 statt 403 bei fremder Aufgabe.
## Hinweise für Slice-Planung
- Verantwortlicher kann Person ODER Gruppe (oneOf)
- Standard-Sortierung: Frist asc + Priorität (26.2.9)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M072 — Aufgaben-Listen pro Modul (Inline)
**Block:** Block 3 · Modul 26
**Pflichtenheft-Quelle:** block3.md Abschnitt 26.3, 26.5
## Ziel
Aufgaben-Bereich an Kontakten/Firmen/Leads/Verkaufsfällen/Projekten. Direktes Anlegen aus Detail-Ansicht mit Auto-Verknüpfung. Quellen: Manuell, Chat-Nachricht „Als Aufgabe markieren", Form-Aktion mit Vorlage, Automation-Aktion.
## Pflichtenheft-Bezug
- 26.3 — Verknüpfungs-Bereiche
- 26.5 — Quellen
## Abhängigkeiten
- **Vorbedingung:** M071, M104 (Chat), M121 (Form-Builder), M075 (Automation für „Aufgabe erstellen"-Aktion)
- **Wird benötigt von:** M073, alle Module mit Aufgaben-Anzeige
## Erfolgskriterium
Aus Verkaufsfall „Aufgabe anlegen" → vorausgefüllt mit Verkaufsfall-Verknüpfung; Chat-Nachricht „Als Aufgabe markieren" erzeugt Aufgabe mit Beschreibung = Nachrichten-Inhalt + Chat-Eintrag „Aufgabe erstellt aus dieser Nachricht".
## Hinweise für Slice-Planung
- Form-Aktion-Konfig mit Frist-Berechnung (26.5.3)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M073 — Aufgaben: Erinnerungen + Push + Email
**Block:** Block 3 · Modul 26
**Pflichtenheft-Quelle:** block3.md Abschnitt 26.6, 26.7
## Ziel
Auto-Erinnerungen 24h vor / bei / 24h nach Frist. Empfänger: Verantwortlicher + Beobachter. Bündelung max 1/4h pro User. Auto-Archivierung erledigt nach 30 Tagen.
## Pflichtenheft-Bezug
- 26.6 — Erinnerungen + Auto-Archivierung
- 26.7 — Verlaufs-Strom-Integration
## Abhängigkeiten
- **Vorbedingung:** M071, M072, M011 (Notifications)
- **Wird benötigt von:** M074, Aufgaben-Workflow
## Erfolgskriterium
Aufgabe mit Frist morgen → 1× Push heute; Bündelung verhindert >1 Notification pro 4h; erledigte Aufgabe nach 30d auto-archiviert.
## Hinweise für Slice-Planung
- BullMQ-cron für Erinnerungen
- Bündelungs-Window pro User
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M074 — Aufgaben-Sync mit ERP-Aufgaben-Welt [N11]
**Block:** Block 3 · Modul 26
**Pflichtenheft-Quelle:** block3.md Abschnitt 26.10 [N11, 09.05.2026]
## Ziel
Pro Mandant aktivierbar pro angebundenem ERP-Adapter. KWP-Box als Phase 1. Sync-Modi: A (Spiegel ERP→HiveGrid), B (Spiegel HiveGrid→ERP), C (bidirektional mit „KWP gewinnt"). Identifikations-Brücke pro Adapter konfigurierbar (KWP-Box: Email-Adresse). Visueller Marker („KWP" Badge). Klartext-Hinweis bei Sync-Aussetzern. Aushebel-Schutz.
## Pflichtenheft-Bezug
- 26.10.1-26.10.7 — alle Punkte
## Abhängigkeiten
- **Vorbedingung:** M071-M073, M089-M093 (KWP-Sync-Foundation), M008-M010 (Apps-Engine)
- **Wird benötigt von:** Geerkens-KWP-Aufgaben-Workflow
## Erfolgskriterium
Mandanten-Admin aktiviert KWP-Sync Modus C; Aufgabe in HiveGrid → erscheint in KWP-Box; KWP-Box-erledigt → spiegelt zu HiveGrid mit Klartext „erledigt in KWP um [Zeit]".
## Hinweise für Slice-Planung
- Per-Adapter-Sync-Konfiguration
- Konflikt-Auflösung Re-use M093
- Sync-Status-Marker im Aufgaben-Detail
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,87 @@
# M075 — Automation: Schema + Auslöser-Registry
**Block:** Block 4 — USP-Säulen · Modul 17
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/blocks/block4.md` Abschnitte 17.1, 17.2
## Ziel
Datenmodell für Automatisierungen + Registry aller Phase-1-Auslöser (CRM, Leads, Sales, Auftrag, Forms, Booking, Email, Telefonie, Aufgaben, Zeit, KWP, Apps-Engine, HR, Customer-Portal).
## Pflichtenheft-Bezug
- 17.1 — Aufbau (Auslöser, Bedingungen, Aktionen, Steuerung; aktiv/inaktiv; Erstellungs-Quelle)
- 17.2 — Vollständige Auslöser-Liste (17.2.1-17.2.14)
## Abhängigkeiten
- **Vorbedingung:** M001 (Audit), M007 (Idempotenz), Module der Auslöser-Quellen müssen Events emittieren
- **Wird benötigt von:** M076-M082, alle Module mit Trigger-Bedarf
## Out of Scope
- Editor → M078
- Schutz-Mechanismen → M081
- Logs → M082
## Erfolgskriterium
Test-Automation mit Auslöser „Lead empfangen" feuert bei Lead-Submit; Trigger-Eintrag im Audit-Log.
## Hinweise für Slice-Planung
- Auslöser-Registry als Plug-Architektur (Module registrieren sich)
- Filter pro Auslöser (Pipeline, Stufe, Quelle, Schwellenwert)
- Archivierung statt Löschung (17.1.4)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M076 — Automation: Aktion-Registry + Steuerungs-Bausteine
**Block:** Block 4 · Modul 17
**Pflichtenheft-Quelle:** block4.md Abschnitt 17.3
## Ziel
Registry aller Phase-1-Aktionen (CRM, Leads, Sales, Projekte, Kommunikation, Aufgaben, KWP, externe HTTP, Steuerung, KI, Kalender, Dateien) + Steuerungs-Bausteine (Wartezeit, Verzweigung, parallel, Merge). KEINE Schleifen (Anti-Liste).
## Pflichtenheft-Bezug
- 17.3.1-17.3.12 — komplette Aktions-Liste
- 17.3.9 — Schleifen ausdrücklich nicht erlaubt (Anti-Liste)
## Abhängigkeiten
- **Vorbedingung:** M075, M083 (KI-Provider für 17.3.10)
- **Wird benötigt von:** M077-M082
## Out of Scope
- Sub-Workflows / Loops → Anti-Liste, Phase 2
- Custom-JS-Expressions → Anti-Liste, Phase 2
## Erfolgskriterium
Test-Automation: Auslöser → Bedingung → Email senden → Wartezeit 1h → Aufgabe anlegen funktioniert; Schleifen-Versuch in Editor abgelehnt.
## Hinweise für Slice-Planung
- Aktion-Interface mit Idempotency-Key (M007)
- Steuerungs-Bausteine als spezielle „Aktion"-Subtypen
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M077 — Automation: Bedingungen
**Block:** Block 4 · Modul 17
**Pflichtenheft-Quelle:** block4.md Abschnitt 17.4
## Ziel
Bedingungs-Engine: Feld-Vergleich, Schlagwort, Tageszeit/Wochentag, Gruppen-Mitgliedschaft. Phase 1 ohne Custom-JS.
## Pflichtenheft-Bezug
- 17.4.1-17.4.4 — alle erlaubten Bedingungen
- 17.4.5 — Custom-JS Phase 2 ausgeschlossen
## Abhängigkeiten
- **Vorbedingung:** M075, M076
- **Wird benötigt von:** M078
## Erfolgskriterium
Test: „Volumen > 10000 EUR UND Schlagwort = ‚VIP'" greift korrekt; Bedingung wertet Pre-Save aus.
## Hinweise für Slice-Planung
- AND/OR-Kombinatoren mit Klammer-Logik
- Type-safe Feld-Picker (kennt Auslöser-Felder)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M078 — Automation: Visueller Editor
**Block:** Block 4 · Modul 17
**Pflichtenheft-Quelle:** block4.md Abschnitt 17.5
## Ziel
xyflow-basierter Editor mit Knoten/Verbindungen, Mini-Map, Zoom, Undo/Redo, Konfigurations-Panel pro Knoten, Pre-Save-Validierung mit Klartext-Hinweisen, Pflicht-Aktivierung als separater Schritt.
## Pflichtenheft-Bezug
- 17.5 — alle Punkte
## Abhängigkeiten
- **Vorbedingung:** M075-M077, M015 (UI-Layer)
- **Wird benötigt von:** M079, M086 (KI-Sprache → Editor füllt)
## Out of Scope
- KI-Erstellung → M086
- Test-Lauf → M079
## Erfolgskriterium
Editor-User baut Wenn-Dann-Flow per Drag&Drop; Pre-Save-Validator listet alle Probleme (17.5.6); Aktivierung explizit (17.5.7).
## Hinweise für Slice-Planung
- `@xyflow/react` bereits in Boilerplate-Deps
- Knoten-Label mit Klartext (17.5.4)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M079 — Automation: Test-Lauf + Schwellenwert-Vorschau
**Block:** Block 4 · Modul 17
**Pflichtenheft-Quelle:** block4.md Abschnitt 17.7 (Bauprinzip A.10)
## Ziel
Test-Lauf-Simulation ohne echte Wirkung. Schwellenwert-Pflicht-Vorschau bei >100 Datensätzen mit Empfänger-Sample.
## Pflichtenheft-Bezug
- 17.7.1 — Test-Lauf
- 17.7.2 — Schwellenwert-Vorschau (mandant-konfigurierbar) mit erste-5-Empfänger
- A.10.1 — KI-erzeugte Automation immer erst Vorschau
## Abhängigkeiten
- **Vorbedingung:** M075-M078
- **Wird benötigt von:** M080, M086
## Erfolgskriterium
Test-Lauf zeigt Schritt-für-Schritt Klartext („Email würde gesendet an X mit Betreff Y"); >100-Empfänger-Lauf erfordert explizite Bestätigung.
## Hinweise für Slice-Planung
- Dry-run-Mode ohne echten Aktion-Aufruf (Mock-Adapter)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,83 @@
# M080 — Automation: 24h-Undo-Fenster + Reversibilität
**Block:** Block 4 · Modul 17
**Pflichtenheft-Quelle:** block4.md Abschnitt 17.7.3-17.7.5 (Bauprinzip A.10.2)
## Ziel
Jede Ausführung 24h rückgängig machbar. Reversibel: angelegte Datensätze, Status-Änderungen, Tag-Änderungen. Email-Versand nicht zurückziehbar, aber Empfänger-Liste sichtbar.
## Pflichtenheft-Bezug
- 17.7.3 — 24h-Fenster
- 17.7.4 — Reversibilitäts-Liste
- 17.7.5 — Mehrfach-Bestätigung + Audit
- A.10.2 — 24h-Rückgängig-Fenster generell
## Abhängigkeiten
- **Vorbedingung:** M075-M079, M001
- **Wird benötigt von:** M081
## Erfolgskriterium
Test-Run-Wirkung: 50 Datensätze angelegt → Undo binnen 24h löscht sie; nach 24h Undo-Knopf weg.
## Hinweise für Slice-Planung
- Undo-Token pro Run mit Snapshot der Auswirkungen
- BullMQ-delayed Cleanup-Job nach 24h
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M081 — Automation: Schleifen-Schutz + Webhook-Sturm + Anomalie
**Block:** Block 4 · Modul 17
**Pflichtenheft-Quelle:** block4.md Abschnitt 17.8 (Bauprinzipien A.16, A.17)
## Ziel
- Webhook-Sturm-Schutz: Hard-Limit 1000/h pro Mandant + Anomalie-Erkennung (10x Threshold)
- Schleifen-Schutz: max 5 Auto-Trigger pro Datensatz/Min, Pre-Save-Graph-Analyse
- Halbe-Ausführung: Idempotenz pro Schritt + Resume-from-failed-step + Backoff (1m/5m/15m/1h/6h/24h)
## Pflichtenheft-Bezug
- 17.8.1-17.8.3 — alle drei Schutz-Mechanismen mit Klartext-Beispielen
- A.16, A.17 — Querschnitt-Bezug
## Abhängigkeiten
- **Vorbedingung:** M007 (Idempotenz), M010 (Webhook-Schutz Apps-Engine), M075-M078
- **Wird benötigt von:** M082
## Erfolgskriterium
Stress-Test: 1500 Webhooks/h → 500 verworfen + Notification; Schleifen-Detection blockt vor Speichern; halbe Ausführung resumed ab Schritt 4.
## Hinweise für Slice-Planung
- Klartext aus 17.8 (Pflichtenheft) übernehmen
- Anomalie-Detector Rolling-Window
- Backoff-Strategie als BullMQ-Retry-Config
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M082 — Automation: Klartext-Logs + Re-Run + Trigger-Volumen-Metering
**Block:** Block 4 · Modul 17
**Pflichtenheft-Quelle:** block4.md Abschnitte 17.9 + Pricing-Vorbereitung
## Ziel
Pro Run Klartext-Detail (Schritte, Dauer, Eingabe/Ausgabe, Fehler in Klartext). Manueller Re-Run + Undo aus Log. Trigger-Volumen pro Mandant/Stunde (Pricing-Vorbereitung, Limits später per Konfiguration).
## Pflichtenheft-Bezug
- 17.9 — Logs (Beispiel-Texte 17.9.3)
- Anhang H.1.1 — Trigger-Volumen-Metering vorbereitet
## Abhängigkeiten
- **Vorbedingung:** M075-M081
- **Wird benötigt von:** M156 (Pay-as-you-go)
## Erfolgskriterium
Run-Detail zeigt Schritt-Liste mit Dauer + Status; Re-Run aus Log funktioniert; Volumen-Counter sichtbar im Plattform-Admin.
## Hinweise für Slice-Planung
- Run-Log als unveränderlicher Stream
- Klartext-Beispiele aus 17.9.3
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,87 @@
# M089 — KWP-API-Connector (REST/OAuth über Apps-Engine)
**Block:** Block 4 · Modul 19
**Pflichtenheft-Quelle:** block4.md Modul 19 + Bauprinzip A.18 · **Re-Cut 2026-06-04 (KWP-API), siehe `docs/milestones/M19-KWP-API-RECUT.md`**
## Ziel
First-Party-Connector für die offizielle **KWP-REST-API**, aufgesetzt auf das M33a-Adapter-Interface. Eine `App{type:"kwp"}` + eine `DataConnection{type:"rest-api"|"oauth2"}` pro KWP-Server; API-Credentials verschlüsselt in `DataConnection.config` (Per-Tenant-DEK, AD-8). Ausgehende Calls via `adapterFetch()` (HTTPS-only, SSRF-Guard). Implementiert `connect / disconnect / validateConnection / syncPull / syncPush / handleWebhook`.
## Was sich durch die KWP-API ändert (Re-Cut)
- **Der ursprüngliche Windows-Client (`kwpsync.exe` + NSSM + MSSQL-Direktzugriff + DPAPI + Auto-Update) entfällt komplett.** Kein externes Programm mehr — der Connector lebt im Monorepo (`app/domain/integrations/kwp/**`).
- KWP wird ein **regulärer `rest-api`-Adapter** statt `windows_client`-Sonderweg; passt direkt ins `appsEngine.prisma`-Muster.
## Abhängigkeiten
- **Vorbedingung:** M008–M010 (M33a Adapter-Interface — `connect/syncPull/syncPush/...`, harte Vorbedingung); AD-8 (Per-Tenant-DEK)
- **Offen/blockierend:** konkreter **KWP-API-Vertrag** (Auth, Endpoints, Rate-Limits, Webhooks, Versionierung) — vor Detail-Planung mit KWP klären (siehe RECUT-Doku)
- **Wird benötigt von:** M090–M095
## Out of Scope
- `kwpsync.exe` / Windows-Service / NSSM / MSSQL-Direktzugriff (durch API obsolet)
- Andere ERPs (Taifun, TopKontor) → Phase 2
## Erfolgskriterium
KWP-App via Setup verbunden; `validateConnection` liefert grün; Test-`syncPull` liefert einen KWP-Datensatz; Test-`syncPush` schreibt einen Datensatz via API nach KWP; alles als `AppSyncRun`/`AppSyncItem` protokolliert.
## Hinweise für Slice-Planung
- Connector als reines Domain-Modul (`app/domain/integrations/kwp/**`), Layer-Trennung (AGENTS.md)
- `appsEngine.prisma`-Modelle nutzen; KWP-spezifische Modelle in eigenem `prisma/schema/kwp.prisma`
- Mapping HiveGrid↔KWP via `AppSyncItem`; Idempotenz via `IdempotencyKey`
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,83 @@
# M090 — KWP-API Connection-Health
**Block:** Block 4 · Modul 19
**Pflichtenheft-Quelle:** block4.md Modul 19 + Bauprinzip A.18 · **Re-Cut 2026-06-04 (KWP-API)**
## Ziel
Verbindungs-Gesundheit der KWP-API über den generischen M33a-Health-Probe (`validateConnection`-Call im Intervall) statt eines Client-Heartbeats. Status nach `AdapterStatus` (aktiv/eingeschränkt/defekt). Bei `defekt`: Alarm an Plattform-Admin + Mandanten-Admin (Geerkens).
## Was sich durch die KWP-API ändert (Re-Cut)
- **Stark vereinfacht:** Client-Heartbeat (5 Min), 15-Min-Watchdog und Auto-Restart entfallen (kein lokaler Client mehr). Ersetzt durch periodischen Health-Call der Cloud an die KWP-API.
## Pflichtenheft-Bezug
- A.18.1-A.18.3 (sinngemäß auf API-Health übertragen)
## Abhängigkeiten
- **Vorbedingung:** M089, M011 (Notifications)
- **Wird benötigt von:** M091
## Erfolgskriterium
Health-Status pro KWP-Connection sichtbar im Plattform-Admin; simulierter API-Ausfall setzt Status auf `defekt` und löst Push + Email aus; Erholung sendet Klartext-Bestätigung.
## Hinweise für Slice-Planung
- Nutzt `foundation/adapters` (`AdapterStatus`) + `notify()`; Probe-Intervalle aktiv 5min / eingeschränkt 1min / defekt 15min (M33a)
- Health-Cron nach Muster `apps/worker/.../dsgvo-grace-cron.ts`
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,83 @@
# M091 — KWP-Push-Queue + Replay (Cloud-Outbox)
**Block:** Block 4 · Modul 19
**Pflichtenheft-Quelle:** block4.md Modul 19 + Bauprinzip A.19 · **Re-Cut 2026-06-04 (KWP-API)**
## Ziel
Push-Operationen HiveGrid→KWP laufen über die transaktionale **Cloud-Outbox** (`kwp.push.*`-Prefix) + `@toolctrl/queue`. Bei KWP-API-Ausfall: Retry mit Backoff; bei Wiederverbindung chronologisches **Rate-Limited-Replay (max 100 Ops/Min)** mit sichtbarem Fortschritt (SSE).
## Was sich durch die KWP-API ändert (Re-Cut)
- **Vereinfacht:** Die lokale SQLite-Queue im Client entfällt — es gibt nur noch **eine** Cloud-Queue (Outbox). Kein Zwei-Layer-Resilienz-Konstrukt mehr.
## Pflichtenheft-Bezug
- A.19.1-A.19.3
## Abhängigkeiten
- **Vorbedingung:** M089, M090
- **Wird benötigt von:** M092, M093
## Erfolgskriterium
Simulierter 6h-KWP-API-Ausfall → Push-Ops sammeln sich in der Outbox; bei Erholung Replay in chronologischer Reihenfolge mit Rate-Limit + Fortschrittsanzeige; Konflikte zeigen Klartext-Auflösung (M093).
## Hinweise für Slice-Planung
- Outbox-Prefix-Routing (`kwp.push.*`) in `apps/worker/src/outbox/event-router.ts`; Queue-Name in `packages/queue/src/names.ts` registrieren
- Idempotenz via `buildIdempotentJobId()` + `IdempotencyKey`
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M092 — KWP-API-Contract-Sentinel
**Block:** Block 4 · Modul 19
**Pflichtenheft-Quelle:** block4.md Modul 19 + Bauprinzip A.11 · **Re-Cut 2026-06-04 (KWP-API)**
## Ziel
Statt MSSQL-Schema-Drift jetzt **API-Vertrags-/Versions-Überwachung**: jede KWP-API-Response wird gegen ein erwartetes zod-Schema validiert; bei Vertragsbruch (unerwartete Felder/Typen, API-Version-Bump) → Sync **automatisch pausiert** + Alarm an **Plattform-Admin zuerst** (vor Geerkens).
## Was sich durch die KWP-API ändert (Re-Cut)
- **Vereinfacht bis ggf. integrierbar:** Bei stabiler, versionierter API ändert KWP das Schema nicht mehr „still". Der tägliche MSSQL-Snapshot+Hash-Diff entfällt; übrig bleibt eine laufende zod-Response-Validierung + Versions-Check. Ob eigenständiges Milestone oder Teil des M089-Connectors hängt vom KWP-API-Versionierungs-Modell ab (offen).
## Pflichtenheft-Bezug
- A.11.1-A.11.2
- 33a.6 — Schema-/Contract-Drift generell
## Abhängigkeiten
- **Vorbedingung:** M089-M091, M011 (Notifications)
- **Offen:** KWP-API-Versionierungs-/Changelog-Modell (klären) — entscheidet den Umfang
- **Wird benötigt von:** stabiler Geerkens-Betrieb
## Erfolgskriterium
Eine bewusst veränderte/unerwartete API-Response (Feld umbenannt) wird von der zod-Validierung erkannt; Sync pausiert; Plattform-Admin erhält Push vor Geerkens es bemerkt; Mandant sieht Klartext „Wir wurden informiert".
## Hinweise für Slice-Planung
- zod-Schemas pro KWP-Endpoint; `KwpApiContractSnapshot` (API-Version + Schema-Fingerprint) statt MSSQL-Snapshot
- Auto-Pause über M33a-Status (`degraded`) + `notify()` an Plattform-Admin zuerst, dann Mandant
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M093 — KWP: Konflikt-Auflösung „KWP gewinnt" [N14]
**Block:** Block 4 · Modul 19
**Pflichtenheft-Quelle:** block4.md Modul 19.6 + [N14, 09.05.2026] + Bauprinzip A.15 · **Re-Cut 2026-06-04: inhaltlich unverändert**
## Ziel
Bei Versions-Konflikt KWP↔HiveGrid: Default „KWP gewinnt immer" (statt Last-Write-Wins). Diff-View für manuelle Auflösung. Klartext-Notification mit Restore-Knopf für überschriebenen User.
## Was sich durch die KWP-API ändert (Re-Cut)
- **Unverändert** — transport-unabhängige Domain-Regel. Einzige Anpassung: Konflikt-Erkennung läuft über das `version_hash`/`last_modified`-Feld der **API-Response** statt über ein MSSQL-Feld; Restore des überschriebenen Stands via `AppSyncItem.rolledBackData`.
## Pflichtenheft-Bezug
- A.15.1-A.15.2 — Optimistic Locking + Diff-View, Last-Write-mit-Sichtbarkeit
- M19.6 + [N14] — KWP-spezifischer Default „KWP gewinnt"
## Abhängigkeiten
- **Vorbedingung:** M089-M092
- **Wird benötigt von:** alle Module mit KWP-Schreib-Pfad (M064 Sales-Pipeline, M066 Auftrag, M067 Plantafel)
## Erfolgskriterium
Sandra ändert Auftrag in KWP, Mandanten-Mitarbeiter ändert parallel in HiveGrid; KWP-Wert gewinnt; Mitarbeiter sieht Klartext-Notification + Restore.
## Hinweise für Slice-Planung
- `version_hash` aus KWP-API-Response je Datensatz; Restore aus `AppSyncItem.rolledBackData`
- Diff-View-Component reusable (auch für M092/M094)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M094 — KWP: Bidirektionale Plantafel-Sync [N10]
**Block:** Block 4 · Modul 19
**Pflichtenheft-Quelle:** block4.md M19 + [N10, 09.05.2026] + M04.6.14 · **Re-Cut 2026-06-04 (KWP-API)**
## Ziel
Plantafel-Änderungen bidirektional: HiveGrid→KWP via API-Call (`syncPush`), KWP→HiveGrid via Webhook (`handleWebhook`) bzw. Cron-Pull. Konflikt-Default „KWP gewinnt" (siehe M093).
## Was sich durch die KWP-API ändert (Re-Cut)
- **Vereinfacht:** Kein `kwpsync.exe`-Schreibpfad in MSSQL mehr. Bietet die KWP-API Webhooks, wird **Trigger-basierter Pull Phase-1-fähig** (statt Phase 2); sonst Cron-Pull mit dokumentiertem Intervall.
## Pflichtenheft-Bezug
- M04.6.14 + [N10] — bidirektional, KWP gewinnt bei Konflikt
## Abhängigkeiten
- **Vorbedingung:** M089-M093, M067 (Plantafel-Modul)
- **Offen:** KWP-API muss Plantafel-Endpoints + idealerweise Webhooks bieten (klären)
- **Wird benötigt von:** Geerkens-Plantafel-Workflow
## Erfolgskriterium
Plantafel-Move in HiveGrid landet in KWP <30 Sek; KWP-Änderung erscheint in HiveGrid <30 Sek (Webhook) bzw. zum nächsten Pull; gleichzeitige Konflikte werden mit „KWP gewinnt" aufgelöst.
## Hinweise für Slice-Planung
- HiveGrid→KWP via `syncPush`/`adapterFetch`; KWP→HiveGrid via `handleWebhook` (signiert) oder Cron-`syncPull`
- Fällt KWP-Webhook weg → Pull-Intervall + Latenz-Trade-off dokumentieren
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,87 @@
# M095 — KWP: Dokumenten-Archiv-Sync KWP→HiveGrid [N5]
**Block:** Block 4 · Modul 19
**Pflichtenheft-Quelle:** block4.md M19.2.5 + M23.9.7 + [N5, 09.05.2026] · **Re-Cut 2026-06-04 (KWP-API)**
## Ziel
KWP-Kunden- und Projekt-Archiv-Struktur einseitig (KWP → HiveGrid) gespiegelt über den **KWP-API-Dokumenten-Endpoint**; Ablage in `@toolctrl/storage` (Scaleway-S3), read-only lesbar in HiveGrid. Quelle bleibt KWP.
## Was sich durch die KWP-API ändert (Re-Cut)
- **Vereinfacht:** Kein lokaler Dateizugriff via Client. Dokumente werden über die API gelistet + heruntergeladen und in S3 abgelegt; inkrementell (nur neue/geänderte).
## Pflichtenheft-Bezug
- M19.2.5 + M23.9.7 + [N5] — Dokumenten-Archiv-Sync, einseitig
## Abhängigkeiten
- **Vorbedingung:** M089-M093, M052-M055 (Dateien-Modul)
- **Offen:** KWP-API muss Dokumenten-Listing + Download bieten (klären)
- **Wird benötigt von:** M066 (Auftrag-CRUD mit Archiv)
## Out of Scope
- Bidirektionaler Datei-Sync (HiveGrid → KWP)
## Erfolgskriterium
KWP-Datei „Auftrag_42/Foto.jpg" erscheint in HiveGrid-Auftrag-Archiv-Sicht <2 Min nach Upload in KWP; Schreibversuch in HiveGrid lehnt ab mit Klartext.
## Hinweise für Slice-Planung
- API-Dokumenten-Listing + Download → `@toolctrl/storage` (Signed-URLs); `KwpDocument`-Mapping (`direction=downloaded_from_kwp`)
- Inkrementeller Sync (Cursor/seit-Datum); „in KWP gelöscht"-Badge
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M096 — Email-Inbox: Gmail-OAuth-Integration via Apps-Engine
**Block:** Block 5 · Modul 9
**Pflichtenheft-Quelle:** `_bmad-output/pflichtenheft/blocks/block5.md` Abschnitte 9.1, 9.5, 9.4
## Ziel
Gmail (inkl. Workspace) und Microsoft Outlook/365 OAuth-Anbindung pro Mitarbeiter (Mehrfach-Postfach). Standard-Postfach-Markierung. Einmalige Sende-Domain-Verifikation pro Mandant (DKIM/SPF/DMARC mit Auto-Probe alle 5 Min, 7-Tage-Timeout).
## Pflichtenheft-Bezug
- 9.1 — Gmail + Outlook in Phase 1; andere IMAP/T-Online/GMX → Phase 2 (9.9.1)
- 9.4 — Sende-Domain-Verifikation (DKIM/SPF/DMARC)
- 9.5 — Mailbox-Sync (Push, 90 Tage Initial-Import, Token-Refresh, Watchdog 4h)
## Abhängigkeiten
- **Vorbedingung:** M008-M010 (Apps-Engine), M002 (Klartext)
- **Wird benötigt von:** M097-M099, M100 (Marketing-Versand braucht verifizierte Domain)
## Out of Scope
- Andere Email-Provider → Phase 2
## Erfolgskriterium
Gmail-OAuth-Setup in <2 Min; DNS-Verifikation findet Einträge automatisch; Token-Refresh läuft monatelang stabil.
## Hinweise für Slice-Planung
- Adapter via Apps-Engine (M008)
- Pub/Sub für Push-Sync, Polling-Watchdog als Sicherheitsnetz (9.5.5)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M097 — Email-Inbox: Sync + Inbox-UI + Threading + Auto-Verknüpfung
**Block:** Block 5 · Modul 9
**Pflichtenheft-Quelle:** block5.md Abschnitte 9.2, 9.3
## Ziel
Inbox mit Listen-Ansicht (Filter: Postfach/Eingang-Ausgang/Lese-Status/Verknüpfung/Datum/Anhang), Volltext-Suche, Detail mit Thread, Tracking-Pixel-Schutz (Bilder erst nach Klick), Mark-as-Read-Sync zurück zum Provider. Auto-Verknüpfung (Email-Adresse, Betreff-Kürzel `[Deal #X]`, Heuristik bei genau-einem-offenen-Deal).
## Pflichtenheft-Bezug
- 9.2 — Inbox-Sicht
- 9.3 — Auto-Verknüpfung
## Abhängigkeiten
- **Vorbedingung:** M096, M042 (Kontakt für Match), M060/M066 (Deal/Auftrag)
- **Wird benötigt von:** M098, M099, M045 (Activity-Stream)
## Erfolgskriterium
Mail von bekanntem Kontakt → automatisch verknüpft; Mail mit `[Deal #42]` → automatisch zum Deal; manuelle Override hält stand (9.3.4).
## Hinweise für Slice-Planung
- Bilder-Lade-Schutz CSP-basiert
- Newsletter/Bulk via List-Header-Detection (9.3.6)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M098 — Email-Versand + Vorlagen + Variable-Resolution
**Block:** Block 5 · Modul 9
**Pflichtenheft-Quelle:** block5.md Abschnitt 9.7
## Ziel
Versand aus Kontakt-/Deal-/Projekt-Detail oder Inbox (Antwort/Weiterleiten). Editor mit Formatierung + Anhängen (≤25 MB). Mehrfach-Postfach-Auswahl. Native Versand über Provider (Mail erscheint in Provider-Gesendet-Ordner). Optional BCC-Logging.
## Pflichtenheft-Bezug
- 9.7 — Versand
- 9.6 — Quotenschutz (1B/Tag Gmail, 10K/Tag Outlook, Drosselung)
## Abhängigkeiten
- **Vorbedingung:** M096, M097
- **Wird benötigt von:** M092 (Calendar-Bestätigungen), M122 (Booking-Bestätigung)
## Erfolgskriterium
Mail aus Kontakt-Detail mit Vorlage + Variable `{{first_name}}` korrekt aufgelöst, an Empfänger zugestellt, im Gmail-Gesendet-Ordner sichtbar.
## Hinweise für Slice-Planung
- TipTap-Editor (in Boilerplate-Deps)
- Variable-Resolver mit Kontakt-Properties
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M099 — Email-Tracking + Delivery-Status + Bounces
**Block:** Block 5 · Modul 9 (sowie M10)
**Pflichtenheft-Quelle:** block5.md Abschnitt 9.6 (transaktionale) + Modul 10.4-10.6 (Marketing)
## Ziel
Delivery-Status pro Versand (zugestellt/bounced/spam-marked). Hard-/Soft-Bounce-Handling (Sperrliste-Auto-Add bei Hard-Bounce). Quoten-Schutz pro Provider.
## Pflichtenheft-Bezug
- 9.6 — Quoten + Bounces
- 10.6 — Bounce-Handling Marketing
## Abhängigkeiten
- **Vorbedingung:** M098
- **Wird benötigt von:** M100-M104
## Erfolgskriterium
Hard-Bounce setzt Adresse auf Sperrliste mit Klartext-Hinweis im Kontakt-Detail; Soft-Bounce 3× retry über 24h, dann wie Hard-Bounce.
## Hinweise für Slice-Planung
- Bounce-Webhook vom Provider
- Sperrliste pro Mandant
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,85 @@
# M100 — Email-Marketing: Editor (Block-Style)
**Block:** Block 5 · Modul 10
**Pflichtenheft-Quelle:** block5.md Abschnitte 10.1, 10.4 (Pixel-Tracking-Hinweis)
## Ziel
Kampagnen-Builder mit Schritten (Basis → Inhalt → Empfänger → Test → Versand-Zeit → Bestätigung). Personalisierungs-Platzhalter `{{first_name}}` etc. SHK-Standard-Templates. Vorschau Desktop+Mobile. Test-Mail an sich selbst.
## Pflichtenheft-Bezug
- 10.1 — Newsletter + Sequenzen (Sequenzen Phase 1 via Automation, 10.1.6)
- 10.4.6 — Datenschutz-Hinweis Tracking-Pixel im Footer
## Abhängigkeiten
- **Vorbedingung:** M096, M098, M158 (SHK-Standard-Templates)
- **Wird benötigt von:** M101-M104
## Out of Scope
- Drag-&-Drop-Builder → Phase 2 (10.11.5)
- Bedingter Inhalt → Phase 2 (10.11.4)
## Erfolgskriterium
Kampagne „Wartungs-Erinnerung" mit Template + Variablen erstellbar; Vorschau zeigt Desktop+Mobile mit Sample-Daten; Test-Mail kommt an.
## Hinweise für Slice-Planung
- TipTap-Editor reuse
- Spam-Score-Check vor Versand (10.9.3)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M101 — Email-Marketing: Segmente + Empfänger-Auswahl
**Block:** Block 5 · Modul 10
**Pflichtenheft-Quelle:** block5.md Abschnitte 10.2, 10.7
## Ziel
Segment-Filter (Tags, Lifecycle, Custom-Felder, Verantwortlicher, Erstellt-Datum, verknüpft mit Deal, Sprache) verschachtelt UND/ODER. Live-Empfänger-Anzahl + 50-Stichprobe. Statisch vs. dynamisch. Auto-Ausschluss (keine Einwilligung, abgemeldet, Sperrliste, archiviert) mit Klartext-Counter. DSGVO-Einwilligungs-Pflicht-Doku pro Kontakt.
## Pflichtenheft-Bezug
- 10.2 — Segmente
- 10.7 — DSGVO-Einwilligungs-Pflicht (kritisch)
## Abhängigkeiten
- **Vorbedingung:** M042-M046, M100
- **Wird benötigt von:** M102-M104
## Erfolgskriterium
Segment „Wartungsvertrag-Kunden ohne Wartung > 365d" liefert Live-Anzahl; Versand-Bestätigung zeigt „X aus Y Empfängern werden ausgeschlossen (Abmeldung/Bounce/keine Einwilligung)".
## Hinweise für Slice-Planung
- Filter-DSL als JSON
- Double-Opt-In-Flow (10.7.3)
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,82 @@
# M102 — Email-Marketing: Versand-Engine + DKIM/SPF + Frequenz-Schutz
**Block:** Block 5 · Modul 10
**Pflichtenheft-Quelle:** block5.md Abschnitte 10.5, 10.7.5, 10.9
## Ziel
Versand-Worker mit Tagebudget pro Plan (Cloud 10K, Cloud+ 50K, Trial 200), Frequenz-Schutz (max 5 Mails/Empfänger/Woche), Pflicht-Footer (Absender-Adresse, Abmelde-Link auto-injected falls vergessen). Domain-Reputation-Schutz.
## Pflichtenheft-Bezug
- 10.5 — Unsubscribe-Pflicht (Abmelde-Link auto-eingefügt)
- 10.7.5 — Pflicht-Inhalte Footer
- 10.9 — Tages-Limit + Frequenz + Spam-Score-Check
## Abhängigkeiten
- **Vorbedingung:** M096 (Sende-Domain), M101, M007 (Idempotenz)
- **Wird benötigt von:** M103, M104
## Erfolgskriterium
Kampagne ohne Footer-Adresse → Versand blockiert mit Klartext (10.7.5 + 10.12.7); 5. Mail/Woche an Empfänger geblockt.
## Hinweise für Slice-Planung
- BullMQ-Worker für Versand mit Drossel
- Auto-Footer-Injection
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,84 @@
# M103 — Email-Marketing: Reporting (Open/Click + Klick-Karte + Pro-Empfänger)
**Block:** Block 5 · Modul 10
**Pflichtenheft-Quelle:** block5.md Abschnitt 10.4
## Ziel
Pro Kampagne: Versendet/Zugestellt/Hard-Bounce/Soft-Bounce/Geöffnet/Geklickt/Abgemeldet/Spam-Beschwerden + Quoten. Klick-Karte (Links nach Häufigkeit). Pro-Empfänger-Liste. Marketing-Engagement-Aggregat im Kontakt-Detail.
## Pflichtenheft-Bezug
- 10.4 — Tracking-Detail (manuelle A/B in Phase 1, Auto-A/B Phase 2)
## Abhängigkeiten
- **Vorbedingung:** M099, M102
- **Wird benötigt von:** Marketing-Workflow
## Out of Scope
- Auto-A/B-Tests → Phase 2 (10.11.1)
- Geräte/Geo/Heat-Map → Phase 2 (10.11.3)
## Erfolgskriterium
Kampagne-Versand → Tracking-Pixel-Loads zählt Open; Click-Tracking via Redirect-Link; Aggregat im Kontakt zeigt Engagement-%.
## Hinweise für Slice-Planung
- Pixel-Endpoint für Open-Tracking
- Redirect-Endpoint für Click-Tracking
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,81 @@
# M104 — Email-Marketing: Unsubscribe + Bounce-Handling + Pflicht-Footer
**Block:** Block 5 · Modul 10
**Pflichtenheft-Quelle:** block5.md Abschnitte 10.5, 10.6
## Ziel
Public-Abmelde-Seite (kein Login), optionaler Grund + Feedback. Sperrliste pro Mandant (auch nach CRM-Lösch persistent). Ein-Klick-Abmeldung via Provider-Header. Spam-Beschwerden auto-Abmeldung.
## Pflichtenheft-Bezug
- 10.5 — Unsubscribe-Pflicht
- 10.6 — Bounce + Spam-Beschwerden
## Abhängigkeiten
- **Vorbedingung:** M102, M099
- **Wird benötigt von:** Marketing-Workflow
## Erfolgskriterium
Klick auf Abmelde-Link → Public-Page → Bestätigung → Adresse auf Sperrliste; Spam-Beschwerde via Provider-Webhook → Auto-Abmeldung mit Activity-Eintrag.
## Hinweise für Slice-Planung
- Public-Route (kein Login, Token-basiert)
- List-Unsubscribe-Header für Provider-One-Click
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,80 @@
# M105 — Telefonie: HalloPetra-Adapter [N16]
**Block:** Block 5 · Modul 12 [N16, 09.05.2026]
**Pflichtenheft-Quelle:** block5.md Abschnitt 12.1.7
## Ziel
HalloPetra-Anbindung pro Mandant (analog AirCall). Auto-Mitarbeiter-Zuordnung über Email. Eingehende Anrufe + verpasste Anrufe + Mitschnitt-Link + HalloPetra-Notiz im Activity-Stream. Click-to-Call wo API-fähig, sonst tel:-Fallback. HalloPetra-Sprach-Bot/Vorqualifikations-Tags als Lead-Eintrag.
## Pflichtenheft-Bezug
- 12.1.7 — alle Punkte [N16]
## Abhängigkeiten
- **Vorbedingung:** M008-M010 (Apps-Engine), M042
- **Wird benötigt von:** M107-M109
## Erfolgskriterium
HalloPetra-Anruf-Eingang erscheint in HiveGrid mit Anrufer-Nummer + Mitschnitt-Link; Vorqualifikations-Tag als Activity-Eintrag.
## Hinweise für Slice-Planung
- Adapter via Apps-Engine
- Click-to-Call-Detection mit Fallback
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
@@ -0,0 +1,82 @@
# M106 — Telefonie: AirCall-Adapter
**Block:** Block 5 · Modul 12
**Pflichtenheft-Quelle:** block5.md Abschnitte 12.1.1-12.1.6
## Ziel
AirCall-OAuth-Anbindung einmalig pro Mandant. Auto-Mitarbeiter-Zuordnung über Email mit manueller Korrektur. „Verbindung testen". Token-Refresh.
## Pflichtenheft-Bezug
- 12.1.1-12.1.6 — alle Punkte
## Abhängigkeiten
- **Vorbedingung:** M008-M010
- **Wird benötigt von:** M107-M109
## Out of Scope
- Sipgate, Auerswald → Phase 2 (12.10.1)
## Erfolgskriterium
AirCall-OAuth-Flow grün; X von Y Mitarbeitern auto-zugeordnet, Rest manuell; Verbindungs-Test schlägt Verbindungsabbruch erkennbar an.
## Hinweise für Slice-Planung
- AirCall-API über Apps-Engine
---
## Definition of Done — verbindlich (siehe `AGENTS.md` + `docs/INTEGRATION-CONTRACTS.md`)
Dieses Milestone gilt **nur dann als erledigt**, wenn alle Punkte wahr sind. Bei Verstoß: PR-Block.
### Erreichbarkeit
- [ ] **Sidebar-Eintrag** in `packages/ui-hivegrid/src/app-shell/sidebar.config.ts` mit Permission-Gate (oder explizit dokumentiert, warum nur Inline-Verlinkung) — Gruppe gemäß `docs/INTEGRATION-CONTRACTS.md` §1
- [ ] **Route** unter korrektem URL-Pattern (INTEGRATION-CONTRACTS §3)
- [ ] **Breadcrumb** für Detail-Routes (§4)
- [ ] **Mobile-Tab-Bar-Eintrag** falls mobile-relevant (§13)
- [ ] **Customer-Portal-Sichtbarkeit** explizit konfiguriert (§14)
### Querschnitt-Wiring
- [ ] **Audit** läuft (auto via M001 oder manuell)
- [ ] **Activity-Stream** via `logActivity` bei relevanter Aktion (M045)
- [ ] **Notifications** via `notify()` (M011), nicht direkt
- [ ] **Search-Index** registriert in `indexed-entities.ts`, falls suchbar
- [ ] **Permission-Filter** via `withTenantScope()` + `withPermission()` (M004)
- [ ] **Feature-Flag-fähig** (M006) — Modul ohne Deploy abschaltbar
### Code-Layer-Disziplin (PR-Block)
- [ ] Loader baut View-Model; UI-Component empfängt nur VM + Actions
- [ ] Keine Prisma-/Server-Imports in `packages/ui-hivegrid/**`
- [ ] Subframe-Output via Adapter, nicht direkt importiert
- [ ] Alle UI-Texte als i18n-Keys (M003-Build-Lint blockt sonst)
### Tests
- [ ] **Unit-Test** für VM-Builder mit Zod-Schema-Validierung
- [ ] **Smoke-Test** `e2e/smoke/<modul>.spec.ts` (Login → Route → Hauptaktion → erwartetes UI)
- [ ] **Hot-Swap-Drill** grün (Smoke-Test gegen `packages/ui-mock` aus M017)
- [ ] **Visual-Regression-Snapshot** der Hauptansicht (M016)
### Klartext (User-facing)
- [ ] Fehler-Texte aus M002-Catalog (kein HTTP-Code im UI)
- [ ] Empty-State mit Klartext + nächster Aktion
- [ ] Loading-State mit Klartext (kein leerer Spinner)
- [ ] Permission-Denied → 404, nicht 403 (Bauprinzip A.5.3)
### Rollback-Pfad
- [ ] **Forward-Only-DB-Migration** mit Inverse-SQL als Kommentar
- [ ] **Atomic-Slice-Commits** (TC-Default)
- [ ] **Feature-Flag** vorhanden, um das Modul ohne Deploy auszuschalten
---
## Klick-Pfad zum Prüfen (für User)
Wenn dieses Milestone fertig ist, prüft der User die Funktion über folgenden Pfad:
1. Login als geeigneter User-Typ (siehe Erfolgskriterium oben)
2. Sidebar-Gruppe + Eintrag öffnen (gemäß INTEGRATION-CONTRACTS.md §1)
3. Hauptaktion ausführen
4. Erwartetes Ergebnis sichtbar (siehe Erfolgskriterium)
**Falls etwas nicht erreichbar ist:** Milestone ist trotz „grüner Tests" nicht fertig — siehe Erreichbarkeits-Checkliste oben.
Loaded 100 of 5784 files, more files were not shown because too many files have changed in this diff. Show more