- src/payments: provider registry and PaymentProvider interface
(createCheckout, verifyWebhook/parseWebhook, getTransaction, refund,
listTransactions as capabilities), Yoco as the first provider. All four
direct Yoco checkout calls go through payments.createCheckout.
- Webhook split into the provider part (signature, parsing) and shared
processing; same URL (/api/webhooks/yoco), same behaviour.
- YocoTransaction renamed in place to ProviderTransaction (+ provider,
unique per provider + externalId); Payment.provider added and
backfilled to "yoco". Payment.method stays the wallet type so cashups
are unchanged.
- Site settings → Payments: Enabled toggle and order per provider; Yoco's
settings shown while it's enabled. R15 minimum for all online payments.
- New endpoint names (/api/payments/checkout, /api/provider-transactions);
the old /yoco-checkout and /yoco-transactions paths still work.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Waitlist per session: entries for pick-sessions tickets name a session;
offers use that session's free places, never run past its start, and
claim links tick it. Held offers count towards session capacity.
- At the door: the Select items pop-up has the session picker, with
today's session preselected for new attendees.
- On pick-sessions events every ticket shows the session list straight
away. "All sessions" tickets record the ticked sessions
(RegistrationOption.sessionIds) at one price; scanning, attendance,
certificates, reminders and capacity follow them.
- Fix: per-session stock limits weren't enforced (takenCount filtered
WaitlistEntry by a sessionId column that didn't exist, and the error
was swallowed), and the public event page lost its stock info.
- Fix: editing a door registration with picked sessions couldn't be saved.
- Fix: the offline-scanning service worker served /_next/static cache-first
forever, so dev browsers that had opened the scanner ran stale code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Event wizard: how people book (whole course / pick sessions), capacity
per session and per-option session mode. Session picker on the public
registration page, Manual registration and the kiosk; at the door points
to Manual registration. Register, tickets and My Events handle picked
sessions. Adds docs/ROADMAP-v2.md and docs/HANDOVER.md so work can carry
on from another machine, and a pick-sessions e2e test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Timed jobs move from in-process timers to a job registry run by pg-boss:
once per schedule across processes, retries, run history, cron schedules
in the church timezone, and an admin Background jobs page with Run now.
Playwright end-to-end tests run against their own seeded database. A
Gitea Actions workflow runs backend tests, frontend checks and the e2e
tests, and deploys v* tags with scripts/deploy.sh once secrets are set.
Also fixes the at-the-door check-in count for multi-day tickets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>