# Source-Shaped Import Recipe

Analytics accepts source-shaped TimeBack processed_facts rows and normalizes them server-side. Do not pre-compute platform-owned facts before import.

The demo import below writes to the dedicated proof student `student-analytics-integration-001`, not the Ada Learning Report student, so repeated proof runs do not perturb the report rows used by the worked example and verifier.

Demo import:

    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))')
    RUN_ID="skill-pack-$(date +%s)"
    curl -fsS -X POST "$ANALYTICS_BASE_URL/alpha/analytics/v1/source-imports/timeback-xp-time-accuracy" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: demo" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: analytics-$RUN_ID" \
      --data-binary @- <<EOF
    {
      "sourceBatchRef": "analytics-$RUN_ID",
      "rows": [
        {
          "id": "pf_$RUN_ID",
          "user_id": "student-analytics-integration-001",
          "date": "2026-05-22",
          "datetime": "2026-05-22T15:10:00.000Z",
          "subject": "Math",
          "app": "Math Academy",
          "campus_id": "school_alpha_demo",
          "activity_id": "content-fractions-video-01",
          "active_seconds": 600,
          "inactive_seconds": 60,
          "waste_seconds": 0,
          "xp_earned": 25
        }
      ]
    }
    EOF

Then verify the audit row:

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/source-imports?importKind=timeback-xp-time-accuracy&status=materialized&limit=50" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: demo"

Then verify the readable Analytics row:

    curl -fsS "$ANALYTICS_BASE_URL/alpha/analytics/v1/xp-rollups?studentId=student-analytics-integration-001&subjectId=math&windowKind=day&startDate=2026-05-22&endDate=2026-05-23&limit=100" \
      -H "Authorization: Bearer $ANALYTICS_TOKEN" \
      -H "X-Timeback-Tenant: demo"

The proof row should return typed XP rollup fields such as `positive_xp`, `negative_xp`, `net_xp`, `award_count`, `reversal_count`, `policy_ref`, and `quality_status`. Render those returned fields. Do not expect an exact one-row `25` value after repeated demo runs; this proof student/date is a day rollup and may include prior proof imports. Do not require `source_import_id` on this proof row; the import receipt is verified through `source-imports`, and this day rollup may expose nullable provenance while still proving readable materialization.

The packaged verifier is read-only by default. Set `ANALYTICS_RUN_IMPORT=1` only when you intentionally want to run this write smoke against the demo tenant.

If the source row cannot resolve a real student, subject, or required source field, the surface returns a typed Problem such as analytics:adapter_rejected. Preserve it.
