Local checks

Requirements: Node.js 20 or newer.

npm ci
npm test
npm run build

npm run dev serves the Eleventy frontend on port 8080. To exercise Pages Functions, build first and run:

npx wrangler pages dev dist

Working subscription, admin, cron, and feed paths also need suitable local D1/R2 bindings and non-production test credentials.

Deployment order

  1. Run npm test and npm run build.
  2. Review new D1 migrations. Migration 0008 requires the token-hash-only code first. Migrations 0009 and 0010 are safe after the compatible email-template code is live.
  3. Apply remote migrations with npm run migrate.
  4. Deploy dist/ and the Pages Functions through the configured Pages project.
  5. Smoke-test the resident form, one tokenized feed request, the admin authorization boundary, and one rendered email preview.

Configuration map

AreaNames
StorageSUBS_DB, CAL_BUCKET, PROGRAMS_ICS_KEY
EmailRESEND_API_KEY, RESEND_FROM, RESEND_WEBHOOK_SECRET
Bot checkTURNSTILE_SITE_KEY, TURNSTILE_SECRET
Tokens and renewalTOKEN_TTL_DAYS, TOKEN_PEPPER, BASE_PUBLIC
Feed generationNOTION_EVENTS_DB_ID, NOTION_TOKEN, CRON_BEARER_TOKEN
Admin identityACCESS_TEAM_DOMAIN, ACCESS_AUD
Admin authorizationPANEL_URL, AUTHZ_SERVICE_TOKEN
Legacy Internal feedN8N_BASE

Secrets belong in Cloudflare Pages secrets or the local secret environment, never in source or documentation.

Common failure checks

  1. Check RESEND_API_KEY and RESEND_FROM.
  2. Inspect the request event and email_events/Resend outcome.
  3. Confirm the one-minute per-email cooldown is not active.
  4. Confirm Turnstile verification succeeds when enabled.

Feed returns not found

  1. Confirm the token is current, not revoked, and not expired.
  2. Confirm the subscriber and Programs calendar are enabled.
  3. Confirm programs.ics exists in CAL_BUCKET.
  4. Inspect calendar_access_log without copying private token values into tickets or chat.

Programs feed is stale

  1. Check the last regenerate-programs-ics cron result.
  2. Confirm NOTION_TOKEN can read the configured Events database.
  3. Confirm the intended rows have Include in External Feed enabled.
  4. A successful unchanged run will not write R2; that is expected.

Admin API returns 401, 403, or 503

  • 401: verify the Access application, JWT issuer, and audience.
  • 403: confirm the route has an action mapping and the person’s Calendar role includes it.
  • Policy service unavailable or missing AUTHZ_SERVICE_TOKEN: the request fails closed. Check RC Console health rather than adding a bypass.

Email preview is blank or stale

  1. Confirm POST /api/admin/templates/preview reaches the template.read action.
  2. Confirm migrations 0009 and 0010 are applied.
  3. Compare the preview with a test email; both should use the same renderer.
  4. Use version history to restore a bad template or shared-footer edit.

Observability

  • calendar_access_log explains feed delivery status and latency.
  • event_log powers product/security timelines, funnel, cohort, and replay views.
  • email_events records signed provider delivery outcomes.
  • system_state records cron summaries.

Mixpanel checks and environment variables are obsolete and should not be restored.