Files
hope-events/docs/HANDOVER.md
T
joshuaandClaude Opus 5.5 96adf20cf0
CI / Backend tests (push) Canceled after 0s
CI / Frontend lint, typecheck, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
CI / Deploy tagged release (push) Canceled after 0s
Deploy script: roll back once (not inside subshells); docs; bump to 1.37.4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:20:22 +02:00

122 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Handover — where things stand and how to carry on
Last updated: 2026-10-23, after **1.37.4**. The plan itself is in
[ROADMAP-v2.md](./ROADMAP-v2.md) (decisions table at the end); the previous round of
features is in [FEATURES-ROUND-1.md](./FEATURES-ROUND-1.md).
## Done so far (road to 2.0)
| Version | What |
|---------|------|
| 1.32.0 | Early-bird ribbon on event cards |
| 1.33.0 | Multi-day events phase A — sessions, late joining + late pricing, per-session check-in, attendance register, session reminders, certificates (4 templates, verify page) |
| 1.34.0 | Background jobs on pg-boss (admin Background jobs page), Playwright e2e tests, Gitea CI workflow, `scripts/deploy.sh` |
| 1.35.0 | Multi-day events phase B — "pick sessions" (per-session tickets and prices, session capacity) |
| 1.37.4 | Deploy script: no tag = latest main; per-install `ecosystem.config.js` out of git (`ecosystem.config.example.js`) |
| 1.37.3 | Fix: the production build failed on unescaped quotes in a help text |
| 1.37.2 | Payment status checks (PayFast transaction history; job every 15 min; Payments → Reconcile → Waiting for payment), PayFast Test connection |
| 1.37.1 | "Pay online" hidden when no provider is on or under R15; SnapScan/Zapper dropped from the roadmap |
| 1.37.0 | PayFast (signed form, ITN checks), `ProviderCheckout` with amount checks, the "Pay online" page (`/pay/<id>`) where payers choose a provider |
| 1.36.0 | Payment provider interface (`backend/src/payments`) with Yoco behind it, `ProviderTransaction`, `Payment.provider`, Site settings → Payments (on/off and order per provider), R15 minimum |
| 1.35.1 | Waitlist per session, session picker at the door, "All sessions" tickets let people tick sessions at one price; fixes (per-session stock limits, offline service worker serving stale scripts) |
## Next up
1. **1.38.0–1.39.0 — POPIA toolkit** (spec §3 in the roadmap).
2. **1.40.0 + Hub v1** — install/update tooling and the Hope Events Hub (separate repo
`joshua/hope-events-hub`).
## Working on this repo
- **Release routine:** branch `feat/<name>` → commit → bump with
`npm version X.Y.Z --no-git-tag-version` in `.`, `backend` and `frontend` → add the
`## [X.Y.Z] - date` heading under `[Unreleased]` in CHANGELOG.md → `git merge --no-ff`
into `main` → `git tag vX.Y.Z` → `git push origin main <branch> vX.Y.Z`. One minor
version per feature.
- **Before tagging:** run `npx eslint src` in `frontend` over the **whole** app (the deploy runs `next build`, which fails on any lint error, e.g. an unescaped ' or " in JSX text). If a dev server is running, a full check build needs its own folder: `NEXT_DIST_DIR=.next-buildcheck npx next build` (then delete it and `git checkout frontend/tsconfig.json`).
- **Changelog:** add entries to `[Unreleased]` as you go, in plain language.
- **Docs to keep in step:** CHANGELOG.md, FEATURES.md, README.md, SETTINGS.md,
backend/API_DOCUMENTATION.md, the `/docs` route list in `backend/src/index.js`, and
in-app help in `frontend/src/content/help/` (register new pages in `registry.ts`).
- **Prisma migrations:** `npx prisma migrate dev --create-only --name x` against a local
DB. Prisma 7 keeps adding an unrelated `_EventNotifyRecipients` primary-key/index
change — delete those two blocks from the generated SQL. It also rewrites the comment
in `migration_lock.toml`; `git checkout` that file back. New `AdminAuditAction` values
need a migration.
- **Server Node version:** the deployment notes install Node 20, so dependencies must
support Node 20 (that's why pg-boss is pinned to 10.x).
- **Deploying:** `bash scripts/deploy.sh [tag]` on the server (no tag = latest main). Each install
keeps its own `ecosystem.config.js` (PM2 app names, port), which is not in git. The script
runs from a temp copy of itself and rolls back on failure before the PM2 reload. It was
tested by running it against a throwaway clone with npm/pm2 stubbed: across the tracked →
untracked change for the PM2 file, deploying main, failed builds and a bad tag.
- **Pushing:** pushing from some shells fails with "Failed to authenticate user" (a stale
saved credential); pushing from your own terminal works.
## Tests
- Backend unit tests: `cd backend && npm test` (Jest).
- PayFast e2e (`e2e/payfast.spec.ts`) pays into a real PayFast sandbox account and is skipped
unless `E2E_PAYFAST_MERCHANT_ID`, `E2E_PAYFAST_MERCHANT_KEY` and `E2E_PAYFAST_PASSPHRASE` are
set (from the Sandbox dashboard). PayFast's documented public test merchant (10000100) no
longer accepts payments. ITNs can't reach localhost; they're covered by unit tests
(`backend/tests/payments.test.js`) — to try one for real, use a tunnel, a public
`BACKEND_URL` and `PAYFAST_SKIP_IP_CHECK=true`.
- End-to-end: `npm run test:e2e` from the repo root (first time: `npm install` and
`npx playwright install chromium`). They start their own backend (5100) and
frontend (3100) against `<your DATABASE_URL database>_e2e`, which is dropped and
re-seeded every run (`e2e/support/prepare-db.js`). The DB user must be able to
create databases. ~5 minutes in dev mode.
Locally, Playwright reuses servers already running on 5100/3100. If the run times out
waiting for the frontend (the home page returns 500 until the e2e backend is up), start
them yourself — `node e2e/support/prepare-db.js`, then the backend from `backend/`
with `PORT=5100`, the e2e `DATABASE_URL`, `JOBS_ENABLED=false`,
`TWO_FACTOR_REQUIRED_ROLES=false`, and `npx next dev -p 3100` from `frontend/` with
`NEXT_DIST_DIR=.next-e2e NEXT_PUBLIC_API_URL=http://localhost:5100` — then run
`npx playwright test`. Don't edit frontend files while it runs.
- **Careful with ad-hoc scripts against a dev/test database that has SMTP set up:**
registrations and check-ins send real email/WhatsApp. Use made-up `@test.local`
people only.
- CI: `.gitea/workflows/ci.yml` runs everything once a Gitea Actions runner is
registered (none yet). Tag deploys need the `DEPLOY_HOST`, `DEPLOY_USER`,
`DEPLOY_SSH_KEY` (+ optional `DEPLOY_PATH`) secrets.
## Where the multi-day code lives
- `backend/src/utils/sessions.js` — all session rules (dates, check-in window, late
pricing, pick sessions, capacity, grouping); unit tests in `backend/tests/sessions.test.js`.
- `backend/src/utils/certificates.js`, `sessionReminders.js`,
`controllers/attendanceController.js` (register + certificates API).
- `backend/src/jobs/index.js` — the background job registry.
- Frontend: `src/lib/sessions.ts`, `src/components/events/ScheduleEditor.tsx`,
`SessionPicker.tsx`, `SessionSchedule.tsx`, `src/app/dashboard/supervisor/attendance/`.
## Where the payment code lives
- `backend/src/payments/index.js` — the provider registry and the `PaymentProvider` interface
(documented at the top), provider on/off and order (AppSetting `payment_providers`), the R15
minimum, and `createCheckout`. Tests: `backend/tests/payments.test.js`.
- `backend/src/payments/providers/yoco.js` — Yoco: checkouts, webhook signature check, webhook
parsing. Keys/webhook admin stays in `utils/yoco.js` + `controllers/yocoController.js`.
- `backend/src/payments/webhook.js` — shared webhook processing (Payment with `provider`,
donation split, registration status, tickets, emails, `ProviderTransaction`).
- `backend/src/payments/checkouts.js` — registration checkouts (balance, part, + donation).
- `backend/src/payments/status.js` — status checks for notifications that never arrived
(`payment-status` job, Payments → Reconcile → "Waiting for payment"). PayFast looks payments
up in its transaction history (`findPayments`); Yoco's Checkout API documents no lookup, so
Yoco checkouts are "can't check". Tests: `backend/tests/paymentStatus.test.js`.
- **Adding a provider:** write `providers/<id>.js` with the same interface, add it to
`PROVIDERS` in `index.js`, mount `handleProviderWebhook('<id>')` at `/api/webhooks/<id>`
(`routes/webhookRoutes.js`), and give it a settings card in
`frontend/src/components/admin/PaymentsTab.tsx`. New providers start switched off.
- `Payment.method` stays the wallet type (card, apple_pay…) because cashups bucket on it;
the provider is `Payment.provider`.
## Known gaps / follow-ups
- At the door, per-session tickets are booked on new registrations only; editing an
existing registration leaves its booked sessions as they are (the backend refuses
changes to picked lines). "Add & charge" for a session at the scanner isn't built.
- Ticket scanning by camera isn't covered by the e2e tests (headless browsers have no
camera); scans are tested through the API.