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.22] — 2026-08-24
AI fraud protection as a business selling point.
Changed
- Business page now markets the platform's AI checks: a new "AI fraud protection" feature card and a full "Protected by AI, reviewed by humans" section covering order screening, fundraiser/product pre-live checks, delivery-address verification, and the human-review rule for anything flagged. Metadata description updated too.
- Copy reflects what's already wired: fundraisers, products, reviews and organisations are AI-reviewed on submission; orders are screened at checkout; delivery zones are AI-verified.
Notes
- Order fraud screening runs once
ORDER_FRAUD_ENABLED=trueand a provider key are set on the server; the rest of the checks run automatically with the DeepSeek key configured.
[0.9.21] — 2026-08-24
Business fee confirmed: 5% + GST with the first $1,000 of sales free.
Changed
- Free-first-$1,000 is now the product default (not just a server
setting):
wholesalerFreeSalesThresholdCents()defaults to 100000 cents, so every approved business gets its first $1,000 of sales with no platform fee — a $50 saving at 5%. Per-business overrides still available in admin;WHOLESALER_FREE_SALES_CENTS=0disables it. - Business sign-up page makes it the headline: hero banner "No platform charges on your first $1,000 in sales", updated feature card, the example now shows the first sale keeping $90 (fee waived), and the sign-up checklist states it up front. Metadata description updated too.
- Help centre and docs updated ("first $1,000 free" instead of the generic "$X").
[0.9.20] — 2026-08-24
International business applications require manual admin review.
Added
- New country field on business applications (default New Zealand; common countries selectable, "Other" with a free-text name).
- Non-NZ applications are flagged for manual review: the admin
wholesalers page shows the country and an "International — manual review"
badge; applications remain in
APPLIEDstatus until an admin decides (approval is admin-only, and the audit log records the country). - Migration
0026_business_country.
[0.9.19] — 2026-08-24
Stats everywhere — views, popular products, top purchasers, downloads.
Added
- Page-view tracking: every fundraiser page counts total views and unique
daily views (rate-limited, deduped per IP/day; migration
0025_views). - Fundraiser stats dashboard (
Dashboard → Stats & orders): views, raised, orders, units, average order, raised-per-day chart, most popular items, top purchasers (buyer name/email — owner-only, for privacy), recent orders, and a CSV export with delivery details. - Business analytics upgrade: paid-to-you, orders/units, fundraiser page views, top buyer spend, sales-per-day chart, most popular products, top purchasers, and a "what works" table — every fundraiser selling your products with views, orders, units and what you receive. Filter by fundraiser to see each campaign's contribution. Download all orders CSV now includes the full delivery address + commission and honours the fundraiser filter — ready to fulfil.
- Admin analytics: fundraiser page views, site-wide most popular products and top purchasers, alongside the existing totals/charts.
Notes
- Buyer names/emails appear only in owner/admin dashboards, not on public pages (Privacy Act 2020).
[0.9.18] — 2026-08-24
Off-site backup to Dedirock (hardened SFTP).
Added
- Dedirock backup target configured (
23.95.7.102): dedicated non-loginbackupuser, key-only auth, forcedinternal-sftpconfined to/home/backup/generosity, and the authorized key restricted to this server's IP with forwarding/PTY disabled — a compromised app server can't reach the rest of the backup host. - Backup job (
scripts/offsite-backup.sh): pg_dump → gzip, uploads tar, pushed via restricted SFTP with 14-copy retention. - Setup guide (
docs/backup-offsite.md) with the one-time root commands to finish on the app server (move key, install script, cron, test).
Notes
- Requires the one-time root steps in the guide (the key is staged at
/home/deepseekcs/.ssh/generosity-backupon the app server).
[0.9.17] — 2026-08-24
Go-live plan rewritten for the current build.
Changed
docs/go-live.mdrebuilt as a phased checklist (Phase 0 decisions & sign-off → deploy/config → test-mode drills → live switch → first-two-weeks watch), with explicit gates and references to the current setup guides.
[0.9.16] — 2026-08-24
Off-server image storage (Bunny) + automatic unused-image cleanup.
Added
- Bunny Storage support (
lib/uploads.ts): whenBUNNY_STORAGE_ZONEandBUNNY_STORAGE_ACCESS_KEYare set, new uploads go straight to Bunny Storage;BUNNY_PULL_ZONE_URLserves them via the Bunny CDN. Existing/api/uploads/...URLs keep working unchanged (the route serves local files first, then redirects to the CDN) — no database migration needed. - One-off backfill script (
scripts/backfill-uploads-to-bunny.mjs) to move existing files to Bunny. - Upload garbage collector (
lib/upload-gc.ts+/api/cron/upload-gc): scans every product, wholesale product, fundraiser, organisation and blog post for referenced images and deletes the rest after a grace period (UPLOAD_GC_GRACE_DAYS, default 7). Covers the cases you asked about — business removes an item, changes a photo, fundraiser does — plus anything else that becomes unreferenced. Runs against whichever backend is active (local or Bunny). - Setup guide:
docs/upload-storage.md.
Notes
- Everything is env-gated: with no Bunny keys, the site behaves exactly as before (local storage).
- Images are still optimised before storage (1600px, quality 80, metadata stripped), so what reaches Bunny is already small.
[0.9.15] — 2026-08-24
Auto-optimised image uploads — smaller files, originals never stored.
Changed
- Every uploaded image is now processed on the way in: resized to a max long edge of 1600px (never enlarged), re-encoded at quality 80 for JPEG/WebP/AVIF, losslessly compressed for PNG, EXIF/orientation metadata stripped, and the original bytes are never written to disk.
- The site fits images into each layout with CSS (
object-cover), so one lean file serves every space — campaign covers, product cards, storefront banners and blog covers. - Safety net: if optimisation ever produced a larger file (e.g. a tiny already-optimised image), the original is kept instead.
sharpis now a direct dependency (it was already in the tree via Next).
Notes
- Applies to new uploads. Existing uploaded images are untouched — a
one-off script can re-process the current
uploads/folder if you want to reclaim space now.