Changelog
All notable changes to Generous.nz are recorded here, grouped by version. Every deployed build has a version number, a git tag, and an entry below.
Versioning scheme
Versions follow MAJOR.MINOR.PATCH:
- 0.x — pre-launch. Minor bumps mark a completed build phase or major feature set; patches are bug fixes on the current build.
- 1.0.0 — first public launch.
- 1.x+ — post-launch: minor = new features, patch = fixes, major = breaking changes or significant re-architecture.
Each version is tagged in git (v0.2.0) and the current version is kept in
package.json. See docs/version-control.md for how to cut a release.
[0.9.6] — 2026-08-24
Edit fundraising reasons on existing campaigns.
Added
- Each fundraiser card on the dashboard now shows its reason tags (or "No reasons selected") with an Edit reasons / Add reasons button. Owners can change what they're fundraising for at any time, not just at creation.
- Saving re-runs the AI verification against the story (unsupported tags removed, clearly-described tags added, flagged for review if something was removed), so edits stay honest.
[0.9.5] — 2026-08-24
Automatic IndexNow key rotation.
Added
- Rotatable IndexNow key: the active key now lives in the database
(falling back to
INDEXNOW_KEY), so it can change at runtime without a deploy or restart. The verification file at/<key>.txtfollows automatically. - Rotation cron (
/api/cron/indexnow?key=…): generates a fresh 32-char key whenINDEXNOW_ROTATE_DAYShas elapsed (default off; 30 is recommended). Safe to run hourly — it self-throttles to the interval. Each rotation is audited (indexnow.key_rotated).
Notes
- Rotation is hygiene, not security: the key file is public by design. A 30-day cadence invalidates leaked copies without churning the file.
[0.9.4] — 2026-08-24
Fundraising reasons — "what are you fundraising for" tags with AI verification and business opt-outs.
Added
- Fundraiser setup checkboxes: campaigns can tick what they're raising for (medical, education, sport, community, animals, environment, arts & culture, faith, emergency, event, other). Tags show as badges on the public campaign page.
- AI verification in the background: the configured AI reads the story against the selected tags and removes tags the story doesn't support and adds tags it clearly describes. Changes are audited; a campaign that has a tag removed (a likely misrepresentation) is flagged in the moderation queue for human review.
- Business opt-outs: approved businesses can tick "causes you won't fundraise for" in their wholesale dashboard. Fundraisers raising for an excluded cause can't add that business's offers — the catalogue shows "Not available for your fundraiser" and the add-to-store API rejects the add with a clear message.
- New schema (migration
0022_fundraising_reasons):FundraisingReasonenum,Fundraiser.reasons,WholesalerProfile.excludedReasons.
[0.9.3] — 2026-08-24
IndexNow — instant search-engine submission.
Added
- IndexNow integration (
lib/indexnow.ts): new and changed pages are submitted to Bing and other participating search engines the moment they go live. - Key file endpoint —
https://generous.nz/<key>.txtis served automatically whenINDEXNOW_KEYis set (any other key returns 404). - Automatic submissions:
- Blog posts on publish (both
/blog/<slug>and/blog), from the admin area or the external AI publishing API; - Fundraisers when approved and when updated (
/f/<slug>); - Organisation storefronts on creation (
/orgs/<slug>); - P2P supporter pages on creation (
/p2p/<slug>).
- Blog posts on publish (both
- Setup guide:
docs/indexnow.md; env entry added to.env.example.
Notes
- Submissions are best-effort and never block publishing. Batches of 25
URLs per request. Disabled entirely when
INDEXNOW_KEYis unset.
[0.9.2] — 2026-08-24
Business platform fee on sales generated, with growth options.
Added
- Business platform fee: businesses supplying the wholesale catalogue
are now invoiced 5% + GST of the sales generated through fundraisers
(rate via
WHOLESALER_FEE_BPS, default 500 = 5%). Invoices are created on the platform's own Stripe account, auto-charged to the business's saved card on the same weekly cadence as the fundraiser fee, and appear in the business's Billing page and the admin wholesale-invoices area. - Free-first-$X (
WHOLESALER_FREE_SALES_CENTSglobally, or a per-business override in Admin → Wholesalers): the first $X of a business's lifetime sales incur no platform fee. - Credit vouchers: admins can grant credit to a business
(
feeCreditCents) that offsets future platform-fee invoices before the card is charged — the "give $X in credit" growth lever. - Refund/dispute fairness: when a wholesale order is refunded or lost to a chargeback, the business receives an automatic fee credit for that sale (idempotent).
- New fields (migration
0021_business_platform_fee):WholesalerProfile.feeCreditCents,WholesalerProfile.freeSalesThresholdCents,WholesaleSettlement.feeCreditApplied.
Changed
- Admin wholesale-invoice retry now handles card-charged invoices (Stripe invoice re-pay) as well as BECS mandates.
- Help centre, business landing page, Wholesaler Agreement v2.1, Terms of Service, legal sign-off pack and setup docs updated for the business fee.
[0.9.1] — 2026-08-24
Goal-gradient improvements (XXXXX-style).
Changed
- "Raised" now counts product sales too — donations + paid orders (including wholesale sales) drive the progress bar, the dashboard totals, and the organisation storefront, so the number tells the truth on every campaign type.
- "X left to go" under the bar — the goal-gradient trigger shows how much is needed, not just a percentage.
- "Goal reached 🎉" state — when raised crosses the goal the bar celebrates instead of capping silently.
Added
- Goal celebration (
lib/milestones.ts): when a payment crosses the goal, the platform posts a campaign update from the owner and emails every supporter (donors + buyers). Fires once per goal; if a refund drops the total below the goal the flag clears so it can fire again. - Extend goal: fundraisers can raise their target from the dashboard
once reached (resets
goalReachedAtso urgency and celebration restart). - New
Fundraiser.goalReachedAtfield (migration0020_goal_milestones).
Documentation
- Help centre "How goals and progress work" article updated.
[0.9.0] — 2026-08-24
Option A — direct charges. The payment architecture is rebuilt so the platform never touches sale or commission money.
Changed (payment architecture)
- Every payment is now a direct charge to the seller's own Stripe
account (the business for wholesale items, the fundraiser for their own
items, donations and subscriptions). No more destination charges,
transfers,
on_behalf_ofor application fees. - Wholesale: the business is the merchant of record. The buyer pays the business directly; the business pays the fundraiser's commission (minimum 10%) via automatically generated invoices, charged to a card the business saves once (Stripe's official cross-account card-cloning pattern).
- Platform fee: 5% + GST is now invoiced to the fundraiser on a weekly
cycle (
PLATFORM_FEE_BILLING_CADENCE_DAYS, default 7) and auto-charged to a card the fundraiser saves once. It is no longer taken from payments. - Refunds and chargebacks are debited from the seller's Stripe balance; commission on refunded/disputed orders is cancelled or credited against the next invoice. The platform no longer backstops sale/commission chargebacks.
- Receipts show the real seller (business for wholesale, fundraiser
otherwise). Commission invoices include GST only when the fundraiser is
GST-registered (
Fundraiser.gstRegistered).
Added
- New schema (migration
0019_option_a_direct_charges):CommissionInvoice,PlatformFeeInvoice,WholesalerConnectedCustomer, settlementINVOICED/CREDITEDstatuses, billing-card fields. - Commission engine (
lib/commission.ts) and platform-fee billing (lib/platform-fee-billing.ts) with automatic retries and reminders. - Card setup flows: businesses add a commission card in Billing; fundraisers add a fee card in the dashboard (hosted Stripe setup, no card data stored by the platform).
- Commission invoice history on the wholesaler billing page; updated settlement statuses in the admin area.
- New email templates: commission invoice issued/paid, card reminders, platform-fee invoice + reminder.
- Webhook events updated for direct charges and invoices (
invoice.paid,invoice.payment_failed,invoice.finalized); webhook endpoint must listen to events on connected accounts. - Legal sign-off pack for your accountant/lawyer:
docs/legal-signoff-option-a.md.
Documentation
- Fundraiser, Wholesaler, Seller agreements + Terms, Privacy, Refund, Dispute and AML-CFT policies updated to the direct-charge model.
- Help centre updated (how payments work, platform fees, commission invoicing for businesses, Stripe setup with the fee card step).
docs/stripe-architecture.md,docs/wholesale-marketplace.md,docs/stripe-setup.md,docs/go-live.mdrewritten for Option A.
Deployment notes
- Apply migration 0019 on the server (
prisma migrate deployruns automatically on deploy). - Re-point the Stripe webhook to listen to your account AND connected
accounts and enable the new invoice events (see
docs/stripe-setup.md). - Fundraisers and businesses must add their payment cards; run the
test-mode drills in
docs/stripe-setup.mdbefore live.
[0.8.2] — 2026-08-24
Help centre — Stripe setup guides.
Added
- New Stripe setup category in the help centre with three articles:
- Full Stripe account setup (step by step) — what information is needed (legal name, DOB, address, ID, bank account, sometimes IRD), the exact steps from the dashboard through hosted onboarding, and troubleshooting.
- Why do I need to verify my identity and give my bank details? — the KYC/AML reasons in plain language.
- Understanding the admin Payments setup page — what the page checks (keys, webhook events, connected accounts) and how to use it.
- The admin Payments setup page now links to the help article explaining it.
Corrected (review of an external AI answer)
- This platform uses Stripe Connect Standard accounts with Stripe-hosted onboarding — not Express or Custom. The help article reflects that: Stripe collects identity and bank details directly, the platform never sees them, and no business fields or MCC codes are pre-filled by the platform (a Custom-account pattern that does not apply here).
- The required-information list and the “moderate friction” assessment from the reviewed answer were accurate and are now documented in the help centre, written for a casual fundraiser (school PTA, muffin stall, etc.).