Release Notes — Jul 9, 2026 — dev → prod promotion (Fundraising money-flow + admin console + treasury SoD + event re-registration)

What this release is. The dev → prod promotion (MR membervu/membervu-saas!280 — the release branch cut 2026-07-06, refreshed 2026-07-09), everything accumulated on dev since the Jul 1 promotion (!264). Verify on staging (https://stg-rcme.membervu.com; admin portal https://stg-admin.membervu.com) and on the prod release build once landed. The headline is Fundraising becoming a real money-flow feature: donors can donate + upload proof, admins get a campaign console with a pending-proof review queue, and approvals now settle payments + flip invoices with a money-parity audit. Plus event re-registration (fresh check-in QR), a treasury maker-checker permission split, and a batch of payment-correctness / session fixes already documented in their sections.

⚙️ Before you start — environment & logins

SurfaceURLLogin to use
Org portal (tenant)stg-rcme.membervu.comAdmin admin@rcme.membervu.com / Admin123!; Treasurer treasurer@demo.membervu.com / Treasurer123!
Member / donor viewstg-rcme.membervu.comMember testmember@rcme.membervu.com / Member123!
Super-admin portalstg-admin.membervu.comSuper Admin superadmin@zeniark.com / SuperAdmin123!
Email inbox (MailHog)stg-webmail.membervu.com
Scope notes — read before testing.

🎁 Fundraising — money-flow + admin console (highest priority) — #651, #623, #661, #662, #569

New guide section: Fundraising. Work these test cases in order — the donor money-flow first, then the admin console, then the campaign/public surfaces.

#ChangeWhat to verify on stage
#651 money · P1 Donation money-flow end-to-end. Donating creates an Invoice in ISSUED; uploading proof creates a Payment in PENDING; an admin approve settles the Payment (SUCCEEDED/APPROVED), flips the Invoice → PAID, and writes a money-parity audit (G9). Approving an under-covered invoice is blocked (409 PAYMENT_AMOUNT_INSUFFICIENT) and rolls back; reject retains the proof; the donor can resubmit into the same row. Donate to a campaign → an invoice appears ISSUED. Upload proof → payment is PENDING. Admin approves → payment is SUCCEEDED/APPROVED and the invoice flips to PAID, with totals that balance (no over/under count). Try approving a payment that doesn't fully cover the invoice → you get a 409 (amount insufficient) and nothing changes (rolled back). Reject a payment → the proof is still there; the donor resubmits and it lands on the same row. → TC-FUND-001
#623 Admin fundraising console. Campaign management (create/edit/close), a pending-proof review queue with a nav badge count, and campaign close-out. Admin → Fundraising → create/edit a campaign; the review queue lists pending donation proofs and the nav badge shows the count (and decrements as you approve/reject). Close out a campaign → it moves to a closed state and stops accepting donations. → TC-FUND-002
#661 / #662 Campaign cover image + progress + public page. Campaigns take a cover-image upload and expose raisedAmount, pendingProofCount, and a progress bar. A public campaign page supports anonymous donors behind a members-only gate where configured. Upload a campaign cover image → it saves and displays. The campaign card/detail shows a progress bar whose raised and pending-proof figures match the underlying donations. Open the public campaign page as an anonymous visitor → donating works where allowed; a members-only campaign gates non-members. → TC-FUND-003
#569 Donor rejection / resubmission with a donor-safe reference. When a proof is rejected, the donor is told in donor-friendly wordingno "Invoice" terminology — and can resubmit. Reject a donor's proof → the donor sees a clear, non-"Invoice" reference/message and a way to resubmit. Confirm the donor-facing copy never exposes internal "Invoice" wording. → TC-FUND-001

🎟️ Events — re-registration issues a fresh check-in QR — #637

#ChangeWhat to verify on stage
#637 behaviour change Register → cancel → re-register now creates a NEW registration row with a FRESH check-in QR/code (it previously reactivated the same row in place, reusing the old QR). Cancelled rows are retained for audit. You still cannot hold two ACTIVE registrations for the same event at once. Register for an event, cancel, then re-register → you get a new registration with a new check-in code/QR (the old code should no longer be the active one). The cancelled registration is still visible in history. Attempting to end up with two ACTIVE registrations is still blocked. → TC-EVT-002 (see TC-REG-FREE-03 / TC-REG-FREE-06)

🔐 Payments — treasury maker-checker (SoD) — #528

#ChangeWhat to verify on stage
#528 SoD · permissions Treasury verify/dispute is gated on a new FINANCE:VERIFY:treasury permission, kept separate from FINANCE:EDIT:payments (maker-checker / separation-of-duties). Existing ADMIN and Treasurer roles are unaffected (they get the new permission via seeding). As Treasurer/Admin → treasury verify/dispute still works. As a user with FINANCE:EDIT:payments but without FINANCE:VERIFY:treasury → the verify/dispute action is gated / 403, proving the two duties are now split. → TC-PAY-009
Also shipping (already documented in their sections). This promotion also carries the payment-correctness & session fixes accumulated on dev: payment-total correctness — a refund now drops the "Paid" total (#614); shared-account logout scope — logging out no longer kills a co-user's other sessions (#640); bank-proof upload no longer 401s (#641); and single-use email verification tokens (#593). These were covered in the Jul 8 / Jul 6 notes and their respective section pages — re-verify in passing but the Fundraising, event re-registration, and treasury SoD items above are the new-to-prod work.

🚀 Deploy / migration notes (ops + reviewer gate)

13 migrations — deploy via prisma migrate deploy only (applied in timestamp order); never reset/reseed on prod. 12 are additive (new Fundraising tables/columns, campaign fields, permissions) and 1 is a safe index swap backing the event re-registration change (#637) — no destructive step.
🔑 Permissions: 4 new permissions auto-seed at startup (incl. FINANCE:VERIFY:treasury, #528) via the additive backfill — merge-only, never delete existing role↔permission joins. Existing ADMIN/Treasurer roles pick up the new grants automatically.
⚙️ Config: no new env vars this release.
🗃️ Data: the new Fundraising tables are empty on first deploy — there are no campaigns until an admin creates one. Nothing to backfill.
✅ Assert on DATA: reviewers/testers should verify on the real figures — money totals (invoice/payment state, "Paid"/raised amounts) and a fresh check-in code after re-registration — not merely that a screen rendered.

Source of truth: the membervu/membervu-pm tracker + MR membervu/membervu-saas!280 (dev → prod release branch, cut 2026-07-06, refreshed 2026-07-09). Headline issues: #651, #623, #661, #662, #569 (Fundraising), #637 (event re-registration), #528 (treasury SoD); also carried: #614, #640, #641, #593. Builds on the Jul 1, 2026 promotion. Stage builds from dev; gateway flows inert in all QA environments.