Release Notes — Jul 7, 2026 — on stage (dev accumulation since Jul 6)
What this release is. A single backend hardening MR merged to
dev (→ staging) since the Jul 6 accumulation (!281) — membervu/membervu-saas!282 (closes membervu-pm#620). This is a stage/dev accumulation, not a prod promotion — verify on staging (https://stg-rcme.membervu.com; admin portal https://stg-admin.membervu.com). Headline: the concurrency-safe invoice-number fix from #613 (dues path, shipped Jul 6) is now extended to the event-registration invoice and donation / manual invoice paths, so those two money paths no longer risk a duplicate-invoice-number 500 under a race.
⚙️ Before you start — environment & logins
| Surface | URL | Login to use |
|---|---|---|
| Org portal (tenant) | stg-rcme.membervu.com | Admin admin@rcme.membervu.com / Admin123!; Treasurer treasurer@demo.membervu.com / Treasurer123! |
| Member view | stg-rcme.membervu.com | Member testmember@rcme.membervu.com / Member123! |
| Super-admin portal | stg-admin.membervu.com | Super Admin superadmin@zeniark.com / SuperAdmin123! |
| Email inbox (MailHog) | stg-webmail.membervu.com | — |
Scope notes — read before testing.
- Backend-only, no UI change. This window touches only the invoice-creation service code (
auth-service) — there is no new screen, button, or field to look at. It's a regression / robustness fix: existing event-registration and donation flows must keep working normally, and every invoice they create must get a distinct invoice number. - The bug it fixes is race-only. A duplicate invoice number only ever occurred when two invoices were created at the same instant for the same tenant (e.g. two people registering for the same event, or two donations, within the same moment). In ordinary single-user testing you would not see the old failure — so the goal here is to confirm nothing regressed in the normal path, plus (optionally) a light concurrency probe.
- Not a prod release. On
dev/staging only; not promoted to prod. - DB migrations: none this window (code-only change).
💳 Billing — concurrency-safe invoice numbers on event & donation invoices — #620 (!282)
Context (why this matters). On Jul 6, #613 made the dues invoice-number generator retry correctly on a duplicate-number collision (the retry had been silently dead under the new Prisma 7 database driver). #620 is the follow-up that extends that same fix to the other two money paths — event-registration invoices and donation / manual invoices — which were still running the old, dead retry check.
| # | Change | What to verify on stage |
|---|---|---|
| #620 money · concurrency · P2 | Event & donation invoice numbers are now collision-safe. The duplicate-invoice-number retry guard on the event-registration invoice and donation / manual invoice creation paths was dead at runtime under the Prisma 7 driver (it checked a field the driver no longer populates), so a simultaneous double-create could 500 on a duplicate number. The collision is now detected correctly, and where the operation owns its own transaction it retries with a fresh number (same shared helper the dues path uses). |
Normal path (must not regress):
|
⚠ Known residual (by design in this MR). For call sites where invoice creation is bundled into a larger caller-owned database transaction, an in-place auto-retry is not safe (Postgres aborts the whole transaction on the first collision). In that case #620 now correctly detects the collision and returns a clear, typed error instead of silently continuing — full caller-side retry for those paths is a separate, larger refactor and is out of scope for this ticket. Practical impact for testers: in the extremely rare simultaneous-collision case on a bundled path you may still see a single clean error rather than an automatic retry — this is expected, not a new bug. Report any duplicate invoice numbers that do slip through against #620.
🚀 Deploy & regression notes
- No schema migration this window — code-only change in
auth-service(createEventInvoice.ts,billingStore.ts,utils/invoiceNumber.ts). - New backend tests landed alongside the fix (unit + real-DB concurrency tests per path) — a mocked-only test can't catch this class, since it fabricates the error shape the real driver no longer produces.
- Regression focus: paid-event registration → invoice, donation → invoice, and manual "Record Payment" → invoice all still work end-to-end and produce unique invoice numbers.
Source of truth: membervu/membervu-pm#620 · merged via membervu/membervu-saas!282 to dev on 2026-07-07. Stage builds from dev.