Adds a small paragraph directly below the tier list stating the
Baby Ghosts Studio Development Fund charity status, noting that
Canadian taxpayers can claim contributions, and that setup for
receipts happens after joining. Styled in parallel to
.solidarity-note (12px, --text-dim, 1.65 line-height) so it reads as
a bullet, not a banner.
Scope is /join only — /accept-invite and /member/account copy is
untouched per spec §3.
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.
Extract shared SignupFlowOverlay component. Static "Monthly Contribution"
label on all three contribution inputs (was misleadingly dynamic).
"Per Year"/"Per Month" toggle copy; Per Year default on accept-invite,
Per Month default on join. Live billing-summary card on both signup
flows. Welcome-heading on dashboard via ?welcome=1 for new signups.
$0-member polish on account page (hide payment-history + Solidarity
Fund prompts). State-aware contribution-change hint. Invite accept now
creates Helcim customer and sets auth cookie server-side for both free
and paid branches. Pre-registrant invite + /join signup flows manually
verified against Cleo Nguyen preReg and $0-$50 variants.
Persist nextBillingDate on subscription create/update; unset on
cancel or downgrade to free. Account page displays the cached
date and lazily refreshes from Helcim when the cached value is
within 24h of now (or missing).
Add Payment history section (live-read from Helcim, with loading/empty/error states)
and Change card flow (HelcimPay.js zero-dollar auth -> POST /api/helcim/update-card)
to /member/account. Relabel Helcim portal link to "Advanced billing in Helcim →"
and demote it to a secondary link at the bottom of the billing group.
Removes the 3-second setTimeout that deferred navigateTo('/welcome').
The overlay success state was a holdover from the pre-refactor Step-3
inline block; now that /welcome is the single welcome surface, the
delay just stalls a completed action and fights the continuous-flow
goal of the overlay.
After createSubscription() calls checkMemberStatus(), isAuthenticated
flips to true and the <template v-else> branch unmounts, taking the
Teleport (and its overlay) with it. The authenticated 'You're already a
member' UI then showed for the 3-second pre-redirect delay, producing a
visible flash before navigateTo('/welcome') fired.
Teleport now lives at the root div alongside the v-if/v-else branches,
so the overlay stays mounted through the auth state transition and
covers the page continuously until the redirect.
"$50/yr" was ambiguous — could mean the $5 tier in annual mode or the
$50 tier in monthly mode. On /join the dropdown now shows both prices
("$5/mo → $50/yr") in annual mode. On the account page TierPicker
gains a subtitle slot; annual mode shows "$N/mo tier" beneath the
annual price so members recognize which tier they're on.
Radio-pair cadence selector (Monthly / Annual) added to the join form,
reusing the existing .circle-radio styling. contributionItems computed
reactively; all tier labels and the left-column price list update on
toggle. cadence submitted with the subscription payload. payment-setup
hardcoded to monthly (annual upgrades go through /join).
pending_payment now grants the same RSVP/peer-support capabilities as active,
and status banner/label copy is rewritten to be non-threatening ("Setting up
payment", "Paused", "Closed"). Aligns member-facing copy across the account
page with the capability model.
Introduces /community-guidelines and /policies/{privacy,terms,[slug]} pages,
swaps the signup/invite checkbox from agreedToTerms to agreedToGuidelines,
adds Member.agreement.acceptedAt, and stamps the field when a Helcim
customer is created.
Members (and pre-registrants) hitting wiki.ghostguild.org were getting bounced
to /coming-soon with a "Pre-Register" link, even when the OIDC flow was
working correctly.
- Allowlist /auth/oidc-error, /auth/logout-confirm, /auth/logout-success,
and /verify in the coming-soon middleware so OIDC errors and main-site
magic links stop redirecting to the pre-register page.
- Raise OIDC Interaction TTL from 10m to 15m so it outlives the magic-link
JWT and legitimate members don't hit expired-interaction errors when they
click the email a few minutes late.
- Differentiate the "email isn't a registered member" response on the wiki
login route and show a dedicated "Not a member yet" state with a
pre-register link and contact email, instead of the misleading
"Check your inbox" that silently failed.
Delete uses findOneAndDelete with author match (no TOCTOU window);
existence check only runs on miss to distinguish 403 vs 404. Posts
list capped at 200. Drop unused resolveTagChannel and refreshParams;
route slack URL building through the composable's slackUrl helper.
Replace window.confirm with an inline Delete? / Cancel / Confirm flow on
post cards. Add focus-visible outlines, initials in avatar placeholders,
and promote post/form titles from h3 to h2 for heading order.
- Timezone: curated USelectMenu dropdown (app/config/timezones.js), preserves unknown saved values
- Profile save now uses useToast() for success/error; remove inline save banner
- Nav onboarding dot nudged down 1px for optical alignment with lowercase text
- Onboarding: skip a suggestion with POST /api/onboarding/track {skip}; member.onboarding.skipped map; does not affect graduation
- CirclePicker takes :saved-value so 'Current' badge stays until save completes
- PrivacyToggle is binary (USwitch labeled Private); member schema enum reduced to ['members','private']; zod coerces legacy 'public'
- New /member/payment-setup page: HelcimPay $0 verify + update-contribution, wired from account.vue via requiresPaymentSetup redirect
- Helcim portal: NUXT_PUBLIC_HELCIM_PORTAL_URL env + account.vue 'Manage billing in Helcim' link
- Migration script: scripts/migrate-privacy-public-to-members.js
- Add Board to exploreItems in AppNavigation
- Update ecology.vue + connections.vue redirects to /board
- Rename all communityEcology refs to board in member profiles, dashboard, admin, onboarding
- Update API path /api/members/me/community-ecology → /api/members/me/board
- Renamed ecologyTagOptions, ecologyFilterTags, ecologyTagLabel → board* throughout refs, computed, helpers, and template
- Removed .filter-bar div (duplicate count display)
- Updated pageSubtitle to use filteredSuggestions.length so subtitle reflects active tag filtering