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.14] — 2026-08-24
Finished the listing-expiry loop ("extend it anytime" is now real).
Added
- My listings dashboard page (
/dashboard/products): every fundraiser listing in one table — price, moderation status, expiry date and a quick extend/relist control (15/30/45/90 days). Expired listings show a "Relist for…" button; live ones "Extend by…". - Sidebar link to My listings, and a second CTA on the Getting Started page's "List products" step.
Confirmed already in place
- Getting Started page (six steps: sign up → connect payout account → fundraiser → list products → share your link → get paid).
- Every campaign, organisation storefront and P2P page has its own shareable link with a copy button on campaign pages.
- Auto-expiry (15/30/45/90 days) on the listing form, enforced everywhere (checkout, explore, catalogue), with the update API supporting extension.
[0.9.13] — 2026-08-24
Full-system audit: half-finished features, correctness fixes and old-idea remnants.
Fixed
- Physical wholesale orders now email the business with the buyer's delivery address, zone and delivery charge — previously only vouchers notified suppliers, so physical orders relied on the dashboard alone.
- Removed the leftover destination-charge transfer engine from the
codebase (
lib/wholesale-transfers.tsnow only runs the velocity check). The old webhook paths that would have attempted platform→seller transfers (double-paying the business under direct charges) are gone. - Admin dispute view and analytics export no longer show the obsolete "transfer ID / reversal" fields from the old model (the export now lists shipping zone and charge instead).
docs/architecture.mdupdated from the old application-fee/transfer model to the current direct-charge + invoiced-fee model.
Verified during the audit
- The webhook handles direct-charge checkouts, commission/platform-fee/ business-fee invoices, disputes, refunds and payouts with no transfer remnants.
- All 14 released versions are tagged; type-check and production build pass.
- The branch had been reset to an old commit externally (v0.8.0) while the correct code lived in the tags — the branch was restored to v0.9.12 and this release is committed on top.
Known "waiting on you" items (not code bugs)
- Live Stripe keys + webhook re-pointing (listen to connected-account events and invoice events).
- Server env keys:
RESEND_API_KEY(email),DEEPSEEK_API_KEY(AI),BLOG_API_TOKEN,CRON_SECRET,INDEXNOW_KEY(+ optionalINDEXNOW_ROTATE_DAYS),ORDER_FRAUD_ENABLED. - Fee numbers:
WHOLESALER_FEE_BPS(default 5%) and the free-first-$X threshold (default none). - Lawyer/accountant sign-off on the legal docs and the Option A money flow.
- The dormant BECS subscription-fee invoicing (Phase 3 item, fee default $0) is still available but not scheduled.
[0.9.12] — 2026-08-24
Geographical delivery + metro/rural shipping charges with AI zone checking.
Added
- Delivery coverage on wholesale products: businesses choose where they ship (all of NZ, North Island only, South Island only) and set simple metro and rural delivery charges for physical products.
- Delivery address at checkout: buyers of physical wholesale items enter their delivery details (name, street, city, region, 4-digit postcode). The zone is derived from the NZ postcode rule (rural codes start 7/8/9), the correct metro/rural charge is added to the order, and out-of-coverage orders are declined with a clear message.
- AI address verification: the AI cross-checks the address against the postcode and the supplier's coverage. Disagreements don't block the sale — the order is flagged in the moderation queue for a human to verify before fulfilment.
- Order & fulfilment visibility: shipping charge, zone and the full delivery address are stored on the order, shown to the business on their orders page, included in the buyer's receipt email, and sent to the supplier's fulfilment notification so they can ship without chasing the buyer.
- Business page + help centre updated to explain delivery coverage and metro/rural charges.
- New schema (migration
0024_shipping_zones):ShippingCoverageenum,WholesaleProduct.shippingCoverage/MetroCents/RuralCents, and order shipping fields.
Notes
- The platform fee and the fundraiser's commission apply to the item price only — the delivery charge is passed through to the seller.
- Vouchers are digital and never require a delivery address.
[0.9.11] — 2026-08-24
XML sitemap generator installed on the site.
Added
/sitemap.xml— a live sitemap generated by Next.js on every request. It lists the key static pages, all legal documents, published blog posts, live fundraisers, organisation storefronts and P2P pages, with last-updated dates and priorities. New content appears automatically.robots.txt— allows all crawlers and points them at the sitemap.
Notes
- A downloaded
2026-AdvertiseOnline-generator.zipcouldn't be located on this machine (checked Downloads, Desktop, Documents, OneDrive, attachments and phone folders) — if it's re-attached or its path shared, it can be inspected and installed alongside this.
[0.9.10] — 2026-08-24
Security hardening pass — full audit + fixes.
Fixed
- Login brute force: credential sign-in is now rate-limited (10 attempts per email per 15 minutes), returning the same error as a wrong password so attackers can't detect locked accounts.
- AI cost abuse: the AI content generation endpoint is now rate-limited (40 calls per IP per 10 minutes) so a logged-in user can't burn through your DeepSeek/OpenAI tokens.
- IP-spoofable rate limits: the rate limiter trusted the first
X-Forwarded-Forvalue, which an attacker could spoof through the proxy. It now prefersX-Real-IPand otherwise uses the last (proxy-appended) forwarded address. - Upload validation: uploads now verify the file's magic bytes (not just
the client-declared type), so a renamed HTML/script file can't be stored
or served as an image. Uploaded files also get
X-Content-Type-Options: nosniff. - Blog sanitizer hardened: rendered markdown now also strips iframes,
objects, embeds, forms, SVG/MathML, links, metas and bases, plus
data:andvbscript:URIs on top of the existing script/event-handler stripping. - Security headers on every response:
X-Content-Type-Options,X-Frame-Options: DENY,Referrer-Policy,Permissions-Policy, and a Content Security Policy (frame-ancestors none, base-uri/form-action self, remote images allowed for cover photos). - Blog publishing API rate limit on the token-based update/delete endpoints (30 per 10 minutes).
Dependencies (npm audit)
- postcss upgraded to a patched 8.5.x (resolves 4 high advisories, including the source-map disclosure issues).
- sharp overridden to patched 0.35.x (resolves the libvips CVE cluster).
- Remaining:
deepmerge-tsinside the Prisma CLI tooling (dev-only, not shipped to the runtime). The full remediation for the bundled sharp/postcss chain is a Next.js 16 upgrade, which is a separate breaking-change task.
Verified by review
- Authorization (ownership) checks confirmed on fundraiser/product/wholesale product & order/update/review/export/admin routes.
- Webhook signature verification, server-side price/fee computation, Stripe direct-charge account routing, and the no-open-redirect login flow all confirmed.
[0.9.9] — 2026-08-24
AI token efficiency pass — every AI call tightened.
Changed
- Tighter prompts everywhere: moderation/review prompts, order fraud screening, campaign risk scoring and the fundraiser-reasons check were rewritten to be short and specific (JSON-only replies, no filler).
- Per-task output caps (
max_tokens):- Content generation: now capped per type (80–400) instead of a flat 700.
- Moderation/AI review: 120 (was default 300).
- Order fraud screening: 120 (was 250).
- Fundraiser-reasons verification: 200 (was 500).
- Campaign risk scoring: 120 (was 200).
- Long inputs truncated before they're sent (stories capped at ~3–4k characters, generation context at 2.5k) so prompt cost stays low.
- Provider consistency fix: content generation and campaign risk scoring now use the configured review provider (DeepSeek preferred, OpenAI fallback) instead of only checking for an OpenAI key — so the AI tools actually run with a DeepSeek key instead of silently using template fallbacks.
[0.9.8] — 2026-08-24
Site-wide content audit for the new payment system.
Changed (non-legal pages & copy)
- Landing page: "Get paid safely" now explains the 5% + GST fee is invoiced to the fundraiser, never taken from donations.
- Getting started: step 6 clarified — payments go straight to your bank; wholesale commissions are paid automatically by the business; the platform fee is invoiced weekly to the card you add.
- Business page: the example breakdown now reflects the direct-charge model (buyer pays the business $100 → $10 commission → $5.75 fee invoiced → business keeps $84.25), instead of the old "fee from the sale" wording.
- Campaign page "Where the money goes": explains donations/sales go straight to the seller's own Stripe account and the fee is invoiced to the fundraiser.
- Dashboard sales page: updated the split explanation and column labels — buyers pay sellers directly; wholesale suppliers are paid directly (not "from the sale"); fees shown as invoiced.
- Connect payout account button: no longer says money is "held securely" — it's paid out by Stripe directly, and notes the fee card step.
- Help centre: "Covering platform fees" and "Campaign settings" updated to match the invoiced-fee model and the new reasons editor.
- Fee references aligned: the stored subscription fee reference and the
PLATFORM_FEE_PERCENTconstant now use 5.0 (not the old 5.75 application fee), with migration0023_subscription_fee_percent. - Stripe onboarding comment/URL cleanup (Standard accounts only).
Verified
- Fundraiser Stripe setup end to end: Standard account via hosted onboarding,
account.updatedsync, dashboard payout-account + fee-card steps, and the help guide all match the current flow.
[0.9.7] — 2026-08-24
Legal pages fully aligned to the SaaS/direct-charge model.
Changed
- Audited all legal pages for leftover marketplace wording and removed
it:
- Terms of Service: platform reframed as software/tools/administration; "marketplace platform" wording removed.
- Privacy Policy: same reframe + typo fix ("an agency"); version 2.0 with a direct-charge change note.
- Seller Agreement: no longer describes the Platform as a "marketplace and payment facilitator"; chargebacks clarified as taken from the seller's own Stripe balance. Version corrected to 2.0.
- Fundraiser Agreement: "marketplace items" → "catalogue items"; "hold or reverse payouts" → "pause payouts or commission invoicing".
- Refund, Dispute and AML/CFT policies: bumped to 2.0 with change notes describing the direct-charge model (seller is merchant of record; the Platform never holds or routes money).
- Verified the whole site (all pages and components) has no remaining "marketplace" phrasing.