Verified Programs calendar subscriptions for residents, with a protected operator console for delivery, health, and email management.
Documentation
| Area | Start here |
|---|---|
| Subscription behavior | Programs calendar flow |
| Runtime and request flow | Architecture |
| Routes and response contracts | API reference |
| Tables and storage | Data model |
| External services | Integrations |
| Deployment and recovery | Operations guide |
Live site: calendar.ihnyc-rc.org
Repository: dghauri0/ihnyc-rc-cal-landing
Programs subscription · June 2026
What a resident experiences
flowchart LR PERSON["1. Enter name and email"] --> MAIL["2. Receive a magic link"] MAIL --> VERIFY["3. Open the link"] VERIFY --> URL["4. Receive a private calendar URL"] URL --> APP["5. Calendar app refreshes the feed"]
The private URL contains a random calendar token. The service stores only its SHA-256 hash; it does not need the plaintext token after issuing the URL.
What runs behind that flow
- Eleventy builds the public pages from
src/intodist/. - Cloudflare Pages Functions handle subscriptions, renewal, admin APIs, and feed delivery.
- D1 stores subscribers, token hashes, access logs, email events, templates, and first-party product/security events.
- R2 stores the generated
programs.icsfile. - Resend delivers magic-link and renewal email.
- Turnstile can screen automated subscription requests.
- A scheduled endpoint rebuilds
programs.icsfrom selected Notion events every 15 minutes. - The legacy Internal calendar alone still proxies to n8n.
- The admin Tools area edits each email’s subject, headline, body, button, supporting prose, and one shared footer. Preview uses the real email renderer and saves version history.
- The admin uses the shared Admin Kit controls while keeping the Calendar visual system.
Mixpanel has been removed. Current analytics are first-party D1 records; see Calendar analytics.
Public Programs flow
POST /api/subs/new?calendar_id=programsvalidates the request, applies the cooldown, and sends a short-lived magic link.GET /api/subs/verify?...&v=...consumes the one-time verification code and mints a calendar token.GET /cal/programs.ics?token=...&calendar_id=programshashes the presented token, validates its record, and returns the R2 object.- Renewal email contains a separate, expiring signed credential. It can extend the token record but cannot fetch the calendar feed.
sequenceDiagram participant Resident participant Calendar as Calendar service participant Email as Resend participant D1 participant R2 Resident->>Calendar: Request a subscription Calendar->>D1: Store one-time code hash Calendar->>Email: Send magic link Email-->>Resident: Verification link Resident->>Calendar: Open link Calendar->>D1: Consume code and store token hash Calendar-->>Resident: Private feed URL Resident->>Calendar: Calendar app fetches with token Calendar->>D1: Validate token hash Calendar->>R2: Read programs.ics R2-->>Resident: Calendar feed
Admin access has two gates
Every /api/admin/* request must pass both checks:
- Identity: the Cloudflare Access JWT is verified in application code.
- Authorization: the request is mapped to an action such as
subscriber.revoke; RC Console confirms that the person’s current role includes it.
Unknown routes and policy-service failures are denied. See RC Console identity and access for the relationship.
Key routes
| Route | Method | Access | Purpose |
|---|---|---|---|
/subscribe-programs | GET | Public | Resident subscription page |
/api/subs/new | POST | Public; Turnstile when configured | Start subscription |
/api/subs/verify | GET | One-time magic link | Mint the private feed token |
/renew | GET | Signed renewal credential | Show the renewal confirmation |
/api/subs/extend | POST | Signed renewal credential or legacy token | Extend an existing token |
/cal/programs.ics | GET/HEAD | Calendar token | Serve Programs ICS from R2 |
/cal/internal.ics | GET/HEAD | Internal access boundary | Proxy the legacy Internal feed |
/api/cron/regenerate-programs-ics | POST | Cron bearer token | Rebuild the Programs feed from Notion |
/api/cron/renewal-warnings | POST | Cron bearer token | Send renewal reminders |
/api/admin/* | Varies | Access JWT and RC Console role | Operate and observe the service |
See the API reference for the complete admin action list.
Storage
flowchart LR CAL["Calendar Pages Functions"] --> SUBS[("D1: subscriptions and token hashes")] CAL --> EVENTS[("D1: events, email outcomes, templates")] CAL --> FEED[("R2: programs.ics")] NOTION["Notion Events"] -->|scheduled rebuild| CAL ADMIN["RC Console policy service"] -. allow or deny admin action .-> CAL
Detailed documentation
- end-user — subscribe and troubleshoot as a resident
- architecture — request routing and trust boundaries
- programs-ics-generation — Notion-to-R2 feed generation, timed and all-day events
- mixpanel — current D1 analytics and the retired Mixpanel path
- api — routes, methods, and authorization
- data — D1 and R2 data model
- ops — development, deployment, and failure checks
