# Report Recipes

These recipes regenerate report facts by calling Analytics Alpha only. They do not compute platform-owned values.

Set credentials:

    export ANALYTICS_BASE_URL="https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/implementation/api"
    TOKEN_JSON=$(curl -fsS -X POST "$ANALYTICS_BASE_URL/dev/mint?tenantId=demo")
    export ANALYTICS_TOKEN=$(printf '%s' "$TOKEN_JSON" | node -e 'let s="";process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>process.stdout.write(JSON.parse(s).token))')
    export ANALYTICS_TENANT=demo

## Learning Report: Time Commitment

Question: how many active minutes per enrolled school day should this student show?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&startDate=2026-05-01&endDate=2026-06-01" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render active_minutes, enrolled_school_day_count, minutes_per_enrolled_school_day, school_day_policy_ref, null_reason, and quality_status exactly as returned.

This default call is the report path. Do not pass `includeUnavailable=true` for a Learning Report panel; that flag is only for auditing `subject_id=null`, `source_missing`, `policy_pending`, or impossible minutes/day repair rows.

## Learning Report: XP

Question: what awarded XP total should this student show for the term?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render positive_xp, negative_xp, net_xp, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, xp_completion_percent, on_track, award_count, reversal_count, source_ledger_refs, source_import_id, and policy_ref exactly as returned. Do not compute goal progress or fill missing goal fields from local formulas.

For `windowKind=range|term|school_year`, use the exact materialized
`window_start`/`window_end`, not calendar guesses. If `data` is empty and
`meta.null_reason` is `no_exact_window`, retry only with one of the returned
`meta.available_windows`; do not reuse an overlapping row or compute XP locally.

Ada's Learning Report row is the pinned demo row `xp_rollup_demo_student_01ht7g3yzv7qb5n4ykq1k0z9a9_term`. The source-import proof recipe uses a different student/date and may accumulate repeated demo proof imports; do not compare that proof row to Ada's report panel.

## Learning Report: Accuracy

Question: what accuracy should this student show for the reporting window?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/accuracy-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render correct_question_count, incorrect_question_count, total_question_count, accuracy_percent, source_fact_refs, null_reason, and quality_status exactly as returned. Do not compute accuracy from question attempts or processed_facts.

## Learning Report: Attempts

Question: how many attempts did this student need in the reporting window?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/attempt-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render attempt_count, max_attempt_ordinal, source_event_refs, source_import_id, and policy_ref exactly as returned. Do not parse Events extensions or infer attempts from local answer state.

## Learning Report: Response Latency

Question: how long did responses take?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/response-latency-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render response_count, response_time_ms_total, response_time_ms_avg, response_time_ms_min, response_time_ms_max, source_event_refs, source_import_id, and policy_ref exactly as returned. The unit is milliseconds. Do not invent response_latency or time-to-answer aliases.

## Learning Report: Hint Usage

Question: how often did this student request, view, or use hints?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/hint-usage-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render hint_request_count, hint_view_count, hint_used_count, source_event_refs, source_import_id, and policy_ref exactly as returned. Do not count hint buttons locally from player UI state.

## Learning Report: Mastery Changes

Question: which durable mastery changes occurred during the reporting window?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/mastery-deltas?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&stateDimension=durable_mastery&startDate=2026-05-01&endDate=2026-06-01" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render kc_id, state_dimension, effective_at, previous_value, new_value, delta_value, transition_kind, and policy_ref. Do not compute mastery state.

## Learning Report: MAP RIT And Growth X

Question: what RIT and Growth X should the MAP panel show?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/map-growth-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&termId=term_2026_winter&growthWindow=winter_to_winter&normsSet=2025" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render rit_score, start_rit, achievement_percentile, conditional_growth_percentile, observed_growth, projected_growth, growth_x, growth_x_target, on_track, sitting_count, retake_count, map_sitting_refs, and policy_ref. `growth_percentile` is a compatibility alias for `conditional_growth_percentile`, not a second metric. To change norms, change only normsSet. Do not load a private norms table.

For the Ada demo fixture, use exactly `growthWindow=winter_to_winter`; that is the seeded Learning Report MAP row selected by `checks/expected.json` and verified against the live convergence answer key.

## Learning Report: Completion

