← All docs

Analytics Specification

You can't improve what you don't measure — and you can't trust a metric you never defined. This document is the single source of truth for what Applied Product & Venture Design tracks, why, and how success is judged. The machine-readable version lives in lib/analytics/spec.ts (typed against the frozen event enum in lib/schemas/analytics.ts); events are emitted client-side via track() in lib/analytics/track.ts.

Tracked events

Every event carries name, props, and an ISO ts timestamp. Props are limited to strings, numbers, and booleans. The table below lists the required props per event; emitters may add extra props but never omit required ones.

| Event | When it fires | Required props | Fired from | Metrics informed | |---|---|---|---|---| | mission_started | Learner clicks Start on a mission intro and enters the first step | missionId (string), category (string) | Mission player | Mission completion rate, DAU/WAU, mode-usage split | | mission_step_completed | Learner finishes a mission step and advances | missionId (string), stepIndex (number), stepType (string) | Mission player | Mission completion rate (drop-off location) | | mission_completed | Learner completes the final step of a mission | missionId (string), category (string), durationSeconds (number) | Mission player | Mission completion rate, day-7 retention, DAU/WAU | | quiz_answered | Learner submits a concept-check answer | missionId (string), questionId (string), correct (boolean) | Mission player concept-check | Quiz accuracy | | artifact_submitted | Learner saves a completed artifact to their portfolio | templateId (string), fieldCount (number) | Studio editor | Artifact submission rate, day-7 retention | | sim_run_started | Learner starts a new simulator run | simulatorId (string) | Simulator | Mode-usage split, DAU/WAU | | sim_turn_advanced | Learner commits a decision; the engine advances one turn | simulatorId (string), turn (number) | Simulator decision panel | Mode-usage split | | sim_run_ended | A run reaches its end state (final turn, win/lose, or abandoned) | simulatorId (string), turnsPlayed (number), outcome (string) | Simulator end-of-run summary | Mode-usage split | | calculator_used | A calculator produces outputs (first successful compute per view) | calculatorId (string) | Calculator page | Mode-usage split, DAU/WAU | | template_opened | Learner opens a template in the Studio editor | templateId (string) | Studio template gallery | Artifact submission rate (funnel entry), mode-usage split | | ai_message_sent | Learner sends a message to any AI surface | surface (string) | Mission coach, Office Hours, Product Court, Studio feedback | Mode-usage split, DAU/WAU | | boss_fight_started | Learner begins a boss-fight case | bossFightId (string) | Boss Fights | Mode-usage split | | boss_fight_graded | The AI grader returns a score for a submission | bossFightId (string), score (number), passed (boolean) | Boss Fights grading result | Quiz accuracy (graded complement) | | page_viewed | Learner navigates to any route | path (string) | App-wide navigation | DAU/WAU, day-7 retention, mode-usage split |

Cohort definitions

All dashboard views support filtering by these cohorts.

Signup-week cohort

Bucket = the ISO week (YYYY-Www) of the learner's earliest page_viewed event. Assigned once, never changes. Used to compare retention and completion curves across weekly vintages — the canonical axis for the day-7 retention target.

Acquisition-channel cohort

Bucket = the utm_source (or referrer class when no UTM is present) captured on the learner's first page_viewed event. Assigned once at first touch. Example buckets: organic-search, newsletter, partner, direct, paid-social. Used to compare engagement quality across channels, not just volume.

Category-progress cohort

Bucket = the curriculum category of the learner's most advanced mission_completed event, in curriculum order (fundamentals → customer-market → value-prop → mvp-experimentation → business-models → metrics-analytics → growth → strategy-funding → product-leadership). Recomputed on every mission_completed. Used to see where in the journey engagement or quality changes.

Dashboard metrics

| Metric | Definition | Derived from | |---|---|---| | DAU / WAU | Distinct learners with ≥1 event per day/week, plus the DAU/WAU stickiness ratio | page_viewed, mission_started, mission_completed, sim_run_started, calculator_used, ai_message_sent | | Mission completion rate | Distinct (user, mission) pairs with mission_completed ÷ pairs with mission_started | mission_started, mission_step_completed, mission_completed | | Artifact submission rate | Distinct (user, template) pairs with artifact_submitted ÷ pairs with template_opened | template_opened, artifact_submitted | | Day-7 retention | Share of a signup-week cohort with ≥1 event on day 7 (±1 day) after first event | page_viewed, mission_completed, artifact_submitted | | Quiz accuracy | quiz_answered with correct=true ÷ all quiz_answered; average boss_fight_graded score reported alongside | quiz_answered, boss_fight_graded | | Mode-usage split | Share of mode-entry events per period across missions, simulators, calculators, studio, AI chat, boss fights | mission_started, sim_run_started, sim_turn_advanced, sim_run_ended, calculator_used, template_opened, ai_message_sent, boss_fight_started, page_viewed |

Dashboard layout

Three panels, each filterable by any cohort above and by date range.

1. Funnels

  • Mission funnel: mission_startedmission_step_completed (per step index) → mission_completed. Shows exactly which step bleeds learners, per mission and per category.
  • Artifact funnel: template_openedartifact_submitted, per template.
  • Boss-fight funnel: boss_fight_startedboss_fight_graded (split by passed).

2. Engagement over time

  • DAU and WAU lines with the stickiness ratio.
  • Mode-usage split as a stacked area over time.
  • Retention curves (day 1 through day 30) per signup-week cohort.

3. Per-category completion

  • Mission completion rate per curriculum category (bar chart), with quiz accuracy overlaid — a category that completes well but quizzes poorly needs content work, not funnel work.
  • Category-progress cohort distribution: how far the active base has advanced through the curriculum.

Acceptance criteria (targets to validate after launch)

Per the PRD, success is defined by learner outcomes, not shipped features. These are the launch targets; the exact thresholds should be revisited once real launch data exists.

  • ≥70% mission completion once started — of learners who fire mission_started for a mission, at least 70% eventually fire mission_completed for it.
  • ≥40% day-7 retention — at least 40% of each signup-week cohort is active on day 7.
  • ≥80% average concept-check score — the accuracy across quiz_answered events averages 80% or higher.

If a target misses, the dashboard is built to say where: the mission funnel isolates the step, cohorts isolate the audience, and the per-category view isolates the content.

Local implementation note

Today, track() writes to the console and a localStorage ring buffer (last 500 events) — enough to develop and demo the dashboard against real interaction data. The event contract above is transport-agnostic: swapping the sink for a real pipeline changes nothing about names, props, or metric definitions.