Pulse — the student's mock analysis inside Cetking Universe

Added 9 Oct 2026. Address: /pulse (e.g. https://cetking-platform.vercel.app/pulse). Demo: /pulse?demo=1. Design source of truth: repo CetkingLearning/pulse (PULSE-LIVE-MEMORY.md).

Ravneet's decisions (9 Oct 2026)

  • Pulse lives inside Universe (Mocky world), same login.
  • Scores come from any source: Cetking Universe mocks (now), TCY (later, totals only), and later a student pasting any scorecard text into Rav chat ("we make sense of it"). Paste is not built yet — the tables are ready for it (pulse_sources rows chat_paste and manual, both active = false).
  • First use: the Expected CAT 2026 mock taken in Universe (/mocks/cat/<slug>). Future scope unlimited: any exam, any test — add rows, not rebuilds.

How it flows

student takes mock (/mocks/cat/<slug>, public/mock-shell/cat.html)
  → shell records seconds + visits per question (invisible to student)
  → POST /api/mocks/<slug>/submit → mock_attempts (+ item_seconds, item_visits)
  → Supabase trigger trg_pulse_from_mock_attempt → pulse_attempts / _sections / _questions
     (signed-in students only; if Pulse ever errors, the mock still saves)
student opens /pulse (iframe of public/pulse/pulse.html)
  → GET /api/pulse/me → lib/pulse/load.ts reads ONLY this student's rows
  → lib/pulse/viewmodel.ts computes every number (code, no AI) → window.Pulse.setDashboard(model)

Supabase (Cetking Learn, Mocky Universe) — migration pulse_universal_scorecard_v1

RLS on, no public policies: only the server (service key) reads them.

Table One row = Notes
pulse_sources a place scores can come from universe_mock (questions), tcy (totals), chat_paste / manual (later, student_supplied)
pulse_section_map exam section → lane CAT VARC→verbal, DILR→logic, QA→quant; MBA CET rows too. New exam = new rows
pulse_attempts one test attempt, any source cetking_id, source + source_ref (unique), exam, test_kind, counts, reported score, evidence_level, review_status (pending for student-supplied)
pulse_attempt_sections one section of an attempt provider's own section name kept
pulse_attempt_questions one question of an attempt outcome, seconds, visits, topic/difficulty tags; mistake_tag only with tag_source student/faculty
pulse_targets student's target per exam/cycle empty until My Target writes it

mock_attempts got two columns: item_seconds, item_visits (jsonb, {} for old attempts). Function pulse_ingest_mock_attempt(uuid) re-copies one attempt (safe to re-run).

Adding a new source later (e.g. chat paste)

  1. Read/confirm the numbers, insert one pulse_attempts row with source = 'chat_paste', review_status = 'pending', evidence_level = 'sections' (or totals), plus pulse_attempt_sections rows using the exam's own section names.
  2. Student confirms → review_status = 'confirmed'. Pulse picks it up — no page or engine change needed.
  3. Set pulse_sources.active = true for that source.

What Pulse shows — and hides (guardrails in lib/pulse/viewmodel.ts)

  • No evidence → slot hidden. Zero is a value. Accuracy = correct / attempted. Reported score only.
  • Trends compare full mocks only; sectionals never mix in.
  • Hidden until Rav approves a method: predicted percentile, marks to target, radar charts, pacing score, readiness, "marks you can buy", score-mover bars, healthy bands.
  • Mistake types only when a student/faculty tagged them. Never "attempt more" under 70% accuracy.
  • Bottleneck = first rule that matches: 3+ easy wrong (≥1 in 5 easy) → time on wrong ≥25% → over-attempting (acc <70%, attempt >75%) → under-attempting (acc >80%, attempt <70%, most questions left) → abandoned Logic sets

    6 min → score flat 4 mocks (≤3 marks) → spread >10 marks.

  • Change tab rules are Rav's defaults: 3-minute leave, 6-minute Verbal passage cap, 90-second short Verbal, 90-second Logic take-or-leave.

Tests

tests/pulse-viewmodel.test.ts (15 checks: TCY-only, zero, section mapping, each rule, guardrails, sectionals, target/days, cloneable charts). Browser check done 9 Oct 2026 at 390px and 1440px: all six tabs, 6 charts, no sideways scroll, no errors; signed-out and no-mocks notes; mock sends seconds + visits.

Not done yet

TCY automatic sync into pulse_attempts · chat paste · student mistake tagging · My Target → pulse_targets · Rav chat showing a Pulse card · a solutions/review screen per question.

Source: GitHub cetking-one/docs/PULSE.md. Edit the file there; this page updates on the next release.