18 Commits
Author SHA1 Message Date
joshuaandClaude Opus 5.5 e697564ff5 Hub 2.0 step 7: dashboard per product, revenue, linked products
Dashboard: monthly recurring revenue after discounts, overdue invoices,
per-product installs, latest version, behind, critical and licences.
Install page: the church's other products and whether they're listed to
this site.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 09:03:39 +02:00
joshuaandClaude Opus 5.5 59e6b9f03c Hub 2.0 step 6: AI cap and markup per church
The cap and markup move from the licence to the customer (migrated), use
is counted over all the church's installs under one lock per church, and
the licence token carries the church's cap. Settings → AI shows product.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 08:55:43 +02:00
joshuaandClaude Opus 5.5 fbbf72dcd8 Hub 2.0 step 5: the church's address
Own domain R0, Cross Code address R10, domain included R25 (custom price
for other endings), once per invoice and never discounted; renewal date
with a reminder 30 days before, once per renewal, and Renewed to move it on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 16:24:10 +02:00
joshuaandClaude Opus 5.5 7478e84e9d Hub 2.0 step 4: billing per customer
- One invoice per customer per period for all its products; the schedule
  moves from Licence to Customer (migration copies it, so billing carries
  on unchanged); licences get billedFrom / billedUntil
- Website (R99, 5 GB) and App (on active members) prices next to the
  Events tiers; founding prices per product, then bundles (15% two, 25%
  three); extra website storage R20 per 5 GB, never discounted
- A product added to a billed customer starts after its free month; days
  before its first full period are prorated, never charged twice
- Annual review per product (Events income, App members), one notice of
  licence change per product; invoices, PDFs and emails name products
- Customer page: schedule, per-product billing, next-invoice preview
- Invoices from before 2.0 kept as they were (still recalculable)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 16:18:23 +02:00
joshuaandClaude Opus 5.5 816452e1c2 Hub 2.0 step 3: releases per product, with requirements
- Release.product and requires; unique (product, version); latest version
  per product (latest_version stays Cross Events' latest)
- Release sources per product (Releases page): repository, tag prefix,
  notes file. Defaults: every product from crosscode-platform plus Cross
  Events' v1.2.3 tags from hope-events. A product's releases are only
  removed when all its sources were read and found tags
- "— requires accounts 1.2.0" in a notes heading: Request update answers
  409 REQUIREMENT_NOT_MET until the church's install of that product is new
  enough; install page and Releases page show it; v2 replies carry requires
- @crosscode/contracts 1.1.0 vendored (optional requires on releases)
- Alerts, dashboard and install lists compare against each product's latest

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 15:57:46 +02:00
joshuaandClaude Opus 5.5 ad602b2846 Hub 2.0 step 1: products foundation
- Product enum (events, accounts, website, app) on Licence and Install,
  Install.publicKey; existing rows are events
- One open licence per product per customer: partial unique index, with a
  migration guard that names customers with duplicates (npm run check:hub2
  lists them beforehand)
- Licence keys per product (CEH-, CCA-, CCW-, CCP-); free Accounts licence
  created with the first other product licence
- Protocol v1 registers Events licences only (409 WRONG_PRODUCT); only Events
  licences can be invoiced until billing per customer
- Cross Code Hub in the UI, emails and PDFs
- @crosscode/contracts 1.0.0 vendored (backend/vendor)
- Steps merge into release/2.0, not main (plan updated)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 15:28:06 +02:00
joshuaandClaude Opus 5.5 6fce0fe90e Billing: invoices, approval, receipts, statements, licence changes (1.7.0)
- Invoices drafted 14 days before each licence's invoice date and emailed
  to the alert email for approval; approved ones go out on their date from
  08:00 SA time. Drafts can be edited, recalculated, sent early, put back
  to draft or voided; one-off invoices too.
- Annual tier review from the 12-month event-income band; approving a tier
  change emails a notice of licence change, applied when the invoice goes out.
  Notices can also be sent by hand.
- Founding churches (35% off as its own line), payments with receipts,
  statements for any dates.
- Every billing email is styled HTML with a PDF (invoice / tax invoice,
  receipt, statement, licence change) and logged per customer.
- Settings -> Billing: business and bank details, VAT (off: plain invoices;
  on: VAT-inclusive tax invoices), timing and numbering.
- Migration 20261103111645_invoicing; pdfkit 0.17.2; tests/billing.test.js;
  scripts/sample-billing-pdfs.js.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 13:42:45 +02:00
joshuaandClaude Opus 5.5 219b08538f Billing tiers on the install page, plan picker on licences (1.6.2)
- Install page shows the 12-month event-income band (Cross Events 2.0.2+),
  the tier it falls in with its price and founding price, and flags a
  licence whose plan is a different tier.
- Licence card: Plan picker (Trial or Seed to Network).
- Protocol doc: 14 income bands and eventIncome12m.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 12:18:02 +02:00
joshuaandClaude Opus 5.5 ae7e10844d Sonnet 5.5 as the default AI model, and a model list with prices (1.6.1)
Settings -> AI picks the model from a list (utils/aiModels.js: Sonnet,
Haiku, Opus 5.5 with list prices) or takes another model ID; choosing
one fills in its prices. Blank prices use the built-in ones, and cache
reads are metered at each model's own price.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 17:21:30 +02:00
joshuaandClaude Opus 5.5 49f62aeb75 WIP Hub 1.6.0: AI proxy for Cross Events 2.0
Signed /installs/ai/status and /installs/ai/complete (protocol 3b):
the Hub holds the Claude key, holds each call's worst case against the
licence's monthly cap in a locked transaction, calls Claude Haiku 5.5
and meters real cost and charged amount (markup) in rand. Settings ->
AI, licence markup override, AI use on the install page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 09:16:04 +02:00
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
joshuaandClaude Opus 5.5 0adb304024 Releases from git tags and WHATS-NEW.md; docs, changelog (1.4.0)
The Hub reads the Cross Events repo's v* tags (each a release, the newest the
latest version) and the client notes from WHATS-NEW.md as of the newest tag,
every 15 minutes and on Sync now. Urgent/security in a version heading marks it
urgent. Repo address, notes path and an optional encrypted token on the
Releases page; manual releases only when no repo is set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:13:30 +02:00
joshuaandClaude Opus 5.5 1449e5046e Releases with what's new, notices to churches, withdrawn update requests
- Releases page: each Cross Events version with notes and an urgent flag; the
  newest is the latest version (moved off Settings; the old setting becomes the
  first release). Installs get the notes for every newer version.
