mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 08:29:36 +01:00
init
This commit is contained in:
commit
4e448afa57
19 changed files with 4391 additions and 0 deletions
1
.claude/skills/ddd-model
Symbolic link
1
.claude/skills/ddd-model
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
/home/sebi/git/tools/go-clean-ddd-skill/skills/ddd-model
|
||||
BIN
docs/mvp/2026-02-15-fleischerei-erp-feature-definition.docx
Normal file
BIN
docs/mvp/2026-02-15-fleischerei-erp-feature-definition.docx
Normal file
Binary file not shown.
1002
docs/mvp/2026-02-15-fleischerei-erp-feature-definition.md
Normal file
1002
docs/mvp/2026-02-15-fleischerei-erp-feature-definition.md
Normal file
File diff suppressed because it is too large
Load diff
609
docs/mvp/2026-02-16-abhangigkeitsanalyse-fleischerei-erp.md
Normal file
609
docs/mvp/2026-02-16-abhangigkeitsanalyse-fleischerei-erp.md
Normal file
|
|
@ -0,0 +1,609 @@
|
|||
# Abhängigkeitsanalyse: Fleischerei-ERP Epics
|
||||
|
||||
## Kontext
|
||||
|
||||
Das Dokument "2026-02-15-fleischerei-erp-feature-definition.md" beschreibt 13 Epics für ein MVP-Fleischerei-ERP-System. Diese Analyse identifiziert die Abhängigkeiten zwischen den Epics, um eine fundierte Priorisierungsentscheidung zu ermöglichen.
|
||||
|
||||
## Epic-Übersicht
|
||||
|
||||
| Epic | Name | Komplexität | MVP-Kritisch |
|
||||
|------|------|-------------|--------------|
|
||||
| 1 | ERP Grundlagen | Hoch | Ja |
|
||||
| 2 | Waagen/Kassen-Anbindung | Mittel | Ja |
|
||||
| 3 | QM & Compliance (HACCP) | Hoch | Ja |
|
||||
| 4 | Rezeptur- & Stammdatenmanagement | Hoch | Ja |
|
||||
| 5 | Beschaffung & Rohstoffmanagement | Mittel | Ja |
|
||||
| 6 | Kundenanforderungen & Deklaration | Mittel | Ja |
|
||||
| 7 | Produktionsplanung & -steuerung | Hoch | Ja |
|
||||
| 8 | Bestandsführung & Inventur | Hoch | Ja |
|
||||
| 9 | Reporting & Auswertungen | Mittel | Ja |
|
||||
| 10 | Benutzerverwaltung & Rollen | Niedrig | Ja |
|
||||
| 11 | Mehrfilialen-Management | Mittel | Teilweise |
|
||||
| 12 | Dokumentenarchivierung & GoBD | Mittel | Ja |
|
||||
| 13 | FIBU-Integration / Steuerberater | Niedrig | Teilweise |
|
||||
|
||||
## Abhängigkeitsmatrix
|
||||
|
||||
### Foundation Layer (keine Abhängigkeiten)
|
||||
|
||||
**Epic 10: Benutzerverwaltung & Rollen**
|
||||
- ✅ **Keine Abhängigkeiten**
|
||||
- **Benötigt von:** Allen anderen Epics (Zugriffskontrolle)
|
||||
- **Empfehlung:** Als erstes implementieren - ist Grundlage für alle anderen Features
|
||||
|
||||
### Core Layer (abhängig von Foundation)
|
||||
|
||||
**Epic 1: ERP Grundlagen**
|
||||
- **Abhängigkeiten:** Epic 10 (Benutzerverwaltung für rollenbasierte Zugriffe)
|
||||
- **Benötigt von:** Epic 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13 (alle!)
|
||||
- **Kritische Komponenten:**
|
||||
- Artikelstamm (1.1) → Basis für fast alles
|
||||
- Lieferantenstamm (1.2) → Benötigt für Epic 3, 5
|
||||
- Kundenstamm (1.3) → Benötigt für Epic 1.4, 1.5
|
||||
- **Empfehlung:** Direkt nach Epic 10 implementieren
|
||||
|
||||
**Epic 8: Bestandsführung & Inventur**
|
||||
- **Abhängigkeiten:** Epic 1 (Artikelstamm)
|
||||
- **Benötigt von:** Epic 5 (Beschaffung), Epic 7 (Produktion), Epic 9 (Reports)
|
||||
- **Hinweis:** Zentrale Datenquelle für viele andere Epics
|
||||
- **Empfehlung:** Früh implementieren, parallel zu Epic 4
|
||||
|
||||
### Domain Layer (abhängig von Core)
|
||||
|
||||
**Epic 4: Rezeptur- & Stammdatenmanagement**
|
||||
- **Abhängigkeiten:** Epic 1 (Artikelstamm als Basis)
|
||||
- **Benötigt von:**
|
||||
- Epic 6 (Deklaration - Nährwerte, Allergene automatisch berechnen)
|
||||
- Epic 7 (Produktionsplanung - Materialbedarf berechnen)
|
||||
- Epic 2 (Etikettendruck - Rezeptur-Infos)
|
||||
- Epic 9 (Deckungsbeitragsrechnung - Kostenberechnung)
|
||||
- **Kritische Abhängigkeit:** Epic 4.2 (Ausbeute) → Epic 7.3 (Materialbedarf)
|
||||
- **Empfehlung:** Parallel zu Epic 8 implementieren
|
||||
|
||||
**Epic 12: Dokumentenarchivierung & GoBD**
|
||||
- **Abhängigkeiten:** Epic 1 (Dokumente wie Rechnungen, Lieferscheine)
|
||||
- **Benötigt von:** Epic 3 (HACCP-Dokumentation), Epic 13 (DATEV-Export)
|
||||
- **Hinweis:** Sollte früh als technische Basis implementiert werden
|
||||
- **Empfehlung:** Früh implementieren, parallel zur Domain-Entwicklung
|
||||
|
||||
### Integration Layer (abhängig von Domain)
|
||||
|
||||
**Epic 5: Beschaffung & Rohstoffmanagement**
|
||||
- **Abhängigkeiten:**
|
||||
- Epic 1 (Lieferantenstamm, Artikelstamm)
|
||||
- Epic 8 (Bestandsführung - Wareneingang bucht Bestand ein)
|
||||
- Epic 3.3 (Wareneingangskontrolle ist Teil von HACCP)
|
||||
- Epic 7 (optional: Bedarfsplanung aus Produktionsplan - Epic 5.1)
|
||||
- **Benötigt von:** Epic 7 (Bedarfsplanung)
|
||||
- **Empfehlung:** Nach Epic 8 und Epic 3 implementieren
|
||||
|
||||
**Epic 3: QM & Compliance (HACCP)**
|
||||
- **Abhängigkeiten:**
|
||||
- Epic 1 (Lieferanten für Wareneingangskontrolle)
|
||||
- Epic 10 (Benutzer für Schulungsverwaltung)
|
||||
- Epic 12 (Dokumentenarchivierung für HACCP-Nachweise)
|
||||
- **Benötigt von:** Epic 9 (HACCP-Reports), Epic 5 (Wareneingangskontrolle)
|
||||
- **Hinweis:** Relativ isoliert, kann parallel entwickelt werden
|
||||
- **Empfehlung:** Parallel zu Epic 4/8 starten, Epic 3.3 vor Epic 5.3
|
||||
|
||||
**Epic 6: Kundenanforderungen & Deklaration**
|
||||
- **Abhängigkeiten:**
|
||||
- Epic 4 (Rezepturen - Nährwerte und Allergene automatisch berechnen)
|
||||
- Epic 1 (Artikelstamm)
|
||||
- **Benötigt von:** Epic 2 (Etikettendruck)
|
||||
- **Empfehlung:** Nach Epic 4 implementieren
|
||||
|
||||
**Epic 7: Produktionsplanung & -steuerung**
|
||||
- **Abhängigkeiten:**
|
||||
- Epic 4 (Rezepturen, Ausbeute-Berechnung für Materialbedarf)
|
||||
- Epic 8 (Bestandsführung für Produktionsrückmeldung)
|
||||
- Epic 9 (optional: Verkaufstrends-Analyse für Epic 7.2)
|
||||
- **Benötigt von:** Epic 5 (Bedarfsplanung), Epic 9 (Reports)
|
||||
- **Kritische Abhängigkeit:** Epic 7.4 (Produktionsrückmeldung) → Epic 8 (Bestandsbuchungen)
|
||||
- **Empfehlung:** Nach Epic 4 und Epic 8 implementieren
|
||||
|
||||
**Epic 2: Waagen/Kassen-Anbindung**
|
||||
- **Abhängigkeiten:**
|
||||
- Epic 1 (Artikelstamm für Synchronisation)
|
||||
- Epic 4 (Rezepturen für Nährwerte auf Etikett)
|
||||
- Epic 6 (Deklaration/Etiketten-Generierung)
|
||||
- **Benötigt von:** Epic 8 (Bondaten-Import für Bestandsabgang), Epic 9 (Verkaufsstatistik)
|
||||
- **Hinweis:** Epic 2.4 (Etikettendruck) benötigt Epic 6 vollständig
|
||||
- **Empfehlung:** Nach Epic 4 und Epic 6 implementieren
|
||||
|
||||
### Reporting Layer (abhängig von allen)
|
||||
|
||||
**Epic 9: Reporting & Auswertungen**
|
||||
- **Abhängigkeiten:**
|
||||
- Epic 1 (Verkaufsdaten)
|
||||
- Epic 2 (Bondaten für Verkaufsstatistik)
|
||||
- Epic 3 (HACCP-Daten für HACCP-Reports)
|
||||
- Epic 4 (Rezepturen für Deckungsbeitrag)
|
||||
- Epic 5 (Einkaufsdaten)
|
||||
- Epic 7 (Produktionsdaten)
|
||||
- Epic 8 (Bestandsdaten)
|
||||
- **Benötigt von:** Epic 7 (Verkaufstrends für Produktionsplanung)
|
||||
- **Hinweis:** Kann iterativ entwickelt werden, einzelne Reports nach Verfügbarkeit der Daten
|
||||
- **Empfehlung:** Iterativ implementieren, parallel zu anderen Epics
|
||||
|
||||
### Optional/Later Layer
|
||||
|
||||
**Epic 11: Mehrfilialen-Management**
|
||||
- **Abhängigkeiten:**
|
||||
- Epic 1 (Artikelstamm)
|
||||
- Epic 8 (Bestandsführung)
|
||||
- Epic 9 (Reporting)
|
||||
- **Hinweis:** Für MVP nur 1-2 Filialen, einfache Version reicht
|
||||
- **Empfehlung:** Später implementieren, erst wenn Kern-Features stabil sind
|
||||
|
||||
**Epic 13: FIBU-Integration / Steuerberater**
|
||||
- **Abhängigkeiten:**
|
||||
- Epic 1 (Rechnungen)
|
||||
- Epic 12 (Dokumentenarchivierung)
|
||||
- **Hinweis:** DATEV-Export ist MVP-Muss, vollautomatische FIBU optional
|
||||
- **Empfehlung:** DATEV-Export nach Epic 1, vollautomatische FIBU (13.2) deutlich später
|
||||
|
||||
## Empfohlene Implementierungs-Wellen
|
||||
|
||||
### Welle 1: Foundation (Woche 1-3)
|
||||
1. **Epic 10: Benutzerverwaltung & Rollen**
|
||||
- Basis für alles
|
||||
- Einfach zu implementieren
|
||||
- Keine Abhängigkeiten
|
||||
|
||||
2. **Epic 1: ERP Grundlagen (Kern-Features)**
|
||||
- 1.1 Artikelstamm (ohne Lieferanten-/Kunden-Zuordnung)
|
||||
- 1.2 Lieferantenstamm (Basis)
|
||||
- 1.3 Kundenstamm (Basis)
|
||||
|
||||
### Welle 2: Core Domain (Woche 4-8)
|
||||
3. **Epic 8: Bestandsführung (Basis)**
|
||||
- 8.1 Bestandsverwaltung Rohstoffe
|
||||
- 8.2 Bestandsverwaltung Eigenproduktion
|
||||
- 8.3 Bestandsbewegungen (manuell)
|
||||
|
||||
4. **Epic 4: Rezeptur- & Stammdatenmanagement**
|
||||
- 4.1 Rezepturverwaltung
|
||||
- 4.2 Ausbeute-Berechnung
|
||||
- 4.3 Chargen-Tracking
|
||||
|
||||
5. **Epic 12: Dokumentenarchivierung (Basis)**
|
||||
- 12.1 Dokumentenverwaltung
|
||||
- 12.2 Revisionssichere Archivierung
|
||||
|
||||
6. **Epic 3: QM & Compliance (parallel zu 4/12)**
|
||||
- 3.1 Temperaturprotokollierung
|
||||
- 3.2 Reinigungspläne
|
||||
- 3.3 Wareneingangskontrolle
|
||||
|
||||
### Welle 3: Integration & Production (Woche 9-14)
|
||||
7. **Epic 5: Beschaffung & Rohstoffmanagement**
|
||||
- 5.2 Bestellwesen
|
||||
- 5.3 Wareneingang (mit Epic 3.3)
|
||||
- 5.4 Lieferanten-QM
|
||||
|
||||
8. **Epic 6: Deklaration**
|
||||
- 6.1 Allergenkennzeichnung (aus Epic 4)
|
||||
- 6.2 Nährwertberechnung (aus Epic 4)
|
||||
- 6.3 Qualitätssiegel-Management
|
||||
|
||||
9. **Epic 7: Produktionsplanung (Kern)**
|
||||
- 7.1 Produktionsplan erstellen
|
||||
- 7.3 Produktionsauftrag
|
||||
- 7.4 Produktionsrückmeldung
|
||||
|
||||
### Welle 4: Sales & Reporting (Woche 15-20)
|
||||
10. **Epic 1: ERP Grundlagen (Verkauf)**
|
||||
- 1.4 Auftragserfassung
|
||||
- 1.5 Lieferschein & Rechnung
|
||||
|
||||
11. **Epic 2: Waagen/Kassen-Anbindung**
|
||||
- 2.1 Stammdaten-Synchronisation
|
||||
- 2.4 Etikettendruck (benötigt Epic 6)
|
||||
- 2.2 Bondaten-Rückfluss
|
||||
- 2.3 TSE-Prüfung
|
||||
|
||||
12. **Epic 9: Reporting (iterativ)**
|
||||
- 9.1 Verkaufsstatistik (benötigt Epic 2.2)
|
||||
- 9.3 HACCP-Berichte
|
||||
- 9.4 Warenwirtschafts-Reports
|
||||
|
||||
### Welle 5: Advanced Features (Woche 21-26)
|
||||
13. **Epic 7: Produktionsplanung (Advanced)**
|
||||
- 7.2 Verkaufstrends-Analyse (benötigt Epic 9.1)
|
||||
- 7.5 Integration B2B-Aufträge (optional)
|
||||
|
||||
14. **Epic 5: Beschaffung (Advanced)**
|
||||
- 5.1 Bedarfsplanung (benötigt Epic 7)
|
||||
|
||||
15. **Epic 9: Reporting (Advanced)**
|
||||
- 9.2 Deckungsbeitragsrechnung (benötigt Epic 4.4)
|
||||
- 9.5 Einkaufs-Reports
|
||||
|
||||
16. **Epic 4: Rezeptur (Advanced)**
|
||||
- 4.4 Kalkulationsgrundlagen
|
||||
|
||||
### Welle 6: Optional/Later (Nach MVP)
|
||||
17. **Epic 11: Mehrfilialen-Management**
|
||||
- Nach Stabilisierung des Kern-MVPs
|
||||
|
||||
18. **Epic 13: FIBU-Integration**
|
||||
- 13.1 DATEV-Schnittstelle (MVP)
|
||||
- 13.2 Automatische FIBU (optional, nur wenn vollautomatisch)
|
||||
- 13.3 Zahlungsverkehr (falls 13.2)
|
||||
|
||||
19. **Epic 3/8: Weitere HACCP/Bestand-Features**
|
||||
- 3.4 Probenentnahme
|
||||
- 3.5 Schulungsverwaltung
|
||||
- 3.6 Wartungsverwaltung
|
||||
- 3.7 SOPs
|
||||
- 3.8 Audit-Vorbereitung
|
||||
- 8.4 MHD-Warnungen
|
||||
- 8.5 Inventur
|
||||
|
||||
20. **Epic 6: Weitere Deklarations-Features**
|
||||
- 6.4 Herkunftskennzeichnung
|
||||
- 6.5 Etiketten-Generierung (erweitert)
|
||||
|
||||
21. **Epic 12: Weitere Dokumentations-Features**
|
||||
- 12.3 Suchfunktion
|
||||
- 12.4 Automatische Löschfristen
|
||||
- 12.5 Export & Datenübergabe
|
||||
|
||||
## Kritische Pfade
|
||||
|
||||
### Kritischer Pfad 1: Produktion
|
||||
```
|
||||
Epic 10 (Benutzer) → Epic 1 (Artikel) → Epic 4 (Rezepturen) → Epic 8 (Bestand) → Epic 7 (Produktion)
|
||||
```
|
||||
**Dauer:** ca. 11-14 Wochen
|
||||
|
||||
### Kritischer Pfad 2: Verkauf
|
||||
```
|
||||
Epic 10 → Epic 1 → Epic 4 → Epic 6 (Deklaration) → Epic 2 (Waagen/Kassen) → Epic 9.1 (Verkaufsstatistik)
|
||||
```
|
||||
**Dauer:** ca. 15-20 Wochen
|
||||
|
||||
### Kritischer Pfad 3: HACCP
|
||||
```
|
||||
Epic 10 → Epic 1 → Epic 12 (Dokumentenarchiv) → Epic 3 (HACCP) → Epic 9.3 (HACCP-Reports)
|
||||
```
|
||||
**Dauer:** ca. 8-11 Wochen (parallel zu Pfad 1/2)
|
||||
|
||||
## Risiken & Blocker
|
||||
|
||||
### Technische Risiken
|
||||
|
||||
1. **Epic 2: Waagen/Kassen-Anbindung**
|
||||
- **Risiko:** Integration mit Bizerba/Mettler-Waagen komplex
|
||||
- **Mitigation:** Früh Proof-of-Concept entwickeln, Hardware-Spezifikationen klären
|
||||
- **Blocker für:** Epic 8 (Bondaten), Epic 9.1 (Verkaufsstatistik)
|
||||
|
||||
2. **Epic 4.3: Chargen-Tracking**
|
||||
- **Risiko:** Lückenlose Rückverfolgbarkeit komplex zu implementieren
|
||||
- **Mitigation:** Datenmodell genau planen, mit Branchenexperten validieren
|
||||
- **Blocker für:** Epic 7 (Produktion), Epic 3.3 (Wareneingangskontrolle)
|
||||
|
||||
3. **Epic 12: GoBD-Compliance**
|
||||
- **Risiko:** Rechtliche Anforderungen nicht vollständig verstanden
|
||||
- **Mitigation:** Frühzeitig mit Steuerberater/Rechtsexperten abstimmen
|
||||
- **Blocker für:** Epic 1.5 (Rechnungen), Epic 13 (FIBU)
|
||||
|
||||
### Fachliche Risiken
|
||||
|
||||
1. **Epic 3: HACCP-Anforderungen unklar**
|
||||
- **Research-Bedarf:** Gesetzliche Anforderungen für kleinere Betriebe recherchieren
|
||||
- **Impact:** Umfang von Epic 3 könnte größer/kleiner sein als gedacht
|
||||
- **Mitigation:** Research in Welle 1 durchführen
|
||||
|
||||
2. **Epic 1.4: Auftragsarten unklar**
|
||||
- **Research-Bedarf:** Details zu Auftragsarten klären (Workflows)
|
||||
- **Impact:** Epic 1.4 und Epic 7.5 könnten komplexer sein
|
||||
- **Mitigation:** User Workshops in Welle 1 durchführen
|
||||
|
||||
3. **Epic 13.2: Vollautomatische FIBU riskant**
|
||||
- **Risiko:** Könnte zu komplex für MVP sein
|
||||
- **Mitigation:** Als optional markieren, nur wenn wirklich vollautomatisch umsetzbar
|
||||
|
||||
## Parallelisierungs-Möglichkeiten
|
||||
|
||||
### Welle 2 (Parallel):
|
||||
- **Team 1:** Epic 4 (Rezepturen)
|
||||
- **Team 2:** Epic 8 (Bestand) + Epic 12 (Dokumentenarchiv)
|
||||
- **Team 3:** Epic 3 (HACCP)
|
||||
|
||||
### Welle 3 (Parallel):
|
||||
- **Team 1:** Epic 5 (Beschaffung)
|
||||
- **Team 2:** Epic 6 (Deklaration)
|
||||
- **Team 3:** Epic 7 (Produktion)
|
||||
|
||||
### Welle 4 (Parallel):
|
||||
- **Team 1:** Epic 1.4/1.5 (Aufträge/Rechnungen)
|
||||
- **Team 2:** Epic 2 (Waagen/Kassen)
|
||||
- **Team 3:** Epic 9 (Reporting - iterativ)
|
||||
|
||||
## Empfohlene Priorisierung (Top → Bottom)
|
||||
|
||||
1. **Must-Have für Tag 1 (Welle 1):**
|
||||
- Epic 10: Benutzerverwaltung
|
||||
- Epic 1: ERP Grundlagen (Stammdaten)
|
||||
|
||||
2. **Must-Have für Basic Operation (Welle 2):**
|
||||
- Epic 8: Bestandsführung
|
||||
- Epic 4: Rezepturen
|
||||
- Epic 12: Dokumentenarchiv
|
||||
- Epic 3: HACCP (Basis)
|
||||
|
||||
3. **Must-Have für Production (Welle 3):**
|
||||
- Epic 5: Beschaffung
|
||||
- Epic 6: Deklaration
|
||||
- Epic 7: Produktion (Kern)
|
||||
|
||||
4. **Must-Have for Sales (Welle 4):**
|
||||
- Epic 1.4/1.5: Aufträge/Rechnungen
|
||||
- Epic 2: Waagen/Kassen
|
||||
- Epic 9: Reporting (Basis)
|
||||
|
||||
5. **Nice-to-Have for MVP (Welle 5):**
|
||||
- Epic 7.2: Verkaufstrends
|
||||
- Epic 5.1: Bedarfsplanung
|
||||
- Epic 9.2: Deckungsbeitrag
|
||||
- Epic 4.4: Kalkulation
|
||||
|
||||
6. **Post-MVP (Welle 6):**
|
||||
- Epic 11: Mehrfilialen (erweitert)
|
||||
- Epic 13.2: Vollautomatische FIBU
|
||||
- Weitere Features aus Epic 3, 6, 8, 12
|
||||
|
||||
## Projekt-Kontext (aus User-Feedback)
|
||||
|
||||
- **Team-Größe:** 2-3 Entwickler (kleines Team)
|
||||
- **Priorisierung:** HACCP-First (Compliance als Hauptfokus)
|
||||
- **Waagen-Erfahrung:** Keine (Proof-of-Concept benötigt)
|
||||
- **Zeitrahmen:** 4-6 Monate (16-24 Wochen)
|
||||
|
||||
## Angepasste Implementierungs-Strategie (HACCP-First)
|
||||
|
||||
### Anpassungen für HACCP-First Ansatz
|
||||
|
||||
**Kritischer Pfad (angepasst):**
|
||||
```
|
||||
Epic 10 (Benutzer) → Epic 1 (Stammdaten) → Epic 12 (Dokumentenarchiv) → Epic 3 (HACCP) → Epic 9.3 (HACCP-Reports)
|
||||
```
|
||||
|
||||
**Sekundäre Pfade (parallel, soweit möglich):**
|
||||
1. Produktion: Epic 4 → Epic 8 → Epic 7
|
||||
2. Beschaffung: Epic 5 (benötigt Epic 3.3 + Epic 8)
|
||||
|
||||
**Wichtig:** Epic 3.3 (Wareneingangskontrolle) und Epic 5.3 (Wareneingang) müssen koordiniert werden.
|
||||
|
||||
### Angepasste Wellen für 2-3 Entwickler
|
||||
|
||||
#### Welle 1: Foundation (Woche 1-3)
|
||||
**Team-Split: 2 Entwickler + 1 für PoC**
|
||||
|
||||
1. **Dev 1:** Epic 10 (Benutzerverwaltung) → Epic 1.1 (Artikelstamm Basis)
|
||||
2. **Dev 2:** Epic 1.2 (Lieferantenstamm) → Epic 1.3 (Kundenstamm)
|
||||
3. **Dev 3 (falls verfügbar):** Proof-of-Concept Waagen-Integration (Epic 2)
|
||||
|
||||
**Parallel:** Research zu HACCP-Anforderungen durchführen
|
||||
|
||||
#### Welle 2: Dokumentation & HACCP Basis (Woche 4-7)
|
||||
**Team-Split: 1+1 oder 2 sequenziell**
|
||||
|
||||
1. **Dev 1:** Epic 12.1 + 12.2 (Dokumentenarchiv Basis - revisionssicher)
|
||||
2. **Dev 2:** Epic 3.1 (Temperaturprotokollierung) → Epic 3.2 (Reinigungspläne)
|
||||
|
||||
**Parallel (falls 3. Dev verfügbar):** Epic 4.1 (Rezepturverwaltung Basis)
|
||||
|
||||
#### Welle 3: HACCP Kern + Bestand (Woche 8-11)
|
||||
**Team-Split: Sequenziell**
|
||||
|
||||
1. **Dev 1+2:** Epic 8.1 + 8.2 (Bestandsverwaltung Basis)
|
||||
2. **Dev 1:** Epic 3.3 (Wareneingangskontrolle) - benötigt Epic 5.3 (koordiniert entwickeln)
|
||||
3. **Dev 2:** Epic 4.1 + 4.3 (Rezepturen + Chargen-Tracking)
|
||||
|
||||
#### Welle 4: Beschaffung & HACCP Erweitert (Woche 12-15)
|
||||
**Team-Split: 1+1**
|
||||
|
||||
1. **Dev 1:** Epic 5.2 + 5.3 (Bestellwesen + Wareneingang) - koordiniert mit Epic 3.3
|
||||
2. **Dev 2:** Epic 3.5 (Schulungsverwaltung) → Epic 3.6 (Wartungsverwaltung) → Epic 3.7 (SOPs)
|
||||
|
||||
**Ergebnis:** HACCP-Kern ist fertig, Beschaffung funktioniert
|
||||
|
||||
#### Welle 5: Produktion & HACCP Reporting (Woche 16-19)
|
||||
**Team-Split: 1+1**
|
||||
|
||||
1. **Dev 1:** Epic 7.1 + 7.3 + 7.4 (Produktionsplanung Kern - benötigt Epic 4 + 8)
|
||||
2. **Dev 2:** Epic 9.3 (HACCP-Berichte) → Epic 3.8 (Audit-Vorbereitung)
|
||||
3. **Dev 1+2:** Epic 3.4 (Probenentnahme) - falls Zeit
|
||||
|
||||
**Ergebnis:** HACCP-System komplett, Produktion läuft
|
||||
|
||||
#### Welle 6: Verkauf & Deklaration (Woche 20-24)
|
||||
**Team-Split: 1+1 oder sequenziell**
|
||||
|
||||
1. **Dev 1:** Epic 6.1 + 6.2 + 6.3 (Deklaration - Allergene, Nährwerte, Siegel)
|
||||
2. **Dev 2:** Epic 1.4 + 1.5 (Auftragserfassung + Rechnungen)
|
||||
3. **Dev 1+2:** Epic 2.1 + 2.4 (Waagen-Synchronisation + Etiketten) - basierend auf PoC aus Welle 1
|
||||
|
||||
**Hinweis:** Epic 2.2 (Bondaten) kann in Welle 7 verschoben werden, falls Zeit knapp
|
||||
|
||||
**Optional (falls Zeit):** Epic 9.1 (Verkaufsstatistik) + Epic 8.4 (MHD-Warnungen)
|
||||
|
||||
### Post-MVP (nach Woche 24)
|
||||
- Epic 2.2 + 2.3 (Bondaten + TSE) - falls nicht in Welle 6 geschafft
|
||||
- Epic 9.1 + 9.2 + 9.4 + 9.5 (Reporting erweitert)
|
||||
- Epic 7.2 (Verkaufstrends) + Epic 5.1 (Bedarfsplanung)
|
||||
- Epic 4.4 (Kalkulationsgrundlagen) + Epic 4.2 (Ausbeute)
|
||||
- Epic 8.5 (Inventur)
|
||||
- Epic 11 (Mehrfilialen erweitert)
|
||||
- Epic 13 (FIBU-Integration erweitert)
|
||||
- Epic 6.4 + 6.5 (Herkunft + Etiketten erweitert)
|
||||
- Epic 12.3 + 12.4 + 12.5 (Dokumentenarchiv erweitert)
|
||||
|
||||
## Zusammenfassung (angepasst)
|
||||
|
||||
**Kernaussagen:**
|
||||
|
||||
1. **HACCP-First:** Epic 3 wird priorisiert, Verkauf (Epic 2) kommt später
|
||||
|
||||
2. **Kritischer Pfad (HACCP):**
|
||||
```
|
||||
Epic 10 → 1 → 12 → 3 → 9.3
|
||||
```
|
||||
**Dauer:** ca. 15-19 Wochen
|
||||
|
||||
3. **Sekundäre Pfade (parallel):**
|
||||
- Produktion: Epic 4 → 8 → 7 (parallel zu Epic 3)
|
||||
- Beschaffung: Epic 5 (koordiniert mit Epic 3.3)
|
||||
|
||||
4. **Parallelisierung:** Begrenzt auf 2 Epics gleichzeitig (kleines Team)
|
||||
|
||||
5. **Risiko-Management:**
|
||||
- **Epic 2 (Waagen):** Proof-of-Concept in Welle 1, Hauptimplementierung in Welle 6
|
||||
- **Epic 4.3 (Chargen):** Früh implementieren (Welle 3), kritisch für HACCP
|
||||
- **Epic 12 (GoBD):** Früh implementieren (Welle 2), Basis für HACCP-Dokumentation
|
||||
|
||||
6. **Research-Bedarf:** HACCP-Anforderungen in Welle 1 klären (parallel zur Entwicklung)
|
||||
|
||||
**Geschätzte MVP-Dauer:** 20-24 Wochen (5-6 Monate) für HACCP-fokussiertes MVP mit Produktion und Beschaffung
|
||||
|
||||
**Nach 19 Wochen:** HACCP-Kern + Produktion komplett
|
||||
**Nach 24 Wochen:** + Verkauf/Waagen/Deklaration
|
||||
|
||||
## Entscheidungsgrundlage zur Priorisierung
|
||||
|
||||
### Quick Decision Matrix
|
||||
|
||||
| Entscheidung | Option A: HACCP-First (gewählt) | Option B: Produktion-First | Option C: Balanced |
|
||||
|--------------|----------------------------------|----------------------------|-------------------|
|
||||
| **Hauptvorteil** | Compliance frühzeitig sichergestellt | Interne Nutzung früh möglich | Alle Bereiche gleichzeitig |
|
||||
| **Zeitpunkt erste Nutzung** | Woche 15 (HACCP-Dokumentation) | Woche 11 (Produktion) | Woche 20+ (alles zusammen) |
|
||||
| **Risiko** | Verkauf kommt spät (Woche 20+) | Compliance-Lücken anfangs | Komplexe Koordination |
|
||||
| **Team-Auslastung** | Gut (2 parallele Stränge) | Sehr gut (sequenziell) | Schwierig (3+ parallel) |
|
||||
| **Für wen geeignet** | Audit steht bevor | Produktion läuft bereits | Großes Team (6+) |
|
||||
|
||||
### Priorisierungs-Checkliste
|
||||
|
||||
**Wenn JA, dann höher priorisieren:**
|
||||
|
||||
**Epic 3 (HACCP):**
|
||||
- [ ] Steht ein Audit/eine Kontrolle bevor?
|
||||
- [ ] Gibt es aktuell Compliance-Probleme?
|
||||
- [ ] Ist HACCP-Dokumentation manuell sehr aufwendig?
|
||||
- [x] HACCP-First gewählt
|
||||
|
||||
**Epic 7 (Produktion):**
|
||||
- [ ] Wird bereits produziert und Rezepturen sind komplex?
|
||||
- [ ] Ist Rückverfolgbarkeit (Chargen) kritisch?
|
||||
- [ ] Gibt es Überproduktions-Probleme?
|
||||
|
||||
**Epic 2 (Waagen/Verkauf):**
|
||||
- [ ] Ladenverkauf ist Hauptumsatzquelle
|
||||
- [ ] Neue Waagen werden gerade eingeführt
|
||||
- [ ] Etikettendruck ist aktuell fehlerhaft
|
||||
|
||||
**Epic 5 (Beschaffung):**
|
||||
- [ ] Einkauf ist unübersichtlich
|
||||
- [ ] Lieferanten-Qualität ist Problem
|
||||
- [ ] Bestellungen werden vergessen
|
||||
|
||||
### Empfohlene Meilensteine
|
||||
|
||||
**Meilenstein 1 (Woche 7): "Foundation Complete"**
|
||||
- ✅ Benutzer können sich anmelden (Epic 10)
|
||||
- ✅ Artikel, Lieferanten, Kunden sind erfasst (Epic 1)
|
||||
- ✅ Dokumente werden revisionssicher gespeichert (Epic 12)
|
||||
- ✅ Temperaturen + Reinigungen werden dokumentiert (Epic 3.1, 3.2)
|
||||
|
||||
**Meilenstein 2 (Woche 11): "HACCP Core Ready"**
|
||||
- ✅ Wareneingangskontrolle funktioniert (Epic 3.3)
|
||||
- ✅ Bestellungen können erfasst werden (Epic 5.2, 5.3)
|
||||
- ✅ Bestände werden geführt (Epic 8)
|
||||
- ✅ Rezepturen mit Chargen (Epic 4.1, 4.3)
|
||||
|
||||
**Meilenstein 3 (Woche 15): "HACCP Complete"**
|
||||
- ✅ Schulungen + Wartungen dokumentiert (Epic 3.5, 3.6, 3.7)
|
||||
- ✅ HACCP-Berichte können generiert werden (Epic 9.3)
|
||||
- ✅ Audit-Vorbereitung funktioniert (Epic 3.8)
|
||||
- ✅ System ist audit-ready
|
||||
|
||||
**Meilenstein 4 (Woche 19): "Production Ready"**
|
||||
- ✅ Produktionsplanung funktioniert (Epic 7.1, 7.3, 7.4)
|
||||
- ✅ Produktion bucht automatisch Bestände (Epic 7.4)
|
||||
- ✅ Rückverfolgbarkeit von Rohstoff bis Endprodukt (Epic 4.3)
|
||||
|
||||
**Meilenstein 5 (Woche 24): "Sales Ready"**
|
||||
- ✅ Deklaration (Allergene, Nährwerte) funktioniert (Epic 6)
|
||||
- ✅ Aufträge + Rechnungen können erstellt werden (Epic 1.4, 1.5)
|
||||
- ✅ Waagen-Integration funktioniert (Epic 2.1, 2.4)
|
||||
- ✅ Etiketten können gedruckt werden (Epic 2.4)
|
||||
|
||||
### Trade-Off Entscheidungen
|
||||
|
||||
**Wenn Zeit knapp wird, diese Features verschieben (Post-MVP):**
|
||||
|
||||
1. **Epic 2.2 + 2.3** (Bondaten + TSE)
|
||||
- **Impact:** Keine automatische Bestandsbuchung aus Verkauf
|
||||
- **Workaround:** Manuelle Bestandserfassung oder tägliche Inventur
|
||||
|
||||
2. **Epic 7.2** (Verkaufstrends-Analyse)
|
||||
- **Impact:** Keine datenbasierte Produktionsplanung
|
||||
- **Workaround:** Planung nach Bauchgefühl (Status Quo)
|
||||
|
||||
3. **Epic 9.2 + 9.5** (Deckungsbeitrag + Einkaufs-Reports)
|
||||
- **Impact:** Keine automatische Margen-Analyse
|
||||
- **Workaround:** Excel-Export + manuelle Analyse
|
||||
|
||||
4. **Epic 4.2 + 4.4** (Ausbeute + Kalkulation)
|
||||
- **Impact:** Keine automatische Preisberechnung
|
||||
- **Workaround:** Manuelle Kalkulation (Status Quo)
|
||||
|
||||
5. **Epic 8.4 + 8.5** (MHD-Warnungen + Inventur)
|
||||
- **Impact:** Keine automatischen Warnungen
|
||||
- **Workaround:** Manuelle MHD-Kontrolle
|
||||
|
||||
**Diese Features NICHT verschieben (MVP-kritisch):**
|
||||
|
||||
1. **Epic 10** (Benutzerverwaltung) - Basis für alles
|
||||
2. **Epic 1.1-1.3** (Stammdaten) - Basis für alles
|
||||
3. **Epic 12.1-12.2** (Dokumentenarchiv) - GoBD-Pflicht
|
||||
4. **Epic 3.1-3.3** (HACCP Kern) - Compliance-Pflicht
|
||||
5. **Epic 4.1 + 4.3** (Rezepturen + Chargen) - Rückverfolgbarkeit
|
||||
6. **Epic 8.1-8.3** (Bestandsführung) - Warenwirtschaft
|
||||
7. **Epic 5.2-5.3** (Bestellwesen + Wareneingang) - Einkauf
|
||||
|
||||
### Nächste Schritte (konkret)
|
||||
|
||||
**Diese Woche:**
|
||||
1. ✅ Abhängigkeitsanalyse durchgeführt
|
||||
2. ⏳ HACCP-Research durchführen (gesetzliche Anforderungen klären)
|
||||
3. ⏳ Proof-of-Concept für Waagen-Integration planen
|
||||
4. ⏳ Team-Kickoff: Welle 1 starten (Epic 10 + Epic 1)
|
||||
|
||||
**Nächste 2 Wochen:**
|
||||
5. ⏳ Epic 10 (Benutzerverwaltung) implementieren
|
||||
6. ⏳ Epic 1.1-1.3 (Stammdaten) implementieren
|
||||
7. ⏳ Waagen-PoC entwickeln (parallel)
|
||||
|
||||
**Monat 2:**
|
||||
8. ⏳ Epic 12 (Dokumentenarchiv) implementieren
|
||||
9. ⏳ Epic 3.1-3.2 (HACCP Basis) implementieren
|
||||
|
||||
**Monat 3:**
|
||||
10. ⏳ Epic 8 (Bestand) + Epic 4 (Rezepturen) implementieren
|
||||
11. ⏳ Epic 3.3 (Wareneingangskontrolle) koordiniert mit Epic 5.3
|
||||
|
||||
**Monat 4:**
|
||||
12. ⏳ Epic 5 (Beschaffung) + Epic 3.5-3.7 (HACCP erweitert)
|
||||
13. ⏳ Epic 9.3 (HACCP-Reports) + Epic 3.8 (Audit)
|
||||
|
||||
**Monat 5:**
|
||||
14. ⏳ Epic 7 (Produktion) implementieren
|
||||
15. ⏳ HACCP + Produktion Testing
|
||||
|
||||
**Monat 6:**
|
||||
16. ⏳ Epic 6 (Deklaration) + Epic 1.4-1.5 (Verkauf)
|
||||
17. ⏳ Epic 2 (Waagen) implementieren
|
||||
18. ⏳ End-to-End Testing + Deployment
|
||||
83
docs/mvp/ddd/00-overview.md
Normal file
83
docs/mvp/ddd/00-overview.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# DDD Domain Model - Effigenix Fleischerei-ERP
|
||||
|
||||
**Erstellt:** 2026-02-17
|
||||
**Technologie:** Java 21+
|
||||
**Architektur:** Domain-Driven Design + Clean Architecture
|
||||
|
||||
## Überblick
|
||||
|
||||
Dieses Dokument beschreibt das Domain-Driven Design (DDD) Modell für das Effigenix Fleischerei-ERP System.
|
||||
|
||||
## Projektziele
|
||||
|
||||
1. **ERP-Grundlagen** für Stammdatenverwaltung, Auftragsabwicklung und Fakturierung
|
||||
2. **HACCP-Compliance** - Vollständiges QM-System als Kernmehrwert für kleine Betriebe
|
||||
3. **Rezeptur-Management** - Mehrstufige Rezepturen mit Chargen-Tracking und Rückverfolgbarkeit
|
||||
4. **Produktionsplanung** - Verkaufstrends-Analyse zur Vermeidung von Überproduktion
|
||||
5. **Mehrfilialen-Unterstützung** - Zentrale Produktion mit Belieferung mehrerer Filialen
|
||||
|
||||
## DDD-Phasen
|
||||
|
||||
### Phase 0: Technologie-Auswahl ✅
|
||||
- **Sprache:** Java 21+
|
||||
- **Patterns:** Result Types, Sealed Interfaces, Pattern Matching
|
||||
- **Architektur:** Clean Architecture (Domain → Application → Infrastructure)
|
||||
|
||||
### Phase 1: Domain Discovery ✅
|
||||
- **Subdomain-Klassifizierung:** Core, Supporting, Generic
|
||||
- **DDD-Investment:** Volles DDD für 7 Core Domains
|
||||
|
||||
### Phase 2: Bounded Contexts ✅
|
||||
- **11 Bounded Contexts** identifiziert
|
||||
- **Context Map** mit Beziehungen erstellt
|
||||
- **Ubiquitous Language** für jeden BC definiert
|
||||
|
||||
### Phase 3: Tactical Modeling ✅
|
||||
- **Aggregates** identifiziert für alle Core BCs
|
||||
- **Entities** und **Value Objects** definiert
|
||||
- **Invarianten** dokumentiert
|
||||
|
||||
### Phase 4: Invarianten (TODO)
|
||||
- Detaillierte Invarianten-Dokumentation
|
||||
- Enforcement Points definieren
|
||||
|
||||
### Phase 5: Code-Generierung (TODO)
|
||||
- Java-Code aus Aggregates generieren
|
||||
- Repository Interfaces
|
||||
- Use Cases
|
||||
|
||||
### Phase 6: Validation (TODO)
|
||||
- DDD-Rules-Checklist durchgehen
|
||||
- Clean Architecture Compliance prüfen
|
||||
|
||||
## Dokumentationsstruktur
|
||||
|
||||
```
|
||||
docs/mvp/ddd/
|
||||
├── 00-overview.md (dieses Dokument)
|
||||
├── 01-domain-classification.md
|
||||
├── 02-bounded-contexts.md
|
||||
├── 03-ubiquitous-language.md
|
||||
├── 04-production-bc.md
|
||||
├── 05-quality-bc.md
|
||||
├── 06-labeling-bc.md
|
||||
├── 07-inventory-bc.md
|
||||
├── 08-procurement-bc.md
|
||||
├── 09-filiales-bc.md
|
||||
└── 10-supporting-bcs.md
|
||||
```
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
1. ✅ Bounded Contexts dokumentieren
|
||||
2. ✅ Aggregates für Core BCs modellieren
|
||||
3. ⏳ Invarianten detailliert ausarbeiten
|
||||
4. ⏳ Java-Code generieren
|
||||
5. ⏳ Validierung durchführen
|
||||
|
||||
## Referenzen
|
||||
|
||||
- Feature-Definition: `docs/mvp/2026-02-15-fleischerei-erp-feature-definition.md`
|
||||
- Abhängigkeitsanalyse: `docs/mvp/2026-02-16-abhangigkeitsanalyse-fleischerei-erp.md`
|
||||
- Java Style Guide: `.claude/skills/ddd-model/languages/java/style-guide.md`
|
||||
- DDD Rules: `.claude/skills/ddd-model/rules/ddd-rules.md`
|
||||
171
docs/mvp/ddd/01-domain-classification.md
Normal file
171
docs/mvp/ddd/01-domain-classification.md
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
# Domain-Klassifizierung
|
||||
|
||||
**Datum:** 2026-02-17
|
||||
|
||||
## Subdomain-Typen und DDD-Investment
|
||||
|
||||
Die Klassifizierung bestimmt den DDD-Aufwand:
|
||||
|
||||
| Subdomain Type | DDD Investment | Patterns |
|
||||
|----------------|----------------|----------|
|
||||
| **Core** | Voll | Aggregates, Domain Events, Domain Services, CQRS |
|
||||
| **Supporting** | Vereinfacht | Aggregates, Value Objects, einfache Services |
|
||||
| **Generic** | Minimal | CRUD, Transaction Script |
|
||||
|
||||
---
|
||||
|
||||
## CORE DOMAIN (7 Bereiche)
|
||||
|
||||
### 1. HACCP/QM & Compliance
|
||||
**Warum Core:**
|
||||
- ✅ **Kernmehrwert** für kleine Betriebe - Wettbewerbsvorteil
|
||||
- ✅ **Komplexe Invarianten** - Kritische Kontrollpunkte, Grenzwerte
|
||||
- ✅ **Compliance-kritisch** - Gesetzliche Pflicht, Audit-Vorbereitung
|
||||
- ✅ **Geschäftskritisch** - Ohne HACCP keine Betriebserlaubnis
|
||||
|
||||
**Epics:** 3 (QM & Compliance)
|
||||
|
||||
---
|
||||
|
||||
### 2. Rezeptur-Management
|
||||
**Warum Core:**
|
||||
- ✅ **Mehrstufige Strukturen** - Rezepte können Zwischenprodukte enthalten
|
||||
- ✅ **Chargen-Tracking** - Lückenlose Rückverfolgbarkeit (gesetzlich!)
|
||||
- ✅ **Komplexe Berechnungen** - Ausbeute, Nährwerte, Kosten
|
||||
- ✅ **Geschäftskritisch** - Basis für Produktion, Deklaration, Kalkulation
|
||||
|
||||
**Epics:** 4 (Rezeptur- & Stammdatenmanagement)
|
||||
|
||||
---
|
||||
|
||||
### 3. Produktionsplanung
|
||||
**Warum Core:**
|
||||
- ✅ **Verkaufstrends-Analyse** - Datenbasierte Planung (Kernmehrwert!)
|
||||
- ✅ **Vermeidung von Überproduktion** - Echtes Geschäftsproblem lösen
|
||||
- ✅ **Komplexe Bedarfsberechnung** - Rezeptur + Ausbeute + Lagerbestand
|
||||
- ✅ **Wettbewerbsvorteil** - Viele Betriebe planen nach "Bauchgefühl"
|
||||
|
||||
**Epics:** 7 (Produktionsplanung & -steuerung)
|
||||
|
||||
---
|
||||
|
||||
### 4. Deklaration & Nährwerte
|
||||
**Warum Core:**
|
||||
- ✅ **Automatische Berechnung** aus Rezepturen - Komplexe Logik
|
||||
- ✅ **Rechtskonforme Etiketten** - Compliance-kritisch
|
||||
- ✅ **Allergenkennzeichnung** - Fehler können lebensbedrohlich sein
|
||||
- ✅ **Qualitätssiegel-Management** - Bio/Regional-Nachweis
|
||||
|
||||
**Epics:** 6 (Kundenanforderungen & Deklaration)
|
||||
|
||||
---
|
||||
|
||||
### 5. Inventory (Bestandsführung)
|
||||
**Warum Core:**
|
||||
- ✅ **Chargen-Tracking** - Gesetzlich vorgeschrieben für Rückverfolgbarkeit
|
||||
- ✅ **Lückenlose Traceability** - Rohstoff-Charge → Produktion → Verkauf
|
||||
- ✅ **MHD-Tracking mit FEFO** - Komplexe Logik, nicht Standard-WaWi
|
||||
- ✅ **Basis für HACCP** - Ohne korrekte Chargen-Führung keine Compliance
|
||||
- ✅ **Existenziell bei Rückrufen** - Welche Produkte betroffen?
|
||||
|
||||
**Epics:** 8 (Bestandsführung & Inventur)
|
||||
|
||||
---
|
||||
|
||||
### 6. Procurement (Beschaffung)
|
||||
**Warum Core:**
|
||||
- ✅ **Bedarfsplanung** aus Produktionsplan - Business-Logik, kein CRUD
|
||||
- ✅ **Wareneingangskontrolle** - Integraler Teil von HACCP
|
||||
- ✅ **Lieferanten-Qualitätsmanagement** - Fließt in Compliance ein
|
||||
- ✅ **Chargen-Zuordnung** - Start der Rückverfolgbarkeitskette
|
||||
- ✅ **Compliance-kritisch** - Fehler gefährden HACCP
|
||||
|
||||
**Epics:** 5 (Beschaffung & Rohstoffmanagement)
|
||||
|
||||
---
|
||||
|
||||
### 7. Filiales (Mehrfilialen)
|
||||
**Warum Core:**
|
||||
- ✅ **Zentrale Produktion mit Belieferung** - Komplexe Koordination
|
||||
- ✅ **Interfilial-Transfers** - Chargen-Tracking über Standorte
|
||||
- ✅ **Filial-übergreifende Produktionsplanung** - Bedarf aggregieren
|
||||
- ✅ **Langfristige Strategie** - Nach MVP wird Mehrfilialen wichtig
|
||||
- ✅ **Wettbewerbsvorteil** - Skalierungsfähigkeit
|
||||
|
||||
**Epics:** 11 (Mehrfilialen-Management)
|
||||
|
||||
---
|
||||
|
||||
## SUPPORTING DOMAIN (3 Bereiche)
|
||||
|
||||
### Master Data (Stammdaten)
|
||||
**Warum Supporting:**
|
||||
- Wichtig, aber **keine komplexe Geschäftslogik**
|
||||
- Artikel, Lieferanten, Kunden = Standard-CRUD
|
||||
- **Unterstützt** Core Domains (Production, Procurement, Sales)
|
||||
|
||||
**Epics:** 1.1-1.3 (Artikelstamm, Lieferantenstamm, Kundenstamm)
|
||||
|
||||
---
|
||||
|
||||
### Sales (Verkauf)
|
||||
**Warum Supporting:**
|
||||
- Auftragserfassung, Rechnungen, Lieferscheine = **Standard-ERP**
|
||||
- Keine komplexe Geschäftslogik (im Vergleich zu Production/HACCP)
|
||||
- **Unterstützt** Geschäftsprozess, aber kein Wettbewerbsvorteil
|
||||
|
||||
**Epics:** 1.4-1.5 (Auftragserfassung, Lieferschein & Rechnung)
|
||||
|
||||
---
|
||||
|
||||
### Scale Integration (Waagen/Kassen)
|
||||
**Warum Supporting:**
|
||||
- **Technische Integration**, keine Geschäftslogik
|
||||
- Wichtig für Workflow, aber **kein Kernmehrwert**
|
||||
- **Unterstützt** Verkauf und Etikettierung
|
||||
|
||||
**Epics:** 2 (Waagen/Kassen-Anbindung)
|
||||
|
||||
---
|
||||
|
||||
## GENERIC SUBDOMAINS (3 Bereiche)
|
||||
|
||||
### Reporting
|
||||
**Warum Generic:**
|
||||
- Standardfunktionalität - **jedes ERP braucht Reports**
|
||||
- Keine Differenzierung zum Wettbewerb
|
||||
- CRUD über aggregierte Daten
|
||||
|
||||
**Epics:** 9 (Reporting & Auswertungen)
|
||||
|
||||
---
|
||||
|
||||
### Document Archive (GoBD)
|
||||
**Warum Generic:**
|
||||
- **Gesetzliche Pflicht**, aber Standardfunktionalität
|
||||
- Commodity - viele Standardlösungen verfügbar
|
||||
- Keine Geschäftslogik, nur Speicherung + Retrieval
|
||||
|
||||
**Epics:** 12 (Dokumentenarchivierung & GoBD)
|
||||
|
||||
---
|
||||
|
||||
### User Management
|
||||
**Warum Generic:**
|
||||
- **Commodity** - jede Software braucht Benutzerverwaltung
|
||||
- Vordefinierte Rollen, keine komplexe Logik
|
||||
- Standardlösung (Spring Security, Keycloak, etc.)
|
||||
|
||||
**Epics:** 10 (Benutzerverwaltung & Rollen)
|
||||
|
||||
---
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
| Kategorie | Anzahl | DDD-Aufwand | Begründung |
|
||||
|-----------|--------|-------------|------------|
|
||||
| **Core** | 7 | Hoch | Wettbewerbsvorteil, komplexe Logik, Compliance-kritisch |
|
||||
| **Supporting** | 3 | Mittel | Wichtig, aber Standard-ERP-Funktionalität |
|
||||
| **Generic** | 3 | Niedrig | Commodity, CRUD, keine Differenzierung |
|
||||
|
||||
**Gesamt:** 13 Bereiche aus Feature-Definition abgedeckt
|
||||
203
docs/mvp/ddd/02-bounded-contexts.md
Normal file
203
docs/mvp/ddd/02-bounded-contexts.md
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
# Bounded Contexts (Kontextgrenzen) & Context Map
|
||||
|
||||
**Datum:** 2026-02-17
|
||||
|
||||
## Context Map (Kontextkarte)
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph CORE["⚡ KERN-DOMÄNE"]
|
||||
Produktion["<b>Produktion</b><br/>Rezept, Charge,<br/>Ausbeute, Produktionsauftrag"]
|
||||
Qualitaet["<b>Qualität</b><br/>(HACCP/QM)<br/>Temperaturprotokolle,<br/>Reinigung, Schulung,<br/>Wartung"]
|
||||
Deklaration["<b>Deklaration</b><br/>Allergene, Nährwerte,<br/>Etiketten, Qualitätssiegel"]
|
||||
Bestand["<b>Bestandsführung</b><br/>Lagerbestände, Chargen-Tracking,<br/>Rückverfolgbarkeit, MHD, FEFO,<br/>Lagerorte"]
|
||||
Beschaffung["<b>Beschaffung</b><br/>Bedarfsplanung,<br/>Bestellungen,<br/>Wareneingang,<br/>Qualitätsprüfung"]
|
||||
Filialen["<b>Filialen</b><br/>Standorte, Interfilial-Transfer,<br/>Zentrale Produktion,<br/>Verteilung"]
|
||||
|
||||
Produktion -->|Rezeptdaten| Deklaration
|
||||
Produktion -->|Verbraucht/Produziert| Bestand
|
||||
Qualitaet -->|Prüft| Bestand
|
||||
Bestand -->|Beliefert| Beschaffung
|
||||
Bestand -->|Transfers| Filialen
|
||||
end
|
||||
|
||||
subgraph SUPPORTING["🔧 UNTERSTÜTZENDE DOMÄNE"]
|
||||
Stammdaten["<b>Stammdaten</b><br/>Artikel, Kunden,<br/>Lieferanten"]
|
||||
Verkauf["<b>Verkauf</b><br/>Aufträge, Rechnungen,<br/>Lieferscheine"]
|
||||
Waagen["<b>Waagen-Integration</b><br/>Synchronisation,<br/>Bondaten, Etikettendruck"]
|
||||
|
||||
Stammdaten -->|Stellt Artikel bereit| Verkauf
|
||||
Waagen -->|Bondaten| Verkauf
|
||||
end
|
||||
|
||||
subgraph GENERIC["📊 GENERISCHE SUBDOMÄNEN"]
|
||||
Reporting["<b>Reporting</b><br/>Analysen, Statistiken,<br/>Dashboards"]
|
||||
Dokumentenarchiv["<b>Dokumentenarchiv</b><br/>(GoBD)<br/>Audit Trail,<br/>Revisionssicher"]
|
||||
Benutzerverwaltung["<b>Benutzerverwaltung</b><br/>Rollen, Berechtigungen"]
|
||||
end
|
||||
|
||||
Stammdaten -.->|Stellt Artikel bereit| CORE
|
||||
Filialen -.->|Koordiniert Mehrfilialen| SUPPORTING
|
||||
CORE -.->|Konsumiert Daten| GENERIC
|
||||
SUPPORTING -.->|Konsumiert Daten| GENERIC
|
||||
|
||||
style CORE fill:#e1f5ff,stroke:#0066cc,stroke-width:3px
|
||||
style SUPPORTING fill:#fff4e6,stroke:#ff9800,stroke-width:2px
|
||||
style GENERIC fill:#f5f5f5,stroke:#666,stroke-width:1px
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bounded Context Details (Kontextdetails)
|
||||
|
||||
### Kern-Domäne (7 BCs)
|
||||
|
||||
#### 1. Produktions-Kontext
|
||||
- **Verantwortung:** Rezepturverwaltung, Produktionsplanung, Chargen-Erzeugung
|
||||
- **Aggregate:** Rezept, Charge, Produktionsauftrag
|
||||
- **Upstream:** Stammdaten (Artikelkatalog)
|
||||
- **Downstream:** Deklaration (Rezeptdaten), Bestandsführung (Bestandsbewegungen)
|
||||
|
||||
#### 2. Qualitäts-Kontext (HACCP/QM)
|
||||
- **Verantwortung:** HACCP-Compliance, Qualitätsmanagement, Audit-Vorbereitung
|
||||
- **Aggregate:** Temperaturprotokoll, Reinigungsnachweis, Wareneingangsprüfung, Schulungsnachweis, Wartungsprotokoll
|
||||
- **Upstream:** Beschaffung (Wareneingangsprüfung), Stammdaten (Lieferanten, Mitarbeiter)
|
||||
- **Downstream:** Reporting (HACCP-Berichte), Dokumentenarchiv (Audit-Nachweise)
|
||||
|
||||
#### 3. Deklarations-Kontext
|
||||
- **Verantwortung:** Automatische Berechnung von Nährwerten und Allergenen, Etikettengenerierung
|
||||
- **Aggregate:** Produktetikett, Allergene-Matrix
|
||||
- **Upstream:** Produktion (Rezeptdaten für Berechnungen)
|
||||
- **Downstream:** Waagen-Integration (Etikettendruck)
|
||||
|
||||
#### 4. Bestandsführungs-Kontext
|
||||
- **Verantwortung:** Chargen-basierte Bestandsführung, Rückverfolgbarkeit, MHD-Tracking
|
||||
- **Aggregate:** Bestand, Bestandsbewegung
|
||||
- **Upstream:** Produktion (Produktionsausstoß), Beschaffung (Wareneingang), Verkauf (verkaufte Artikel)
|
||||
- **Downstream:** Beschaffung (Lagerbestände für Bedarfsplanung), Reporting (Bestandsberichte)
|
||||
|
||||
#### 5. Beschaffungs-Kontext
|
||||
- **Verantwortung:** Bedarfsplanung, Bestellwesen, Wareneingangskontrolle, Lieferanten-QM
|
||||
- **Aggregate:** Bestellung, Wareneingang, Bedarfsplan
|
||||
- **Upstream:** Bestandsführung (aktueller Bestand), Produktion (Produktionsaufträge), Stammdaten (Lieferanten, Artikel)
|
||||
- **Downstream:** Qualität (Wareneingangsprüfung), Bestandsführung (Bestandszugang)
|
||||
|
||||
#### 6. Filialen-Kontext
|
||||
- **Verantwortung:** Mehrfilialen-Management, Interfilial-Transfers, zentrale Produktion
|
||||
- **Aggregate:** Filiale, Interfilial-Transfer, Verteilungsplan
|
||||
- **Upstream:** Alle Kern-BCs (koordiniert Mehrfilialen-Operationen)
|
||||
- **Downstream:** Bestandsführung (Interfilial-Bestandsbewegungen), Produktion (filialspezifische Produktion)
|
||||
|
||||
---
|
||||
|
||||
### Supporting Domain (3 BCs)
|
||||
|
||||
#### 8. Master Data BC
|
||||
- **Verantwortung:** Stammdatenverwaltung für Artikel, Lieferanten, Kunden
|
||||
- **Aggregates:** Article, Supplier, Customer
|
||||
- **Downstream:** Alle BCs nutzen Master Data als Referenz
|
||||
|
||||
#### 9. Sales BC
|
||||
- **Verantwortung:** Auftragserfassung, Rechnungsstellung, Lieferscheine
|
||||
- **Aggregates:** Order, Invoice, DeliveryNote
|
||||
- **Upstream:** Master Data (customers, articles), Inventory (stock availability)
|
||||
- **Downstream:** Inventory (sales deduct stock), Reporting (sales statistics)
|
||||
|
||||
#### 10. Scale Integration BC
|
||||
- **Verantwortung:** Waagen/Kassen-Anbindung, Bondaten-Import, Etikettendruck
|
||||
- **Aggregates:** ScaleSyncJob, BondDataImport
|
||||
- **Upstream:** Master Data (article sync), Labeling (label templates)
|
||||
- **Downstream:** Inventory (bond data → stock movements), Sales (sales data)
|
||||
|
||||
---
|
||||
|
||||
### Generic Subdomains (3 BCs)
|
||||
|
||||
#### 11. Reporting BC
|
||||
- **Verantwortung:** Auswertungen, Statistiken, Dashboards
|
||||
- **Upstream:** Alle BCs liefern Daten für Reports
|
||||
- **Keine Aggregates** (Read-only, CQRS Query Side)
|
||||
|
||||
#### 12. Document Archive BC (GoBD)
|
||||
- **Verantwortung:** Revisionssichere Dokumentenarchivierung
|
||||
- **Aggregates:** Document, AuditLog
|
||||
- **Upstream:** Quality (HACCP documents), Sales (invoices), Procurement (delivery notes)
|
||||
|
||||
#### 13. User Management BC
|
||||
- **Verantwortung:** Benutzer, Rollen, Permissions
|
||||
- **Aggregates:** User, Role
|
||||
- **Downstream:** Alle BCs nutzen User Management für Autorisierung
|
||||
|
||||
---
|
||||
|
||||
## Context Relationships
|
||||
|
||||
### Partnership
|
||||
- **Production ↔ Inventory:** Enge Zusammenarbeit bei Chargen-Tracking
|
||||
- **Procurement ↔ Quality:** Wareneingangskontrolle gemeinsam
|
||||
|
||||
### Customer-Supplier
|
||||
- **Production → Labeling:** Production liefert Rezeptdaten
|
||||
- **Master Data → alle BCs:** Master Data liefert Stammdaten
|
||||
|
||||
### Conformist
|
||||
- **Labeling → Production:** Labeling übernimmt Recipe-Struktur 1:1
|
||||
- **Reporting → alle BCs:** Reporting passt sich an alle Datenmodelle an
|
||||
|
||||
### Anti-Corruption Layer
|
||||
- **Scale Integration → Inventory:** ACL übersetzt Bondaten in StockMovements
|
||||
- **FIBU Integration → Sales:** ACL übersetzt zu DATEV-Format
|
||||
|
||||
---
|
||||
|
||||
## Integration Patterns
|
||||
|
||||
### Event-Driven
|
||||
- **Production.BatchCompleted** → Inventory (stock in)
|
||||
- **Procurement.GoodsReceived** → Inventory (stock in)
|
||||
- **Sales.ItemSold** → Inventory (stock out)
|
||||
|
||||
### Request-Response
|
||||
- **Labeling → Production:** GET /recipes/{id} für Nährwertberechnung
|
||||
- **Procurement → Inventory:** GET /stock/{articleId} für Bedarfsplanung
|
||||
|
||||
### Shared Database (Anti-Pattern, vermeiden!)
|
||||
- ❌ Nicht verwenden - jeder BC hat eigene Datenbank
|
||||
|
||||
---
|
||||
|
||||
## Deployment Strategy
|
||||
|
||||
### Monolith First (MVP)
|
||||
Alle BCs in einer Anwendung:
|
||||
```
|
||||
effigenix-erp/
|
||||
├── domain/
|
||||
│ ├── production/
|
||||
│ ├── quality/
|
||||
│ ├── labeling/
|
||||
│ ├── inventory/
|
||||
│ ├── procurement/
|
||||
│ └── filiales/
|
||||
├── application/
|
||||
└── infrastructure/
|
||||
```
|
||||
|
||||
### Microservices Later (nach MVP)
|
||||
Extraktion von BCs in Services:
|
||||
```
|
||||
production-service
|
||||
quality-service
|
||||
inventory-service
|
||||
procurement-service
|
||||
filiales-service
|
||||
master-data-service
|
||||
sales-service
|
||||
scale-integration-service
|
||||
```
|
||||
|
||||
**Empfohlene Reihenfolge:**
|
||||
1. Scale Integration (eigener Prozess wegen Hardware-Anbindung)
|
||||
2. Reporting (Read-only, CQRS)
|
||||
3. Inventory (hohe Last)
|
||||
4. Production (geschäftskritisch, isolieren)
|
||||
233
docs/mvp/ddd/03-ubiquitous-language.md
Normal file
233
docs/mvp/ddd/03-ubiquitous-language.md
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
# Ubiquitous Language - Glossar
|
||||
|
||||
**Datum:** 2026-02-17
|
||||
|
||||
Diese Datei definiert die **Ubiquitous Language** für jeden Bounded Context. Diese Begriffe müssen im Code (Klassennamen, Methoden, Variablen) exakt so verwendet werden.
|
||||
|
||||
---
|
||||
|
||||
## Production BC
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Rezept | Recipe | Aggregate | Mehrstufige Anleitung zur Herstellung eines Produkts aus Rohstoffen und Zwischenprodukten |
|
||||
| Zutat | Ingredient | Entity | Rohstoff oder Zwischenprodukt, das in einem Rezept verwendet wird |
|
||||
| Ausbeute | Yield | Value Object | Verhältnis zwischen Input (Rohmaterial) und Output (Endprodukt) nach Verarbeitungsverlusten, in Prozent |
|
||||
| Charge | Batch | Aggregate | Eindeutig identifizierte Produktionseinheit mit Datum, Rezept, Menge und verwendeten Rohstoffchargen |
|
||||
| Produktionsauftrag | Production Order | Aggregate | Auftrag zur Herstellung einer bestimmten Menge eines Produkts nach Rezept |
|
||||
| Rückverfolgbarkeit | Traceability | Concept | Lückenlose Dokumentation von Rohstoff-Charge → Produktions-Charge → Verkauf |
|
||||
| Zwischenprodukt | Intermediate Product | Concept | Produkt, das in Rezept A hergestellt wird und als Zutat in Rezept B verwendet wird |
|
||||
| Ausschuss | Waste | Value Object | Menge an Material, die während Produktion verloren geht oder unbrauchbar ist |
|
||||
| Rezeptur-Version | Recipe Version | Value Object | Versionsnummer eines Rezepts, um Änderungen nachvollziehbar zu machen |
|
||||
|
||||
---
|
||||
|
||||
## Quality BC (HACCP/QM)
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| HACCP | HACCP | Concept | Hazard Analysis Critical Control Points - systematische Präventivmaßnahmen für Lebensmittelsicherheit |
|
||||
| Kritischer Kontrollpunkt | Critical Control Point (CCP) | Concept | Stelle im Prozess, an der Kontrolle notwendig ist, um Gefahren zu vermeiden |
|
||||
| Temperaturprotokoll | Temperature Log | Aggregate | Dokumentierte Temperaturmessung an kritischem Punkt (Kühlraum, Theke) mit Grenzwerten |
|
||||
| Reinigungsnachweis | Cleaning Record | Aggregate | Dokumentation einer durchgeführten Reinigung mit Datum, Person, Checkliste |
|
||||
| Reinigungsplan | Cleaning Plan | Aggregate | Vordefinierter Plan mit Intervallen und Checklisten für Reinigungsaufgaben |
|
||||
| Wareneingangskontrolle | Goods Receipt Inspection | Aggregate | Prüfung von Temperatur, MHD, Sichtkontrolle, Dokumenten bei Warenanlieferung |
|
||||
| Schulungsnachweis | Training Record | Aggregate | Zertifikat oder Nachweis einer absolvierten Schulung (HACCP, Hygiene) mit Gültigkeitsdatum |
|
||||
| Wartungsprotokoll | Maintenance Record | Aggregate | Dokumentation von Gerätewartungen (planmäßig oder Störung) mit Befund |
|
||||
| Messwert | Measurement | Value Object | Gemessener Wert mit Einheit (z.B. Temperatur in °C) |
|
||||
| Grenzwert | Critical Limit | Value Object | Minimal-/Maximalwert für CCP (z.B. Kühlraum: 2-7°C) |
|
||||
| Abweichung | Deviation | Concept | Überschreitung eines Grenzwerts oder Nichteinhaltung eines Verfahrens |
|
||||
| Korrekturmaßnahme | Corrective Action | Entity | Maßnahme zur Behebung einer Abweichung |
|
||||
|
||||
---
|
||||
|
||||
## Labeling BC
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Allergen | Allergen | Value Object | Einer der 14 EU-Hauptallergene, die kennzeichnungspflichtig sind |
|
||||
| Spurenkennzeichnung | Trace Declaration | Value Object | "Kann Spuren von X enthalten" bei gemeinsamer Verarbeitung |
|
||||
| Nährwerttabelle | Nutrition Facts Table | Entity | Rechtlich vorgeschriebene Angabe von Kalorien, Fett, Eiweiß, etc. pro 100g |
|
||||
| Qualitätssiegel | Quality Label | Value Object | Bio, Regional, Tierwohl-Zertifizierung |
|
||||
| Herkunftskennzeichnung | Origin Labeling | Value Object | Angabe des Herkunftslandes/-region für Rohstoffe |
|
||||
| Etikett | Label | Aggregate | Gedrucktes Etikett mit allen Pflichtangaben |
|
||||
| Pflichtangabe | Mandatory Declaration | Concept | Rechtlich vorgeschriebene Information auf Etikett (Name, Zutaten, Allergene, MHD, Hersteller) |
|
||||
| Allergenkennzeichnung | Allergen Declaration | Concept | Hervorhebung von Allergenen in Zutatenliste (z.B. **Milch**, **Gluten**) |
|
||||
| Allergene Matrix | Allergen Matrix | Aggregate | Übersichtstabelle: welches Produkt enthält welche Allergene (für Aushang) |
|
||||
| Zertifizierungsnummer | Certification Number | Value Object | Nummer des Bio-/Regional-/Tierwohl-Zertifikats |
|
||||
|
||||
---
|
||||
|
||||
## Inventory BC
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Bestand | Stock | Aggregate | Aktueller Bestand eines Artikels in einem Lagerort, chargengenau |
|
||||
| Lagerort | Storage Location | Value Object | Physischer Ort (Kühlraum, Tiefkühler, Trockenlager, Theke) |
|
||||
| Bestandsbewegung | Stock Movement | Aggregate | Veränderung des Bestands (Wareneingang, Produktion, Verkauf, Umbuchung) |
|
||||
| MHD | Best-Before Date | Value Object | Mindesthaltbarkeitsdatum, chargenspezifisch |
|
||||
| FEFO | First-Expired-First-Out | Concept | Verkaufspriorisierung nach MHD (ältestes MHD zuerst) |
|
||||
| Charge | Batch | Concept | Eindeutig identifizierte Menge eines Artikels mit gleicher Herkunft/Produktion |
|
||||
| Chargennummer | Batch Number | Value Object | Eindeutige Identifikation einer Charge (ProductionBatchId oder SupplierBatchId) |
|
||||
| Verfügbarer Bestand | Available Stock | Value Object | Bestand abzüglich Reservierungen |
|
||||
| Reservierung | Reservation | Entity | Vorgemerkter Bestand für Produktionsauftrag oder Kundenauftrag |
|
||||
| Schwund | Shrinkage | Concept | Bestandsverlust durch Verderb, Bruch, Diebstahl |
|
||||
| Inventur | Inventory Count | Aggregate | Physische Zählung des Bestands mit Soll-Ist-Abgleich |
|
||||
|
||||
---
|
||||
|
||||
## Procurement BC
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Bestellung | Purchase Order | Aggregate | Bestellung an Lieferant mit Artikeln, Mengen, Liefertermin |
|
||||
| Wareneingang | Goods Receipt | Aggregate | Annahme und Erfassung gelieferter Ware mit Qualitätsprüfung |
|
||||
| Lieferanten-Chargennummer | Supplier Batch Number | Value Object | Chargen-Nummer des Lieferanten für Rückverfolgbarkeit |
|
||||
| Bedarfsplanung | Demand Planning | Aggregate | Berechnung des Einkaufsbedarfs aus Produktionsplan und Lagerbestand |
|
||||
| Lieferschein | Delivery Note | Value Object | Vom Lieferanten mitgeliefertes Dokument |
|
||||
| Veterinärbescheinigung | Veterinary Certificate | Value Object | Gesetzlich vorgeschriebenes Dokument für Fleischwaren |
|
||||
| Qualitätszertifikat | Quality Certificate | Value Object | Bio-, Regional-, Tierwohl-Zertifikat des Lieferanten |
|
||||
| Bestellmenge | Order Quantity | Value Object | Bestellte Menge (kann von empfangener Menge abweichen) |
|
||||
| Mindestbestellmenge | Minimum Order Quantity | Value Object | Vom Lieferanten vorgegebene Mindestmenge |
|
||||
| Zahlungsziel | Payment Terms | Value Object | Vereinbarte Zahlungsfrist (z.B. "Netto 30 Tage") |
|
||||
| Lieferantenbewertung | Supplier Rating | Entity | Bewertung nach Qualität, Pünktlichkeit, Preis-Leistung |
|
||||
|
||||
---
|
||||
|
||||
## Filiales BC
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Filiale | Branch | Aggregate | Standort mit eigenem Bestand, ggf. eigener Produktion/Verkauf |
|
||||
| Filialtyp | Branch Type | Value Object | PRODUCTION_AND_SALES, SALES_ONLY, PRODUCTION_ONLY |
|
||||
| Interfilial-Transfer | Inter-Branch Transfer | Aggregate | Warenversand von Filiale A nach Filiale B mit Chargen-Tracking |
|
||||
| Zentrale Produktion | Central Production | Concept | Produktion an einem Standort für Belieferung mehrerer Filialen |
|
||||
| Verteilungsplan | Distribution Plan | Aggregate | Plan zur Verteilung eines Produktionsbatches an mehrere Filialen |
|
||||
| Liefertermin | Delivery Date | Value Object | Geplanter oder tatsächlicher Liefertermin für Interfilial-Transfer |
|
||||
| Transportdokument | Transport Document | Value Object | Lieferschein für interne Lieferung zwischen Filialen |
|
||||
| Filiallager | Branch Warehouse | Concept | Lagerbestand einer spezifischen Filiale |
|
||||
|
||||
---
|
||||
|
||||
## Master Data BC
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Artikel | Article | Aggregate | Produkt oder Rohstoff mit Stammdaten |
|
||||
| Verkaufseinheit | Sales Unit | Entity | Einheit, in der Artikel verkauft wird (Stück, kg, 100g) |
|
||||
| Preismodell | Price Model | Value Object | FIXED (fester Preis) oder WEIGHT_BASED (Preis × Gewicht) |
|
||||
| Lieferant | Supplier | Aggregate | Geschäftspartner, von dem Waren bezogen werden |
|
||||
| Kunde | Customer | Aggregate | Geschäftspartner, an den Waren verkauft werden |
|
||||
| Rahmenvertrag | Frame Contract | Entity | Langfristige Vereinbarung mit Kunde über Preise/Mengen |
|
||||
| Artikelnummer | Article Number (SKU) | Value Object | Eindeutige Identifikation eines Artikels |
|
||||
| Produktgruppe | Product Category | Value Object | Kategorisierung von Artikeln (z.B. "Wurst", "Aufschnitt", "Frischfleisch") |
|
||||
| Kundenpräferenz | Customer Preference | Value Object | Präferenz für Bio, Regional, Tierwohl, etc. |
|
||||
|
||||
---
|
||||
|
||||
## Sales BC
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Auftrag | Order | Aggregate | Kundenauftrag (Vorbestellung oder B2B-Auftrag) |
|
||||
| Auftragsart | Order Type | Value Object | PRE_ORDER (Vorbestellung), B2B_ORDER, WALK_IN (Ladenverkauf) |
|
||||
| Rechnung | Invoice | Aggregate | Rechnungsdokument mit Positionen und Betrag |
|
||||
| Lieferschein | Delivery Note | Aggregate | Dokument für Warenauslieferung (mit oder ohne Rechnungsfunktion) |
|
||||
| Gutschrift | Credit Note | Aggregate | Stornierung oder Teilstornierung einer Rechnung |
|
||||
| Zahlungsstatus | Payment Status | Value Object | OPEN, PAID, OVERDUE, CANCELLED |
|
||||
| Sammelrechnung | Collective Invoice | Concept | Monatliche Zusammenfassung mehrerer Lieferungen (B2B) |
|
||||
|
||||
---
|
||||
|
||||
## Scale Integration BC
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Waagensynchronisation | Scale Sync | Aggregate | Übertragung von Artikelstammdaten an Waage |
|
||||
| Bondaten | Bond Data | Aggregate | Verkaufsdaten aus Kassensystem |
|
||||
| Etikettendruck | Label Print | Concept | Druck von Etiketten an Waage mit aktuellem Gewicht |
|
||||
| TSE | Technical Security Equipment | Concept | Technische Sicherheitseinrichtung für Kassensysteme (Deutschland) |
|
||||
|
||||
---
|
||||
|
||||
## Shared Concepts (BC-übergreifend)
|
||||
|
||||
| Begriff (DE) | Begriff (EN) | Typ | Definition |
|
||||
|--------------|--------------|-----|------------|
|
||||
| Menge | Quantity | Value Object | Numerischer Wert mit Einheit (kg, g, Stück, Liter) |
|
||||
| Geld | Money | Value Object | Betrag mit Währung (z.B. 100 EUR) |
|
||||
| Zeitstempel | Timestamp | Value Object | Datum + Uhrzeit |
|
||||
| Benutzer-ID | User ID | Value Object | Eindeutige Identifikation eines Benutzers |
|
||||
| Status | Status | Value Object (Enum) | Zustand eines Objekts (z.B. ACTIVE, INACTIVE, PENDING) |
|
||||
|
||||
---
|
||||
|
||||
## Naming Conventions (Java)
|
||||
|
||||
### Packages
|
||||
```java
|
||||
com.effigenix.domain.production // Production BC
|
||||
com.effigenix.domain.quality // Quality BC
|
||||
com.effigenix.domain.labeling // Labeling BC
|
||||
com.effigenix.domain.inventory // Inventory BC
|
||||
com.effigenix.domain.procurement // Procurement BC
|
||||
com.effigenix.domain.filiales // Filiales BC (Plural!)
|
||||
com.effigenix.domain.masterdata // Master Data BC
|
||||
```
|
||||
|
||||
### Classes (Englisch!)
|
||||
```java
|
||||
// Aggregates: Singular noun
|
||||
Recipe, Batch, ProductionOrder
|
||||
TemperatureLog, CleaningRecord
|
||||
ProductLabel, AllergenMatrix
|
||||
Stock, StockMovement
|
||||
PurchaseOrder, GoodsReceipt
|
||||
Branch, InterBranchTransfer
|
||||
|
||||
// Value Objects: Descriptive noun
|
||||
RecipeId, BatchId, YieldPercentage
|
||||
Temperature, CriticalLimit
|
||||
AllergenType, NutritionFacts
|
||||
Quantity, Money, Timestamp
|
||||
```
|
||||
|
||||
### Methods (Englisch!)
|
||||
```java
|
||||
// Domain behavior (verbs)
|
||||
recipe.addIngredient(...)
|
||||
batch.complete(...)
|
||||
stock.withdraw(...)
|
||||
purchaseOrder.confirm(...)
|
||||
|
||||
// Factory methods
|
||||
Recipe.create(...)
|
||||
Batch.of(...)
|
||||
|
||||
// Getters (no "get" prefix)
|
||||
recipe.id()
|
||||
batch.status()
|
||||
stock.availableQuantity()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns (NICHT verwenden!)
|
||||
|
||||
❌ **Technische Begriffe im Domain:**
|
||||
- ~~DTO~~, ~~Entity~~ (nur als Typ-Suffix in Infrastructure)
|
||||
- ~~Save~~, ~~Update~~, ~~Delete~~ (stattdessen: Domain-Verben)
|
||||
|
||||
❌ **Abkürzungen ohne Definition:**
|
||||
- ~~WE~~ → Wareneingang / Goods Receipt
|
||||
- ~~BS~~ → Bestand / Stock
|
||||
|
||||
❌ **Deutsche Begriffe im Code:**
|
||||
- ~~Rezept.java~~ → Recipe.java
|
||||
- ~~addZutat()~~ → addIngredient()
|
||||
|
||||
✅ **Deutsche Begriffe nur in:**
|
||||
- Dokumentation
|
||||
- UI/UX
|
||||
- User Stories
|
||||
- Glossar (wie dieses Dokument)
|
||||
518
docs/mvp/ddd/04-production-bc.md
Normal file
518
docs/mvp/ddd/04-production-bc.md
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
# Production BC - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Production
|
||||
**Domain Type:** CORE
|
||||
**Verantwortung:** Rezepturverwaltung, Produktionsplanung, Chargen-Erzeugung
|
||||
|
||||
---
|
||||
|
||||
## Aggregates
|
||||
|
||||
### 1. Recipe (Aggregate Root)
|
||||
|
||||
**Verantwortung:** Verwaltet mehrstufige Rezepturen mit Zutaten und Produktionsschritten.
|
||||
|
||||
```
|
||||
Recipe (Aggregate Root)
|
||||
├── RecipeId (VO)
|
||||
├── Name (VO)
|
||||
├── Version (VO)
|
||||
├── RecipeType (VO: RAW_MATERIAL | INTERMEDIATE | FINISHED_PRODUCT)
|
||||
├── YieldPercentage (VO) - Ausbeute in %
|
||||
├── Ingredients[] (Entity)
|
||||
│ ├── Position (VO) - Reihenfolge im Rezept
|
||||
│ ├── ArticleId (VO) - Reference to Master Data
|
||||
│ ├── Quantity (VO)
|
||||
│ ├── RecipeId (VO) - For intermediate products (nested recipes)
|
||||
│ └── IsSubstitutable (VO) - Kann durch Alternativzutat ersetzt werden?
|
||||
├── ProductionSteps[] (Entity)
|
||||
│ ├── StepNumber (VO)
|
||||
│ ├── Description (VO)
|
||||
│ ├── Duration (VO) - Geschätzte Dauer
|
||||
│ └── Temperature (VO) - Optional, für Räuchern/Kochen
|
||||
└── Status (VO: DRAFT | ACTIVE | ARCHIVED)
|
||||
```
|
||||
|
||||
**Invarianten:**
|
||||
```java
|
||||
/**
|
||||
* Recipe aggregate root.
|
||||
*
|
||||
* Invariants:
|
||||
* - Recipe must have at least one ingredient
|
||||
* - Yield percentage must be between 1-100%
|
||||
* - Ingredient quantities must be positive
|
||||
* - Nested recipes cannot create circular dependencies (A → B → A)
|
||||
* - Sum of ingredient quantities should roughly match expected input
|
||||
* - Position numbers in Ingredients must be unique
|
||||
* - StepNumber in ProductionSteps must be sequential (1, 2, 3, ...)
|
||||
*/
|
||||
```
|
||||
|
||||
**Business Methods:**
|
||||
```java
|
||||
public Result<RecipeError, Void> addIngredient(
|
||||
ArticleId articleId,
|
||||
Quantity quantity,
|
||||
Optional<RecipeId> nestedRecipeId
|
||||
);
|
||||
|
||||
public Result<RecipeError, Void> removeIngredient(ArticleId articleId);
|
||||
|
||||
public Result<RecipeError, Void> updateYield(YieldPercentage newYield);
|
||||
|
||||
public Result<RecipeError, Void> addProductionStep(
|
||||
String description,
|
||||
Optional<Duration> duration
|
||||
);
|
||||
|
||||
public Result<RecipeError, Void> activate();
|
||||
|
||||
public Result<RecipeError, Void> archive();
|
||||
|
||||
// Query methods
|
||||
public Quantity calculateRequiredInput(Quantity desiredOutput);
|
||||
public List<ArticleId> getAllIngredients(); // Flattened, including nested
|
||||
public boolean containsNestedRecipe();
|
||||
```
|
||||
|
||||
**Domain Events:**
|
||||
```java
|
||||
RecipeCreated
|
||||
RecipeActivated
|
||||
RecipeArchived
|
||||
IngredientAdded
|
||||
IngredientRemoved
|
||||
YieldPercentageChanged
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Batch (Aggregate Root)
|
||||
|
||||
**Verantwortung:** Repräsentiert eine Produktions-Charge mit lückenloser Rückverfolgbarkeit.
|
||||
|
||||
```
|
||||
Batch (Aggregate Root)
|
||||
├── BatchId (VO) - Eindeutige Chargennummer (z.B. "BATCH-2026-02-17-001")
|
||||
├── RecipeId (VO) - Reference to Recipe
|
||||
├── ProductionDate (VO)
|
||||
├── PlannedQuantity (VO)
|
||||
├── ActualQuantity (VO) - Nach Produktionsrückmeldung
|
||||
├── Status (VO: PLANNED | IN_PRODUCTION | COMPLETED | CANCELLED)
|
||||
├── ProducedBy (VO: UserId)
|
||||
├── ProducedAt (VO: BranchId) - Für Mehrfilialen
|
||||
├── ExpiryDate (VO) - MHD des Endprodukts
|
||||
├── UsedIngredientBatches[] (Entity) - CRITICAL for traceability!
|
||||
│ ├── RawMaterialBatchId (VO) - Batch of used raw material
|
||||
│ ├── ArticleId (VO)
|
||||
│ ├── SupplierBatchNumber (VO) - Von Wareneingang
|
||||
│ ├── QuantityUsed (VO)
|
||||
│ └── ExpiryDate (VO) - MHD des Rohstoffs
|
||||
├── Waste (VO) - Ausschuss/Schwund
|
||||
└── Remarks (VO) - Optional, für Abweichungen
|
||||
|
||||
Invariants:
|
||||
- Batch must reference a valid Recipe
|
||||
- ActualQuantity must be <= (PlannedQuantity / Recipe.YieldPercentage)
|
||||
- Status can only transition: PLANNED → IN_PRODUCTION → COMPLETED (or CANCELLED)
|
||||
- Cannot complete without recording used ingredient batches
|
||||
- ExpiryDate must be in the future at production time
|
||||
- Waste must be >= 0
|
||||
- All UsedIngredientBatches must match Recipe.Ingredients
|
||||
```
|
||||
|
||||
**Business Methods:**
|
||||
```java
|
||||
public static Result<BatchError, Batch> plan(
|
||||
RecipeId recipeId,
|
||||
Quantity plannedQuantity,
|
||||
LocalDate productionDate,
|
||||
LocalDate expiryDate,
|
||||
UserId producedBy,
|
||||
BranchId branchId
|
||||
);
|
||||
|
||||
public Result<BatchError, Void> startProduction();
|
||||
|
||||
public Result<BatchError, Void> recordIngredientUsage(
|
||||
ArticleId articleId,
|
||||
BatchId rawMaterialBatchId,
|
||||
SupplierBatchNumber supplierBatchNumber,
|
||||
Quantity quantityUsed,
|
||||
LocalDate expiryDate
|
||||
);
|
||||
|
||||
public Result<BatchError, Void> complete(
|
||||
Quantity actualQuantity,
|
||||
Quantity waste,
|
||||
Optional<String> remarks
|
||||
);
|
||||
|
||||
public Result<BatchError, Void> cancel(String reason);
|
||||
|
||||
// Query methods
|
||||
public boolean isTraceable(); // All ingredients have batch numbers
|
||||
public List<BatchId> getUpstreamBatches(); // All used raw material batches
|
||||
public Quantity getYieldEfficiency(); // ActualQuantity / (PlannedQuantity / YieldPercentage)
|
||||
```
|
||||
|
||||
**Domain Events:**
|
||||
```java
|
||||
BatchPlanned
|
||||
BatchStarted
|
||||
IngredientUsageRecorded
|
||||
BatchCompleted(BatchId, ArticleId, Quantity, ExpiryDate) → triggers Inventory stock in
|
||||
BatchCancelled
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. ProductionOrder (Aggregate Root)
|
||||
|
||||
**Verantwortung:** Plant eine zukünftige Produktion.
|
||||
|
||||
```
|
||||
ProductionOrder (Aggregate Root)
|
||||
├── ProductionOrderId (VO)
|
||||
├── RecipeId (VO)
|
||||
├── PlannedQuantity (VO)
|
||||
├── PlannedDate (VO)
|
||||
├── Priority (VO: LOW | NORMAL | HIGH | URGENT)
|
||||
├── Status (VO: PLANNED | RELEASED | IN_PRODUCTION | COMPLETED | CANCELLED)
|
||||
├── CreatedBy (VO: UserId)
|
||||
├── CreatedAt (VO: Timestamp)
|
||||
├── TargetBranch (VO: BranchId) - For multi-branch production
|
||||
├── GeneratedBatchId (VO) - Link to actual Batch when production starts
|
||||
└── Remarks (VO)
|
||||
|
||||
Invariants:
|
||||
- Planned quantity must be positive
|
||||
- Planned date cannot be in the past
|
||||
- Can only release if materials available (checked in Application layer!)
|
||||
- Cannot complete without generating a Batch
|
||||
- Status transitions: PLANNED → RELEASED → IN_PRODUCTION → COMPLETED
|
||||
```
|
||||
|
||||
**Business Methods:**
|
||||
```java
|
||||
public static Result<ProductionOrderError, ProductionOrder> create(
|
||||
RecipeId recipeId,
|
||||
Quantity plannedQuantity,
|
||||
LocalDate plannedDate,
|
||||
Priority priority,
|
||||
BranchId targetBranch,
|
||||
UserId createdBy
|
||||
);
|
||||
|
||||
public Result<ProductionOrderError, Void> release();
|
||||
|
||||
public Result<ProductionOrderError, Void> startProduction(BatchId batchId);
|
||||
|
||||
public Result<ProductionOrderError, Void> complete();
|
||||
|
||||
public Result<ProductionOrderError, Void> cancel(String reason);
|
||||
|
||||
public Result<ProductionOrderError, Void> reschedule(LocalDate newDate);
|
||||
```
|
||||
|
||||
**Domain Events:**
|
||||
```java
|
||||
ProductionOrderCreated
|
||||
ProductionOrderReleased → triggers Demand Planning update
|
||||
ProductionOrderStarted
|
||||
ProductionOrderCompleted
|
||||
ProductionOrderCancelled
|
||||
ProductionOrderRescheduled
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Value Objects
|
||||
|
||||
### RecipeId
|
||||
```java
|
||||
public record RecipeId(String value) {
|
||||
public RecipeId {
|
||||
if (value == null || value.isBlank()) {
|
||||
throw new IllegalArgumentException("RecipeId cannot be empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### BatchId
|
||||
```java
|
||||
public record BatchId(String value) {
|
||||
// Format: "BATCH-YYYY-MM-DD-XXX"
|
||||
public static BatchId generate(LocalDate productionDate, int sequenceNumber) {
|
||||
String value = String.format("BATCH-%s-%03d",
|
||||
productionDate, sequenceNumber);
|
||||
return new BatchId(value);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### YieldPercentage
|
||||
```java
|
||||
public record YieldPercentage(int value) {
|
||||
public YieldPercentage {
|
||||
if (value < 1 || value > 100) {
|
||||
throw new IllegalArgumentException(
|
||||
"Yield percentage must be between 1-100, got: " + value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public Quantity calculateRequiredInput(Quantity desiredOutput) {
|
||||
// If yield is 80%, and we want 100kg output, we need 125kg input
|
||||
return desiredOutput.multiply(100.0 / value);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### RecipeType
|
||||
```java
|
||||
public enum RecipeType {
|
||||
RAW_MATERIAL, // Rohstoff, kein Rezept
|
||||
INTERMEDIATE, // Zwischenprodukt (z.B. Gewürzmischung)
|
||||
FINISHED_PRODUCT // Endprodukt
|
||||
}
|
||||
```
|
||||
|
||||
### ProductionOrderPriority
|
||||
```java
|
||||
public enum Priority {
|
||||
LOW,
|
||||
NORMAL,
|
||||
HIGH,
|
||||
URGENT
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Domain Services
|
||||
|
||||
### RecipeValidator
|
||||
```java
|
||||
public class RecipeValidator {
|
||||
/**
|
||||
* Validates that recipe does not create circular dependencies.
|
||||
*/
|
||||
public Result<RecipeError, Void> validateNoCyclicDependency(
|
||||
Recipe recipe,
|
||||
RecipeRepository recipeRepository
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### BatchTraceabilityService
|
||||
```java
|
||||
public class BatchTraceabilityService {
|
||||
/**
|
||||
* Finds all upstream batches (raw materials) used in a batch.
|
||||
*/
|
||||
public List<BatchId> findUpstreamBatches(BatchId batchId);
|
||||
|
||||
/**
|
||||
* Finds all downstream batches (finished products) that used a raw material batch.
|
||||
* CRITICAL for recalls!
|
||||
*/
|
||||
public List<BatchId> findDownstreamBatches(BatchId rawMaterialBatchId);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Repository Interfaces
|
||||
|
||||
```java
|
||||
package com.effigenix.domain.production;
|
||||
|
||||
import com.effigenix.shared.result.Result;
|
||||
|
||||
public interface RecipeRepository {
|
||||
Result<RepositoryError, Void> save(Recipe recipe);
|
||||
Result<RepositoryError, Recipe> findById(RecipeId id);
|
||||
Result<RepositoryError, List<Recipe>> findActive();
|
||||
Result<RepositoryError, List<Recipe>> findByArticleId(ArticleId articleId);
|
||||
}
|
||||
|
||||
public interface BatchRepository {
|
||||
Result<RepositoryError, Void> save(Batch batch);
|
||||
Result<RepositoryError, Batch> findById(BatchId id);
|
||||
Result<RepositoryError, List<Batch>> findByProductionDate(LocalDate date);
|
||||
Result<RepositoryError, List<Batch>> findByStatus(BatchStatus status);
|
||||
|
||||
// For traceability
|
||||
Result<RepositoryError, List<Batch>> findByUpstreamBatch(BatchId upstreamBatchId);
|
||||
}
|
||||
|
||||
public interface ProductionOrderRepository {
|
||||
Result<RepositoryError, Void> save(ProductionOrder order);
|
||||
Result<RepositoryError, ProductionOrder> findById(ProductionOrderId id);
|
||||
Result<RepositoryError, List<ProductionOrder>> findByPlannedDate(LocalDate date);
|
||||
Result<RepositoryError, List<ProductionOrder>> findByStatus(ProductionOrderStatus status);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Domain Errors
|
||||
|
||||
```java
|
||||
public sealed interface RecipeError permits
|
||||
RecipeError.InvalidYieldPercentage,
|
||||
RecipeError.CyclicDependencyDetected,
|
||||
RecipeError.NoIngredientsError,
|
||||
RecipeError.RecipeNotFound {
|
||||
String message();
|
||||
}
|
||||
|
||||
public sealed interface BatchError permits
|
||||
BatchError.InvalidQuantity,
|
||||
BatchError.InvalidStatusTransition,
|
||||
BatchError.MissingIngredientBatches,
|
||||
BatchError.ExpiryDateInPast,
|
||||
BatchError.RecipeNotFound {
|
||||
String message();
|
||||
}
|
||||
|
||||
public sealed interface ProductionOrderError permits
|
||||
ProductionOrderError.PlannedDateInPast,
|
||||
ProductionOrderError.InvalidQuantity,
|
||||
ProductionOrderError.InvalidStatusTransition,
|
||||
ProductionOrderError.RecipeNotFound {
|
||||
String message();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration with other BCs
|
||||
|
||||
### Upstream Dependencies
|
||||
- **Master Data BC:** Recipe references ArticleId
|
||||
- **User Management BC:** Batch/ProductionOrder reference UserId
|
||||
- **Filiales BC:** ProductionOrder references BranchId
|
||||
|
||||
### Downstream Integrations
|
||||
- **Inventory BC:** `BatchCompleted` event triggers stock in
|
||||
- **Labeling BC:** Labeling reads Recipe data for nutrition calculation
|
||||
- **Procurement BC:** ProductionOrder triggers demand planning
|
||||
|
||||
---
|
||||
|
||||
## Use Cases (Application Layer)
|
||||
|
||||
```java
|
||||
// application/production/CreateRecipe.java
|
||||
public class CreateRecipe {
|
||||
public Result<ApplicationError, RecipeDTO> execute(CreateRecipeCommand cmd);
|
||||
}
|
||||
|
||||
// application/production/PlanProduction.java
|
||||
public class PlanProduction {
|
||||
public Result<ApplicationError, ProductionOrderDTO> execute(PlanProductionCommand cmd);
|
||||
}
|
||||
|
||||
// application/production/StartProductionBatch.java
|
||||
public class StartProductionBatch {
|
||||
public Result<ApplicationError, BatchDTO> execute(StartBatchCommand cmd);
|
||||
}
|
||||
|
||||
// application/production/CompleteProductionBatch.java
|
||||
public class CompleteProductionBatch {
|
||||
public Result<ApplicationError, BatchDTO> execute(CompleteBatchCommand cmd);
|
||||
// Triggers BatchCompleted event → Inventory stock in
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example: Batch Creation Flow
|
||||
|
||||
```java
|
||||
// 1. Plan Production Order
|
||||
ProductionOrder order = ProductionOrder.create(
|
||||
recipeId,
|
||||
Quantity.of(100, "kg"),
|
||||
LocalDate.now().plusDays(1),
|
||||
Priority.NORMAL,
|
||||
branchId,
|
||||
userId
|
||||
);
|
||||
|
||||
// 2. Release Order (checks material availability in Application layer)
|
||||
order.release();
|
||||
|
||||
// 3. Start Production → Create Batch
|
||||
Batch batch = Batch.plan(
|
||||
order.recipeId(),
|
||||
order.plannedQuantity(),
|
||||
LocalDate.now(),
|
||||
LocalDate.now().plusDays(30), // MHD
|
||||
userId,
|
||||
branchId
|
||||
);
|
||||
batch.startProduction();
|
||||
order.startProduction(batch.id());
|
||||
|
||||
// 4. Record ingredient usage
|
||||
batch.recordIngredientUsage(
|
||||
ArticleId.of("ART-001"),
|
||||
BatchId.of("BATCH-2026-02-15-042"), // Supplier batch
|
||||
SupplierBatchNumber.of("SUPPLIER-12345"),
|
||||
Quantity.of(50, "kg"),
|
||||
LocalDate.now().plusDays(20) // MHD of raw material
|
||||
);
|
||||
|
||||
// 5. Complete Batch
|
||||
batch.complete(
|
||||
Quantity.of(80, "kg"), // Actual output
|
||||
Quantity.of(5, "kg"), // Waste
|
||||
Optional.of("Leichter Schwund beim Räuchern")
|
||||
);
|
||||
order.complete();
|
||||
|
||||
// 6. BatchCompleted event → Inventory creates Stock entry
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests (Domain Layer)
|
||||
```java
|
||||
@Test
|
||||
void createBatch_withValidData_succeeds() {
|
||||
var result = Batch.plan(recipeId, quantity, date, expiryDate, userId, branchId);
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void completeBatch_withoutIngredients_fails() {
|
||||
var batch = Batch.plan(...).unsafeGetValue();
|
||||
batch.startProduction();
|
||||
|
||||
var result = batch.complete(quantity, waste, Optional.empty());
|
||||
|
||||
assertThat(result.isFailure()).isTrue();
|
||||
// Should fail with MissingIngredientBatches error
|
||||
}
|
||||
```
|
||||
|
||||
### Integration Tests (Application Layer)
|
||||
```java
|
||||
@Test
|
||||
void completeProductionBatch_updatesInventory() {
|
||||
// Given: Production order and started batch
|
||||
// When: Complete batch
|
||||
var result = completeProductionBatch.execute(command);
|
||||
|
||||
// Then: Inventory stock should increase
|
||||
var stock = inventoryRepository.findByArticle(articleId);
|
||||
assertThat(stock.quantity()).isEqualTo(expectedQuantity);
|
||||
}
|
||||
```
|
||||
490
docs/mvp/ddd/04-produktions-kontext.md
Normal file
490
docs/mvp/ddd/04-produktions-kontext.md
Normal file
|
|
@ -0,0 +1,490 @@
|
|||
# Produktions-Kontext - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Produktion
|
||||
**Domain-Typ:** KERN
|
||||
**Verantwortung:** Rezepturverwaltung, Produktionsplanung, Chargen-Erzeugung
|
||||
|
||||
---
|
||||
|
||||
## Aggregate
|
||||
|
||||
### 1. Rezept (Aggregate Root)
|
||||
|
||||
**Verantwortung:** Verwaltet mehrstufige Rezepturen mit Zutaten und Produktionsschritten.
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Rezept (Aggregate Root)
|
||||
├── RezeptId (Wertobjekt)
|
||||
├── Name (Wertobjekt)
|
||||
├── Version (Wertobjekt)
|
||||
├── RezeptTyp (Wertobjekt: ROHSTOFF | ZWISCHENPRODUKT | ENDPRODUKT)
|
||||
├── AusbeuteInProzent (Wertobjekt) - Ausbeute in %
|
||||
├── Zutaten[] (Entität)
|
||||
│ ├── Position (Wertobjekt) - Reihenfolge im Rezept
|
||||
│ ├── ArtikelId (Wertobjekt) - Referenz zu Stammdaten
|
||||
│ ├── Menge (Wertobjekt)
|
||||
│ ├── RezeptId (Wertobjekt) - Für Zwischenprodukte (verschachtelte Rezepte)
|
||||
│ └── IstErsetzbar (Wertobjekt) - Kann durch Alternativzutat ersetzt werden?
|
||||
├── Produktionsschritte[] (Entität)
|
||||
│ ├── SchrittNummer (Wertobjekt)
|
||||
│ ├── Beschreibung (Wertobjekt)
|
||||
│ ├── Dauer (Wertobjekt) - Geschätzte Dauer
|
||||
│ └── Temperatur (Wertobjekt) - Optional, für Räuchern/Kochen
|
||||
└── Status (Wertobjekt: ENTWURF | AKTIV | ARCHIVIERT)
|
||||
```
|
||||
|
||||
**Invarianten:**
|
||||
```java
|
||||
/**
|
||||
* Rezept Aggregate Root.
|
||||
*
|
||||
* Invarianten:
|
||||
* - Rezept muss mindestens eine Zutat haben
|
||||
* - Ausbeute muss zwischen 1-100% liegen
|
||||
* - Zutatmengen müssen positiv sein
|
||||
* - Verschachtelte Rezepte dürfen keine Zyklen erzeugen (A → B → A)
|
||||
* - Summe der Zutatmengen sollte ungefähr dem erwarteten Input entsprechen
|
||||
* - Positionsnummern bei Zutaten müssen eindeutig sein
|
||||
* - SchrittNummer bei Produktionsschritten muss sequenziell sein (1, 2, 3, ...)
|
||||
*/
|
||||
```
|
||||
|
||||
**Geschäftsmethoden:**
|
||||
```java
|
||||
// Zutat hinzufügen
|
||||
public Result<RezeptFehler, Void> zutatHinzufuegen(
|
||||
ArtikelId artikelId,
|
||||
Menge menge,
|
||||
Optional<RezeptId> verschachteltesRezeptId
|
||||
);
|
||||
|
||||
// Zutat entfernen
|
||||
public Result<RezeptFehler, Void> zutatEntfernen(ArtikelId artikelId);
|
||||
|
||||
// Ausbeute aktualisieren
|
||||
public Result<RezeptFehler, Void> ausbeuteAktualisieren(AusbeuteInProzent neueAusbeute);
|
||||
|
||||
// Produktionsschritt hinzufügen
|
||||
public Result<RezeptFehler, Void> produktionsschrittHinzufuegen(
|
||||
String beschreibung,
|
||||
Optional<Duration> dauer
|
||||
);
|
||||
|
||||
// Rezept aktivieren
|
||||
public Result<RezeptFehler, Void> aktivieren();
|
||||
|
||||
// Rezept archivieren
|
||||
public Result<RezeptFehler, Void> archivieren();
|
||||
|
||||
// Abfragemethoden
|
||||
public Menge berechneBenoeteigtenInput(Menge gewuenschterOutput);
|
||||
public List<ArtikelId> holeAlleZutaten(); // Flach, inkl. verschachtelte
|
||||
public boolean enthaeltVerschachtelteRezepte();
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
RezeptErstellt
|
||||
RezeptAktiviert
|
||||
RezeptArchiviert
|
||||
ZutatHinzugefuegt
|
||||
ZutatEntfernt
|
||||
AusbeuteGeaendert
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Charge (Aggregate Root)
|
||||
|
||||
**Verantwortung:** Repräsentiert eine Produktions-Charge mit lückenloser Rückverfolgbarkeit.
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Charge (Aggregate Root)
|
||||
├── ChargenId (Wertobjekt) - Eindeutige Chargennummer (z.B. "CHARGE-2026-02-17-001")
|
||||
├── RezeptId (Wertobjekt) - Referenz zu Rezept
|
||||
├── Produktionsdatum (Wertobjekt)
|
||||
├── GeplantemMenge (Wertobjekt)
|
||||
├── TatsaechlicheMenge (Wertobjekt) - Nach Produktionsrückmeldung
|
||||
├── Status (Wertobjekt: GEPLANT | IN_PRODUKTION | ABGESCHLOSSEN | STORNIERT)
|
||||
├── ProduziertVon (Wertobjekt: BenutzerId)
|
||||
├── ProduziertIn (Wertobjekt: FilialId) - Für Mehrfilialen
|
||||
├── Verfallsdatum (Wertobjekt) - MHD des Endprodukts
|
||||
├── VerwendeteZutatenchargen[] (Entität) - KRITISCH für Rückverfolgbarkeit!
|
||||
│ ├── RohstoffChargenId (Wertobjekt) - Charge des verwendeten Rohstoffs
|
||||
│ ├── ArtikelId (Wertobjekt)
|
||||
│ ├── LieferantenChargennummer (Wertobjekt) - Vom Wareneingang
|
||||
│ ├── VerwendeteMenge (Wertobjekt)
|
||||
│ └── Verfallsdatum (Wertobjekt) - MHD des Rohstoffs
|
||||
├── Ausschuss (Wertobjekt) - Ausschuss/Schwund
|
||||
└── Bemerkungen (Wertobjekt) - Optional, für Abweichungen
|
||||
|
||||
Invarianten:
|
||||
- Charge muss ein gültiges Rezept referenzieren
|
||||
- TatsaechlicheMenge muss <= (GeplantemMenge / Rezept.AusbeuteInProzent) sein
|
||||
- Status kann nur übergehen: GEPLANT → IN_PRODUKTION → ABGESCHLOSSEN (oder STORNIERT)
|
||||
- Kann nicht abgeschlossen werden ohne verwendete Zutatenchargen zu erfassen
|
||||
- Verfallsdatum muss in der Zukunft liegen zum Produktionszeitpunkt
|
||||
- Ausschuss muss >= 0 sein
|
||||
- Alle VerwendeteZutatenchargen müssen zu Rezept.Zutaten passen
|
||||
```
|
||||
|
||||
**Geschäftsmethoden:**
|
||||
```java
|
||||
// Charge planen
|
||||
public static Result<ChargenFehler, Charge> planen(
|
||||
RezeptId rezeptId,
|
||||
Menge geplantemMenge,
|
||||
LocalDate produktionsdatum,
|
||||
LocalDate verfallsdatum,
|
||||
BenutzerId produziertVon,
|
||||
FilialId filialId
|
||||
);
|
||||
|
||||
// Produktion starten
|
||||
public Result<ChargenFehler, Void> produktionStarten();
|
||||
|
||||
// Zutatverbrauch erfassen
|
||||
public Result<ChargenFehler, Void> zutatverbrauchErfassen(
|
||||
ArtikelId artikelId,
|
||||
ChargenId rohstoffChargenId,
|
||||
LieferantenChargennummer lieferantenChargennummer,
|
||||
Menge verwendeteMenge,
|
||||
LocalDate verfallsdatum
|
||||
);
|
||||
|
||||
// Charge abschließen
|
||||
public Result<ChargenFehler, Void> abschliessen(
|
||||
Menge tatsaechlicheMenge,
|
||||
Menge ausschuss,
|
||||
Optional<String> bemerkungen
|
||||
);
|
||||
|
||||
// Charge stornieren
|
||||
public Result<ChargenFehler, Void> stornieren(String grund);
|
||||
|
||||
// Abfragemethoden
|
||||
public boolean istRueckverfolgbar(); // Alle Zutaten haben Chargennummern
|
||||
public List<ChargenId> holeVorgelageteChargen(); // Alle verwendeten Rohstoffchargen
|
||||
public Menge berechneAusbeuteEffizienz(); // TatsaechlicheMenge / (GeplantemMenge / AusbeuteInProzent)
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
ChargeGeplant
|
||||
ChargeGestartet
|
||||
ZutatverbrauchErfasst
|
||||
ChargeAbgeschlossen(ChargenId, ArtikelId, Menge, Verfallsdatum) → löst Bestandszugang aus
|
||||
ChargeStorniert
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Produktionsauftrag (Aggregate Root)
|
||||
|
||||
**Verantwortung:** Plant eine zukünftige Produktion.
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Produktionsauftrag (Aggregate Root)
|
||||
├── ProduktionsauftragId (Wertobjekt)
|
||||
├── RezeptId (Wertobjekt)
|
||||
├── GeplantemMenge (Wertobjekt)
|
||||
├── GeplantesDatum (Wertobjekt)
|
||||
├── Prioritaet (Wertobjekt: NIEDRIG | NORMAL | HOCH | DRINGEND)
|
||||
├── Status (Wertobjekt: GEPLANT | FREIGEGEBEN | IN_PRODUKTION | ABGESCHLOSSEN | STORNIERT)
|
||||
├── ErstelltVon (Wertobjekt: BenutzerId)
|
||||
├── ErstelltAm (Wertobjekt: Zeitstempel)
|
||||
├── Zielfiliale (Wertobjekt: FilialId) - Für Mehrfilialen-Produktion
|
||||
├── ErzeugeChargenId (Wertobjekt) - Link zur tatsächlichen Charge bei Produktionsstart
|
||||
└── Bemerkungen (Wertobjekt)
|
||||
|
||||
Invarianten:
|
||||
- Geplante Menge muss positiv sein
|
||||
- Geplantes Datum darf nicht in der Vergangenheit liegen
|
||||
- Kann nur freigegeben werden, wenn Materialien verfügbar sind (geprüft in Anwendungsschicht!)
|
||||
- Kann nicht abgeschlossen werden ohne eine Charge zu erzeugen
|
||||
- Status-Übergänge: GEPLANT → FREIGEGEBEN → IN_PRODUKTION → ABGESCHLOSSEN
|
||||
```
|
||||
|
||||
**Geschäftsmethoden:**
|
||||
```java
|
||||
// Produktionsauftrag erstellen
|
||||
public static Result<ProduktionsauftragFehler, Produktionsauftrag> erstellen(
|
||||
RezeptId rezeptId,
|
||||
Menge geplantemMenge,
|
||||
LocalDate geplantesDatum,
|
||||
Prioritaet prioritaet,
|
||||
FilialId zielfiliale,
|
||||
BenutzerId erstelltVon
|
||||
);
|
||||
|
||||
// Freigeben
|
||||
public Result<ProduktionsauftragFehler, Void> freigeben();
|
||||
|
||||
// Produktion starten
|
||||
public Result<ProduktionsauftragFehler, Void> produktionStarten(ChargenId chargenId);
|
||||
|
||||
// Abschließen
|
||||
public Result<ProduktionsauftragFehler, Void> abschliessen();
|
||||
|
||||
// Stornieren
|
||||
public Result<ProduktionsauftragFehler, Void> stornieren(String grund);
|
||||
|
||||
// Umplanen
|
||||
public Result<ProduktionsauftragFehler, Void> umplanen(LocalDate neuesDatum);
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
ProduktionsauftragErstellt
|
||||
ProduktionsauftragFreigegeben → löst Bedarfsplanung-Update aus
|
||||
ProduktionsauftragGestartet
|
||||
ProduktionsauftragAbgeschlossen
|
||||
ProduktionsauftragStorniert
|
||||
ProduktionsauftragUmgeplant
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Wertobjekte
|
||||
|
||||
### RezeptId
|
||||
```java
|
||||
public record RezeptId(String wert) {
|
||||
public RezeptId {
|
||||
if (wert == null || wert.isBlank()) {
|
||||
throw new IllegalArgumentException("RezeptId darf nicht leer sein");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ChargenId
|
||||
```java
|
||||
public record ChargenId(String wert) {
|
||||
// Format: "CHARGE-YYYY-MM-DD-XXX"
|
||||
public static ChargenId generieren(LocalDate produktionsdatum, int sequenzNummer) {
|
||||
String wert = String.format("CHARGE-%s-%03d",
|
||||
produktionsdatum, sequenzNummer);
|
||||
return new ChargenId(wert);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### AusbeuteInProzent
|
||||
```java
|
||||
public record AusbeuteInProzent(int wert) {
|
||||
public AusbeuteInProzent {
|
||||
if (wert < 1 || wert > 100) {
|
||||
throw new IllegalArgumentException(
|
||||
"Ausbeute muss zwischen 1-100% liegen, ist: " + wert
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public Menge berechneBenoeteigtenInput(Menge gewuenschterOutput) {
|
||||
// Bei 80% Ausbeute und 100kg gewünschtem Output brauchen wir 125kg Input
|
||||
return gewuenschterOutput.multiplizieren(100.0 / wert);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### RezeptTyp
|
||||
```java
|
||||
public enum RezeptTyp {
|
||||
ROHSTOFF, // Rohstoff, kein Rezept
|
||||
ZWISCHENPRODUKT, // Zwischenprodukt (z.B. Gewürzmischung)
|
||||
ENDPRODUKT // Endprodukt
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Domänen-Services
|
||||
|
||||
### RezeptValidator
|
||||
```java
|
||||
public class RezeptValidator {
|
||||
/**
|
||||
* Validiert, dass Rezept keine zyklischen Abhängigkeiten erzeugt.
|
||||
*/
|
||||
public Result<RezeptFehler, Void> validiereKeineZyklischeAbhaengigkeit(
|
||||
Rezept rezept,
|
||||
RezeptRepository rezeptRepository
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### ChargenRueckverfolgbarkeitService
|
||||
```java
|
||||
public class ChargenRueckverfolgbarkeitService {
|
||||
/**
|
||||
* Findet alle vorgelagerten Chargen (Rohstoffe), die in einer Charge verwendet wurden.
|
||||
*/
|
||||
public List<ChargenId> findeVorgelageteChargen(ChargenId chargenId);
|
||||
|
||||
/**
|
||||
* Findet alle nachgelagerten Chargen (Endprodukte), die einen Rohstoff verwendet haben.
|
||||
* KRITISCH für Rückrufe!
|
||||
*/
|
||||
public List<ChargenId> findeNachgelageteChargen(ChargenId rohstoffChargenId);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Repository-Schnittstellen
|
||||
|
||||
```java
|
||||
package com.effigenix.domain.produktion;
|
||||
|
||||
import com.effigenix.shared.result.Result;
|
||||
|
||||
public interface RezeptRepository {
|
||||
Result<RepositoryFehler, Void> speichern(Rezept rezept);
|
||||
Result<RepositoryFehler, Rezept> findeNachId(RezeptId id);
|
||||
Result<RepositoryFehler, List<Rezept>> findeAktive();
|
||||
Result<RepositoryFehler, List<Rezept>> findeNachArtikelId(ArtikelId artikelId);
|
||||
}
|
||||
|
||||
public interface ChargenRepository {
|
||||
Result<RepositoryFehler, Void> speichern(Charge charge);
|
||||
Result<RepositoryFehler, Charge> findeNachId(ChargenId id);
|
||||
Result<RepositoryFehler, List<Charge>> findeNachProduktionsdatum(LocalDate datum);
|
||||
Result<RepositoryFehler, List<Charge>> findeNachStatus(ChargenStatus status);
|
||||
|
||||
// Für Rückverfolgbarkeit
|
||||
Result<RepositoryFehler, List<Charge>> findeNachVorgelagerterCharge(ChargenId vorgelagertChargenId);
|
||||
}
|
||||
|
||||
public interface ProduktionsauftragRepository {
|
||||
Result<RepositoryFehler, Void> speichern(Produktionsauftrag auftrag);
|
||||
Result<RepositoryFehler, Produktionsauftrag> findeNachId(ProduktionsauftragId id);
|
||||
Result<RepositoryFehler, List<Produktionsauftrag>> findeNachGeplantemDatum(LocalDate datum);
|
||||
Result<RepositoryFehler, List<Produktionsauftrag>> findeNachStatus(ProduktionsauftragStatus status);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Domänen-Fehler
|
||||
|
||||
```java
|
||||
public sealed interface RezeptFehler permits
|
||||
RezeptFehler.UngueltigeAusbeute,
|
||||
RezeptFehler.ZyklischeAbhaengigkeitEntdeckt,
|
||||
RezeptFehler.KeineZutatenVorhanden,
|
||||
RezeptFehler.RezeptNichtGefunden {
|
||||
String nachricht();
|
||||
}
|
||||
|
||||
public sealed interface ChargenFehler permits
|
||||
ChargenFehler.UngueltigeMenge,
|
||||
ChargenFehler.UngueltigerStatusUebergang,
|
||||
ChargenFehler.FehlendeZutatenchargen,
|
||||
ChargenFehler.VerfallsdatumInVergangenheit,
|
||||
ChargenFehler.RezeptNichtGefunden {
|
||||
String nachricht();
|
||||
}
|
||||
|
||||
public sealed interface ProduktionsauftragFehler permits
|
||||
ProduktionsauftragFehler.GeplantesDatumInVergangenheit,
|
||||
ProduktionsauftragFehler.UngueltigeMenge,
|
||||
ProduktionsauftragFehler.UngueltigerStatusUebergang,
|
||||
ProduktionsauftragFehler.RezeptNichtGefunden {
|
||||
String nachricht();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration mit anderen Kontexten
|
||||
|
||||
### Upstream-Abhängigkeiten
|
||||
- **Stammdaten-Kontext:** Rezept referenziert ArtikelId
|
||||
- **Benutzerverwaltung:** Charge/Produktionsauftrag referenziert BenutzerId
|
||||
- **Filialen-Kontext:** Produktionsauftrag referenziert FilialId
|
||||
|
||||
### Downstream-Integrationen
|
||||
- **Bestandsführung:** `ChargeAbgeschlossen` Event löst Bestandszugang aus
|
||||
- **Deklaration:** Deklaration liest Rezeptdaten für Nährwertberechnung
|
||||
- **Beschaffung:** Produktionsauftrag löst Bedarfsplanung aus
|
||||
|
||||
---
|
||||
|
||||
## Anwendungsfälle (Anwendungsschicht)
|
||||
|
||||
```java
|
||||
// application/produktion/RezeptErstellen.java
|
||||
public class RezeptErstellen {
|
||||
public Result<AnwendungsFehler, RezeptDTO> ausfuehren(RezeptErstellenKommando cmd);
|
||||
}
|
||||
|
||||
// application/produktion/ProduktionPlanen.java
|
||||
public class ProduktionPlanen {
|
||||
public Result<AnwendungsFehler, ProduktionsauftragDTO> ausfuehren(ProduktionPlanenKommando cmd);
|
||||
}
|
||||
|
||||
// application/produktion/ProduktionschargeStarten.java
|
||||
public class ProduktionschargeStarten {
|
||||
public Result<AnwendungsFehler, ChargenDTO> ausfuehren(ChargeStartenKommando cmd);
|
||||
}
|
||||
|
||||
// application/produktion/ProduktionschargeAbschliessen.java
|
||||
public class ProduktionschargeAbschliessen {
|
||||
public Result<AnwendungsFehler, ChargenDTO> ausfuehren(ChargeAbschliessenKommando cmd);
|
||||
// Löst ChargeAbgeschlossen Event aus → Bestandszugang
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Beispiel: Chargen-Erstellungs-Ablauf
|
||||
|
||||
```java
|
||||
// 1. Produktionsauftrag planen
|
||||
Produktionsauftrag auftrag = Produktionsauftrag.erstellen(
|
||||
rezeptId,
|
||||
Menge.von(100, "kg"),
|
||||
LocalDate.now().plusDays(1),
|
||||
Prioritaet.NORMAL,
|
||||
filialId,
|
||||
benutzerId
|
||||
);
|
||||
|
||||
// 2. Auftrag freigeben (prüft Materialverfügbarkeit in Anwendungsschicht)
|
||||
auftrag.freigeben();
|
||||
|
||||
// 3. Produktion starten → Charge erstellen
|
||||
Charge charge = Charge.planen(
|
||||
auftrag.rezeptId(),
|
||||
auftrag.geplantemMenge(),
|
||||
LocalDate.now(),
|
||||
LocalDate.now().plusDays(30), // MHD
|
||||
benutzerId,
|
||||
filialId
|
||||
);
|
||||
charge.produktionStarten();
|
||||
auftrag.produktionStarten(charge.id());
|
||||
|
||||
// 4. Zutatverbrauch erfassen
|
||||
charge.zutatverbrauchErfassen(
|
||||
ArtikelId.von("ART-001"),
|
||||
ChargenId.von("CHARGE-2026-02-15-042"), // Lieferanten-Charge
|
||||
LieferantenChargennummer.von("SUPPLIER-12345"),
|
||||
Menge.von(50, "kg"),
|
||||
LocalDate.now().plusDays(20) // MHD des Rohstoffs
|
||||
);
|
||||
|
||||
// 5. Charge abschließen
|
||||
charge.abschliessen(
|
||||
Menge.von(80, "kg"), // Tatsächlicher Output
|
||||
Menge.von(5, "kg"), // Ausschuss
|
||||
Optional.of("Leichter Schwund beim Räuchern")
|
||||
);
|
||||
auftrag.abschliessen();
|
||||
|
||||
// 6. ChargeAbgeschlossen Event → Bestandsführung erzeugt Bestandseintrag
|
||||
```
|
||||
192
docs/mvp/ddd/05-qualitaets-kontext.md
Normal file
192
docs/mvp/ddd/05-qualitaets-kontext.md
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
# Qualitäts-Kontext (HACCP/QM) - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Qualität
|
||||
**Domain-Typ:** KERN
|
||||
**Verantwortung:** HACCP-Compliance, Qualitätsmanagement, Audit-Vorbereitung
|
||||
|
||||
---
|
||||
|
||||
## Aggregate
|
||||
|
||||
### 1. Temperaturprotokoll (Aggregate Root)
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Temperaturprotokoll
|
||||
├── TemperaturprotokollId (Wertobjekt)
|
||||
├── Messpunkt (Wertobjekt: KUEHLRAUM | TIEFKUEHLER | VERKAUFSTHEKE | PRODUKTIONSRAUM)
|
||||
├── GeraetId (Wertobjekt) - Referenz zu Ausstattung
|
||||
├── GemessenAm (Wertobjekt: Zeitstempel)
|
||||
├── Temperatur (Wertobjekt: mit Einheit °C)
|
||||
├── GemessenVon (Wertobjekt: BenutzerId)
|
||||
├── KritischeGrenzwertMin (Wertobjekt)
|
||||
├── KritischeGrenzwertMax (Wertobjekt)
|
||||
└── Status (Wertobjekt: OK | WARNUNG | KRITISCH)
|
||||
|
||||
Invarianten:
|
||||
- Temperatur muss im physikalisch möglichen Bereich liegen (-50°C bis +50°C)
|
||||
- GemessenAm darf nicht in der Zukunft liegen
|
||||
- Status = KRITISCH wenn Temperatur außerhalb kritischer Grenzwerte
|
||||
- Status = WARNUNG wenn Temperatur nahe an Grenzwerten (innerhalb 10%)
|
||||
- KritischeGrenzwertMin < KritischeGrenzwertMax
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
TemperaturKritischeGrenzwerteUeberschritten(TemperaturprotokollId, Messpunkt, Temperatur)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Reinigungsnachweis (Aggregate Root)
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Reinigungsnachweis
|
||||
├── ReinigungsnachweisId (Wertobjekt)
|
||||
├── Bereich (Wertobjekt: PRODUKTIONSRAUM | KUEHLRAUM | VERKAUFSTHEKE | GERAET)
|
||||
├── ReinigungsplanId (Wertobjekt) - Referenz zu Reinigungsplan
|
||||
├── GeplantesFuer (Wertobjekt: Datum)
|
||||
├── AbgeschlossenAm (Wertobjekt: Zeitstempel)
|
||||
├── AbgeschlossenVon (Wertobjekt: BenutzerId)
|
||||
├── Checklisten-Eintraege[] (Entität)
|
||||
│ ├── Eintrag (Wertobjekt: "Boden gewischt", "Oberflächen desinfiziert")
|
||||
│ ├── Erledigt (Wertobjekt: boolean)
|
||||
│ └── Bemerkungen (Wertobjekt: optional)
|
||||
└── GesamtBemerkungen (Wertobjekt)
|
||||
|
||||
Invarianten:
|
||||
- Alle Checklisten-Einträge müssen erledigt sein zum Abschluss
|
||||
- AbgeschlossenAm muss >= GeplantesFuer sein
|
||||
- Kann nicht abgeschlossen werden ohne AbgeschlossenVon
|
||||
- Kann nach Abschluss nicht mehr geändert werden
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
ReinigungUeberfaellig(ReinigungsplanId, Bereich, LocalDate geplantesFuer)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Wareneingangspruefung (Aggregate Root)
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Wareneingangspruefung
|
||||
├── PruefungId (Wertobjekt)
|
||||
├── WareneingangId (Wertobjekt) - Referenz zu Beschaffungs-Kontext
|
||||
├── GeprueftAm (Wertobjekt)
|
||||
├── GeprueftVon (Wertobjekt: BenutzerId)
|
||||
├── Temperaturpruefung (Entität)
|
||||
│ ├── GemesseneTemperatur (Wertobjekt)
|
||||
│ ├── ErwarteterBereich (Wertobjekt)
|
||||
│ └── Status (Wertobjekt: BESTANDEN | DURCHGEFALLEN)
|
||||
├── Sichtpruefung (Entität)
|
||||
│ ├── VerpackungIntakt (Wertobjekt: boolean)
|
||||
│ ├── Farbe (Wertobjekt: NORMAL | ABNORMAL)
|
||||
│ ├── Geruchstest (Wertobjekt: NORMAL | ABNORMAL)
|
||||
│ └── Bemerkungen (Wertobjekt)
|
||||
├── MHD-Pruefung (Entität)
|
||||
│ ├── Verfallsdatum (Wertobjekt)
|
||||
│ ├── TageBeisVerfallsdatum (Wertobjekt)
|
||||
│ ├── MinimalAkzeptableTage (Wertobjekt)
|
||||
│ └── Status (Wertobjekt: BESTANDEN | DURCHGEFALLEN)
|
||||
├── Dokumentenpruefung (Entität)
|
||||
│ ├── LieferscheinErhalten (Wertobjekt: boolean)
|
||||
│ ├── VeterinaerbescheinigungErhalten (Wertobjekt: boolean)
|
||||
│ ├── Qualitaetszertifikate[] (Wertobjekt)
|
||||
│ └── AlleDokumenteVollstaendig (Wertobjekt: boolean)
|
||||
├── LieferantenChargennummer (Wertobjekt) - Für Rückverfolgbarkeit!
|
||||
└── Endergebnis (Wertobjekt: ANGENOMMEN | ABGELEHNT | BEDINGT_ANGENOMMEN)
|
||||
|
||||
Invarianten:
|
||||
- Alle Prüfungen müssen durchgeführt sein, bevor Endergebnis gesetzt werden kann
|
||||
- Bei ABGELEHNT müssen GesamtBemerkungen angegeben werden
|
||||
- Temperatur muss im akzeptablen Bereich liegen für ANGENOMMEN
|
||||
- MHD muss Mindesttage haben für ANGENOMMEN
|
||||
- Veterinärbescheinigung erforderlich für Fleischprodukte
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
WareneingangAbgelehnt(PruefungId, WareneingangId, String grund)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Schulungsnachweis (Aggregate Root)
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Schulungsnachweis
|
||||
├── SchulungsnachweisId (Wertobjekt)
|
||||
├── MitarbeiterId (Wertobjekt: BenutzerId)
|
||||
├── SchulungsTyp (Wertobjekt: HACCP | HYGIENE | LEBENSMITTELSICHERHEIT | GERAETEBEDIENUNG)
|
||||
├── Schulungsdatum (Wertobjekt)
|
||||
├── GueltigBis (Wertobjekt) - Auffrischung notwendig
|
||||
├── Schulender (Wertobjekt) - Intern oder extern
|
||||
├── Zertifikatsnummer (Wertobjekt)
|
||||
├── ZertifikatsDokumentUrl (Wertobjekt)
|
||||
└── Status (Wertobjekt: GUELTIG | ABGELAUFEN | WIDERRUFEN)
|
||||
|
||||
Invarianten:
|
||||
- GueltigBis muss nach Schulungsdatum liegen
|
||||
- Status = ABGELAUFEN wenn GueltigBis < HEUTE
|
||||
- Kann nicht widerrufen werden ohne Grund
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
SchulungLaeuftDemnaechstAb(SchulungsnachweisId, BenutzerId, LocalDate ablaufdatum)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Wartungsprotokoll (Aggregate Root)
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Wartungsprotokoll
|
||||
├── WartungsprotokollId (Wertobjekt)
|
||||
├── GeraetId (Wertobjekt)
|
||||
├── WartungsTyp (Wertobjekt: GEPLANT | REPARATUR | INSPEKTION)
|
||||
├── GeplantesFuer (Wertobjekt: Datum)
|
||||
├── DurchgefuehrtAm (Wertobjekt: Zeitstempel)
|
||||
├── DurchgefuehrtVon (Wertobjekt) - Internes Personal oder externe Firma
|
||||
├── Befunde (Wertobjekt)
|
||||
├── Massnahmen (Wertobjekt)
|
||||
├── NaechsteWartungFaellig (Wertobjekt: Datum)
|
||||
└── Status (Wertobjekt: ABGESCHLOSSEN | AUSSTEHEND | FEHLGESCHLAGEN)
|
||||
|
||||
Invarianten:
|
||||
- DurchgefuehrtAm muss >= GeplantesFuer sein
|
||||
- Bei FEHLGESCHLAGEN müssen Befunde und Massnahmen dokumentiert sein
|
||||
- NaechsteWartungFaellig muss basierend auf Wartungsintervall berechnet werden
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
WartungUeberfaellig(GeraetId, LocalDate geplantesFuer)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Repository-Schnittstellen
|
||||
|
||||
```java
|
||||
public interface TemperaturprotokollRepository {
|
||||
Result<RepositoryFehler, Void> speichern(Temperaturprotokoll protokoll);
|
||||
Result<RepositoryFehler, List<Temperaturprotokoll>> findeNachZeitraum(
|
||||
LocalDate von, LocalDate bis
|
||||
);
|
||||
Result<RepositoryFehler, List<Temperaturprotokoll>> findeKritische();
|
||||
}
|
||||
|
||||
public interface WareneingangspruefungRepository {
|
||||
Result<RepositoryFehler, Void> speichern(Wareneingangspruefung pruefung);
|
||||
Result<RepositoryFehler, Wareneingangspruefung> findeNachWareneingangId(
|
||||
WareneingangId id
|
||||
);
|
||||
}
|
||||
```
|
||||
162
docs/mvp/ddd/05-quality-bc.md
Normal file
162
docs/mvp/ddd/05-quality-bc.md
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
# Quality BC (HACCP/QM) - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Quality
|
||||
**Domain Type:** CORE
|
||||
**Verantwortung:** HACCP-Compliance, Qualitätsmanagement, Audit-Vorbereitung
|
||||
|
||||
---
|
||||
|
||||
## Aggregates
|
||||
|
||||
### 1. TemperatureLog (Aggregate Root)
|
||||
|
||||
```
|
||||
TemperatureLog
|
||||
├── TemperatureLogId (VO)
|
||||
├── MeasurementPoint (VO: COLD_ROOM | FREEZER | DISPLAY_COUNTER | PRODUCTION_ROOM)
|
||||
├── DeviceId (VO) - Reference to Equipment
|
||||
├── MeasuredAt (VO: Timestamp)
|
||||
├── Temperature (VO: with unit °C)
|
||||
├── MeasuredBy (VO: UserId)
|
||||
├── CriticalLimitMin (VO)
|
||||
├── CriticalLimitMax (VO)
|
||||
└── Status (VO: OK | WARNING | CRITICAL)
|
||||
|
||||
Invariants:
|
||||
- Temperature must be within physically possible range (-50°C to +50°C)
|
||||
- MeasuredAt cannot be in the future
|
||||
- Status = CRITICAL if temperature outside critical limits
|
||||
- Status = WARNING if temperature close to limits (within 10%)
|
||||
- CriticalLimitMin < CriticalLimitMax
|
||||
```
|
||||
|
||||
### 2. CleaningRecord (Aggregate Root)
|
||||
|
||||
```
|
||||
CleaningRecord
|
||||
├── CleaningRecordId (VO)
|
||||
├── Area (VO: PRODUCTION_ROOM | COLD_STORAGE | SALES_COUNTER | EQUIPMENT)
|
||||
├── CleaningPlanId (VO) - Reference to CleaningPlan
|
||||
├── ScheduledFor (VO: Date)
|
||||
├── CompletedAt (VO: Timestamp)
|
||||
├── CompletedBy (VO: UserId)
|
||||
├── ChecklistItems[] (Entity)
|
||||
│ ├── Item (VO: "Floor mopped", "Surfaces disinfected")
|
||||
│ ├── Checked (VO: boolean)
|
||||
│ └── Remarks (VO: optional)
|
||||
└── OverallRemarks (VO)
|
||||
|
||||
Invariants:
|
||||
- All checklist items must be checked to complete
|
||||
- CompletedAt must be >= ScheduledFor
|
||||
- Cannot complete without CompletedBy
|
||||
- Cannot modify after completion
|
||||
```
|
||||
|
||||
### 3. GoodsReceiptInspection (Aggregate Root)
|
||||
|
||||
```
|
||||
GoodsReceiptInspection
|
||||
├── InspectionId (VO)
|
||||
├── GoodsReceiptId (VO) - Reference to Procurement BC
|
||||
├── InspectedAt (VO)
|
||||
├── InspectedBy (VO: UserId)
|
||||
├── TemperatureCheck (Entity)
|
||||
│ ├── MeasuredTemperature (VO)
|
||||
│ ├── ExpectedRange (VO)
|
||||
│ └── Status (VO: PASSED | FAILED)
|
||||
├── VisualInspection (Entity)
|
||||
│ ├── PackagingIntact (VO: boolean)
|
||||
│ ├── ColorAppearance (VO: NORMAL | ABNORMAL)
|
||||
│ ├── SmellTest (VO: NORMAL | ABNORMAL)
|
||||
│ └── Remarks (VO)
|
||||
├── MHDCheck (Entity)
|
||||
│ ├── ExpiryDate (VO)
|
||||
│ ├── DaysUntilExpiry (VO)
|
||||
│ ├── MinimumAcceptableDays (VO)
|
||||
│ └── Status (VO: PASSED | FAILED)
|
||||
├── DocumentCheck (Entity)
|
||||
│ ├── DeliveryNoteReceived (VO: boolean)
|
||||
│ ├── VeterinaryCertificateReceived (VO: boolean)
|
||||
│ ├── QualityCertificates[] (VO)
|
||||
│ └── AllDocumentsComplete (VO: boolean)
|
||||
├── SupplierBatchNumber (VO) - For traceability!
|
||||
└── FinalResult (VO: ACCEPTED | REJECTED | CONDITIONALLY_ACCEPTED)
|
||||
|
||||
Invariants:
|
||||
- All checks must be performed before FinalResult can be set
|
||||
- If REJECTED, OverallRemarks must be provided
|
||||
- Temperature must be within acceptable range for ACCEPTED
|
||||
- MHD must have minimum days for ACCEPTED
|
||||
- VeterinaryCertificate required for meat products
|
||||
```
|
||||
|
||||
### 4. TrainingRecord (Aggregate Root)
|
||||
|
||||
```
|
||||
TrainingRecord
|
||||
├── TrainingRecordId (VO)
|
||||
├── EmployeeId (VO: UserId)
|
||||
├── TrainingType (VO: HACCP | HYGIENE | FOOD_SAFETY | EQUIPMENT_OPERATION)
|
||||
├── TrainingDate (VO)
|
||||
├── ValidUntil (VO) - Auffrischung notwendig
|
||||
├── Trainer (VO) - Internal or external
|
||||
├── CertificateNumber (VO)
|
||||
├── CertificateDocumentUrl (VO)
|
||||
└── Status (VO: VALID | EXPIRED | REVOKED)
|
||||
|
||||
Invariants:
|
||||
- ValidUntil must be after TrainingDate
|
||||
- Status = EXPIRED if ValidUntil < TODAY
|
||||
- Cannot revoke without reason
|
||||
```
|
||||
|
||||
### 5. MaintenanceRecord (Aggregate Root)
|
||||
|
||||
```
|
||||
MaintenanceRecord
|
||||
├── MaintenanceRecordId (VO)
|
||||
├── EquipmentId (VO)
|
||||
├── MaintenanceType (VO: SCHEDULED | REPAIR | INSPECTION)
|
||||
├── ScheduledFor (VO: Date)
|
||||
├── PerformedAt (VO: Timestamp)
|
||||
├── PerformedBy (VO) - Internal staff or external company
|
||||
├── Findings (VO)
|
||||
├── Actions (VO)
|
||||
├── NextMaintenanceDue (VO: Date)
|
||||
└── Status (VO: COMPLETED | PENDING | FAILED)
|
||||
|
||||
Invariants:
|
||||
- PerformedAt must be >= ScheduledFor
|
||||
- If FAILED, Findings and Actions must be documented
|
||||
- NextMaintenanceDue must be calculated based on maintenance interval
|
||||
```
|
||||
|
||||
## Repository Interfaces
|
||||
|
||||
```java
|
||||
public interface TemperatureLogRepository {
|
||||
Result<RepositoryError, Void> save(TemperatureLog log);
|
||||
Result<RepositoryError, List<TemperatureLog>> findByPeriod(
|
||||
LocalDate from, LocalDate to
|
||||
);
|
||||
Result<RepositoryError, List<TemperatureLog>> findCritical();
|
||||
}
|
||||
|
||||
public interface GoodsReceiptInspectionRepository {
|
||||
Result<RepositoryError, Void> save(GoodsReceiptInspection inspection);
|
||||
Result<RepositoryError, GoodsReceiptInspection> findByGoodsReceiptId(
|
||||
GoodsReceiptId id
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Domain Events
|
||||
|
||||
```java
|
||||
TemperatureCriticalLimitExceeded(TemperatureLogId, MeasurementPoint, Temperature)
|
||||
CleaningOverdue(CleaningPlanId, Area, LocalDate scheduledFor)
|
||||
GoodsReceiptRejected(InspectionId, GoodsReceiptId, String reason)
|
||||
TrainingExpiringSoon(TrainingRecordId, UserId, LocalDate expiryDate)
|
||||
MaintenanceOverdue(EquipmentId, LocalDate scheduledFor)
|
||||
```
|
||||
42
docs/mvp/ddd/06-labeling-bc.md
Normal file
42
docs/mvp/ddd/06-labeling-bc.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Labeling BC - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Labeling
|
||||
**Domain Type:** CORE
|
||||
**Verantwortung:** Automatische Berechnung von Nährwerten/Allergenen, Etikettengenerierung
|
||||
|
||||
## Aggregates
|
||||
|
||||
### ProductLabel (Aggregate Root)
|
||||
|
||||
```
|
||||
ProductLabel
|
||||
├── ProductLabelId
|
||||
├── ArticleId - Reference to Master Data
|
||||
├── RecipeId - Reference to Production BC (for auto-calculation)
|
||||
├── ProductName
|
||||
├── Manufacturer
|
||||
├── Ingredients[] (Entity) - From Recipe, sorted descending by weight
|
||||
├── Allergens[] (VO) - Auto-calculated from ingredients
|
||||
├── TraceDeclarations[] (VO) - "May contain traces of..."
|
||||
├── NutritionFacts (Entity) - Auto-calculated from recipe
|
||||
│ ├── EnergyKJ, EnergyKcal, Fat, SaturatedFat, Carbs, Sugars, Protein, Salt
|
||||
│ └── CalculationBase (PER_100G | PER_PORTION)
|
||||
├── QualityLabels[] (VO) - Bio, Regional, Animal Welfare
|
||||
├── OriginLabeling (VO)
|
||||
└── LabelVersion
|
||||
|
||||
Invariants:
|
||||
- All EU allergens must be declared
|
||||
- Ingredients sorted by quantity (highest first) - EU regulation
|
||||
- Nutrition facts must sum correctly from recipe
|
||||
- If BIO label, all ingredients must be BIO-certified
|
||||
- Allergens automatically inherited from ingredients (no manual override!)
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
|
||||
```java
|
||||
GenerateLabelFromRecipe - Calculates nutrition & allergens from recipe
|
||||
PrintLabelAtScale - Sends label to scale for printing with current weight
|
||||
UpdateAllergenMatrix - Regenerates allergen matrix for all products
|
||||
```
|
||||
163
docs/mvp/ddd/07-bestandsfuehrungs-kontext.md
Normal file
163
docs/mvp/ddd/07-bestandsfuehrungs-kontext.md
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
# Bestandsführungs-Kontext - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Bestandsführung
|
||||
**Domain-Typ:** KERN
|
||||
**Verantwortung:** Chargen-basierte Bestandsführung, Rückverfolgbarkeit, MHD-Tracking
|
||||
|
||||
---
|
||||
|
||||
## Aggregate
|
||||
|
||||
### 1. Bestand (Aggregate Root)
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Bestand (Aggregate Root)
|
||||
├── BestandId (Wertobjekt)
|
||||
├── ArtikelId (Wertobjekt) - Referenz zu Stammdaten
|
||||
├── LagerortId (Wertobjekt)
|
||||
├── FilialId (Wertobjekt)
|
||||
├── Bestandsmenge (Wertobjekt: Menge) - Aktueller Gesamtbestand
|
||||
├── Chargen[] (Entität) - Chargen-spezifischer Bestand (KRITISCH!)
|
||||
│ ├── ChargenId (Wertobjekt) - ProduktionsChargenId ODER LieferantenChargenId
|
||||
│ ├── ChargenTyp (Wertobjekt: PRODUZIERT | EINGEKAUFT)
|
||||
│ ├── Menge (Wertobjekt)
|
||||
│ ├── Verfallsdatum (Wertobjekt: MHD)
|
||||
│ ├── EingegangenenAm (Wertobjekt)
|
||||
│ └── Status (Wertobjekt: VERFUEGBAR | RESERVIERT | ABGELAUFEN | VERKAUFT)
|
||||
├── MinimalBestandsmenge (Wertobjekt) - Für Warnungen bei niedrigem Bestand
|
||||
└── Nachbestellpunkt (Wertobjekt) - Auslöser für Beschaffung
|
||||
|
||||
Invarianten:
|
||||
- Bestandsmenge = SUMME(Chargen.Menge wo Status = VERFUEGBAR)
|
||||
- Kann nicht mehr abheben als verfügbar
|
||||
- FEFO durchgesetzt: Ältestes Verfallsdatum zuerst
|
||||
- Negativer Bestand nicht erlaubt
|
||||
- Chargen mit Verfallsdatum < HEUTE müssen Status = ABGELAUFEN haben
|
||||
```
|
||||
|
||||
**Geschäftsmethoden:**
|
||||
```java
|
||||
// Bestand hinzufügen
|
||||
public Result<BestandFehler, Void> hinzufuegen(
|
||||
ChargenId chargenId,
|
||||
ChargenTyp chargenTyp,
|
||||
Menge menge,
|
||||
LocalDate verfallsdatum
|
||||
);
|
||||
|
||||
// Bestand abheben (mit FEFO)
|
||||
public Result<BestandFehler, List<ChargenAbhebung>> abheben(Menge menge);
|
||||
|
||||
// Charge reservieren
|
||||
public Result<BestandFehler, Void> reservieren(ChargenId chargenId, Menge menge);
|
||||
|
||||
// Abgelaufene Chargen markieren
|
||||
public Result<BestandFehler, List<ChargenId>> markiereAbgelaufeneChargen();
|
||||
|
||||
// Abfragemethoden
|
||||
public Menge verfuegbareMenge();
|
||||
public List<Charge> findeChargenNachFEFO(); // Sortiert nach Verfallsdatum
|
||||
public boolean istUnterMinimalBestand();
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
BestandUnterMinimum(ArtikelId, FilialId, Menge)
|
||||
ChargeLaeuftDemnaechstAb(ChargenId, ArtikelId, Verfallsdatum)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Bestandsbewegung (Aggregate Root)
|
||||
|
||||
**Event Sourcing Kandidat!**
|
||||
|
||||
**Struktur:**
|
||||
```
|
||||
Bestandsbewegung (Aggregate Root)
|
||||
├── BestandsbewegungId (Wertobjekt)
|
||||
├── ArtikelId (Wertobjekt)
|
||||
├── ChargenId (Wertobjekt) - KRITISCH für Rückverfolgbarkeit
|
||||
├── BewegungsTyp (Wertobjekt: WARENEINGANG | PRODUKTIONSAUSGANG | VERKAUF |
|
||||
│ INTERFILIAL_TRANSFER | AUSSCHUSS | INVENTUR_KORREKTUR)
|
||||
├── VonLagerort (Wertobjekt: LagerortId) - Null bei WARENEINGANG
|
||||
├── ZuLagerort (Wertobjekt: LagerortId) - Null bei VERKAUF/AUSSCHUSS
|
||||
├── VonFiliale (Wertobjekt: FilialId)
|
||||
├── ZuFiliale (Wertobjekt: FilialId) - Für Interfilial-Transfers
|
||||
├── Menge (Wertobjekt)
|
||||
├── Bewegungsdatum (Wertobjekt: Zeitstempel)
|
||||
├── DurchgefuehrtVon (Wertobjekt: BenutzerId)
|
||||
├── Grund (Wertobjekt: für AUSSCHUSS/KORREKTUR)
|
||||
├── Referenzdokument (Wertobjekt) - WareneingangId, ProduktionsauftragId, RechnungId
|
||||
└── Rueckverfolgbarkeitskette (Wertobjekt) - Link zu vorgelagerten/nachgelagerten Bewegungen
|
||||
|
||||
Invarianten:
|
||||
- Menge muss positiv sein
|
||||
- WARENEINGANG: VonLagerort muss null sein
|
||||
- VERKAUF oder AUSSCHUSS: ZuLagerort muss null sein
|
||||
- INTERFILIAL_TRANSFER: VonFiliale != ZuFiliale
|
||||
- AUSSCHUSS benötigt Grund
|
||||
- Alle Bewegungen müssen eine Charge referenzieren
|
||||
```
|
||||
|
||||
**Domänen-Events:**
|
||||
```java
|
||||
BestandsbewegungErfasst(BestandsbewegungId, ChargenId, BewegungsTyp)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Repository-Schnittstellen
|
||||
|
||||
```java
|
||||
public interface BestandRepository {
|
||||
Result<RepositoryFehler, Void> speichern(Bestand bestand);
|
||||
Result<RepositoryFehler, Bestand> findeNachArtikelUndLagerort(
|
||||
ArtikelId artikelId,
|
||||
LagerortId lagerortId,
|
||||
FilialId filialId
|
||||
);
|
||||
Result<RepositoryFehler, List<Bestand>> findeUnterMinimalBestand();
|
||||
}
|
||||
|
||||
public interface BestandsbewegungRepository {
|
||||
Result<RepositoryFehler, Void> speichern(Bestandsbewegung bewegung);
|
||||
Result<RepositoryFehler, List<Bestandsbewegung>> findeNachCharge(ChargenId chargenId);
|
||||
Result<RepositoryFehler, List<Bestandsbewegung>> findeNachZeitraum(
|
||||
LocalDate von, LocalDate bis
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rückverfolgbarkeits-Beispiel
|
||||
|
||||
```java
|
||||
// Beispiel: Rückruf wegen kontaminierter Rohstoff-Charge
|
||||
|
||||
// 1. Finde alle Bestandsbewegungen für Lieferanten-Charge
|
||||
List<Bestandsbewegung> wareneingang = repository.findeNachCharge(
|
||||
ChargenId.von("SUPPLIER-BATCH-12345")
|
||||
);
|
||||
|
||||
// 2. Finde Produktionschargen, die diesen Rohstoff verwendet haben
|
||||
List<ChargenId> produktionschargen = wareneingang.stream()
|
||||
.filter(b -> b.bewegungsTyp() == BewegungsTyp.PRODUKTIONSAUSGANG)
|
||||
.map(b -> b.referenzdokument().produktionsChargenId())
|
||||
.toList();
|
||||
|
||||
// 3. Finde alle Verkäufe dieser Produktionschargen
|
||||
List<Bestandsbewegung> verkaeufe = produktionschargen.stream()
|
||||
.flatMap(chargeId -> repository.findeNachCharge(chargeId).stream())
|
||||
.filter(b -> b.bewegungsTyp() == BewegungsTyp.VERKAUF)
|
||||
.toList();
|
||||
|
||||
// 4. Extrahiere betroffene Kunden/Rechnungen
|
||||
List<RechnungId> betroffeneRechnungen = verkaeufe.stream()
|
||||
.map(b -> b.referenzdokument().rechnungId())
|
||||
.toList();
|
||||
|
||||
// → Rückruf kann durchgeführt werden!
|
||||
```
|
||||
68
docs/mvp/ddd/07-inventory-bc.md
Normal file
68
docs/mvp/ddd/07-inventory-bc.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Inventory BC - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Inventory
|
||||
**Domain Type:** CORE
|
||||
**Verantwortung:** Chargen-basierte Bestandsführung, Rückverfolgbarkeit, MHD-Tracking
|
||||
|
||||
## Aggregates
|
||||
|
||||
### Stock (Aggregate Root)
|
||||
|
||||
```
|
||||
Stock
|
||||
├── StockId
|
||||
├── ArticleId - Reference to Master Data
|
||||
├── StorageLocationId
|
||||
├── BranchId
|
||||
├── StockLevel (Quantity) - Current total
|
||||
├── Batches[] (Entity) - Batch-level inventory (CRITICAL!)
|
||||
│ ├── BatchId - ProductionBatchId OR SupplierBatchId
|
||||
│ ├── BatchType (PRODUCED | PURCHASED)
|
||||
│ ├── Quantity
|
||||
│ ├── ExpiryDate (MHD)
|
||||
│ ├── ReceivedAt
|
||||
│ └── Status (AVAILABLE | RESERVED | EXPIRED | SOLD)
|
||||
├── MinimumStockLevel
|
||||
└── ReorderPoint
|
||||
|
||||
Invariants:
|
||||
- StockLevel = SUM(Batches.Quantity where Status = AVAILABLE)
|
||||
- Cannot withdraw more than available
|
||||
- FEFO enforced: oldest expiry first
|
||||
- Negative stock not allowed
|
||||
- Expired batches must have Status = EXPIRED
|
||||
```
|
||||
|
||||
### StockMovement (Aggregate Root) - Event Sourcing candidate!
|
||||
|
||||
```
|
||||
StockMovement
|
||||
├── StockMovementId
|
||||
├── ArticleId
|
||||
├── BatchId - CRITICAL for traceability
|
||||
├── MovementType (GOODS_RECEIPT | PRODUCTION_OUTPUT | SALE |
|
||||
│ INTER_BRANCH_TRANSFER | WASTE | ADJUSTMENT)
|
||||
├── FromLocation, ToLocation
|
||||
├── FromBranch, ToBranch
|
||||
├── Quantity
|
||||
├── MovementDate
|
||||
├── PerformedBy (UserId)
|
||||
├── Reason (for WASTE/ADJUSTMENT)
|
||||
├── ReferenceDocument (GoodsReceiptId, ProductionOrderId, InvoiceId)
|
||||
└── TraceabilityChain - Link to upstream/downstream
|
||||
|
||||
Invariants:
|
||||
- Quantity must be positive
|
||||
- GOODS_RECEIPT: FromLocation = null
|
||||
- SALE/WASTE: ToLocation = null
|
||||
- INTER_BRANCH_TRANSFER: FromBranch != ToBranch
|
||||
- All movements must reference a Batch
|
||||
```
|
||||
|
||||
## Domain Events
|
||||
|
||||
```java
|
||||
StockLevelBelowMinimum(ArticleId, BranchId, Quantity)
|
||||
BatchExpiringSoon(BatchId, ArticleId, ExpiryDate)
|
||||
StockMovementRecorded(StockMovementId, BatchId, MovementType)
|
||||
```
|
||||
83
docs/mvp/ddd/08-procurement-bc.md
Normal file
83
docs/mvp/ddd/08-procurement-bc.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# Procurement BC - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Procurement
|
||||
**Domain Type:** CORE
|
||||
**Verantwortung:** Bedarfsplanung, Bestellwesen, Wareneingangskontrolle, Lieferanten-QM
|
||||
|
||||
## Aggregates
|
||||
|
||||
### PurchaseOrder (Aggregate Root)
|
||||
|
||||
```
|
||||
PurchaseOrder
|
||||
├── PurchaseOrderId
|
||||
├── SupplierId
|
||||
├── OrderDate
|
||||
├── RequestedDeliveryDate
|
||||
├── Status (DRAFT | ORDERED | CONFIRMED | PARTIALLY_RECEIVED | FULLY_RECEIVED | CANCELLED)
|
||||
├── OrderedBy (UserId)
|
||||
├── BranchId
|
||||
├── Items[] (Entity)
|
||||
│ ├── ArticleId
|
||||
│ ├── OrderedQuantity
|
||||
│ ├── ReceivedQuantity - Updated on goods receipt
|
||||
│ └── UnitPrice
|
||||
├── TotalAmount - Calculated
|
||||
└── PaymentTerms
|
||||
|
||||
Invariants:
|
||||
- Status cannot skip states
|
||||
- TotalAmount = SUM(Items.Quantity * Items.UnitPrice)
|
||||
- ReceivedQuantity <= OrderedQuantity per item
|
||||
- FULLY_RECEIVED when all items received
|
||||
```
|
||||
|
||||
### GoodsReceipt (Aggregate Root)
|
||||
|
||||
```
|
||||
GoodsReceipt
|
||||
├── GoodsReceiptId
|
||||
├── PurchaseOrderId
|
||||
├── SupplierId
|
||||
├── SupplierDeliveryNote
|
||||
├── ReceivedAt
|
||||
├── ReceivedBy (UserId)
|
||||
├── Items[] (Entity)
|
||||
│ ├── ArticleId
|
||||
│ ├── OrderedQuantity
|
||||
│ ├── ReceivedQuantity
|
||||
│ ├── SupplierBatchNumber - CRITICAL for traceability!
|
||||
│ ├── ExpiryDate (MHD)
|
||||
│ └── QualityStatus (ACCEPTED | REJECTED | PENDING_INSPECTION)
|
||||
├── QualityInspectionId - Reference to Quality BC
|
||||
├── Documents[] (Entity) - Photos/PDFs
|
||||
└── Status (PENDING_INSPECTION | ACCEPTED | REJECTED)
|
||||
|
||||
Invariants:
|
||||
- Cannot accept without completed quality inspection
|
||||
- All items must have SupplierBatchNumber
|
||||
- Veterinary certificate required for meat
|
||||
- Triggers StockMovement when accepted
|
||||
```
|
||||
|
||||
### DemandPlan (Aggregate Root)
|
||||
|
||||
```
|
||||
DemandPlan
|
||||
├── DemandPlanId
|
||||
├── PlanningPeriod (Week or Month)
|
||||
├── BranchId
|
||||
├── GeneratedAt
|
||||
├── Items[] (Entity)
|
||||
│ ├── ArticleId
|
||||
│ ├── CurrentStock - Snapshot from Inventory
|
||||
│ ├── PlannedConsumption - From ProductionOrders
|
||||
│ ├── AverageConsumption - Historical
|
||||
│ ├── SuggestedOrderQuantity - Calculated
|
||||
│ └── MinimumOrderQuantity - Supplier constraint
|
||||
└── Status (DRAFT | APPROVED | ORDERED)
|
||||
|
||||
Invariants:
|
||||
- SuggestedOrderQuantity = PlannedConsumption - CurrentStock + SafetyStock
|
||||
- If < MinimumOrderQuantity, use MinimumOrderQuantity
|
||||
```
|
||||
80
docs/mvp/ddd/09-filiales-bc.md
Normal file
80
docs/mvp/ddd/09-filiales-bc.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Filiales BC - Detailliertes Domain Model
|
||||
|
||||
**Bounded Context:** Filiales
|
||||
**Domain Type:** CORE
|
||||
**Verantwortung:** Mehrfilialen-Management, Interfilial-Transfers, zentrale Produktion
|
||||
|
||||
## Aggregates
|
||||
|
||||
### Branch (Aggregate Root)
|
||||
|
||||
```
|
||||
Branch
|
||||
├── BranchId
|
||||
├── BranchName
|
||||
├── BranchType (PRODUCTION_AND_SALES | SALES_ONLY | PRODUCTION_ONLY)
|
||||
├── Address
|
||||
├── OpeningHours
|
||||
├── Status (ACTIVE | INACTIVE | CLOSED)
|
||||
├── Manager (UserId)
|
||||
├── ContactInfo
|
||||
├── Capabilities
|
||||
│ ├── CanProduce (boolean)
|
||||
│ ├── CanSell (boolean)
|
||||
│ └── CanReceiveGoods (boolean)
|
||||
└── AssignedEmployees[] (UserId)
|
||||
|
||||
Invariants:
|
||||
- BranchType must match Capabilities
|
||||
- Manager must be in AssignedEmployees
|
||||
- Cannot close with pending production orders
|
||||
```
|
||||
|
||||
### InterBranchTransfer (Aggregate Root)
|
||||
|
||||
```
|
||||
InterBranchTransfer
|
||||
├── TransferId
|
||||
├── FromBranch (BranchId)
|
||||
├── ToBranch (BranchId)
|
||||
├── TransferDate
|
||||
├── RequestedBy (UserId)
|
||||
├── Status (REQUESTED | APPROVED | IN_TRANSIT | RECEIVED | CANCELLED)
|
||||
├── Items[] (Entity)
|
||||
│ ├── ArticleId
|
||||
│ ├── BatchId - CRITICAL for traceability!
|
||||
│ ├── Quantity
|
||||
│ ├── ExpiryDate
|
||||
│ └── ReceivedQuantity
|
||||
├── ShippedAt
|
||||
├── ReceivedAt
|
||||
└── TransportDocumentId
|
||||
|
||||
Invariants:
|
||||
- FromBranch != ToBranch
|
||||
- Status: REQUESTED → APPROVED → IN_TRANSIT → RECEIVED
|
||||
- ShippedAt < ReceivedAt
|
||||
- Triggers two StockMovements (out + in)
|
||||
```
|
||||
|
||||
### DistributionPlan (Aggregate Root)
|
||||
|
||||
```
|
||||
DistributionPlan
|
||||
├── DistributionPlanId
|
||||
├── ProductionBatchId - From Production BC
|
||||
├── ProducingBranch (BranchId)
|
||||
├── PlannedFor (Date)
|
||||
├── Status (PLANNED | IN_DISTRIBUTION | COMPLETED)
|
||||
├── Distributions[] (Entity)
|
||||
│ ├── TargetBranch (BranchId)
|
||||
│ ├── AllocatedQuantity
|
||||
│ ├── TransferId - Link to InterBranchTransfer
|
||||
│ └── DeliveryStatus (PENDING | SHIPPED | DELIVERED)
|
||||
├── TotalQuantityProduced
|
||||
└── RemainingAtCentral
|
||||
|
||||
Invariants:
|
||||
- SUM(AllocatedQuantity) + RemainingAtCentral = TotalQuantityProduced
|
||||
- ProducingBranch must be PRODUCTION_ONLY or PRODUCTION_AND_SALES
|
||||
```
|
||||
111
docs/mvp/ddd/10-supporting-bcs.md
Normal file
111
docs/mvp/ddd/10-supporting-bcs.md
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# Supporting BCs - Übersicht
|
||||
|
||||
**Domain Type:** SUPPORTING
|
||||
**DDD-Aufwand:** Vereinfacht (weniger Komplexität als Core)
|
||||
|
||||
---
|
||||
|
||||
## Master Data BC
|
||||
|
||||
### Article (Aggregate Root)
|
||||
|
||||
```
|
||||
Article
|
||||
├── ArticleId
|
||||
├── ArticleName
|
||||
├── ArticleNumber (SKU)
|
||||
├── Category (ProductCategory)
|
||||
├── SalesUnits[] (Entity)
|
||||
│ ├── Unit (PIECE_FIXED | KG | 100G | PIECE_VARIABLE)
|
||||
│ ├── PriceModel (FIXED | WEIGHT_BASED)
|
||||
│ └── Price (Money)
|
||||
├── Status (ACTIVE | INACTIVE)
|
||||
└── Supplier References[]
|
||||
```
|
||||
|
||||
### Supplier (Aggregate Root)
|
||||
|
||||
```
|
||||
Supplier
|
||||
├── SupplierId
|
||||
├── Name
|
||||
├── Address
|
||||
├── PaymentTerms
|
||||
├── QualityCertificates[]
|
||||
└── Rating (Quality, Delivery, Price)
|
||||
```
|
||||
|
||||
### Customer (Aggregate Root)
|
||||
|
||||
```
|
||||
Customer
|
||||
├── CustomerId
|
||||
├── CustomerType (B2C | B2B)
|
||||
├── Name
|
||||
├── DeliveryAddresses[]
|
||||
├── FrameContract (optional)
|
||||
└── Preferences (Bio, Regional, etc.)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Sales BC
|
||||
|
||||
### Order (Aggregate Root)
|
||||
|
||||
```
|
||||
Order
|
||||
├── OrderId
|
||||
├── OrderType (PRE_ORDER | B2B_ORDER | WALK_IN)
|
||||
├── CustomerId
|
||||
├── OrderDate
|
||||
├── DeliveryDate
|
||||
├── Items[]
|
||||
└── Status (OPEN | CONFIRMED | FULFILLED)
|
||||
```
|
||||
|
||||
### Invoice (Aggregate Root)
|
||||
|
||||
```
|
||||
Invoice
|
||||
├── InvoiceId
|
||||
├── OrderId
|
||||
├── InvoiceDate
|
||||
├── Items[]
|
||||
├── TotalAmount
|
||||
└── PaymentStatus (OPEN | PAID | OVERDUE)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scale Integration BC
|
||||
|
||||
### ScaleSyncJob (Aggregate Root)
|
||||
|
||||
```
|
||||
ScaleSyncJob
|
||||
├── SyncJobId
|
||||
├── ScaleId
|
||||
├── SyncType (ARTICLES | PRICES | LABELS)
|
||||
├── Status (PENDING | IN_PROGRESS | COMPLETED | FAILED)
|
||||
└── SyncedAt
|
||||
```
|
||||
|
||||
### BondDataImport (Aggregate Root)
|
||||
|
||||
```
|
||||
BondDataImport
|
||||
├── ImportId
|
||||
├── ImportDate
|
||||
├── BranchId
|
||||
├── ScaleId
|
||||
├── SalesData[] (Entity)
|
||||
│ ├── ArticleId
|
||||
│ ├── Quantity
|
||||
│ ├── Price
|
||||
│ ├── SoldAt
|
||||
│ └── BatchId (if traceable)
|
||||
└── Status (PENDING | IMPORTED | FAILED)
|
||||
|
||||
Triggers: StockMovement for each sale
|
||||
```
|
||||
180
docs/mvp/ddd/README.md
Normal file
180
docs/mvp/ddd/README.md
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
# DDD Domain Model - Effigenix Fleischerei-ERP
|
||||
|
||||
**Sprache:** Deutsch (für Domain-Experten)
|
||||
**Code:** Englisch (siehe Java Style Guide)
|
||||
**Erstellt:** 2026-02-17
|
||||
**Technologie:** Java 21+ mit DDD + Clean Architecture
|
||||
|
||||
---
|
||||
|
||||
## 📚 Dokumentationsstruktur
|
||||
|
||||
### Übersichtsdokumente
|
||||
|
||||
| Dokument | Beschreibung |
|
||||
|----------|--------------|
|
||||
| `00-overview.md` | Gesamtüberblick, DDD-Phasen, Projektziele |
|
||||
| `01-domain-classification.md` | Core/Supporting/Generic Klassifizierung mit Begründungen |
|
||||
| `02-bounded-contexts.md` | **Context Map** (Mermaid) + Kontextbeziehungen |
|
||||
| `03-ubiquitous-language.md` | Glossar DE/EN für alle Bounded Contexts |
|
||||
|
||||
### Kern-Domäne (Core) - 7 Kontexte
|
||||
|
||||
| Dokument | Bounded Context | Aggregates |
|
||||
|----------|-----------------|------------|
|
||||
| `04-produktions-kontext.md` | **Produktion** | Rezept, Charge, Produktionsauftrag |
|
||||
| `05-qualitaets-kontext.md` | **Qualität (HACCP/QM)** | Temperaturprotokoll, Reinigungsnachweis, Wareneingangsprüfung, Schulungsnachweis, Wartungsprotokoll |
|
||||
| `06-labeling-bc.md` | **Deklaration** | Produktetikett, Allergene-Matrix |
|
||||
| `07-bestandsfuehrungs-kontext.md` | **Bestandsführung** | Bestand, Bestandsbewegung |
|
||||
| `08-procurement-bc.md` | **Beschaffung** | Bestellung, Wareneingang, Bedarfsplan |
|
||||
| `09-filiales-bc.md` | **Filialen** | Filiale, Interfilial-Transfer, Verteilungsplan |
|
||||
|
||||
### Unterstützende Domäne (Supporting) - 3 Kontexte
|
||||
|
||||
| Dokument | Bounded Context | Aggregates |
|
||||
|----------|-----------------|------------|
|
||||
| `10-supporting-bcs.md` | **Stammdaten** | Artikel, Lieferant, Kunde |
|
||||
| `10-supporting-bcs.md` | **Verkauf** | Auftrag, Rechnung, Lieferschein |
|
||||
| `10-supporting-bcs.md` | **Waagen-Integration** | Synchronisations-Job, Bondaten-Import |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Verwendung für Domain-Experten
|
||||
|
||||
### Für Besprechungen mit Fleischerei-Experten
|
||||
|
||||
**Diese Dokumente verwenden deutsche Begriffe**, um die Kommunikation zu erleichtern:
|
||||
|
||||
- ✅ **Rezept** statt Recipe
|
||||
- ✅ **Charge** statt Batch
|
||||
- ✅ **Wareneingang** statt Goods Receipt
|
||||
- ✅ **Rückverfolgbarkeit** statt Traceability
|
||||
|
||||
**Im Code werden englische Begriffe verwendet** (siehe `03-ubiquitous-language.md`):
|
||||
|
||||
```java
|
||||
// Dokumentation: Rezept
|
||||
// Code: Recipe
|
||||
public class Recipe { ... }
|
||||
|
||||
// Dokumentation: Charge
|
||||
// Code: Batch
|
||||
public class Batch { ... }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Wichtige Konzepte
|
||||
|
||||
### 1. Aggregate
|
||||
|
||||
Ein **Aggregat** ist eine Gruppe von Objekten, die immer konsistent zusammen geändert werden müssen.
|
||||
|
||||
**Beispiel: Rezept-Aggregat**
|
||||
```
|
||||
Rezept (Aggregate Root)
|
||||
├── RezeptId
|
||||
├── Name
|
||||
├── Zutaten[] (Teil des Aggregats)
|
||||
├── Produktionsschritte[] (Teil des Aggregats)
|
||||
└── Status
|
||||
```
|
||||
|
||||
- **Aggregate Root** = Einstiegspunkt (nur Rezept ist von außen zugänglich)
|
||||
- **Invarianten** = Regeln, die IMMER gelten müssen (z.B. "Rezept muss mind. 1 Zutat haben")
|
||||
- **Transaktionsgrenze** = Ein Rezept = eine Datenbanktransaktion
|
||||
|
||||
### 2. Wertobjekte (Value Objects)
|
||||
|
||||
**Unveränderliche Objekte**, die nur durch ihre Werte definiert sind.
|
||||
|
||||
**Beispiel:**
|
||||
```java
|
||||
// Zwei Geldbeträge mit gleichen Werten sind identisch
|
||||
Money betrag1 = Money.of(100, "EUR");
|
||||
Money betrag2 = Money.of(100, "EUR");
|
||||
// betrag1.equals(betrag2) = true
|
||||
|
||||
// Im Gegensatz zu Entities (haben ID)
|
||||
Charge charge1 = Charge.of(ChargenId.of("CHARGE-001"), ...);
|
||||
Charge charge2 = Charge.of(ChargenId.of("CHARGE-002"), ...);
|
||||
// charge1.equals(charge2) = false (verschiedene IDs)
|
||||
```
|
||||
|
||||
### 3. Rückverfolgbarkeit (Traceability)
|
||||
|
||||
**KRITISCH für Fleischerei-Betriebe!**
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Lieferanten-Charge<br/>SUPPLIER-12345] -->|verwendet in| B[Produktions-Charge<br/>BATCH-2026-02-17-001]
|
||||
B -->|verkauft als| C[Rechnung<br/>INV-2026-02-20-042]
|
||||
C -->|an| D[Kunde<br/>CUST-123]
|
||||
|
||||
style A fill:#ffe6e6
|
||||
style B fill:#e6f3ff
|
||||
style C fill:#e6ffe6
|
||||
style D fill:#fff9e6
|
||||
```
|
||||
|
||||
**Bei Rückruf:**
|
||||
1. Finde alle Produktionschargen mit betroffener Lieferanten-Charge
|
||||
2. Finde alle Verkäufe dieser Produktionschargen
|
||||
3. Informiere betroffene Kunden
|
||||
|
||||
**Code:** Siehe `07-bestandsfuehrungs-kontext.md` - Rückverfolgbarkeits-Beispiel
|
||||
|
||||
---
|
||||
|
||||
## 📊 Context Map
|
||||
|
||||
Die **Context Map** zeigt, wie die verschiedenen Bounded Contexts zusammenarbeiten:
|
||||
|
||||
**Siehe:** `02-bounded-contexts.md`
|
||||
|
||||
**Kernaussagen:**
|
||||
- **Produktion** liefert Rezeptdaten an **Deklaration** (für Nährwertberechnung)
|
||||
- **Produktion** verbraucht/produziert in **Bestandsführung**
|
||||
- **Qualität** prüft **Wareneingang** (aus Beschaffung)
|
||||
- **Bestandsführung** ist zentral - alle schreiben/lesen dort
|
||||
|
||||
---
|
||||
|
||||
## ✅ Validierung mit Domain-Experten
|
||||
|
||||
### Checkliste für Review-Meetings
|
||||
|
||||
**Vorbereitung:**
|
||||
1. Relevanten Bounded Context öffnen (z.B. `04-produktions-kontext.md`)
|
||||
2. Aggregate-Struktur durchgehen
|
||||
3. Invarianten besprechen
|
||||
|
||||
**Fragen an Experten:**
|
||||
- ✅ Sind alle Zutaten erfasst, die in einem Rezept sein können?
|
||||
- ✅ Gibt es weitere Produktionsschritte, die dokumentiert werden müssen?
|
||||
- ✅ Welche Grenzwerte gelten für Temperaturprotokolle?
|
||||
- ✅ Welche Dokumente sind bei Wareneingang Pflicht?
|
||||
- ✅ Wie läuft ein Interfilial-Transfer praktisch ab?
|
||||
|
||||
**Ergebnis:**
|
||||
- Dokumentation anpassen basierend auf Feedback
|
||||
- Neue Invarianten hinzufügen
|
||||
- Fehlende Aggregate/Entities ergänzen
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Nächste Schritte
|
||||
|
||||
1. ✅ **Phase 0-3 abgeschlossen** - Bounded Contexts & Aggregates modelliert
|
||||
2. ⏳ **Phase 4: Invarianten** - Detaillierte Geschäftsregeln pro Aggregat
|
||||
3. ⏳ **Phase 5: Code-Generierung** - Java 21+ Code aus Modellen
|
||||
4. ⏳ **Phase 6: Validierung** - DDD-Rules-Checklist
|
||||
|
||||
---
|
||||
|
||||
## 📞 Kontakt
|
||||
|
||||
**Für Rückfragen zum Domain Model:**
|
||||
- Dokumentation: `docs/mvp/ddd/`
|
||||
- Code-Beispiele: `.claude/skills/ddd-model/languages/java/templates/`
|
||||
- DDD-Regeln: `.claude/skills/ddd-model/rules/ddd-rules.md`
|
||||
Loading…
Add table
Add a link
Reference in a new issue