Current model
Calendar analytics are first-party records in the D1 event_log table. recordEvent() writes one event name, optional internal subscriber/token/calendar ids, an optional deduplication key, and event-specific JSON context.
flowchart LR FLOW["Subscription, renewal,<br/>feed, cron, or webhook"] --> RECORD["recordEvent()"] RECORD --> D1[("D1 event_log")] D1 --> ADMIN["Admin observability,<br/>funnel, cohort, and replay views"] RECORD -. logging failure .-> CONTINUE["User flow continues"]
The write is awaited but best-effort: a D1 logging error is recorded to the Worker log and does not break the resident action.
What is recorded
Major groups include:
| Journey | Example events |
|---|---|
| Magic-link request | started, Turnstile passed/failed, rate limited, request created, email sent/failed |
| Verification | link clicked, request consumed, token minted/failed, subscriber disabled |
| Feed delivery | token invalid/revoked/expired/seen, ICS fetched |
| Renewal | 14-day or 3-day warning, token extended, admin resend/extend/expire |
| Feed generation | Programs ICS regenerated |
| Email delivery | delivered, bounced, complained from the verified Resend webhook |
This list explains the families, not an immutable enum. The recordEvent() call sites remain authoritative.
Privacy boundaries
event_loguses internal numeric subscriber and token ids when a flow has them; it does not copy the subscriber email into the event row.- Retryable cron and webhook paths use a
dedup_key, and a partial unique index prevents duplicate events. - Feed-request security data such as hashed IP, user agent, country, status, and latency belongs to
calendar_access_log, not to Mixpanel. - Raw subscriber email remains in the operational
subscriberstable because the service needs it to send and manage subscriptions.
Mixpanel history
Mixpanel was formerly a second event destination with a hashed distinct_id. That integration has been removed from server code, browser code, environment configuration, and the admin UI. There is no current /api/admin/mixpanel-test endpoint.
This file keeps its old mixpanel path so existing links do not break; its content describes the current D1 system.
Sources
ihnyc-rc-cal-landing/functions/_lib/events.tsihnyc-rc-cal-landing/functions/api/admin/events.tsihnyc-rc-cal-landing/functions/api/admin/funnel.tsihnyc-rc-cal-landing/functions/api/admin/cohort.tsihnyc-rc-cal-landing/functions/api/admin/replay.tsihnyc-rc-cal-landing/migrations/0006_events_and_email.sql