Event Tracking (PostHog Facade)
Status: Shipped — vendor-agnostic facade over posthog-node.
Last reviewed: 2026-05-28
What
A minimal, vendor-neutral analytics facade exposed as the global EventTrackingService. Today it wraps the PostHog Node SDK; the public methods (track, identify) keep callers from binding to PostHog directly.
Specifically NOT in this feature:
- No DB log of events (PostHog is the system of record).
- No webhook ingestion from PostHog back into FitKit.
- No client-side capture from web (PostHog browser SDK is configured separately, not in this module).
- No A/B testing / feature flag plumbing.
Why
- Funnel analytics: announcement publishes, signups, conversions, payments.
- Decouple call sites from the vendor — swapping to Segment / Amplitude / Snowflake would touch one file.
- Production-only by design — local dev events would pollute funnels. Non-prod runs as a log-only no-op.
Personas
System-internal. No user-facing surface. The data product team consumes PostHog dashboards.
Capabilities
track(distinctId, event, properties?)— fire-and-forget capture. Logs at info level always; sends to PostHog when configured + in production.identify(distinctId, properties?)— set / update PostHog person properties.- Auto-flush — 20-event batch or 10s interval (PostHog SDK defaults overridden).
- Lifecycle —
onModuleDestroyshuts down the PostHog client; flushes pending events on app stop.
Capabilities (gaps)
- No backend-side queue between API call and PostHog send — a slow PostHog wouldn’t block (try/catch), but events could be lost on shutdown if
onModuleDestroydoesn’t flush in time. - No structured event taxonomy enforcement (any string event name accepted). Event names today:
announcement_published, payment-related events fromPaymentObservabilityService, others. A typed registry would be a useful follow-up. - No PII redaction policy at this layer — callers are responsible for what they pass into
properties.
Related
../announcements/— capturesannouncement_published.../payments/—PaymentObservabilityServicedelegates here for PostHog calls.../analytics/— separate folder if it exists for client-side surfaces.
Source code
- API:
apps/api/src/event-tracking/event-tracking.{service,module}.ts
Config
| Env | Purpose |
|---|---|
NODE_ENV | Must be production for any send to occur |
POSTHOG_API_KEY | Required for prod sending; absent → log-only |
POSTHOG_HOST | Optional; defaults to https://eu.i.posthog.com |