AnalyticsType contract as production (track with dual identification, identify), with console logging instead of a remote provider — session, ensureAnonymousAnalyticsId, login, and trackFrontendEvent behave like production adapters.
Why
The local provider lets you develop and test analytics instrumentation without an external account or API key. Everytrack() call prints a structured log line with the event name, properties, and identification attributes — enough to confirm your instrumentation is correct before deploying.
How it works
Dual identity ontrack: Same contract as production: { anonymousId: string; userId?: string }. The local adapter logs these values for visibility.
identify: Implemented as a noop or console log (see apps/tools/analytics/local/src/index.ts) — no network call. The backend still calls identify after login and for legacy sync; you see those calls in the console during local dev.
Session and login: Identical to production: anonymousAnalyticsId in session, middleware ensure + sync, identifyUserInAnalytics after login. Only the outbound provider differs.
Backend-only for now: No browser SDK ships with this template; trackFrontendEvent still flows through the backend with the same identification resolution.
Setup
This is the default fordevelopment.ts and test.ts and requires no extra dependencies or environment variables:
ANALYTICS_APP in .env.development (for example ANALYTICS_APP=refract-dev). The backend attaches that value as the app property on every outbound track event.
Future: browser SDK and one canonical id
When you add a browser analytics SDK later, the intended pattern is to surface the sameanonymousAnalyticsId the backend already stores in session — for example a first-party cookie on responses — so the client initializes with the same id the server uses, not a second generator. HttpOnly vs JS-readable and SameSite are decisions for that phase.
Extending this system
- Adjust logging in
apps/tools/analytics/local/src/index.ts. - Run
make test module=tooling-analytics-local.
What not to do
❌ Never pointproduction.tsatLOCALexpecting silent safe behavior in prod — you would only get console noise, not real analytics. ❌ Never duplicate session or identify logic in the local package — keep it inapps/backend/src/utilities/analyticsIdentification.ts.
File conventions
What’s next?
- Amplitude — the production provider to configure in
production.ts. - PostHog — another production provider with policy-enforced payload controls.
- Configuration — switching pluggable tool implementations.
