1
0
Fork 0
mirror of https://github.com/s-frick/effigenix.git synced 2026-03-28 17:04:49 +01:00
Commit graph

28 commits

Author SHA1 Message Date
Sebastian Frick
a9f5956812 feat(production): Produktion starten und Rohstoffverbrauch dokumentieren (StartBatch, RecordConsumption)
PLANNED-Chargen können in Produktion genommen werden (IN_PRODUCTION),
anschließend wird der Rohstoff-Verbrauch pro InputBatch dokumentiert.
Bildet die Grundlage für die Chargen-Genealogie (Tracing).
2026-02-20 16:52:33 +01:00
Sebastian Frick
e8cbb948b7 feat(inventory): Bestandsparameter ändern (MinimumLevel, MinimumShelfLife)
Stock.update(StockUpdateDraft) ermöglicht optionale Aktualisierung von
MinimumLevel und MinimumShelfLife mit identischer Validierung wie create().
PUT /api/inventory/stocks/{id} Endpoint, UpdateStock Use Case + Tests.

Closes #9
2026-02-20 16:39:02 +01:00
Sebastian Frick
1c65ac7795 feat(production): Chargen abfragen und suchen (GetBatch, ListBatches, FindBatchByNumber)
Full Vertical Slice für Batch-Lese-Endpoints:
- GET /api/production/batches/{id}
- GET /api/production/batches (Filter: status, productionDate, articleId)
- GET /api/production/batches/by-number/{batchNumber}

articleId-Filter löst über RecipeRepository.findByArticleId() die
zugehörigen Recipes auf und sucht dann Batches per findByRecipeIds().

Closes #34
2026-02-20 09:22:25 +01:00
Sebastian Frick
fef3baa0ae refactor(inventory): InvalidFilterCombination Error und CreateStockResponse trennen
- StockError.InvalidFilterCombination statt InvalidArticleId für
  ungültige Filter-Kombination in ListStocks
- CreateStockResponse als eigenständiges DTO für POST createStock
  (ohne batches/quantities), StockResponse bleibt für GET-Endpoints
- MinimumLevelResponse als shared Top-Level-Record extrahiert
2026-02-20 09:13:56 +01:00
Sebastian Frick
1ef37497c3 feat(inventory): GET-Endpoints für Bestandsposition und Chargen abfragen
Query-Endpoints für Stock-Aggregate: GET /api/inventory/stocks (mit
optionalen Filtern storageLocationId/articleId) und GET /api/inventory/stocks/{id}.
StockResponse enthält nun Batches, totalQuantity, availableQuantity und
quantityUnit. Abgesichert über @PreAuthorize STOCK_READ.
2026-02-20 09:13:56 +01:00
Sebastian Frick
6c1e6c24bc feat(production): articleId für Rezepte, TUI-Verbesserungen mit UoM-Carousel, ArticlePicker und Zutaten-Reorder
Backend:
- articleId als Pflichtfeld im Recipe-Aggregate (Domain, Application, Infrastructure)
- Liquibase-Migration 015 mit defaultValue für bestehende Daten
- Alle Tests angepasst (Unit, Integration)

Frontend:
- UoM-Carousel-Selektor in RecipeCreateScreen, AddBatchScreen, AddIngredientScreen
- ArticlePicker-Komponente mit Typeahead-Suche für Artikelauswahl
- Auto-Position bei Zutatenzugabe (kein manuelles Feld mehr)
- Automatische subRecipeId-Erkennung bei Artikelauswahl
- Zutaten-Reorder per Drag im RecipeDetailScreen (Remove + Re-Add)
- Artikelnamen statt UUIDs in der Rezept-Detailansicht
- Navigation-Context: replace()-Methode ergänzt
2026-02-20 01:15:34 +01:00
Sebastian Frick
b46495e1aa refactor: OffsetDateTime-Migration, atomare Batch-Sequenznummern und Quantity.reconstitute-Overload
- LocalDateTime → OffsetDateTime (UTC) in allen Domain-Klassen, JPA Entities, DTOs und Tests
- Liquibase-Migration 017: TIMESTAMP → TIMESTAMP WITH TIME ZONE für bestehende Spalten
- Custom DateTimeProvider für Spring Data @CreatedDate-Kompatibilität mit OffsetDateTime
- Neue Sequenztabelle (016) mit JPA Entity + PESSIMISTIC_WRITE Lock statt COUNT-basierter
  Batch-Nummernvergabe (Race Condition Fix)
