# Mixpanel Event Tracking

## Objective

Send product events to Mixpanel with identities that survive sign-up and sign-in.

A server-side event pipeline that forwards named product events and user profile updates to Mixpanel, with a stable identity model.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Find every meaningful moment already recorded in the app — sign-up, activation, the core action, upgrade, cancellation — and route them through one tracking call site rather than scattering emits through controllers and views.
2. Define the event catalogue once, in code, as the only source of names and property types, and reject an event whose properties do not match the declared shape instead of sending it and discovering the drift in the dashboard six weeks later.
3. Emit from the server using the app's existing background-job system so tracking never blocks a request, and never ship the project credential into client-side code where anyone can read it and forge events.
4. Give every event a deterministic identifier derived from the record and action that produced it, so a job retried after a timeout produces the same identifier and the destination collapses the duplicate.
5. Decide once whether Mixpanel or Amplitude owns behavioural analytics. If Amplitude Event Tracking is also being applied, put the shared event catalogue and the identity resolution in one place and let each destination be a thin adapter over it, rather than maintaining two divergent lists of event names.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Event names and property types must stay stable once they are in use. Renaming an event or changing a property from a string to a number splits the history into two series and silently breaks every saved report built on it.
- Anonymous activity must be merged into the known user only when the app has real evidence they are the same person. Two people signing in from one shared browser must not have their pre-login behaviour joined onto whichever account authenticated first.
- Retries after a network timeout must not double-count. The send may have succeeded before the connection dropped, so identity of the event has to come from the app, not from the moment of transmission.
- Profile properties overwrite history; event properties do not. A value that describes the moment, such as the plan at the time of purchase, must be sent on the event, or a later upgrade will rewrite every past record to look like it always happened on the new plan.
- Regional data residency and consent settings must be honoured before the first event leaves the app. Sending to the wrong region, or sending at all for a user who declined analytics, is not something a later deletion request repairs.
- Rate limiting and outages must degrade quietly. Buffer, back off with jitter, and drop the oldest events once the buffer is full rather than growing it until the process runs out of memory.
- Personally identifying content — email bodies, message text, addresses, tokens — must never be attached as a property, even when it would be convenient for a funnel.
- The tracking pipeline must be disabled entirely in development, test, and preview environments, or staging noise will pollute production funnels.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Every tracked event is declared in a single catalogue and validated against it before sending.
- [ ] Anonymous sessions merge into the authenticated user without joining unrelated accounts on a shared device.
- [ ] A retried delivery produces one event in the destination, not two.
- [ ] Values that describe a point in time are carried as event properties and are not rewritten by later profile updates.
- [ ] Consent state and the configured region are respected before any event is transmitted.
- [ ] Credentials exist only on the server, and no analytics call blocks a user-facing request.
- [ ] A destination outage causes queued retries and eventual drops, never a failed user action.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
