- Service Name:
ihnyc-rc-cal-landing - Live Site: https://calendar.ihnyc-rc.org
- Repository:
https://github.com/dghauri0/ihnyc-rc-cal-landing.git
π§ Overview
- Cloudflare Pages site with Pages Functions
- Programs calendar uses magic-link verification and token-gated ICS
- Internal calendar feed proxies to n8n
- Turnstile and Mixpanel integrations for bot protection and analytics
- Middleware redirects to
/subscribefor onboarding
Sources: ihnyc-rc-cal-landing/wrangler.toml, ihnyc-rc-cal-landing/functions/_middleware.ts, ihnyc-rc-cal-landing/README.md
π₯ Key User Flows
Programs Subscription Flow
- User submits email on subscription page
- Turnstile bot check (if enabled)
- System sends magic link via Resend
- User clicks link to verify
- System mints token stored in D1
- User receives tokenized ICS URL for calendar app
Internal Calendar Flow
- Admin-only access to
/cal/internal.ics - Proxies to n8n webhook
- Protected via Cloudflare Access at edge
Admin Management
- View subscription stats
- List subscribers
- Revoke or re-enable tokens
Sources: ihnyc-rc-cal-landing/functions/api/subs/new.ts, ihnyc-rc-cal-landing/functions/api/subs/verify.ts, ihnyc-rc-cal-landing/functions/cal/programs.ics.ts, ihnyc-rc-cal-landing/functions/cal/internal.ics.ts
π Detailed Guides
- end-user: How to subscribe, refresh timing, and troubleshooting
- architecture: System overview and routing behavior
- api: Endpoint-level reference
- data: D1 schema and storage model
- integrations: Resend, Turnstile, Mixpanel, n8n
- mixpanel: Event taxonomy and tracking diagrams
- ops: Runbook and operational notes
π Key Routes and Endpoints
| Route | Method | Auth | Purpose | Source |
|---|---|---|---|---|
/api/subs/new | POST | Public (Turnstile) | Start subscription flow | ihnyc-rc-cal-landing/functions/api/subs/new.ts |
/api/subs/verify | GET | Magic link | Mint token and return subscription links | ihnyc-rc-cal-landing/functions/api/subs/verify.ts |
/api/turnstile-site-key | GET | Public | Return Turnstile site key | ihnyc-rc-cal-landing/functions/api/turnstile-site-key.ts |
/cal/programs.ics | GET/HEAD | Token | Serve programs ICS from R2 | ihnyc-rc-cal-landing/functions/cal/programs.ics.ts |
/cal/internal.ics | GET/HEAD | Edge Access | Proxy internal ICS via n8n | ihnyc-rc-cal-landing/functions/cal/internal.ics.ts |
/api/admin/stats | GET | Edge Access | Subscription stats | ihnyc-rc-cal-landing/functions/api/admin/stats.ts |
/api/admin/subs/list | GET | Edge Access | List subscribers | ihnyc-rc-cal-landing/functions/api/admin/subs/list.ts |
/api/admin/revoke | POST | Edge Access | Revoke subscriber tokens | ihnyc-rc-cal-landing/functions/api/admin/revoke.ts |
/api/admin/enable | POST | Edge Access | Re-enable subscriber | ihnyc-rc-cal-landing/functions/api/admin/enable.ts |
ποΈ Data and Storage
| Storage | Binding | Purpose | Schema |
|---|---|---|---|
| D1 | SUBS_DB | Subscribers, tokens, access logs | ihnyc-rc-cal-landing/schema.sql |
| R2 | CAL_BUCKET | Programs ICS file | ihnyc-rc-cal-landing/wrangler.toml |
Sources: ihnyc-rc-cal-landing/wrangler.toml, ihnyc-rc-cal-landing/schema.sql
ER Diagram (Mermaid)
erDiagram subscribers { INTEGER id PK TEXT email TEXT name TEXT status TEXT created_at TEXT updated_at } calendars { TEXT id PK TEXT display_name TEXT ics_key INTEGER is_enabled TEXT created_at TEXT updated_at } verify_requests { INTEGER id PK TEXT email TEXT name TEXT calendar_id FK TEXT code_hash TEXT created_at TEXT expires_at TEXT consumed_at TEXT ip_hash TEXT ua } calendar_tokens { INTEGER id PK INTEGER subscriber_id FK TEXT calendar_id FK TEXT token_hash TEXT created_at TEXT expires_at TEXT last_seen_at TEXT revoked_at } calendar_access_log { INTEGER id PK TEXT ts TEXT calendar_id FK INTEGER token_id FK INTEGER status TEXT path TEXT ua TEXT ip_hash } subscribers ||--o{ calendar_tokens : has calendars ||--o{ verify_requests : verifies calendars ||--o{ calendar_tokens : issues calendars ||--o{ calendar_access_log : logs calendar_tokens ||--o{ calendar_access_log : used_by
Sources: ihnyc-rc-cal-landing/schema.sql
π Automations and Integrations
Email Delivery
- Resend: Magic-link email delivery
- Configured via
RESEND_API_KEYandFROM_EMAIL
Bot Protection
- Turnstile: Bot checks in programs subscription flow
- Activated when
TURNSTILE_SECRETis set
Analytics
- Mixpanel: Event tracking with hashed
distinct_id - Logs subscription events and verification
n8n Integration
- Internal calendar feed proxies to n8n webhook
- Internal subscription flow triggers n8n workflow
Sources: ihnyc-rc-cal-landing/functions/api/subs/new.ts, ihnyc-rc-cal-landing/functions/api/turnstile-site-key.ts, ihnyc-rc-cal-landing/functions/_lib/mixpanel.ts, ihnyc-rc-cal-landing/functions/cal/internal.ics.ts
πΊοΈ Service Flow Diagram
Calendar service architecture and integrations
flowchart LR subgraph Users U_RES["USER: Resident"] U_ADMIN["USER: Admin"] U_CAL["USER: Calendar Client"] end subgraph Services S_CAL["SVC: ihnyc-rc-cal-landing"] end subgraph External_Systems EXT_RESEND["EXT: Resend"] EXT_TURNSTILE["EXT: Cloudflare Turnstile"] EXT_MIXPANEL["EXT: Mixpanel"] EXT_N8N["EXT: n8n"] end subgraph Storage STORE_D1["STORE: D1"] STORE_R2["STORE: R2"] end U_RES -->|subscribe| S_CAL U_ADMIN -->|admin| S_CAL U_CAL -->|fetch ICS| S_CAL S_CAL -->|subscriptions| STORE_D1 S_CAL -->|read ICS| STORE_R2 S_CAL -->|email| EXT_RESEND S_CAL -->|verify| EXT_TURNSTILE S_CAL -->|analytics| EXT_MIXPANEL S_CAL -->|proxy| EXT_N8N
Sources: ihnyc-rc-cal-landing/functions/api/subs/new.ts, ihnyc-rc-cal-landing/functions/api/subs/verify.ts, ihnyc-rc-cal-landing/functions/cal/programs.ics.ts, ihnyc-rc-cal-landing/functions/cal/internal.ics.ts, ihnyc-rc-cal-landing/wrangler.toml
π οΈ Common Ops
Local Development
npx wrangler pages dev publicDeployment
npx wrangler pages deploy publicUpload ICS File to R2
npx wrangler r2 object put ihnyc-calendars/programs.ics --file ./programs.icsSources: ihnyc-rc-cal-landing/README.md
π Environment Variables
| Name | Purpose | Required |
|---|---|---|
RESEND_API_KEY | Email delivery API key | Yes |
FROM_EMAIL | Sender email address | Yes |
BASE_URL | Service base URL | Yes |
N8N_BASE | n8n webhook base URL | For internal flow |
TURNSTILE_SECRET | Bot protection secret | Optional |
TURNSTILE_SITE_KEY | Bot protection site key | Optional |
PROGRAMS_ICS_KEY | ICS file key in R2 | Yes |
MIXPANEL_TOKEN | Analytics token | Optional |
Sources: ihnyc-rc-cal-landing/wrangler.toml, ihnyc-rc-cal-landing/README.md
β Open Questions
Production Configuration
- Are
/admin*and/subscribe-internal*protected by Cloudflare Access in production?
Sources: ihnyc-rc-cal-landing/README.md