- Quantity.reconstitute(amount, uom) 2-Parameter-Overload für bessere Lesbarkeit
2026-02-20 00:41:11 +01:00
Sebastian Frick
b06157b92c feat(production): Charge planen (PlanBatch) (#33)
Batch-Aggregat mit plan()-Factory, automatischer BatchNumber-Generierung
(P-YYYY-MM-DD-XXX) und Validierung (Quantity > 0, bestBeforeDate > productionDate).
Full Vertical Slice: Domain, Application, Infrastructure (JPA, REST, Liquibase).
2026-02-20 00:41:11 +01:00
Sebastian Frick
d963d7fccc fix(inventory): Audit-Logging, testbare Zeitlogik und defensive Null-Prüfung für blockBatch/unblockBatch
- AuditEvents STOCK_BATCH_BLOCKED/UNBLOCKED hinzugefügt, reason wird als Audit-Details geloggt
- LocalDate.now() aus Stock.unblockBatch() entfernt, referenceDate als Parameter (Application Layer übergibt)
- Defensive Null-Prüfung für expiryDate in unblockBatch MHD-Check
- Ticket 003 erstellt zur Klärung ob reason im Domain-Model persistiert werden soll
2026-02-20 00:17:03 +01:00
Sebastian Frick
e7c3258f07 feat(inventory): Charge sperren/entsperren (blockBatch/unblockBatch) (#7)
Gesperrte Chargen können nicht entnommen oder reserviert werden.
blockBatch: AVAILABLE/EXPIRING_SOON → BLOCKED; unblockBatch: BLOCKED → AVAILABLE/EXPIRING_SOON (MHD-Check).
2026-02-19 23:46:34 +01:00
Sebastian Frick
8a9d2bfc30 feat(production): Zyklus-Erkennung bei verschachtelten Rezepten (#32)
Verhindert zirkuläre Abhängigkeiten (A→B→A, A→B→C→A) beim Hinzufügen
von Sub-Rezepten als Zutaten. Iterative DFS-Prüfung mit Pfad-Tracking
für aussagekräftige Fehlermeldungen.
2026-02-19 23:00:22 +01:00
Sebastian Frick
05147227d1 feat(inventory): Charge entnehmen (removeBatch) (#6) 2026-02-19 22:55:12 +01:00
Sebastian Frick
f2003a3093 feat(production): Rezepte abfragen per ID und nach Status filtern (#31)
GET /api/recipes/{id} liefert vollständiges Rezept inkl. Zutaten und Schritte.
GET /api/recipes?status=ACTIVE liefert Summary-Liste mit ingredientCount/stepCount.
2026-02-19 22:30:55 +01:00
Sebastian Frick
6feb3a9f1c feat(inventory): Charge einbuchen (addBatch) (#5)
StockBatch als Child-Entity im Stock-Aggregat mit BatchReference
(batchId + batchType), Quantity, ExpiryDate und Status AVAILABLE.
POST /api/inventory/stocks/{stockId}/batches → 201.
2026-02-19 22:28:48 +01:00
Sebastian Frick
1e12353b9b test(production): Tests für ActivateRecipe und ArchiveRecipe Use Cases
Domain-Tests für archive() in RecipeTest, Application-Layer-Tests
für beide Use Cases mit Mockito (Auth, NotFound, Statusübergänge).
2026-02-19 22:01:10 +01:00
Sebastian Frick
7b1c114693 refactor(test): gemeinsame AbstractIntegrationTest Base-Class
Alle 9 Integration-Test-Klassen nutzen eine gemeinsame Base-Class mit
geteiltem Spring Context (MOCK statt RANDOM_PORT), vorberechnetem
BCrypt-Hash und gemeinsamen Helper-Methoden. Eliminiert ~600 Zeilen
Duplikation und Runtime-BCrypt-Aufrufe im Test-Setup.
2026-02-19 21:37:47 +01:00
Sebastian Frick
5219c93dd1 feat(inventory): Bestandsposition anlegen (#4)
Stock-Aggregate mit MinimumLevel, MinimumShelfLife und StockDraft.
Quantity/UnitOfMeasure nach shared.common verschoben für BC-übergreifende
Nutzung. REST-Endpoint POST /api/inventory/stocks mit Duplikat-Prüfung,
Validierung und Liquibase-Migration.
2026-02-19 21:37:47 +01:00
Sebastian Frick
a132211a74 feat(production): Rezept aktivieren (#29)
Rezepte können vom DRAFT- in den ACTIVE-Status überführt werden.
Voraussetzung: mindestens eine Zutat muss vorhanden sein.
Inkl. Use Case, REST-Endpoint POST /recipes/{id}/activate,
Domain-Tests und Error Handling.
2026-02-19 21:24:39 +01:00
Sebastian Frick
cf93b847e5 feat(production): Produktionsschritte zum Rezept verwalten + AuthorizationPort
Erweitert das Recipe-Aggregate um ProductionStep-Child-Entities (Add/Remove)
mit vollständiger DDD-Konformität. Führt AuthorizationPort-Prüfung in allen
Production Use Cases ein (analog zum usermanagement-Referenz-BC).

Fixes: Request-Validierung (Size, Min/Max), Error-Code-Konsistenz,
Defense-in-Depth für durationMinutes und temperatureCelsius.
2026-02-19 17:37:18 +01:00
Sebastian Frick
bee3f28b5f feat(production): Zutaten zum Rezept verwalten (#27)
Ingredient als Child Entity des Recipe Aggregates implementiert.
Folgt dem Article → SalesUnit Pattern als Full Vertical Slice.

Domain: IngredientId, Ingredient, IngredientDraft, Recipe.addIngredient/removeIngredient
Application: AddRecipeIngredient, RemoveRecipeIngredient Use Cases
Infrastructure: IngredientEntity (JPA), REST-Endpoints (POST/DELETE), Liquibase Migration
Tests: RecipeTest (9 neue), IngredientTest (11 Tests)
2026-02-19 12:53:11 +01:00
Sebastian Frick
6010820944 feat(inventory): Lagerorte abfragen mit Filter nach Typ und Status (#3)
Query UseCase: ListStorageLocations mit optionalen Filtern storageType und active
GET /api/inventory/storage-locations mit STOCK_READ oder STOCK_WRITE
Tests: 10 neue Integrationstests (35 gesamt)
2026-02-19 12:42:25 +01:00
Sebastian Frick
9b9b7311d1 feat(production): Recipe Aggregate als Full Vertical Slice (#26)
Domain: Recipe Aggregate Root mit create(RecipeDraft), RecipeId, RecipeName,
RecipeType, RecipeStatus, RecipeError, RecipeRepository Interface.
Application: CreateRecipe Use Case mit Name+Version Uniqueness-Check.
Infrastructure: JPA Entity/Mapper/Repository, REST POST /api/recipes,
Liquibase Migration, ProductionErrorHttpStatusMapper, Spring Config.
Tests: 15 Unit Tests für Recipe Aggregate (75 total im Production BC).
2026-02-19 10:12:48 +01:00
Sebastian Frick
24a6869faf feat(inventory): StorageLocation bearbeiten und (de-)aktivieren (#2)
Use Cases: UpdateStorageLocation, DeactivateStorageLocation, ActivateStorageLocation
Endpoints: PUT /{id}, PATCH /{id}/deactivate, PATCH /{id}/activate
Repository: existsByNameAndIdNot für Uniqueness-Check bei Update
Tests: 14 neue Integrationstests (25 gesamt)
2026-02-19 10:12:25 +01:00
Sebastian Frick
05878b1ce9 refactor(usermanagement): implement code review findings for User Management BC
Address all 18 findings from security code review (5 critical, 7 medium, 6 low):

Domain: make User and Role immutable with wither-pattern, add status transition
guards (ACTIVE->LOCKED, LOCKED->ACTIVE, ACTIVE|LOCKED->INACTIVE, INACTIVE->ACTIVE)

Application: enforce authorization via AuthorizationPort in all use cases, add
input validation, introduce LockUserCommand/UnlockUserCommand/RemoveRoleCommand,
fix audit event on password change failure (K5), use flatMap/mapError chains

Infrastructure: JWT blacklist with TTL and scheduled cleanup, login rate limiting
(5 attempts/15min), configurable CORS, generic error messages, conditional Swagger,
seed data context restriction

Tests: unit tests for all 10 use cases, adapted domain and integration tests
2026-02-19 10:11:51 +01:00
Sebastian Frick
a1161cfbad feat(production): Quantity VO mit Catch-Weight, YieldPercentage und BatchNumber
Shared Value Objects für den Production BC implementiert (#25):
- Quantity mit Dual-Quantity/Catch-Weight Support und Arithmetik
- UnitOfMeasure Enum (kg, g, L, mL, pc, m)
- YieldPercentage (1-200) mit calculateRequiredInput()
- BatchNumber mit Format P-YYYY-MM-DD-XXX
- QuantityError sealed interface für funktionales Error Handling
- 60 Unit Tests für alle VOs
2026-02-19 09:53:56 +01:00
Sebastian Frick
c474388f32 feat(inventory): StorageLocation Aggregate implementieren (#1)
Vertikaler Slice für Story 1.1 – Lagerort anlegen:

Domain: StorageLocation Aggregate mit VOs (StorageLocationId, StorageLocationName,
StorageType, TemperatureRange), StorageLocationError (sealed interface),
Draft-Records und Repository Interface.

Application: CreateStorageLocation UseCase mit Uniqueness-Check.

Infrastructure: JPA Entity, Mapper, Repository, REST Controller
(POST /api/inventory/storage-locations), Liquibase Migration (009),
InventoryErrorHttpStatusMapper, InventoryUseCaseConfiguration.

Tests: 28 Domain-Unit-Tests, 11 Integration-Tests.

Closes #1
2026-02-19 09:51:48 +01:00
Sebastian Frick
2ace5be394 test(masterdata): Integrationstests für alle vier Masterdata-Aggregate
70 MockMvc-Integrationstests für ProductCategory, Supplier, Article
und Customer Controller. Abgedeckte Szenarien: Happy Paths, Validierung
(400), Duplikate (409), Not Found (404), Autorisierung (403/401) sowie
aggregate-spezifische Operationen (Zertifikate, Bewertungen, Verkaufs-
einheiten, Lieferadressen, Präferenzen, Rahmenverträge).

Außerdem: Manuelle Testfallbeschreibung unter backend/docs/MASTERDATA_MANUAL_TESTS.md
2026-02-19 00:33:52 +01:00
Sebastian Frick
c2c48a03e8 refactor: restructure repository with separate backend and frontend directories
- Move Java backend to backend/ directory
- Create frontend/ directory for TypeScript TUI and future WebUI
- Update .gitignore for Node.js and worktrees
- Update README.md with new repository structure
- Copy documentation to backend/
2026-02-17 22:08:51 +01:00