Feature Analytics
A tracking plan is the product-analytics contract: event names, properties, identity, and an explicit do-not-log list. Prefer a short, stable taxonomy over logging every click.
For KPI formulas, use metrics-definitions. For operator logs, traces, and SLOs, use logging-observability. For A/B setup, use experiment-design. For warehouse producer-consumer schemas, use data-contract-design.
Workflow
- Name the feature and the product questions events must answer (funnel drop-off, activation, failure). This is not a KPI spec.
- Identity:
anonymous_idbefore login; opaqueuser_idafter identify;group_id/ account for B2B. Say when merge happens. Email is not an id. - Map journeys to candidate events. Refuse "track everything".
- For each event: name, trigger, client vs server, required properties, owner.
- Properties: type, allowed values, source. No PII, secrets, or raw payloads.
- Do-not-log list: email, name, phone, address, tokens, passwords, PAN/CVV, SSN, chat/search free text, HTML, full request/response bodies.
- QA: one fire per user action, identity present, no forbidden fields.
- Never invent event volumes, QPS, or storage cost.
Output format
## Tracking plan: <feature>
**Identity:** anonymous_id / user_id / group_id; when identify/group fire
**Source of truth:** client | server | both (say which events)
### Events
| Name | Trigger | Where | Required properties | Owner |
### Properties
| Event | Property | Type | Allowed values | Source |
### Do not log
- …
### QA
- …
### Out of scope
`metrics-definitions` for KPI formulas
`logging-observability` for operator logs
`experiment-design` for A/B setup
Rules
- Never invent event volumes, traffic, or "this will be N events/day".
- Never put PII or secrets in event or user properties.
- Names: object_action, past tense, one casing (snake_case or Title Case). Stable names; aliases are deprecated, not silent renames.
- Money, entitlements, and spoofable outcomes fire server-side.
- Do not write KPI numerators/denominators here (
metrics-definitions). - Do not design operator logs, SLIs, or traces here (
logging-observability). - Do not design randomization, power, or SRM here (
experiment-design). - Opaque ids only. Do not use email, phone, or name as
user_id. - User traits go on identify/group. Event properties are facts about this action. Dual client+server fire needs a
sourceproperty or pick one.
Good: checkout_started with item_count, currency, cart_id. Bad: ButtonClicked plus email, card_number, password, and a guessed million events/day.
Edge cases
- B2B seats vs accounts: events carry both user and group ids; say which identity the funnel is on.
- Anonymous then registered: identify + alias/merge; do not drop the anonymous trail or invent a merge volume.
- Consent / GDPR: no analytics events until consent if that is the policy; do not "just send email for later matching".
- Page views vs semantic events:
page_viewedis not a substitute forinvite_sent/invite_accepted. - Feature-flag exposure: not a product event unless the question needs it as a property; flag rollout itself is not this skill.
- Missing product questions: ask; do not dump a 40-event taxonomy.
- Enums over free text: status, plan, and reason should be closed lists; search queries and chat bodies stay off the event.