feat(wcs): add shared domain contracts

This commit is contained in:
zgw
2026-08-10 15:05:57 +08:00
parent 77067e07b3
commit 74979e3226
5 changed files with 106 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
package com.ruoyi.wcs.domain.shared;
import java.time.Instant;
import java.util.Objects;
public final class DomainEvent {
private final String eventId;
private final String aggregateId;
private final long sequence;
private final Instant occurredAt;
private final String type;
public DomainEvent(String eventId, String aggregateId, long sequence,
Instant occurredAt, String type) {
this.eventId = requireText(eventId, "eventId");
this.aggregateId = requireText(aggregateId, "aggregateId");
if (sequence < 1L) {
throw new IllegalArgumentException("sequence must be positive");
}
this.sequence = sequence;
this.occurredAt = Objects.requireNonNull(occurredAt, "occurredAt");
this.type = requireText(type, "type");
}
public String getEventId() {
return eventId;
}
public String getAggregateId() {
return aggregateId;
}
public long getSequence() {
return sequence;
}
public Instant getOccurredAt() {
return occurredAt;
}
public String getType() {
return type;
}
private static String requireText(String value, String field) {
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException(field + " must not be blank");
}
return value;
}
}

View File

@@ -0,0 +1,7 @@
package com.ruoyi.wcs.domain.shared;
public final class DomainRuleViolation extends RuntimeException {
public DomainRuleViolation(String message) {
super(message);
}
}

View File

@@ -0,0 +1,5 @@
package com.ruoyi.wcs.domain.shared;
public interface IdGenerator {
String nextId();
}

View File

@@ -0,0 +1,7 @@
package com.ruoyi.wcs.domain.shared;
import java.time.Instant;
public interface WcsClock {
Instant now();
}

View File

@@ -0,0 +1,36 @@
package com.ruoyi.wcs.domain.shared;
import org.junit.jupiter.api.Test;
import java.time.Instant;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class SharedContractsTest {
@Test
void rejectsBlankEventIdentity() {
assertThrows(IllegalArgumentException.class, () ->
new DomainEvent("", "ORDER-1", 1L, Instant.EPOCH, "OrderAccepted"));
}
@Test
void rejectsInvalidEventSequence() {
assertThrows(IllegalArgumentException.class, () ->
new DomainEvent("E-1", "ORDER-1", 0L, Instant.EPOCH, "OrderAccepted"));
}
@Test
void exposesDeterministicEventFields() {
Instant occurredAt = Instant.parse("2026-08-04T00:00:00Z");
DomainEvent event = new DomainEvent("E-1", "ORDER-1", 2L,
occurredAt, "OrderPlanned");
assertEquals("E-1", event.getEventId());
assertEquals("ORDER-1", event.getAggregateId());
assertEquals(2L, event.getSequence());
assertEquals(occurredAt, event.getOccurredAt());
assertEquals("OrderPlanned", event.getType());
}
}