mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 12:09:35 +01:00
fix(production): JPA-Save-Pattern, Optimistic Locking und Domain-Validierung
- Managed-Entity-Update statt detach/merge (verhindert DELETE+INSERT-Churn) - @Version für Optimistic Locking mit ConcurrentModification-Error - Null-Checks für quantityUsed/quantityUnit vor BigDecimal-Parsing - Duplicate-Check nach Consumption.create() für robustere Validierung - FetchType.EAGER→LAZY für BatchEntity.consumptions - Liquibase-Migration 020 für version-Spalte
This commit is contained in:
parent
a9f5956812
commit
9eb9c93fb7
17 changed files with 133 additions and 37 deletions
|
|
@ -53,7 +53,7 @@ class FindBatchByNumberTest {
|
|||
LocalDate.of(2026, 6, 1),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class GetBatchTest {
|
|||
LocalDate.of(2026, 6, 1),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class ListBatchesTest {
|
|||
LocalDate.of(2026, 6, 1),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class RecordConsumptionTest {
|
|||
LocalDate.of(2026, 6, 1),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ class RecordConsumptionTest {
|
|||
LocalDate.of(2026, 6, 1),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class StartBatchTest {
|
|||
LocalDate.of(2026, 6, 1),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ class StartBatchTest {
|
|||
LocalDate.of(2026, 6, 1),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ class BatchTest {
|
|||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
PRODUCTION_DATE, BEST_BEFORE_DATE,
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
|
||||
var result = batch.startProduction();
|
||||
|
|
@ -231,7 +231,7 @@ class BatchTest {
|
|||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
PRODUCTION_DATE, BEST_BEFORE_DATE,
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
|
||||
var result = batch.startProduction();
|
||||
|
|
@ -249,7 +249,7 @@ class BatchTest {
|
|||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
PRODUCTION_DATE, BEST_BEFORE_DATE,
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
|
||||
var result = batch.startProduction();
|
||||
|
|
@ -313,7 +313,7 @@ class BatchTest {
|
|||
Quantity.of(new BigDecimal("100"), UnitOfMeasure.KILOGRAM).unsafeGetValue(),
|
||||
PRODUCTION_DATE, BEST_BEFORE_DATE,
|
||||
OffsetDateTime.now(ZoneOffset.UTC), OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
var draft = new ConsumptionDraft("input-1", "article-1", "5.0", "KILOGRAM");
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ class BatchTest {
|
|||
BEST_BEFORE_DATE,
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
OffsetDateTime.now(ZoneOffset.UTC),
|
||||
List.of()
|
||||
0L, List.of()
|
||||
);
|
||||
|
||||
assertThat(batch.id().value()).isEqualTo("batch-1");
|
||||
|
|
|
|||
|
|
@ -111,6 +111,28 @@ class ConsumptionTest {
|
|||
assertThat(result.unsafeGetError()).isInstanceOf(BatchError.InvalidConsumptionQuantity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("should fail when quantity is null")
|
||||
void should_Fail_When_QuantityNull() {
|
||||
var draft = new ConsumptionDraft("input-batch-1", "article-1", null, "KILOGRAM");
|
||||
|
||||
var result = Consumption.create(draft);
|
||||
|
||||
assertThat(result.isFailure()).isTrue();
|
||||
assertThat(result.unsafeGetError()).isInstanceOf(BatchError.InvalidConsumptionQuantity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("should fail when unit is null")
|
||||
void should_Fail_When_UnitNull() {
|
||||
var draft = new ConsumptionDraft("input-batch-1", "article-1", "10", null);
|
||||
|
||||
var result = Consumption.create(draft);
|
||||
|
||||
assertThat(result.isFailure()).isTrue();
|
||||
assertThat(result.unsafeGetError()).isInstanceOf(BatchError.InvalidConsumptionQuantity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("should fail when unit is invalid")
|
||||
void should_Fail_When_UnitInvalid() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue