Release Notes — Jul 8, 2026 — on stage (dev accumulation since Jul 7)

What this release is. Three MRs merged to dev (→ staging) since the Jul 7 note (!282 / #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). No DB migration this window — every change is code-only.

⚙️ 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 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.

💳 Billing & money correctness — payment/billing sweep (!283)

#ChangeWhat to verify on stage
#614 money · P1 Statement/receipt "Paid" total now counts only settled payments. It previously summed all payment rows regardless of status, so FAILED/CANCELLED attempts — and payments that were approved then REFUNDED/REVERSED — inflated the Paid total. Open a member statement / printable receipt for someone who has a mix of settled and failed/cancelled/refunded payments → the Paid figure equals only the settled, non-refunded amounts. A failed attempt or a refunded payment must not raise the Paid total.
#627 New-invoice email is now sent on invoice ISSUED. Creating/issuing an invoice previously sent no notification to the member. Create/issue an invoice for a member → the member receives a "new invoice" email (check MailHog at stg-webmail.membervu.com) with the correct amount and a link.
#630 new control Duplicate-invoice now shows a confirm dialog. Creating an invoice that collides with an existing one used to surface the raw retry with confirmDuplicate: true error text with no way to proceed. Try to create a duplicate invoice → you get a friendly confirmation dialog ("an invoice like this already exists — create anyway?"), not raw error text. Confirming creates it; cancelling aborts cleanly.
#615 Org-profile logo now saves with the form. Uploading/removing the org logo previously fired the API immediately (before Save), and leaked a preview blob URL. It now stages locally and commits only on Save Changes. Admin → Org Profile → change the logo but don't Save → navigate away → logo is unchanged. Change it again and Save → it persists. No error, no orphaned upload.

💵 Payments & paid-event registration (!283)

#ChangeWhat to verify on stage
#625 was blocking Paid-event payment submit fixed. The submit-payment call mis-structured its Authorization-header payload, so paying for a paid event could fail. Register + pay for a paid event as a member → the payment submits successfully (no auth/400 error) and the registration completes.
#626 Paid-event registration now emails a payment link. Registering for a paid event previously sent the member no payment-link email. Register for a paid event → member receives a payment-link email (MailHog) that opens the correct invoice/payment page.
#628 Manual payment survives a session-expiry. If your session expired mid-submit, the entered amount + uploaded proof were discarded with no way to retry after re-login. Start a manual "Record Payment" with an amount + proof; let the session expire (or force it) and submit → after re-authenticating, the amount and proof are preserved and the submit can be retried without re-entering everything.
#631 new control Delete-payment-method confirmation. Deleting a payment method had no confirmation — one misclick was irreversible. Payment Methods → Delete → a confirm modal appears; cancelling keeps the method, confirming removes it.
#632 new column Reference / invoice-number column added to the admin Payments list, which previously showed none. Admin → Payments list → each row shows its reference / invoice number, matching the payment's detail panel.
#633 Sidebar active-state fix. On the Payment Channels page the Dashboard nav link also lit up (double-active); active state now uses an exact / longest-path match. Open Admin → Payment Channels → only that sidebar item is highlighted; Dashboard is not also shown active. Spot-check other sub-routes don't double-highlight.
#634 new control "Set default" payment method. The schema always supported a default but the UI had no way to set it; a single-default invariant is enforced. Payment Methods (both the member account tab and admin surface) → Set default on a method → it becomes default and any prior default is cleared (exactly one default at a time).
#635 Approval notes captured on payment approval. The backend field existed but was dead — the FE had no input to fill it. Admin approves a submitted payment → an approval-notes field is available; the note you enter is saved and shown on the payment afterward.

🏦 Manual payments — proof upload & bank accounts (!285)

#ChangeWhat to verify on stage
#641 was blocking Member proof upload no longer 401s. The XHR upload double-set the Authorization header (Bearer x, Bearer x), so every proof-of-payment upload was rejected. This was the root cause behind the #628 data-loss symptom. As a member, submit a manual payment with a proof-of-payment file → the upload succeeds (no 401), the payment records, and the proof is attached/visible to the admin.
#643 Bank-account controls now gate on the finance-manage permission (not on role) and show a friendly 403 instead of a hard failure. Users who can manage finances can add/edit bank accounts; others get a clear "you don't have permission" message (shown once, not duplicated on a forced submit). As a finance-capable admin/treasurer → Bank Accounts → add/edit a bank account succeeds. As a non-finance user → the controls are gated and a single friendly permission message appears (no raw 403, no duplicate message).
Note. #641 + #643 unblock the whole manual-payment / bank-account path — a member could not upload proof (#641) and an admin could not add the bank account to collect against (#643). Test them together: admin adds a bank account → member submits a manual payment with proof → admin approves it (with notes, per #635).

🔐 Auth & sessions — session-scoped logout (!284)

#ChangeWhat to verify on stage
#640 shared-account Logout is now session-scoped. Previously logout (and password-change / suspension) was userId-scoped: one person logging out of a shared account revoked every concurrent session, hard-logging-out everyone else on that login. Logout now revokes only the presenting refresh-token row; other live sessions stay signed in. Applies to the super-admin/platform portal too. Sign in to the same account in two browsers (or a browser + incognito) → log out in one → the other session stays logged in and keeps working (no forced logout / session-expired modal). Confirm the browser you logged out of is fully signed out. Repeat on stg-admin.membervu.com with a super-admin.

🚀 Deploy & regression notes

Source of truth: membervu/membervu-pm issues #614, #615, #625, #626, #627, #628, #630, #631, #632, #633, #634, #635, #640, #641, #643 · merged to dev via membervu/membervu-saas!283, !284, !285 on 2026-07-07. Stage builds from dev. Last documented window: Jul 7 (!282 / #620).