Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hope Events Hub
Joshua's central management app for every Hope Events install: customers, licences, install health and usage, and alerts. Customers never log in here.
backend/— Express + Prisma (Postgres) API, port 5200frontend/— Next.js dashboard, port 3200docs/hub-protocol.md— the contract with Hope Events installs (a copy lives in thehope-eventsrepo; 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 Hope 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 Hope 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 Hope Events
(backend/src/hub/publicKey.js).
- Create the production key once, on the Hub server:
npm run generate-keys. Back upkeys/hub-signing-key.pemsomewhere safe and offline. - Put the public key it prints into Hope Events (
backend/src/hub/publicKey.js) and release. - Losing or replacing the key means every install needs a Hope Events update with the new public key before it can trust new licences — so don't.
HUB_ENCRYPTION_KEYencrypts install secrets: it must never change after installs register.
Deploying
Same pattern as Hope 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.