Question: what percent of the course is complete?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/completion-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&completionScope=course&scopeId=course_math_grade_4_powerpath&startDate=2026-01-01&endDate=2026-06-01" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render grade_level, is_main_course, progress_source_kind, completed_count, expected_count, xp_earned, xp_remaining, completion_percent, numerator_policy_ref, denominator_policy_ref, null_reason, source_result_refs, and curriculum_scope_refs. Course progress uses app-reported Caliper percent first, then XP remaining fallback. Grade-level progress uses `completionScope=grade_level` and averages main courses only. Do not derive progress from MAP/RIT/R90, walk Curriculum trees, or count Results rows.

## GOALS: Norms, R90, And Remaining School Days

Question: what RIT corresponds to a target percentile?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/norms/rit?subject=math&grade=5&season=winter&role=student&percentile=99&normsSet=2025" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render percentile, output_rit, raw_rit, calculator_version, and links.table exactly as returned. To go the other direction, call:

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/norms/percentile?subject=math&grade=5&season=winter&role=student&rit=247&normsSet=2025" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

If the user needs the readable versioned norms table itself, call `GET /alpha/analytics/v1/norms/table` or `GET /alpha/analytics/v1/norms` and cache only by returned table_version. Do not ship or maintain an app-side norms file.

Question: what R90 / effective grade position corresponds to a RIT score?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/r90?subject=math&rit=239&normsSet=2025" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render r90_grade, effective_grade, r90_grade_level, rit90_grade_band_percent, source_point_kind, table_version, and calculator_version as returned. `r90_percent_complete` is a compatibility field for the same MAP-inferred grade-band position; it is not actual course or grade-level progress. If the app needs the table, call `GET /alpha/analytics/v1/r90/table` and cache only by returned table_version. Do not carry a local R90 table.

Question: how many instructional days remain, and what effort projection should GOALS show?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/school-days-remaining?studentId=student-ada-001&asOf=2026-06-14&endDate=2026-07-24&xpRemaining=600" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render instructional_days_remaining, first_instructional_date, last_instructional_date, school_day_policy_ref, xp_unit, and effort exactly as returned. Do not count calendar days or convert XP to hours locally.

Question: is the student working or strictly mastered above, at, or behind age grade?

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/grade-level-status?studentId=b6fa7128-f641-4efd-9075-375411fd6c39&subject=math&asOfDate=2026-05-20" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Render age_grade, working_grade, highest_mastered_grade, working_age_grade_status, mastered_age_grade_status, working_age_grade_delta, and mastered_age_grade_delta exactly as returned. Do not infer age grade from MAP/RIT, birthdays, prior-year close, or course placement; do not expose generic ahead/at/behind as the preferred contract.

## Time Audit

Use event-time-facts when auditing the source contribution:

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/event-time-facts?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&factKind=active_seconds&sourceEventId=event_demo_closed_student_01ht7g3yzv7qb5n4ykq1k0z9a9" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

Use time-windows when the report wants a window total:

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/time-windows?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=day&startDate=2026-05-14&endDate=2026-05-15" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: $ANALYTICS_TENANT"

## Metric-Check Coverage

- minutes and Caliper events: event-time-facts, time-windows, school-day-minutes.
- XP: xp-rollups.
- accuracy: accuracy-rollups.
- question attempts: attempt-rollups.
- response latency: response-latency-rollups.
- hint usage: hint-usage-rollups.
- mastery and student_kc_state changes: mastery-deltas.
- RIT, Growth X, MAP windows, and MAP sittings/scores: map-growth-rollups.
- percentile/RIT and RIT/R90/grade position: norms, norms/table, norms/rit, norms/percentile, r90/table, r90.
- GOALS forward effort date: school-days-remaining.
- GOALS age-grade status: grade-level-status. Render working_age_grade_status and mastered_age_grade_status from the response; do not compute or rename generic ahead/at/behind locally.
- completion and Curriculum refs: completion-rollups. Read current rows through the paged API (`limit`/`cursor`); do not request or process superseded probe history.
- source-shaped migration import: source-imports/timeback-xp-time-accuracy for TimeBack time/XP/accuracy rows plus source-imports for audit. Use the other documented adapters for MAP, grade/mastery, completion, and migration reconciliation source shapes.
