fix(vouchers): reserve claims atomically before reward dispatch
This commit is contained in:
1 parent
4b88c6955b
commit
8e54cdbc6a
4 files changed
+435
-128
No files matched your search
@@ -27,7 +27,7 @@ The current UI route matrix cannot establish operation-level parity.
|
||||
|
||||
| Area | Evidence / required follow-up |
|
||||
| --- | --- |
|
||||
| Voucher redemption | `src/actions/voucher.ts` reads eligibility, inserts used-row, delivers currency, then updates usage in separate operations. No atomic cap reservation. A failed reward can leave a consumed voucher. |
|
||||
| Voucher redemption | Claim reservation now locks the voucher and duplicate claim, commits usage/cap with an audit intent, then dispatches the reward. Failed or uncertain dispatch retains the reservation and returns the audit reference. Automatic recovery of reward increments remains intentionally unavailable without emulator acknowledgment/idempotency. |
|
||||
| Currency delivery | `src/lib/services/send-currency.ts` uses RCON followed by database fallback; socket dispatch is not emulator acknowledgment. Do not invent exactly-once guarantees or blindly replay increments. |
|
||||
| Reason enforcement | Reason propagation is fixed for the named paths, but operation-level required-reason policies and denied/failure auditing still need a complete cross-entrypoint inventory. |
|
||||
| Functional parity | Compare each query and mutation in Content, Economy, Hotel, People, System and Operations with retained legacy API/actions. A registered handler is not proof of complete functionality. |
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Voucher claim reservation
|
||||
|
||||
The public redemption action now serializes claims on the selected voucher row.
|
||||
It validates amount, capacity and expiration, locks the duplicate-claim read,
|
||||
inserts the used row, increments usage and stores the audit intent in one transaction.
|
||||
No reward dispatch occurs until the transaction resolves successfully. A commit
|
||||
acknowledgment failure prevents dispatch and returns a correlation reference.
|
||||
|
||||
The reward transport remains the existing sendCurrency implementation. A false
|
||||
or thrown result is unconfirmed, not proof that no increment occurred. Such a
|
||||
claim stays consumed and receives a partial audit outcome. It must not be blindly
|
||||
replayed or refunded; staff can inspect the correlated intent and final outcome.
|
||||
A completion-audit failure after successful dispatch does not report failed delivery.
|
||||
|
||||
This does not guarantee exactly-once emulator processing, introduce automatic
|
||||
reward recovery, or claim that database reservation and external dispatch are
|
||||
one distributed transaction. No migration or live data change is performed.
|
||||
|
||||
Tests exercise the real action and generated Drizzle SQL with controlled database,
|
||||
session, audit and currency transports. They prove boundary ordering and error
|
||||
mapping, not actual multi-connection MariaDB locking or emulator acceptance.
|
||||
The initial regression run had nine expected failures before implementation.
|
||||
Reference in new issue
Block a user