- Notices page: a banner for site admins and supervisors (with a time window),
  an email to the customer and admin contact, or both; for every install or
  chosen ones.
- POST /api/installs/update-request/cancel resolves the request and emails Joshua.
- Protocol doc: releases and notices in the heartbeat/register replies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 08:54:35 +02:00
joshuaandClaude Opus 5.5 d235ae6c95 Search and paging on lists, Settings in tabs, pinned sidebar (1.3.0)
- Installs, Customers, Alerts and the audit log get a search box and
  25-per-page paging (Installs also a health filter); install History pages too.
- Settings is split into Releases and alerts / Email / Login and security /
  Audit log tabs, remembered in the URL hash.
- The side navigation is sticky at window height, so Sign out no longer
  scrolls off long pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 07:51:32 +02:00
joshuaandClaude Opus 5.5 613a4450cb SMTP settings on the Settings page, with a test (1.2.0)
SMTP server, port, user, password and from address are now Hub settings in
the database instead of SMTP_* in .env. The password is encrypted with
HUB_ENCRYPTION_KEY and never sent to the browser; a blank field keeps it.
POST /api/admin/settings/smtp-test logs in with the form's values (saved or
not) and sends a test email, returning the server's reason on failure; it is
rate limited and audited. On first start an existing SMTP_* setup is copied
into Settings once. The audit log no longer records the SMTP password.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ls1vMaqhrehXcHJe32jLL9
2026-10-28 01:26:41 +02:00
joshuaandClaude Opus 5.5 affbde14d0 Show campuses on the install page (1.1.1)
The heartbeat's stats.campuses and stats.campusCount were stored but never
shown. The Usage card now has a Campuses row: Off, or On with the active count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 23:50:36 +02:00
joshuaandClaude Opus 5.5 a1e3f9214b Rename to Cross Events Hub; add logo and favicon
Hope Events is now Cross Events. Protocol identifiers (hel1. tokens, CEH- keys)
are unchanged so existing installs keep working.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 13:38:52 +02:00
joshuaandClaude Opus 5.5 e72330893a Hub v1: install API, licences, health dashboard, alerts
- Protocol 1 (docs/hub-protocol.md): public key, register, signed heartbeats
- Ed25519 licence tokens (30-day validity, status, expiry, grace, limits)
- Dashboard: installs, install detail, customers and licences, alerts,
  settings and audit log; two-factor login required
- Alert checks every 5 minutes, emailed once; heartbeat roll-up after 30 days
- Unit tests for encryption, tokens, signatures, TOTP and alert rules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012mt6TCv85T9VKRq3cV7rXq
2026-10-26 12:12:51 +02:00