-
Notifications
You must be signed in to change notification settings - Fork 0
feat(s3): domain model — CollectionOrder aggregate, state machine, events, ports (STA-120) #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.stablecoin.payments.onramp.domain.event; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.time.Instant; | ||
| import java.util.UUID; | ||
|
|
||
| public record CollectionCompletedEvent( | ||
| UUID collectionId, | ||
| UUID paymentId, | ||
| UUID correlationId, | ||
| BigDecimal collectedAmount, | ||
| String currency, | ||
| String paymentRail, | ||
| String psp, | ||
| String pspReference, | ||
| Instant collectedAt | ||
| ) { | ||
|
|
||
| public static final String TOPIC = "fiat.collected"; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.stablecoin.payments.onramp.domain.event; | ||
|
|
||
| import java.time.Instant; | ||
| import java.util.UUID; | ||
|
|
||
| public record CollectionFailedEvent( | ||
| UUID collectionId, | ||
| UUID paymentId, | ||
| UUID correlationId, | ||
| String reason, | ||
| String errorCode, | ||
| Instant failedAt | ||
| ) { | ||
|
|
||
| public static final String TOPIC = "fiat.collection.failed"; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.stablecoin.payments.onramp.domain.event; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.time.Instant; | ||
| import java.util.UUID; | ||
|
|
||
| public record CollectionInitiatedEvent( | ||
| UUID collectionId, | ||
| UUID paymentId, | ||
| UUID correlationId, | ||
| BigDecimal amount, | ||
| String currency, | ||
| String paymentRail, | ||
| String psp, | ||
| Instant initiatedAt | ||
| ) { | ||
|
|
||
| public static final String TOPIC = "fiat.collection.initiated"; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package com.stablecoin.payments.onramp.domain.event; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.time.Instant; | ||
| import java.util.UUID; | ||
|
|
||
| public record RefundCompletedEvent( | ||
| UUID refundId, | ||
| UUID collectionId, | ||
| UUID paymentId, | ||
| BigDecimal refundAmount, | ||
| String currency, | ||
| String pspRefundRef, | ||
| Instant completedAt | ||
| ) { | ||
|
|
||
| public static final String TOPIC = "fiat.refund.completed"; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package com.stablecoin.payments.onramp.domain.event; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.time.Instant; | ||
| import java.util.UUID; | ||
|
|
||
| public record RefundInitiatedEvent( | ||
| UUID refundId, | ||
| UUID collectionId, | ||
| UUID paymentId, | ||
| BigDecimal refundAmount, | ||
| String currency, | ||
| String reason, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid publishing free-form refund reasons on the event bus. Line 13 exposes 🤖 Prompt for AI Agents |
||
| Instant initiatedAt | ||
| ) { | ||
|
Comment on lines
+7
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enforce event invariants in the record constructor. This record currently accepts null IDs/timestamp, blank currency/reason, and non-positive amounts. That allows malformed domain events to escape onto Kafka before any adapter-level validation catches them. Proposed fix package com.stablecoin.payments.onramp.domain.event;
import java.math.BigDecimal;
import java.time.Instant;
+import java.util.Objects;
import java.util.UUID;
public record RefundInitiatedEvent(
UUID refundId,
UUID collectionId,
@@
String reason,
Instant initiatedAt
) {
+ public RefundInitiatedEvent {
+ Objects.requireNonNull(refundId, "refundId must not be null");
+ Objects.requireNonNull(collectionId, "collectionId must not be null");
+ Objects.requireNonNull(paymentId, "paymentId must not be null");
+ Objects.requireNonNull(refundAmount, "refundAmount must not be null");
+ Objects.requireNonNull(currency, "currency must not be null");
+ Objects.requireNonNull(reason, "reason must not be null");
+ Objects.requireNonNull(initiatedAt, "initiatedAt must not be null");
+
+ if (refundAmount.signum() <= 0) {
+ throw new IllegalArgumentException("refundAmount must be positive");
+ }
+ if (currency.isBlank()) {
+ throw new IllegalArgumentException("currency must not be blank");
+ }
+ if (reason.isBlank()) {
+ throw new IllegalArgumentException("reason must not be blank");
+ }
+ }
public static final String TOPIC = "fiat.refund.initiated";
}🤖 Prompt for AI Agents |
||
|
|
||
| public static final String TOPIC = "fiat.refund.initiated"; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.stablecoin.payments.onramp.domain.model; | ||
|
|
||
| public enum AccountType { | ||
| IBAN, | ||
| ACH_ROUTING, | ||
| SORT_CODE, | ||
| PIX_KEY | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.stablecoin.payments.onramp.domain.model; | ||
|
|
||
| public record BankAccount( | ||
| String accountNumberHash, | ||
| String bankCode, | ||
| AccountType accountType, | ||
| String country | ||
| ) { | ||
|
|
||
| public BankAccount { | ||
| if (accountNumberHash == null || accountNumberHash.isBlank()) { | ||
| throw new IllegalArgumentException("Account number hash is required"); | ||
| } | ||
| if (bankCode == null || bankCode.isBlank()) { | ||
| throw new IllegalArgumentException("Bank code is required"); | ||
| } | ||
| if (accountType == null) { | ||
| throw new IllegalArgumentException("Account type is required"); | ||
| } | ||
| if (country == null || country.isBlank()) { | ||
| throw new IllegalArgumentException("Country is required"); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Topic naming inconsistent with other events.
All other events use
fiat.{entity}.{action}pattern:fiat.collection.initiatedfiat.collection.failedfiat.refund.initiatedfiat.refund.completedThis one uses
fiat.collected— breaks the convention and complicates consumer topic subscription patterns.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents