joshuaandClaude Opus 5.5 633813c50d Read release notes from the default branch; changelog (1.4.1)
Notes still only attach to tagged versions, so they can be written ahead of a
release or corrected afterwards without tagging a new version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:25:10 +02:00
2026-10-27 23:55:46 +02:00

Cross Events Hub

Joshua's central management app for every Cross Events install: customers, licences, install health and usage, and alerts. Customers never log in here.

Naming: Cross Events was called Hope Events until October 2026. Older commits, the hope-events repo name and the hel1. licence-token prefix still use the old name. The prefix is part of the protocol, so it stays.

  • backend/ — Express + Prisma (Postgres) API, port 5200
  • frontend/ — Next.js dashboard, port 3200
  • docs/hub-protocol.md — the contract with Cross Events installs (a copy lives in the hope-events repo; change both together)

Installs only ever call the Hub (register, heartbeat); the Hub never reaches into an install and holds no church data — just versions, health and aggregate counts.

Run it locally

Needs Node 20+ and Postgres.

cd backend
cp .env.example .env            # set DATABASE_URL, JWT_SECRET, HUB_ENCRYPTION_KEY
npm install
npx prisma migrate deploy && npx prisma generate
npm run generate-keys           # licence signing key → keys/hub-signing-key.pem
npm run create-admin -- --email you@example.com --name "Your Name"
npm run dev                     # http://localhost:5200

cd ../frontend
cp .env.example .env.local      # NEXT_PUBLIC_API_URL=http://localhost:5200
npm install
npm run dev                     # http://localhost:3200

The first login sets up two-factor with an authenticator app (required).

To try it with Cross Events locally, point the install at the Hub with HUB_URL=http://localhost:5200 and HUB_PUBLIC_KEY (the public key shown in Hub → Settings) in Cross Events' backend/.env.

Releases and notices

  • Releases come from git: every v1.2.3 tag of joshua/hope-events is a release, the newest is the latest version, and the notes churches see come from WHATS-NEW.md on that repo's default branch (only for tagged versions, so notes can be written ahead or corrected later). The Hub checks every 15 minutes (and on Sync now, Releases page). So releasing Cross Events is: write the version's section in WHATS-NEW.md, tag, push — installs see the update with their next heartbeat.
  • Notices (Notices page) are banners on churches' sites for their admins and supervisors, emails to them, or both — e.g. planned maintenance.

The licence signing key

Licences are tokens signed with an Ed25519 key. The private key exists only on the Hub server; installs check licences with the public key, which is built into Cross Events (backend/src/hub/publicKey.js).

  • Create the production key once, on the Hub server: npm run generate-keys. Back up keys/hub-signing-key.pem somewhere safe and offline.
  • Put the public key it prints into Cross Events (backend/src/hub/publicKey.js) and release.
  • Losing or replacing the key means every install needs a Cross Events update with the new public key before it can trust new licences — so don't.
  • HUB_ENCRYPTION_KEY encrypts install secrets: it must never change after installs register.

Deploying

Same pattern as Cross Events: on the server (events-hub.crosscode.co.za), behind nginx with HTTPS, two PM2 processes (backend: npm start; frontend: npm run build && npm start), TRUST_PROXY=1, FRONTEND_URL=https://events-hub.crosscode.co.za, and the frontend's NEXT_PUBLIC_API_URL set to the public API address (e.g. https://events-hub.crosscode.co.za with nginx routing /api to port 5200). Back up the database daily, plus the signing key.

Tests

cd backend && npm test — encryption, licence tokens, request signatures, two-factor codes (RFC 6238 vector) and alert rules.

S
Description
No description provided
Readme
1.7 MiB
Languages
JavaScript 50.9%
TypeScript 46.4%
Shell 2.3%
CSS 0.4%