Commit Graph
100 Commits
Author SHA1 Message Date
joshuaandClaude Opus 5.5 4c577fffb7 Docs: roadmap v3 and Hub protocol moved to crosscode-platform/docs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 09:48:31 +02:00
joshuaandClaude Opus 5.5 cc855ec8bb Docs: Hub 2.0.0 released (phase 1); hub-protocol.md with protocol v2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 09:10:33 +02:00
joshuaandClaude Opus 5.5 d6ff08f5d9 Docs: church installs under /var/www/sites/<church>/<product>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 14:54:05 +02:00
joshuaandClaude Opus 5.5 1adf1d4870 Docs: monorepo move, crosscode deploy script, releases per product
ROADMAP-v3 decisions 21-24: Cross Events moves into crosscode-platform
(2.2.0); one crosscode script deploys Accounts plus the products named;
the Hub tracks releases per product with requirements; the Hub gets the
contracts as a committed file, not from the package registry. Cross Events
versions in the build order move up by one. HANDOVER updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 14:48:36 +02:00
joshuaandClaude Opus 5.5 e42e244edc Roadmap v3: four Website templates; SEO for every public site
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 10:04:13 +02:00
joshuaandClaude Opus 5.5 f85842d4b3 Roadmap v3: Hub protocol v2 (today's is v1), event-feed schema, enum rule
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 09:47:42 +02:00
joshuaandClaude Opus 5.5 78bf6df40c Roadmap v3: sign-in returns to where you came from; crosscode-site per phase
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 09:31:29 +02:00
joshuaandClaude Opus 5.5 47725a689d Roadmap v3: decisions, pricing and authenticator-app 2FA; handover updated
One install of each product per customer; House of Prayer booking
defaults; email and WhatsApp only (no push); Accounts hidden from
members. Pricing: Website R99 with 5 GB plus storage add-on, App from
R99, address once per church (own domain, crosscode.co.za address R10,
domain included R25). Authenticator app 2FA as Cross Events 2.2.0.
Handover now points at ROADMAP-v3; nothing left open in ROADMAP-v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 16:48:23 +02:00
joshuaandClaude Opus 5.5 a9584cdde5 Roadmap v3: Accounts, Church Website, Church App, Cross Code Hub
Plan for selling three products from one Hub: shared users through a
per-church Accounts service, event sync in any direction on one shared
format (crosscode.event/1), PM2 installs per product per church.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 16:14:24 +02:00
joshuaandClaude Opus 5.5 73547a0f8c Feedback Send now and Remind run in the background (2.1.1)
- Send now and Remind answer straight away with who they're going to and
  queue the feedback-send task; the Feedback page refreshes to show progress.
- One-off background tasks (enqueueTask in src/jobs/index.js): pg-boss with
  retries, or in-process after the response when the queue is off.
- Reminders are claimed with the 24-hour rule, so two tasks at once never
  remind the same person twice.
- Tests: tests/tasks.test.js, tests/feedbackPage.test.ts, e2e/feedback.spec.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 14:11:44 +02:00
joshuaandClaude Opus 5.5 b5821e1c18 Handover: Hub 1.7.0 bills on the income bands
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 13:42:46 +02:00
joshuaandClaude Opus 5.5 84a1a9084c Feedback page: results, responses, who hasn't answered, reminders (2.1.0)
- Supervisor -> Feedback (supervisors and admins, campus-scoped): every
  event's form with answered of asked, response rate, average rating and
  last reminder; per event the results per question (with the AI summary),
  each response, and on named forms who was asked and who has answered.
- Remind those who haven't answered (or one person on a named form): a
  fresh link, plus the form to anyone eligible who hasn't had it; nobody gets
  the form or a reminder twice within 24 hours. The 3-day job is unchanged.
- Anonymous forms show no names and no list of who has answered.
- FeedbackInvite.reminderCount (migration 20261103120000_feedback_reminders);
  access log action feedback_responses; help page; dashboard and Ctrl+K links.
- Roadmap: the AI helpers on the privacy pages are dropped; 2.1.0 is the
  feedback page.
- Tests: tests/feedbackPage.test.ts, e2e/feedback.spec.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 13:03:05 +02:00
joshuaandClaude Opus 5.5 ff4c0c76d3 Billing income bands up to R10m, 12-month event income in the heartbeat (2.0.2)
- Heartbeat income bands widened from "over R100 000" to 14 bands up to
  "over R10 000 000"; every licence-tier edge is a band edge (tested).
- New income.eventIncome12m: last 12 months' event income without donations,
  sponsorships or donation legs, which the licence tier is billed on.
- Fix: donation legs were counted twice in the heartbeat income bands.
- Protocol doc, roadmap pricing decisions, changelog, what's new, handover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 12:18:01 +02:00
joshuaandClaude Opus 5.5 89eab66145 Summarise this report on every report (2.0.1)
The eight reports that list people get the AI summary too, sent as
anonymised totals built on the screen (aiReportData.ts): no names,
contact details, notes or comments; consent and medical only as counts.
The server refuses personal columns on those reports and logs each
summary in the access log (ai_report; sensitive for consent and medical).

Roadmap §18: 2.0.1, then crosscode.co.za, then 2.1.0 (AI helpers on the
Consent log and Access log).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 18:42:27 +02:00
joshuaandClaude Opus 5.5 8805101929 Docs: marketing site decisions (crosscode.co.za)
crosscode.co.za as Cross Code's main site with a Cross Events page;
church website and app as "coming later"; repo joshua/crosscode-site;
own server; no prices yet; contact form to info@crosscode.co.za;
privacy notice and terms of use; no cookies. Content from Joshua later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 18:01:23 +02:00
joshuaandClaude Opus 5.5 a4bdf846ad Release 2.0.0
AI helpers, API v1 removed, Argon2id passwords, React Compiler lint
rules back to errors, migration guide. Docs (HANDOVER, roadmap) mark
2.0.0 as released.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 17:49:30 +02:00
joshuaandClaude Opus 5.5 8cc2cefe80 WIP 2.0.0: React Compiler lint rules back to errors; docs
- The 192 places the rules flagged are fixed and the rules are errors
  again (npx eslint src: nothing). lib/hooks.ts: useStateSync (state
  that follows other state, set while rendering), useExternalEffect
  (API loads and browser reads), useNow; lib/navigation.ts hardNavigate
  for full reloads after sign-out or identity switches; other pages use
  the router. Resets moved into the handlers that cause them.
- The banner shows and hides at its times on open pages.
- HANDOVER, roadmap, README, FEATURES, SETTINGS, CHANGELOG updated;
  2.0.0 section drafted in WHATS-NEW.

e2e 102/102 (PayFast sandbox skipped); production build passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 17:45:25 +02:00
joshuaandClaude Opus 5.5 9913a13f70 WIP 2.0.0: v1 removed; Argon2id passwords; node-fetch gone
- /api (v1) answers 410 API_V1_REMOVED, except provider webhooks
  (/api/webhooks/*, /api/whatsapp/webhook) and links in sent messages
  (308s, one-click POST). 43 v1 route files and deprecation.ts removed;
  /docs redirects to /docs/v2; API_DOCUMENTATION.md points there.
- Read-only and impersonation lists name v2 paths only. The campus
  scope route test now runs over v2 routes (v2CampusScope.test.ts).
- Passwords hashed with Argon2id (@node-rs/argon2); bcrypt hashes still
  sign in and are re-hashed at the next sign-in.
- e2e on /api/v2 only (v2() helper); Playwright waits on /api/v2.
- MIGRATING-TO-2.md with the full v1 -> v2 table.
- Two documented response shapes corrected.

Backend 690 tests and e2e 102/102 (PayFast sandbox skipped) pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 16:35:06 +02:00
joshua 8a424ac77e Merge branch 'main' into release/2.0 (1.52.2)
# Conflicts:
#	CHANGELOG.md
#	docs/HANDOVER.md
2026-11-02 14:13:12 +02:00
joshuaandClaude Opus 5.5 51992814d2 Deploy: stop first when files in the install were changed by hand (1.52.2)
A setup wizard run on one server added files to backend/src that the
backend build picked up, so the deploy failed part-way and rolled back.
deploy.sh now lists files git reports as changed or added (ignored files
and the PM2 config don't count) and stops before backing up or checking
out. --check runs only that; ALLOW_LOCAL_CHANGES=1 deploys anyway; the
script also runs from a copy outside the install (the folder you're in).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 14:03:12 +02:00
joshua a0ff8dfc89 Merge branch 'main' into release/2.0 (1.52.0, 1.52.1)
# Conflicts:
#	CHANGELOG.md
#	docs/HANDOVER.md
2026-11-02 13:45:28 +02:00
joshuaandClaude Opus 5.5 1ae4c47001 Docs: every v2 route documents its body, answer and parameters (1.52.1)
Most routes answered by a v1 handler showed an empty body and
`data: unknown` in /docs/v2. Each now documents what its handler reads
and answers, and every path and query parameter is described.

- `documented: { body?, response? }` on v1Route/defineRoute, with shared
  shapes in src/v2/docs.ts. Documentation only: not enforced, so nothing
  that works can start failing; outside production a body or answer that
  doesn't fit is logged ("doesn't match its documented schema").
- QUERY_HELP / PATH_HELP describe common parameters; empty bodies say
  "No body needed".
- Declared the funnel's eventIds and webhook deliveries' status/before.
- tests/v2Docs.test.ts keeps the document complete; frontend types
  regenerated, three call sites' types tightened (no payload change).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 13:26:15 +02:00
joshuaandClaude Opus 5.5 62b10c3db5 Fix: door and manual registrations get their tickets; admin Corrections (1.52.0)
On events with a required attendee form, tickets waited for the forms, but
At the door and Manual registration never asked for them: payment was
recorded and nobody could be checked in.

- The form pops up at the door and in Manual registration; "Fill in later"
  (any staff) issues the tickets once paid and sends the payer a link
  (Registration.formWaivedAt, POST /api/v2/registrations/{id}/form-later).
- One form per person on picked-session bookings; a required form with no
  questions no longer holds tickets back; every caller asks the ticket
  generator (formsOutstanding).
- Kiosk asks for the forms the server says are missing; headings show as text.
- Admin Corrections page and /api/v2/corrections: issue missing tickets,
  pay later (ticketsReleasedAt), make it free (complimentaryDiscount),
  check in or undo after the event.
- Migration 20261102120000_corrections; unit and e2e tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 12:01:10 +02:00
joshuaandClaude Opus 5.5 36cabfee0d Docs: Sonnet 5.5 for every AI helper (Hub 1.6.1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 17:25:16 +02:00
joshuaandClaude Opus 5.5 206a814973 Docs: 2.0 progress, marketing site plan, AI tested
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 09:58:48 +02:00
joshuaandClaude Opus 5.5 311fe8b6f1 WIP 2.0.0: AI helper plumbing (status, usage, Site settings -> AI)
The site calls AI through the Hub (protocol 3b, Hub 1.6.0): src/ai
works out whether the AI buttons show (licence token first, then the
Hub, cached a minute), runs a helper call with per-helper switches and
a per-person daily limit, logs AiCall rows, and emails admins at 80%.
v2 /ai/status, /ai/usage, /ai/settings; useAiStatus, AiButton, AiTab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 09:25:36 +02:00
joshuaandClaude Opus 5.5 376b93a438 Docs: bring HANDOVER and ROADMAP-v2 up to date after 1.51.17
HANDOVER: version table in order with 1.51.4/1.51.5 added; Next up
renumbered with the 2.0 clean-ups (lint rules, node-fetch, password
hashing); event picker points at fetchManagedEvents; stale lines fixed.
ROADMAP: status rewritten as a dated summary; section 14 marks what's
done and that CI was removed; Haiku prices flagged to check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 09:00:49 +02:00
joshuaandClaude Opus 5.5 98e5d05548 WIP 1.51.17: forgot password and sign-in don't reveal accounts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-30 08:47:04 +02:00
joshuaandClaude Opus 5.5 5b50b0ce4f Incoming webhooks and message links on API v2 (1.51.16)
- /api/v2/webhooks/{yoco,payfast,whatsapp}; new provider set-ups use them, the v1 addresses
  keep working with the same handlers.
- Calendar and one-click unsubscribe links point at v2; old links answer 308 (a one-click POST
  to the old address is still handled there).
- /api/webhooks/whatsapp runs the real WhatsApp handler (was an empty stub).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-30 08:34:41 +02:00
joshuaandClaude Opus 5.5 c4fff7c835 Privacy and admin on API v2 (1.51.15)
- v2: my privacy, unsubscribe links, the privacy admin, audit log, jobs, impersonation,
  settings and first-run set-up, the Hub, outbound webhooks, backups, Yoco/PayFast settings.
- Every call the app makes is now on /api/v2 (incoming webhooks and message links: 1.51.16).
- v1Route handles res.download/sendFile; impersonation end/log allowed on v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-30 08:23:49 +02:00
joshuaandClaude Opus 5.5 8747431bd5 WIP 1.51.14: GET /me carries the session fields the app needs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-30 08:07:06 +02:00
joshuaandClaude Opus 5.5 1a25896999 Kids check-in and volunteers on API v2 (1.51.13)
- v2: my family, kids set-up and the check-in desk (board, families, check-in/out, codes,
  offline), volunteering (roles, sign-up, swaps, self check-in) and rosters (roles, assigning,
  manual check-in, hours).
- Frontend: kids desk, rooms, family, serving and rosters on v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 16:50:10 +02:00
joshuaandClaude Opus 5.5 3a5b042525 Tickets and attendance on API v2 (1.51.12)
- v2: tickets (mine, one, send, issue, transfers, scans), scan locks, the attendance register
  and its export, certificates, allocations.
- Frontend: apiV2Raw() for string-path helpers; every ticket/attendance screen on v2.
- v1Route can run a v1 router by URL; an unanswered chain is a 404.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 16:40:27 +02:00
joshuaandClaude Opus 5.5 28e31ffb99 Money on API v2 (1.51.11)
- v2: payments, refunds, donations, payment links and the pay page, providers, cash-ups,
  provider transactions, waitlist, sponsorship, consent, form responses, feedback.
- src/v2/viaV1.ts: v1Route() answers a v2 route with the v1 handler in-process.
- /docs/v2 opens collapsed with a filter (Swagger UI stopped drawing past ~130 endpoints).
- Frontend: every money screen on v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 13:47:49 +02:00
joshuaandClaude Opus 5.5 31ee2a9aee Managing registrations on API v2 (1.51.10)
- v2: staff list (paged), event registrations, registration in full (+ /me), status, manual
  registration, bulk, items, invoice, coupon, attendees and form links, form drafts and responses.
- src/services/registrationAdmin.ts holds the rest of registrationController.js (now v1 wrappers).
- Frontend: fetchAllRegistrations(); every registration screen on v2.
- Roadmap: money gets its own release (1.51.11); webhooks and links move to 1.51.16.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 13:16:59 +02:00
joshuaandClaude Opus 5.5 59fde801f7 Series, season passes, deals and campuses on API v2 (1.51.9)
- v2: series (+ page, compare, follow), season passes (+ buy, pay, mine), bundle deals
  (+ quote), coupon codes (+ check, redemptions), campuses (+ admin, enabled, order, audience).
- src/services/series.ts, deals.ts, campuses.ts; the five controllers are thin v1 wrappers.
- v2 errors carry a service's own code as `reason`.
- Frontend: apiV2Data() for screens with their own record types; these screens on v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 12:39:27 +02:00
joshuaandClaude Opus 5.5 9547793f25 The rest of event set-up on API v2 (1.51.8)
- v2: event in full, calendar file, alias, ticket options and variants, attachments
  (multipart), sections, planned costs, image uploads.
- src/services/eventDetails.ts and src/services/setup.ts; v1 uses them.
- v2 routes can send files (fileResponse) and take uploads (documented as multipart).
- Frontend: fetchEvent() everywhere, lib/eventSetup.ts for set-up calls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 12:18:29 +02:00
joshuaandClaude Opus 5.5 2bcc9ac651 Setting events up on API v2, pg-boss 11 (1.51.7)
- v2: /events/manage, create, PATCH, deactivate, copy-from, notify-recipients.
- src/services/events.ts (from eventController.js, with the schedule helpers); v1 uses it.
- fetchManagedEvents() for every picker; the event wizard writes through v2.
- pg-boss 11 in its own schema (pgboss_v11); old pgboss schema left in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 11:57:08 +02:00
joshuaandClaude Opus 5.5 70850df4f6 Complete command palette, ExcelTS 10, roadmap: v2 for webhooks and sent links (1.51.6)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 11:14:19 +02:00
joshuaandClaude Opus 5.5 849998acb3 Next.js 16, React 19.3, ESLint 10 (1.51.5)
- Next 16 (Turbopack dev and build), React 19.3; tsconfig jsx react-jsx; images remotePatterns.
- ESLint 10 with eslint-config-next 16 flat configs; npm run lint = eslint src. React
  Compiler-era react-hooks rules set to warn (181 existing places) until screens move to v2.
- Removed the empty pass-through middleware.ts.
- e2e: wait for the palette to be ready before Ctrl+K on the staff dashboard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 11:00:30 +02:00
joshuaandClaude Opus 5.5 6164fdcb3b Security and dependency updates, Node 24 for new installs (1.51.4)
- npm audit fixes: next 15.5.28 and @sentry/nextjs 10.78 (critical), zod 4.6.7, multer 2.5.0
  (high), nodemailer 10.3.0, fast-uri, ip-address (moderate). Minimum versions raised.
- cron-parser 5 (v4 unmaintained).
- install.sh installs Node 24 LTS; deploy.sh warns on Node < 22; DEPLOYMENT.md "Upgrading Node".
- Roadmap: every endpoint moves to v2 before 2.0 (1.51.5 - 1.51.11).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 10:19:43 +02:00
joshuaandClaude Opus 5.5 fa4191d18c Roadmap: 2.0 retires only the v1 endpoints that have a v2 replacement
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 09:49:54 +02:00
joshuaandClaude Opus 5.5 4109cb4258 Express 5, scanner on API v2, v1 deprecation headers (1.51.3)
- Express 5 (qs query parser and req.body = {} kept as in Express 4).
- Scanner and at-the-door check-in use /api/v2/checkin; look-up gives attendee, bookedBy,
  ticketOptionId.
- Shared middleware errors on /api/v2 rewritten to { error: { code, message, reason } };
  apiFetch treats reason like v1's code.
- Deprecation + Link: rel="successor-version" on v1 endpoints that have a v2 replacement.
- Roadmap: open question on how much of v1 to retire in 2.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 09:46:24 +02:00
joshuaandClaude Opus 5.5 9012ec64b6 API v2 accounts and check-in (1.51.2)
- v2: auth/signup, auth/login (+ code step, rate limited), PATCH /me; check-in look-up and
  scan returning an outcome for every normal result. Campus rule as v1.
- Sign up/login/2FA/profile moved to src/services/auth.ts; scan preview and scan to
  src/services/checkin.ts. v1 answers unchanged (ServiceError v1Status).
- Login, 2FA step, sign up and profile/password pages use v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 09:31:00 +02:00
joshuaandClaude Opus 5.5 735a76cc74 API v2 registrations and payments (1.51.1)
- v2: register, get, cancel and checkout a registration (owner/admin only).
- Registration create/cancel moved to src/services/registrations.ts and online checkout to
  src/services/payments.ts; v1 controllers call the same services (ServiceError carries status).
- Typed frontend calls: npm run api:types writes openapi.json and schema.d.ts; apiV2() helper.
  Register page, Pay now and My Events cancel use v2; apiFetch reads v2 errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 09:09:09 +02:00
joshuaandClaude Opus 5.5 4ca896130b TypeScript backend and /api/v2 foundations (1.51.0)
- tsconfig (allowJs, strict .ts), npm run build -> dist/, typecheck, dev via tsx, ts-jest.
- src/index.js is now a launcher (dist build when it matches, else tsx); server moved to app.js.
- /api/v2: defineRoute with zod -> request validation, response stripping, OpenAPI 3.1 at
  /docs/v2; one error shape and one paged-list shape. First endpoints: events, event, me,
  my registrations.
- deploy.sh/install.sh build the backend; rollback to older releases skips the build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 08:48:54 +02:00
joshuaandClaude Opus 5.5 ad40618267 Roadmap: AI buttons follow the cap, markup on AI usage
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 08:29:15 +02:00
joshuaandClaude Opus 5.5 8f6f90a151 Searchable event picker and webhook guide (1.50.2)
- EventPicker replaces the plain event dropdowns on staff/supervisor pages and the kiosk:
  upcoming first, past behind "Show past events", search across all, keyboard support.
- Reports events list can be searched ("Select these N").
- Site settings -> Webhooks: "How webhooks work" guide with headers, signature checking
  (Node.js/PHP) and an example of every event type (EVENT_TYPES[].example, shape-tested).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 08:23:09 +02:00
joshuaandClaude Opus 5.5 4c066e67d9 Pagination and search on long lists (1.50.1)
Audit log: search (person, target, IP), role filter, every action in the
filter, inclusive To date. Data requests: search and paging (was cut at
200). Webhook deliveries: status filter and Load older. Supervisor Payments
loads only what it needs (unpaid registrations, recent/today/donation
payments, a person's own for refunds) instead of everything.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMdg2GYqbnKZmPaX1ot
2026-10-29 06:53:54 +02:00
joshuaandClaude Opus 5.5 e9d1b1fb24 Accessibility pass, WCAG 2.2 AA (1.50.0)
Public pages, auth, registration, payment, My Events and the kiosk: skip
link, focus ring, labels tied to fields, named quantity buttons, announced
errors, ModalOverlay popups (focus trap, Escape, focus return), contrast
and underlined in-text links, reduced motion. Branding warns about a primary
colour too light for white text and offers a darker shade. axe-core and
keyboard checks in e2e/accessibility.spec.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 15:41:19 +02:00