Layers

LayerWhat it does
src/Nunjucks, HTML, CSS, and JavaScript source for resident and admin pages
dist/Eleventy build output deployed by Cloudflare Pages
functions/Pages Functions for subscriptions, feeds, renewal, webhooks, cron, and admin APIs
SUBS_DBD1 subscription, event, email, template, and access data
CAL_BUCKETR2 object storage for programs.ics

The top-level Pages middleware allows known pages, APIs, calendar paths, admin paths, and static assets. Unknown paths temporarily redirect to /subscribe, and invalid calendar_id values are stripped.

Programs calendar

The Programs service has two separate paths:

  • a producer that reads selected Notion events every 15 minutes and writes deterministic ICS bytes to R2;
  • a consumer that validates a private token hash and serves those bytes to a calendar app.

Keeping those paths separate means a temporary Notion problem does not stop the last successfully generated feed from being served.

Token and renewal boundary

Feed tokens are shown once to the resident and stored only as SHA-256 hashes. Renewal email does not require recovering that token: it uses a different HMAC-signed credential containing the token-row id and an expiry. The renewal credential can extend a row but cannot read the feed.

Admin boundary

flowchart TD
  REQUEST["Request under /api/admin/"] --> ID["Verify Cloudflare Access JWT"]
  ID -->|invalid| DENY["Deny"]
  ID --> ACTION["Map method + route to action"]
  ACTION -->|unmapped| DENY
  ACTION --> PDP["Ask RC Console policy service"]
  PDP -->|explicit allow| HANDLER["Run the endpoint"]
  PDP -->|deny, error, or timeout| DENY

The outer Cloudflare Access policy and the in-code JWT verification establish identity. The RC Console response establishes action-level authorization. Neither is treated as a substitute for the other.

Internal calendar

The legacy Internal calendar remains separate. Its subscription request and ICS route proxy to n8n and rely on their internal access boundary. This path does not generate the public Programs feed.

Failure behavior

  • Missing or invalid feed tokens return non-revealing responses.
  • Event regeneration skips the R2 write when bytes did not change.
  • Event logging failures do not fail resident requests.
  • Admin policy-service failures deny the admin action.
  • Renewal and webhook paths use idempotency keys where retries are expected.