Scanner-App Tauri v2 Android App mit
Login, Barcode-Scanner, Consume/Move/Book-Flows und Aufgabenliste.
TasksPage lädt echte RELEASED/IN_PROGRESS Produktionsaufträge via API,
Consume-Flow nutzt den konkreten Auftrag für korrekte Rezept-Skalierung
statt blind den ersten IN_PROGRESS-Auftrag zu nehmen.
Backend: FindStockByBatchId Use Case + REST-Endpoint für Stock-Lookup
per Chargennummer.
Einheitliches Paginierungs-Pattern mit page, size und Multi-Field sort
für alle 14 List-Endpoints. Response-Format ändert sich von [...] zu
{ content: [...], page: { number, size, totalElements, totalPages } }.
Backend:
- Shared Kernel: Page<T>, PageRequest, SortField, SortDirection
- PaginationHelper (SQL ORDER BY mit Whitelist), PageResponse DTO
- Paginated Methoden in allen 14 Domain-Repos + JDBC-Implementierungen
- Safety-Limit (500) für findAllBelowMinimumLevel/ExpiryRelevantBatches
- Alle List-Use-Cases akzeptieren PageRequest, liefern Page<T>
- Alle Controller mit page/size/sort Query-Params + PageResponse
Frontend:
- PagedResponse<T> Type auf nested page-Format aktualisiert
- Alle 14 API-Client-Resourcen liefern PagedResponse mit PaginationParams
- Alle Hooks mit Pagination-State (currentPage, totalPages, pageSize)
- Alle List-Screens mit Seiten-Navigation (Pfeiltasten) und Footer
Loadtest:
- Podman-Support im justfile (DOCKER_HOST auto-detect)
- Verschärfte Performance-Schwellwerte basierend auf Ist-Werten
Stock.uniformUnitOfMeasure() gibt die UoM nur zurück wenn alle Chargen
dieselbe Einheit haben, sonst Optional.empty(). StockResponse nutzt
diese Methode statt blind die erste Charge zu nehmen.
RecordConsumption publiziert ConsumptionRecorded-Event, das über
ConsumptionRecordedInventoryListener den BookProductionConsumption
Use Case triggert – Bestandsabzug und PRODUCTION_CONSUMPTION
StockMovement werden automatisch verbucht.
Event-Infrastruktur (DomainEvent, DomainEventPublisher) im Shared Kernel
eingeführt. CompleteBatch publiziert BatchCompleted-Event mit articleId aus
Recipe. ProductionDomainEventPublisher konvertiert in IntegrationEvent,
BatchCompletedInventoryListener bucht automatisch StockBatch (PRODUCED) +
StockMovement (PRODUCTION_OUTPUT) am PRODUCTION_AREA-Lagerort ein.
TUI RecordConsumptionScreen: Rezeptbasierte Zutatenauswahl mit skalierten
Soll-Mengen, Stock-Batch-Picker und Mengen-Vorbelegung.
unsafeGet-Aufrufe in allen 4 Inventory-Controllern und ListStorageLocations
durch typsicheres switch Pattern-Matching auf Result<E,T> ersetzt.
Neuer SharedKernel-Port UserLookupPort ermöglicht cross-BC Auflösung
von User-IDs zu Usernames (z.B. für initiatedBy/completedBy in
InventoryCountResponse).
Vier-Augen-Prinzip (completedBy ≠ initiatedBy), Vollständigkeitsprüfung
aller CountItems, und automatische ADJUSTMENT-StockMovements für
Abweichungen (IN bei Ist > Soll, OUT bei Ist < Soll).
Domain: complete()-Methode, InventoryCountReconciliationService
Application: CompleteInventoryCount UseCase
Infrastruktur: POST /{id}/complete Endpoint, Liquibase-Migration
Closes#19
Spiegelt die bestehende traceForward-Architektur mit invertierter
SQL-JOIN-Richtung, um von einer Endprodukt-Charge alle verwendeten
Rohstoff-Chargen zu ermitteln (Herkunftsnachweis).
Implementiert startCounting() und updateCountItem() auf dem InventoryCount-
Aggregate, zwei neue Use Cases (StartInventoryCount, RecordCountItem) mit
zugehörigen Controller-Endpoints (PATCH /{id}/start, PATCH /{id}/items/{itemId}).
Inkl. Domain-, Application-, Integrations- und Gatling-Lasttests.
stock_movements hat einen FK auf stock_batches mit RESTRICT, daher
schlug das bisherige Delete-All + Re-Insert Pattern fehl sobald
Bestandsbewegungen existierten (HTTP 500 bei Reservierung).
Lösung: Upsert-Pattern (UPDATE bestehende, INSERT neue, DELETE entfernte).
traceForward aus BatchTraceabilityService in BatchRepository verschoben.
Statt einer Query pro Knoten (N+1) wird jetzt eine IN(:parentIds)-Query
pro Tiefenebene ausgeführt (max. maxDepth Queries statt N).
BFS-Traversierung über Chargen-Genealogie (batch_consumptions.input_batch_id)
mit Cycle-Detection und Max-Depth-Guard. REST-Endpoint GET /{id}/trace-forward
liefert flache Liste mit Tiefenangabe für betroffene Endprodukt-Chargen.
- GlobalExceptionHandler und ErrorResponse nach infrastructure.shared
extrahieren (war fälschlich in usermanagement)
- CountItem.deviation() prüft UOM-Kompatibilität
- InvalidInventoryCountId Error-Typ für null/blank ID (400 statt 404)
- saveChildren() auf UPSERT (UPDATE→INSERT) mit Orphan-Cleanup umstellen
- logger.trace → logger.warn bei DB-Fehlern
- Stocks ohne Batches in CreateInventoryCount überspringen
- AuthorizationPort Defense in Depth in alle 3 InventoryCount Use Cases
- Kombinierter DB-Index auf (storage_location_id, status)
InventoryCount-Aggregate mit CountItem-Entities, Auto-Populate aus
Stock-Daten, vollständige DDD-Schichten inkl. Edge-Case-Tests und
Jazzer-Fuzz-Test. 1909 Tests grün.
- BatchNumber in allen ProductionOrder-Endpoints via BatchRepository auflösen
- BatchCreationFailed Error-Variante statt generischem ValidationFailure
- bestBeforeDate-Berechnung als Recipe.calculateBestBeforeDate() in die Domain verschoben
TUI-Anbindung für Reservierung bestätigen (US-4.3), Produktionsauftrag
umterminieren und filtern (US-P17). Status-Werte CREATED→PLANNED und
IN_PRODUCTION→IN_PROGRESS korrigiert. Fehlenden GET /{id} Endpoint für
Produktionsaufträge im Backend ergänzt.
Coverage-guided Fuzz-Tests für ProductionOrder, Recipe und Batch.
Jeder Test fuzzt create() + zufällige Sequenzen aller Mutations-Methoden,
um unbehandelte Exceptions bei beliebigen Inputs aufzudecken.
- jazzer-junit 0.24.0 als Test-Dependency
- Maven-Profile: -Pfuzz (echtes Fuzzing), -Pfuzz-regression (Crash-Replay)
- Surefire: FuzzTests im Default-Lauf ausgeschlossen, reuseForks=false
- Makefile: make fuzz, make fuzz/regression, make fuzz/single
- .gitignore: .cifuzz-corpus/ ausgeschlossen
- MovementType-Ableitung via ReferenceType.toMovementType() in Domain Layer
- Doppelten Batch-Lookup in Stock.confirmReservation() eliminiert
- StockError.MovementCreationFailed statt RepositoryFailure für Domain-Fehler
- 204 No Content statt 200 OK (konsistent mit releaseReservation)
- Batches mit Menge 0 nicht mehr entfernen (FK stock_movements → stock_batches)
Allokierte Mengen werden physisch aus den Chargen abgezogen,
StockMovements erzeugt und die Reservation entfernt.
MovementType wird aus ReferenceType abgeleitet
(PRODUCTION_ORDER→PRODUCTION_CONSUMPTION, SALE_ORDER→SALE).
RescheduleNotAllowed Error-Typ statt InvalidStatusTransition(status, status),
Null-Guard für newDate, Controller-Parameter als Enum statt String (verhindert
500 bei ungültigem Status), partielle Datumsangaben als 400 ablehnen,
ORDER BY in findAll() konsistent mit gefilterten Queries.
Reschedule (PLANNED/RELEASED) mit Datumsvalidierung und List-Endpoint
mit optionaler Filterung nach Datum/Status als Full Vertical Slice.
Lasttests um neue Szenarien erweitert.
cancel() nimmt jetzt einen reason-Parameter entgegen und speichert ihn
im Aggregat, wie im DDD-Modell (04-production-bc.md) spezifiziert.
Liquibase-Migration für cancelled_reason-Spalte ergänzt.
DatabaseProfileInitializer setzt Autoconfigure-Exclusions programmatisch,
da application-no-db.yml bei spätem Profil-Aktivierung nicht geladen wird.
SpringUnitOfWork mit @Profile("!no-db") ausgeschlossen. Stub-Beans für
BatchNumberGenerator, BatchRepository, ProductionOrderRepository,
StockMovementRepository und UnitOfWork ergänzt. generate-openapi.sh
nutzt korrektes -Dspring-boot.run.profiles=no-db.
- InventoryScenario.recordStockMovement(): HTTP-Request mit doIf
guards, verhindert 'No attribute mvStockId' Fehler
- ProductionScenario.productionWorkflow(): Seeded Batch-/Order-IDs
als Fallback wenn planBatch/createProductionOrder fehlschlägt,
stellt sicher dass startBatch/completeBatch/releaseProductionOrder
immer feuern und Gatling-Assertions Stats sammeln können
PostgreSQL JDBC-Treiber kann java.time.Instant nicht direkt an
TIMESTAMP WITH TIME ZONE binden. Schreibparameter werden nun via
atOffset(UTC) konvertiert, Lesezugriffe über OffsetDateTime.toInstant().
Letzter BC migriert: JPA/Hibernate durch JdbcClient ersetzt,
@Transactional durch UnitOfWork-Pattern in allen schreibenden Use Cases.
- 3 neue Jdbc-Repos: JdbcStorageLocationRepository, JdbcStockMovementRepository,
JdbcStockRepository (4-Tabellen-Aggregat mit Batches, Reservations, Allocations)
- 20 Use Cases angepasst (UoW für schreibende, @Transactional entfernt für lesende)
- 15 alte JPA-Dateien gelöscht (6 Entities, 3 Mapper, 3 Adapter, 3 Spring Data Repos)
- 9 Unit-Tests mit UoW-Mock-Pattern aktualisiert
RoleDTO auf generierten Typ umgestellt, exactOptionalPropertyTypes-Konflikte
gelöst, Null-Checks für nullable AddressResponse ergänzt und Enum-Casts
für string-basierte SalesUnit-Felder hinzugefügt.
- StockMovement: API-Client, Hook, List/Detail/Record-Screens mit Typ-Filter
- ProductionOrder: list/getById/start im API-Client, List/Detail-Screens mit Freigabe- und Start-Aktion
- Inventar-Menü um Bestandsbewegungen erweitert
- Produktionsmenü zeigt jetzt Auftragsliste statt direkt Create
- OpenAPI-Typen regeneriert (StockMovementResponse, StartProductionOrderRequest, batchId in ProductionOrderResponse)
Changeset 031 (performed_at-Index) entfernt, da bereits in 028 enthalten.
StockMovementControllerIntegrationTest an JdbcClient-basierte AbstractIntegrationTest migriert
und fehlende Article-FK durch createArticleId() behoben.
Migriert UserManagement und MasterData BCs von JPA/Spring Data auf
JdbcClient + UnitOfWork, analog zum Production-BC. Inventory bleibt auf JPA.
- 6 neue JdbcClient-Repositories (User, Role, Article, Supplier, Customer, ProductCategory)
- 45 Use Cases: UoW für schreibende, @Transactional entfernt bei allen
- AbstractIntegrationTest + 20 Integration-Tests auf JdbcClient umgestellt
- 12 Unit-Test-Klassen mit UoW-Mock erweitert
- 34 alte JPA-Dateien gelöscht (Entities, Spring Data Repos, Adapter, Mapper)
RELEASED ProductionOrder kann mit einer PLANNED Batch verknüpft und
in Produktion gestartet werden. Dabei wechselt der Order auf IN_PROGRESS
und die Batch auf IN_PRODUCTION. Neuer REST-Endpoint POST /{id}/start,
StartOrderProduction Use Case, BatchAlreadyAssigned Error, Liquibase-
Migration für batch_id FK auf production_orders.
Erweitert die StockMovement-Abfrage um batchReference- und from/to-Filter
mit Filter-Priorität stockId > articleId > batchReference > movementType > from/to.
Inkl. DB-Index auf batch_id, Unit-/Integrationstests und Lasttest-Szenarien.