joshuaandClaude Opus 5.5 5a90c713d8 Deploy script with rollback (1.1.2)
scripts/deploy.sh backs up the database (pg_dump), checks out the release,
runs npm ci, prisma migrate deploy and generate, builds the frontend,
restarts the PM2 apps and health-checks them. Any failure puts back the
previous code and build, and restores the dump if new migrations had run.
deployment.md §12 now uses it. tsconfig.tsbuildinfo leaves git so builds
don't leave the tree dirty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 23:55:46 +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.

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%