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.330] — 2026-09-11
Changed
- Saving a campaign is fast again. The save used to wait on two AI calls (the "what are you fundraising for" tag check and the fraud score) before it would respond — about 2 seconds on a good day and much longer when the AI provider was slow. Both now run after the response, alongside the moderation review that was already backgrounded, so the save returns as soon as the campaign is written and the redirect to the campaign page happens immediately. Editing a campaign also no longer waits on the AI tag check or the IndexNow search-engine ping. A slow save now logs a warning so we can see it if it ever creeps back.
[0.9.329] — 2026-09-11
Changed
- Static assets (JS/CSS) are now served from the CDN edge. They were being
served from the origin server; they now come from the Bunny pull zone behind
fast.generous.nz, so the browser fetches them from the nearest edge and the origin only serves the first request per edge. Driven by theASSET_PREFIXenv var (unset = self-hosted), so it can be switched off with an env change and a redeploy. Nginx's Content-Security-Policy now allows the CDN host for scripts and styles. Images were already on Bunny (images.generous.nz).
[0.9.328] — 2026-09-11
Added
- Stripe account guard. If a business's Connect account is disabled
(Stripe sets a disabled reason), deleted, or the business deauthorises the
platform, their catalogue items are paused and the copies fundraisers added
to their own stores are hidden straight away. It runs on the
account.updatedandaccount.application.deauthorizedwebhooks, with an hourly sweep as the backstop for missed webhooks. The business is suspended and admins get an email with the reason; when Stripe reports the account healthy again the guard restores exactly the items it took down (never anything a fundraiser or admin changed themselves) and emails admins again. Businesses that simply haven't finished onboarding have their listings hidden without being suspended, so buyers never reach a dead checkout. - Unfulfilled order guard. Paid orders that haven't been marked shipped or complete after a configurable number of days (default 7) send the seller a nudge — throttled to one reminder per order every three days — and produce an admin alert listing everything waiting, with anything past twice the window flagged as overdue. Runs with the daily reconciliation job.
- Admin → Settings: an Order follow-up & account guard card with the day threshold and a Run checks now button. Admin → Reconciliation: live panels for orders waiting on a seller and businesses paused by the Stripe guard.
- The business is told directly. The moment the guard takes their listings down they get an email explaining what happened, what was hidden, and a one-click link back into Stripe to fix it (falling back to the wholesale setup page if a link can't be created). They're reminded every 7 days while it's still broken, and get a second email when their listings come back.
Changed
- Brand line tidied up: the email and voucher footers and the web app manifest now say "Sell. Donate. Be Generous.nz", matching the site (they still had the old "Make a difference" tagline).
[0.9.326] — 2026-09-11
Changed
- The fundraiser QR code now uses the Generous.nz brand icon in the centre
(
public/icons/generosity-icon.png, converted from the supplied artwork), replacing the older site icon. It sits on the same white backing so the code stays scannable, and the previous icon stays in place as an automatic fallback if the brand asset is ever missing from a deploy.
[0.9.325] — 2026-09-11
Changed
- The campaign form's thank-you message is now prefilled: "Thanks so much for supporting our cause — it really means a lot to us…", so donation receipts carry a warm line instead of arriving bare. It stays optional — fundraisers can rewrite it or clear it (an empty box saves as no message, and the field is prefilled again next time the form is opened). Campaigns that already have their own message keep their own wording untouched.
[0.9.324] — 2026-09-11
Fixed
- "Please enter a URL" after a cover image upload. The uploader saves
images as site-relative paths (
/api/uploads/…), but the cover-image fields were markedtype="url", so the browser blocked the form with "Please enter a URL" even though the upload had succeeded. Those fields — the fundraiser cover image, and the organisation logo and cover image — are now plain text inputs with a URL keyboard hint, so an uploaded image or a pastedhttps://…link both work (the server-side rules already accepted both).
[0.9.323] — 2026-09-11
Fixed
- AI-written copy can no longer send supporters to another site. A generated campaign story pointed supporters at a different fundraising website. Every AI prompt now carries hard rules — this site is the only place to give, never name or link another platform, never invent links, emails, phone numbers or payment details — and a deterministic check runs over the result. If a model still names another platform the draft is regenerated once, and the built-in template (written for this site only) is used if it happens again, so off-platform copy is never shown, saved or published. The saved draft containing that line has been corrected.
- AI moderation now treats off-platform giving as a risk factor for campaigns and listings (another site, an external link, a personal bank account or a mobile number), so anything steering supporters away from the checkout is flagged for a human reviewer.
Changed
- Help centre: the AI story generator article now explains that drafts are always written for Generous.nz and never point supporters elsewhere.
[0.9.322] — 2026-09-11
Added
- Who you are buying from is now explicit at every step of a purchase.
Stripe Checkout carries a message naming the seller and confirming the
payment goes to them (not Generous.nz); the wholesale product page says
"Sold and fulfilled by
— your purchase is with them, not with Generous.nz"; fundraiser store cards name the supplying business; the order receipt email spells out that delivery, product faults and refunds belong to the seller; and the success page explains that refunds and chargebacks come from the seller's account, with us supplying the records if a buyer takes it further. - Help centre article "Who am I buying from?" covering the seller-of-record position and what happens if a business closes or stops trading.
Changed
- Terms of Service 3.2 — wholesale items are bought from the supplying business rather than from Generous.nz, including what happens if that business stops trading or becomes insolvent, what we will still do to help, and a matching limitation-of-liability item.
- Refund Policy 3.2 — new section 2.1 covering seller insolvency, refunds from the seller's Stripe balance and the chargeback route.
- Wholesaler Agreement 3.3 and Seller Agreement 3.1 — duty to tell us promptly if the seller stops trading or becomes insolvent, and to still fulfil or refund orders already accepted.