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_sourcesrowschat_pasteandmanual, bothactive = 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)
- Read/confirm the numbers, insert one
pulse_attemptsrow withsource = 'chat_paste',review_status = 'pending',evidence_level = 'sections'(ortotals), pluspulse_attempt_sectionsrows using the exam's own section names. - Student confirms →
review_status = 'confirmed'. Pulse picks it up — no page or engine change needed. - Set
pulse_sources.active = truefor 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.