feat(admin): manual full-order refund + ledger CSV export
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 22s
CI / ui (pull_request) Has been skipped
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m53s

Closes the admin / reports / catalog work. Each fund row on the /_gm finance
panel gains a Refund action (payments.RefundOrderFull): a full-order refund the
operator records after refunding on the rail — a refund ledger row + a floor-0
chip revoke (never negative, D27), idempotent (a second refund reports
already-refunded). A ledger CSV export (/_gm/ledger.csv, payments.LedgerExport)
streams the whole append-only ledger for tax + reconciliation.

Tests: refund an order in full (chips revoked, a refund row), an idempotent
second refund, the CSV export shape; CSRF-guarded.
This commit is contained in:
Ilia Denisov
2026-07-10 06:46:18 +02:00
parent ec5c6afa23
commit 1bf612a087
8 changed files with 242 additions and 13 deletions
+11 -10
View File
@@ -36,7 +36,7 @@ status — without re-deriving decisions.
| E4 | Durability (PITR) | 2 | DONE |
| E5 | Payment intake | 2 | DONE |
| E6 | Ads | 2 | DONE |
| E7 | Admin, reports & catalog | 2 | TODO |
| E7 | Admin, reports & catalog | 2 | DONE |
| E8 | Guest limits | — | TODO |
| E9 | Tournament fee | future | TODO |
@@ -695,7 +695,7 @@ it tunes without a store release.
## E7 — Admin, reports & catalog
**Status:** TODO · **Release 2** · depends on: E2 (ledger/grant/spend), E5 (payments/refunds),
**Status:** DONE · **Release 2** · depends on: E2 (ledger/grant/spend), E5 (payments/refunds),
E6 (D31 retired the legacy `hint_balance`/`paid_account`) · mechanics: PAYMENTS §11, §12, D32.
**Delivery & baked decisions (this planning round).** A linear PR stack into `development`.
@@ -763,15 +763,16 @@ ledger export — plus the **configurable product catalog editor** (D32).
products + prices and delete only never-transacted ones; grant concrete values raw or by-product
(origin-picked, never chips/tournament); refund an order in full; export the ledger.
**PR stack (linear into `development`).**
**PR stack (linear into `development`, all merged).**
1. **Per-user financial panel** (read-only ledger/segments/benefits on the user card; retires the
`PaidAccount`/`HintBalance` display).
2. **Catalog editor** (product/atom/price CRUD + archive/unarchive + delete-if-clean + shape
validation).
3. **Admin grant** (raw + by-product, refuse chips/tournament, origin-picked, `admin_grant` +
snapshot).
4. **Manual refund** (full order via E5 `Refund`) + **ledger export** (CSV/JSON).
1. ~~**Per-user financial panel**~~ (#230) — read-only ledger/segments/benefits on the user card;
retired the `PaidAccount`/`HintBalance` display.
2. ~~**Catalog editor**~~ (#231) — product/atom/price CRUD + archive/unarchive + delete-if-clean +
shape validation.
3. ~~**Admin grant**~~ (#232, + the D31 hint-wallet wire cleanup that surfaced there) — raw +
by-product, refuse chips/tournament, origin-picked, `admin_grant` + snapshot.
4. ~~**Manual refund** (full order via E5 `Refund`) + **ledger CSV export**~~ — `RefundOrderFull`
(idempotent, floor-0 revoke) on each fund row; `/_gm/ledger.csv`.
**Notes/risks.** High-blast-radius (money, ledger — append-only, trigger-enforced). No mixed-in
refactors. The catalog editor becomes the source of truth for products; the contour SQL seeds