fix(escrow-service): idempotent arbitrate skip, penalize mismatch log, consistent save() return#64
Merged
RedAvocado22 merged 1 commit intoJul 6, 2026
Conversation
…, consistent save() return - ArbitrateEscrowUseCase: skip idempotently (log + return) when already ARBITRATED, instead of letting the domain method throw a misleading "not fully locked yet" error on retry — mirrors the guard pattern already used in ConfirmDepositUseCase/ ReleaseEscrowUseCase/PenalizeEscrowUseCase. - PenalizeEscrowUseCase: when skipping an already-penalized account, warn if the incoming event's cancelledBy differs from the party actually penalized, so a data mismatch is visible instead of silently swallowed. - EscrowAccountRepositoryImpl.save(): return the mutated `account` argument instead of reconstituting a new object via mapper.toDomain(saved). No caller currently reuses the pre-save reference, but returning a different object than the one passed in is a footgun for future callers and was inconsistent with ContractRepositoryImpl.save() in contract-service, which already returns the original object.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #52
Closes #53
#52 — ArbitrateEscrowUseCase / PenalizeEscrowUseCase minor cleanup
ArbitrateEscrowUseCase: added a skip-guard whenstatus == ARBITRATED, same shape as the existing idempotency guards inConfirmDepositUseCase/ReleaseEscrowUseCase/PenalizeEscrowUseCase. Previously a retried admin arbitrate request would fall through intoEscrowAccount.arbitrate()'s own guard and throwIllegalStateException("This payment not fully locked yet.")— a confusing message for what's actually an idempotent-retry case.PenalizeEscrowUseCase: when skipping an already-penalized account, now logs awarnif the incoming event'scancelledBydoesn't match the party that was actually penalized (derived from the stored status), so a data mismatch is visible for debugging instead of silently returning.#53 — EscrowAccountRepositoryImpl.save() return-value inconsistency
save()returnedmapper.toDomain(saved)— a freshly reconstituted object — instead of theaccountargument it had just mutated (domain events already drained from it). No current caller reuses the pre-save reference, but it's inconsistent withContractRepositoryImpl.save()(contract-service), which returns the original object, and is a footgun if a future caller holds ontoaccountafter callingsave(). Now returnsaccountdirectly.Test plan
escrow-servicetest suite passes