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>
- 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>
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>
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>
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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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>
DEPLOYMENT.md: install with --no-ssl, switch URLs to https, TRUST_PROXY,
nginx and /etc/frp/frpc.ini for TLS on the VPS or in frpc (https2http),
checking visitor IPs, updates and troubleshooting. Linked from the README.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pg-boss timestamps are timestamptz, and Prisma's pg adapter drops the offset in raw queries (10:55+02 came back as 10:55Z, shown as 12:55). Read them AT TIME ZONE 'UTC'.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A site the Hub answers INSTALL_NOT_FOUND for drops its install and licence, so it
no longer shows "Active" on the old token.
- Unlicensed is read-only like suspended; read-only also blocks editing events,
options and variants. LICENCE_CHECK_DISABLED (ignored in production) for e2e.
- Heartbeat 30 s after the server starts and after a licence key is connected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>