fix(account): show payment history + next-charge for paid-then-$0 members
Three related changes on /member/account:
1. Payment History section now renders when contributionAmount > 0 OR
past payments exist. Previously a paid member who switched to $0 lost
visibility of their own past charges.
2. New "Next charge: $X on DATE" row renders above the transaction list
when nextPaymentDate is available, using --candle dashed border.
3. server/api/helcim/subscription.get.js now reads dateBilling from
Helcim's GET response and handles data as either object or array.
Helcim's real shape is {data: {id, dateBilling, ...}} — the old code
expected {data: [{nextBillingDate}]} and returned empty strings, so
the Membership-card "Next payment" row never rendered for members
whose cached date was missing. subscription.post.js and
update-contribution.post.js have the same wrong field name in their
CREATE flows; left for a follow-up — the GET refresh masks it.
Manual edit-flow and admin-flow tests also recorded in
docs/LAUNCH_READINESS.md.
This commit is contained in:
parent
a80728f0a8
commit
335a4db7cc
3 changed files with 51 additions and 13 deletions
|
|
@ -22,7 +22,9 @@ Shipped across `accept-invite.vue`, `join.vue`, `member/account.vue`, `welcome.v
|
|||
- **"Per Year" / "Per Month"** toggle copy (was "Annual" / "Monthly"). On `/accept-invite`, Per Year is now the default; `/join` stays on Per Month by default.
|
||||
- **Live billing-summary card** below the contribution input on both signup flows — reads e.g. "You'll be charged $180 today ($15/month × 12). Then $180 every year, until you cancel."
|
||||
- **Welcome heading on dashboard** for new signups: `/member/dashboard?welcome=1` renders "Welcome to Ghost Guild, {name}" instead of "Welcome back, {name}". `/welcome` redirect now always carries the param; `/accept-invite` navigates to the dashboard with the param directly.
|
||||
- **$0 member polish on `/member/account`**: Payment History section hidden when `contributionAmount === 0` (stops showing "first charge will appear after your next billing cycle" to members with no charges). Solidarity-Fund sentence in the Danger Zone also hidden at $0.
|
||||
- **$0 member polish on `/member/account`**: Payment History section hidden for $0 members with no prior charges (condition now `contributionAmount > 0 || paymentHistory.length > 0` — fixes a regression where paid-then-$0 members lost visibility of their past payments). Solidarity-Fund sentence in the Danger Zone also hidden at $0.
|
||||
- **Next charge row above payment history** on `/member/account`: When a member has an upcoming charge, a "Next charge: $X on DATE" row renders above the transaction list (dashed `--candle` border). Separate from the existing compact "Next payment" row in the Membership Card summary.
|
||||
- **Fixed `subscription.get.js` Helcim field mapping.** Helcim's GET `/subscriptions/:id` returns `data` as a single object (not array) with the field `dateBilling` (not `nextBillingDate`). The lazy refresh endpoint now handles both shapes — previously it returned empty strings, so neither the Membership-card "Next payment" nor the new "Next charge" row rendered for any member whose cached `nextBillingDate` was missing. Note: `subscription.post.js` and `update-contribution.post.js` still read `subscription.nextBillingDate` from Helcim's CREATE response (same wrong field), which is why the cache was empty to begin with. Left unfixed in this pass — the lazy GET refresh now masks it. Worth cleaning up post-launch.
|
||||
- **State-aware contribution-change hint** on `/member/account`: "You'll be charged $X today to start your subscription." ($0 → paid) / "Your paid subscription will be cancelled." (paid → $0) / "Changes apply on your next billing cycle." (paid → paid, different amount).
|
||||
- **Server-side invite accept** now creates the Helcim customer and sets the auth cookie before returning, for both free and paid branches.
|
||||
|
||||
|
|
@ -100,14 +102,14 @@ Cannot be verified by Vitest. Both require a real browser + real Helcim test car
|
|||
4. `$17` Annual — Helcim `recurringAmount: 204`, `billingCadence: 'annual'`, Mongo stores monthly-equivalent `17`.
|
||||
5. `$50` Annual (top preset) — Helcim `recurringAmount: 600`.
|
||||
|
||||
- [ ] **Edit flows — `/member/account` as an active paid member:**
|
||||
- Raise amount ($17 → $30). Confirm `updateHelcimSubscription` called with `recurringAmount: 30` (Monthly) or `360` (Annual).
|
||||
- Lower amount ($30 → $5). Same assertion at the new values.
|
||||
- [x] **Edit flows — `/member/account` as an active paid member:** ✅ Passed 2026-04-20 against Cleo's Annual subscription (Helcim sub 138682).
|
||||
- Raise $15 → $30 annual: `updateHelcimSubscription` hit with `recurringAmount: 360`, Mongo `contributionAmount: 30` (Number).
|
||||
- Lower $30 → $5 annual: `recurringAmount: 60`, Mongo `contributionAmount: 5` (Number).
|
||||
- ~~Switch cadence (Monthly $17 ↔ Annual $17).~~ **Deferred from launch.** Server (`update-contribution.post.js:184-189`) explicitly rejects cadence changes on existing subscriptions; no UI toggle exists on `/member/account`. Re-scope post-launch if/when we want to support cadence switch (would need Helcim subscription replacement flow, not a plain update).
|
||||
|
||||
- [ ] **Admin flow — `/admin/members/[id]` edit:**
|
||||
- `contributionAmount` input accepts any non-negative whole dollar. Save writes Number to Mongo.
|
||||
- No chip UI here (admin is plain number input by design).
|
||||
- [x] **Admin flow — `/admin/members/[id]` edit:** ✅ Passed 2026-04-20.
|
||||
- Changed Cleo $5 → $15 via admin PUT. Mongo wrote `contributionAmount: 15` (Number). `contributionTier` field absent across all 34 members (`countDocuments({ contributionTier: { $exists: true } }) === 0`).
|
||||
- Known non-blocker: admin edit does not sync the change to Helcim's `recurringAmount`. Admin override is direct Mongo-only by design; had to PATCH Helcim manually to re-sync Cleo post-test. Worth noting in docs or surfacing in admin UI post-launch.
|
||||
|
||||
**Assert across all flows:**
|
||||
- Mongo `contributionAmount` is always `Number`, never `String`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue