Commit Graph
324 Commits
Author SHA1 Message Date
joshuaandClaude Opus 5.5 c0d01ce993 Outbound webhooks (1.48.0)
Site settings -> Webhooks: admins add https endpoints and choose event
types (registration created/paid/cancelled, payment received/refunded,
ticket checked in, account created, event published). Events are
noticed by a Prisma client extension so every write path is covered,
re-checked before sending, and delivered as signed JSON
(X-CrossEvents-Signature, HMAC-SHA256) with retries, a 30-day delivery
log, Send test and Resend. Public https addresses only; each endpoint
is added to the operator register; kids and volunteer tickets are never
sent. New `webhooks` job. Migration 20261028160000_webhooks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:00:59 +02:00
joshua 0414854dec Merge branch 'fix/update-request-newer' v1.47.4 2026-10-28 12:16:56 +02:00
joshuaandClaude Opus 5.5 dd537a1a16 Fix: update request for an older version than the latest (1.47.4)
After asking for an update, a newer version coming out made the Licence
page claim the newer version was requested, with no way to ask for it.
Now it shows the version asked for, that a newer one is out, and "Ask
for X instead"; the banner shows again. Hub 1.5.0 moves the open request
on (`changed`); with an older Hub the site withdraws and asks again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 12:16:56 +02:00
joshua 2240c8a703 Merge branch 'feat/season-pass' v1.47.3 2026-10-28 11:19:58 +02:00
joshuaandClaude Opus 5.5 a7c8148588 Season passes (1.47.3)
A pass sells a ticket at each of several events in a series for one
price. Supervisors set passes up on the Event series page (events and
ticket per event; fixed once sold). Buying on the series page registers
the buyer at every event at once with one checkout (free passes give
tickets straight away; Pay now if online payment isn't possible). The
price is split over the events in proportion to their normal prices:
each registration line is priced at its share and the webhook records
one Payment per event, so cashups stay per event. Pass registrations
aren't repriced, take no coupons and can't be edited. Migration
20261028150000_season_pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 11:19:58 +02:00
joshua 96d1e67b85 Merge branch 'feat/series-reports' v1.47.2 2026-10-28 10:57:04 +02:00
joshuaandClaude Opus 5.5 e5d615e398 Series: year on year report (1.47.2)
New report (Reports -> Other, or "Compare" on the Event series page):
each event in a series side by side, oldest first - registrations,
tickets, income (dashboard definition), people checked in (average per
session on multi-session events) and attendance rate, with the change
from the event before. Exports like the other reports; campus-scoped
staff see only their campuses' events. GET /api/series/:id/compare.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 10:57:04 +02:00
joshua 0253a1d5fa Merge branch 'feat/event-series' v1.47.1 2026-10-28 10:29:59 +02:00
joshuaandClaude Opus 5.5 740897635f Event series (1.47.1)
Group separate events (Camp 2025, Camp 2026) on a series page at
/series/<slug> with upcoming and past events. Events join a series from
the event editor (copies keep it); a series can span campuses. Event
pages show "Part of ..." and "Next in this series". Signed-in people can
follow a series; the new `series` job emails followers once when a new
event in it goes live, as News & announcements (opted-in only, with
unsubscribe). Follows are in the data export and removed on
anonymising. Migration 20261028140000_event_series.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 10:29:59 +02:00
joshua 7ae0b6d23b Merge branch 'feat/event-clone' v1.47.0 2026-10-28 10:01:18 +02:00
joshuaandClaude Opus 5.5 6ef19d3290 Copy an event (1.47.0)
"Copy" on each event card opens the event editor filled in from that
event (campus, sessions, options, variants, early birds, sections, form,
recipients, feedback questions, certificates, reminders). "New start"
moves every date with it. Allocation groups and, for admins, planned
costs are copied by POST /api/events/:id/copy-from. Registrations,
coupons, attachments, kids check-in and volunteer roles are not copied.

Roadmap: event series and cloning ships as 1.47.0-1.47.3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 10:01:17 +02:00
joshua 51355069da Merge branch 'chore/whats-new-history' 2026-10-28 09:25:08 +02:00
joshuaandClaude Opus 5.5 3a96f9c1dc WHATS-NEW.md: church-facing notes for every version back to 1.0.0
The Hub reads this file from main (Hub 1.4.1), so these show on sites' Licence
page without a new release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:25:08 +02:00
joshua a7261db191 Merge branch 'chore/licence-updates' v1.46.2 2026-10-28 09:13:30 +02:00
joshuaandClaude Opus 5.5 6045d1b05e WHATS-NEW.md for churches; docs, changelog (1.46.2)
Client-facing release notes the Hub reads from git with the version tags, so
the latest version and its notes reach installs without touching the Hub.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:13:30 +02:00
joshuaandClaude Opus 5.5 5df04f5a4a Licence page: what's new, withdraw request, Not now, provider notices
- Site settings -> Licence shows the release notes for every newer version from
  the Hub; urgent (security/serious) updates are marked and can't be put off.
- Withdraw an update request (the provider is told through the Hub).
- "Not now" on the banner or Licence page hides update reminders until the
  next version.
- Notices from the provider show as a dashboard banner for site admins and
  supervisors, in their time window, and on the Licence page.
- New audit actions (migration), API docs, help, protocol doc, tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 08:54:35 +02:00
joshua 35805f0c79 Merge branch 'chore/remove-ci' v1.46.1 2026-10-28 08:15:45 +02:00
joshuaandClaude Opus 5.5 174022296b Remove the Gitea CI workflow; docs, changelog (1.46.1)
There's no Actions runner (no machine that can run Docker), so every push
left a run stuck on "Waiting". Tests and lint are run by hand before a
release, and releases are deployed with scripts/deploy.sh on the server.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 08:15:44 +02:00
joshua bc22a94f92 Merge branch 'feat/volunteer-rosters'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
v1.46.0
2026-10-28 03:59:52 +02:00
joshuaandClaude Opus 5.5 bbde6791cb Volunteer rosters: docs, changelog (1.46.0)
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 03:59:52 +02:00
joshuaandClaude Opus 5.5 e9a2ce9d01 Volunteer rosters: serving, roster and check-in pages, help, e2e
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 03:59:52 +02:00
joshuaandClaude Opus 5.5 39885a8719 Volunteer rosters: roles, sign-ups, swaps, QR check-in, kids-room duty (backend)
Serving roles per event or session, sign-ups and assigning with an overlap
check, swaps that happen on accept (notify recipients emailed), QR and manual
check-in (kids-room roles start rostered duty), optional free volunteer ticket,
day-before reminder job, hours served, privacy hooks. The kids check-in and
volunteer tickets are left out of public event pages and public registration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 03:59:52 +02:00
joshua 1ce6f23ad8 Merge branch 'fix/legal-pages'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
v1.45.1
2026-10-28 01:09:51 +02:00
joshuaandClaude Opus 5.5 1dbc37ba08 Privacy notice and terms of use brought up to date (1.45.1)
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMccH2LkkfYmsSLwPaq
2026-10-28 01:09:51 +02:00
joshua 42a369278e Merge branch 'feat/kids-check-in'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
v1.45.0
2026-10-28 01:01:09 +02:00
joshuaandClaude Opus 5.5 e249d43c79 Kids check-in: docs, changelog (1.45.0)
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 01:01:08 +02:00
joshuaandClaude Opus 5.5 00b465b97d Kids check-in: desk, room screen, setup and parent pages, help, e2e
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 01:01:08 +02:00
joshuaandClaude Opus 5.5 794396ca9c Kids check-in: families, pickup codes, rooms, check-in/out, offline sync (backend)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 00:46:41 +02:00
joshuaandClaude Opus 5.5 09ef2c1df1 Roadmap: kids check-in fully digital, wallet passes removed from scope
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 00:29:10 +02:00
joshua 36c3b117ca Merge branch 'feat/campus-scoped-staff'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
v1.44.0
2026-10-27 22:59:00 +02:00
joshuaandClaude Opus 5.5 cad075bb3f Campus-scoped staff: help, docs, changelog (1.44.0)
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:52:11 +02:00
joshuaandClaude Opus 5.5 159728d269 Campus-scoped staff: frontend and e2e
Admin -> Users 'Limit to campuses'; staff campus pickers, reports, dashboards
and audience picker follow the scope (useMyCampuses); scoped people pick one
of their campuses for new events, and church-wide / other campuses' events
open read-only; 'You work with ...' note; warning before turning campuses off
while staff are limited. e2e: scanner refusal naming the campus, scoped
events list and read-only editor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:50:03 +02:00
joshuaandClaude Opus 5.5 c570fc7ffb Campus-scoped staff: admins set limits; profile returns the scope
PUT /api/users/:id takes scopedCampusIds (supervisors/staff only, audited as
user_campus_scope_changed); GET returns scopedCampuses; the profile returns
campusScope (null when unscoped or campuses are off).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:40:32 +02:00
joshuaandClaude Opus 5.5 00fd26f3a5 Campus-scoped staff: every staff/supervisor route checked
Events, payments, registrations, scan locks and tickets marked; list
controllers filtered (registrations, payments, tickets, scans, stats,
coupons, scheduled messages, form responses, funnel). Owner-or-staff routes
check staff against the record's event (ownerOk). Scanner names the campus
of another campus's ticket. Route test passes; unit tests for the rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:37:42 +02:00
joshuaandClaude Opus 5.5 344f260011 Campus-scoped staff: schema, campusScope helper, route test, first 79 routes
UserCampusScope relation and audit action; scopeEvent/scopeList/unscopedOnly/
campusIndependent/scopeBroadcast markers; tests/campusScopeRoutes.test.js
(still failing: events, payments, registrations, scan locks, tickets left).
Can't delete a campus that has scoped staff.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:28:30 +02:00
joshuaandClaude Opus 5.5 d2d9282a2c Roadmap: 1.44.0 campus-scoped staff decisions
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 17:17:32 +02:00
joshua f36e84fd90 Merge branch 'feat/campuses'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
v1.43.0
2026-10-27 16:56:07 +02:00
joshuaandClaude Opus 5.5 a6909ce506 Campuses frontend, docs and e2e (1.43.0)
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Site settings -> Campuses tab; campus picker in the event editor; campus
filter and badges on the events list, public events page (remembered,
starts on home campus) and reports/dashboards; /campus/<slug> pages and
sitemap; home campus on the profile; "Everyone at a campus" in email and
WhatsApp broadcasts. Help, FEATURES, SETTINGS, API docs, protocol doc
(campusCount), handover and roadmap updated; campuses seeded for e2e.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 16:45:43 +02:00
joshuaandClaude Opus 5.5 955f8d9831 Campuses backend: model, admin/public API, events per campus, filters
- Campus model, Event.campusId (null = all campuses), User.homeCampusId,
  per-campus summary recipients; campuses_enabled setting (off by default)
- /api/campuses: public list and landing page, admin CRUD/order/archive,
  "everyone at campus X" audience (home campus + optional 12-month registrants)
- Events: campus on create/update (audited when moved), ?campus= on the
  public list (with church-wide events) and staff list; campus included
- Home campus on the profile; cleared when anonymising
- Overview stats ?campus= filter; campus summary recipients; campus on
  ticket PDFs; heartbeat reports the real campus setting
- Migration also adds hub_update_requested, missing since 1.42.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 16:23:33 +02:00
joshua 2727fc6554 Merge branch 'docs/multi-campus-plan' 2026-10-27 16:09:06 +02:00
joshuaandClaude Opus 5.5 3d149e6098 Roadmap: split multi-campus into 1.43.0 campuses and 1.44.0 scoped staff
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Records the decisions: scoped staff view and scan "All campuses" events but
can't edit them; "everyone at campus X" is home campus plus optional recent
registrants; campus landing pages in 1.43.0. Later phases move up by one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 16:09:04 +02:00
joshua 30a2142085 Merge branch 'fix/hub-public-key'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
v1.42.1
2026-10-27 14:28:49 +02:00
joshuaandClaude Opus 5.5 95913a5bd5 Build the production Hub public key in (1.42.1)
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
PRODUCTION_PUBLIC_KEY is the key the production Hub serves at
/api/public-key, normalised to PEM, so installs no longer need
HUB_PUBLIC_KEY. Test covers the built-in key with the env var unset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 14:28:48 +02:00
joshua f7e0ec8bc1 Merge branch 'docs/handover-roadmap'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
2026-10-27 14:03:01 +02:00
joshuaandClaude Opus 5.5 08d442e1c1 Handover and roadmap: Cross Events rename, Request update, versions moved up
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
1.41.3 and 1.42.0 / Hub 1.1.0 recorded; Multi-campus is now 1.43.0 and
later phases move up by one. Next steps: roll out update requests, build
the Hub public key in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 14:03:00 +02:00
joshua be4f341e42 Merge branch 'feat/request-update'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
v1.42.0
2026-10-27 13:55:06 +02:00
joshuaandClaude Opus 5.5 1caa0f0ea7 Request update button instead of the deploy command (1.42.0)
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Site settings -> Licence sends a signed update request to the Hub
(docs/hub-protocol.md 3a) instead of showing bash scripts/deploy.sh. Shows
"Update requested" until the site runs that version and hides the update
banner meanwhile. Audit-logged as hub_update_requested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:55:05 +02:00
joshua 91f6481fb7 Merge branch 'fix/cross-events-name'
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
v1.41.3
2026-10-27 13:06:22 +02:00
joshuaandClaude Opus 5.5 bf887720a1 Bump to 1.41.3
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:06:21 +02:00
joshuaandClaude Opus 5.5 6de0b5525b Rename the product to Cross Events in UI text and docs
Display text only: storage keys, slugs, the encryption salt, the repo URL
and applied migrations keep their old names so existing installs keep working.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:06:20 +02:00