FIX/promotion-rollback-to-credit #9
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "FIX/promotion-rollback-to-credit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
When the advertising service discards what a promotion paid for (e.g. a captured billboard deleted while still pending approval), the promotion money sitting in the advertising transit wallet needs to go back to the promotions credit wallet. The promotion itself stays consumed -- only the money is returned -- and only payouts that landed in the transit wallet are reversible (a payout straight to the user's wallet is the user's). - Promotion.rolled_back_at + rollback_to_credit(): row-locked, CAS-stamped, idempotent transfer transit -> credit for SUCCESS/transit-destined payouts. - PromotionRollback model: keyed (user, event_label) -- all the advertising side knows. Handles the async race (payout runs in a Celery task, so the Promotion may not exist yet): Recipient.promote() checks for an unsettled request before paying (suppresses the payout) and after (reverses a payout that landed mid-request). - POST .../event/<event_label>/rollback/ -> {status: reversed|deferred|nothing, amount}. - migration 0011 (hand-written; verified via makemigrations --dry-run + check). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>