Skip to content

SDD-010 — Lab Platform

Kết quả audit labs legacy (SRC-015, 2026-08-13): 288 labs / 2.0MB / 37.6k LOC, cực kỳ bimodal — 186 labs (65%) là pure content trên PickerLab (zero state/logic), 73 dùng LabShell + stage nhỏ, chỉ 29 bespoke (39% code). 93 labs sinh máy nhưng spec JSON gốc không được commit → phải reverse-parse .tsx. Zero asset nhị phân (mọi hình đều procedural SVG/canvas) — tài sản quý nhất là content corpus: 620 quiz prompts, 1.807 options có giải thích, 660 picker items, 288 inquiry triples (predict→observe→check) và pedagogy nhất quán.

1. Nguyên tắc

Labs là content, không phải app. 288 labs sập về 6 archetypes; ~88% trở thành data thuần chạy trên engines dùng chung; chỉ simulations thật mới là code.

2. Interaction Archetypes → Engines (REQ-LAB-01)

EngineArchetype legacyLabsDạng
pickerA1 chip picker → swap stage + note (+A4 static)187JSON config, zero code/lab
parametricA2 slider → SVG/numeric viz58declarative {params[], formula, viz}
stepperA3 animated/stepped simulation (rAF)9config + tick function đăng ký
simA5 multi-scene domain simulator29React components trên shared shell
scene3dA6 three.js1 (anatomy)lazy-load cô lập (734KB không đè lên lab khác)
inquirycross-cutting: predict → observe → checks + quiz288/288một engine duy nhất, mọi lab dùng

3. Lab = Experience trong content system (REQ-LAB-02)

Lab là LearningExperience type lab (SDD-004): metadata D1 (labs registry: id, subject, grade tường minh — không suy từ level, group, accent, mode suy từ implementation — không tin nhãn tay vì legacy sai 24%), content JSON ở R2, immutable version. Một trang lab = engine + config — bỏ mô hình MPA 9-touchpoint (HTML entry + vite input + worker map per lab); router SPA + lazy chunk per engine.

4. Content Migration (REQ-LAB-03)

  1. Script reverse-parse .tsx → JSON (ITEMS, INQUIRY, SCENARIOS là top-level literals; ~highlight~ syntax giữ nguyên) — 186 picker labs tự động 100%.
  2. 58 parametric: trích {params, formula, viz-spec} bán tự động.
  3. 29 bespoke: port logic (solver thật: circuits, photosynthesis, algorithms…), bỏ 206KB CSS trùng lặp + chrome tự chế; re-parent lên shared shell + Design System tokens.
  4. Toàn bộ 288 inquiry blocks vào bảng inquiries — lần đầu tiên bespoke labs có correctness signal.
  5. Nội dung VI-first, cấu trúc i18n-ready (Q-011).

5. Evidence contract (REQ-LAB-04)

Lab phát evidence chuẩn SDD-002 §5 (thay telemetry path-sniffing legacy — truyền lab_id tường minh):

text
lab_open · inquiry_open · inquiry_answer(correct, attempt) · lab_step · lab_complete

lab_completeinquiry_open phải hoạt động từ ngày đầu (legacy khai báo nhưng chết). Mapping lab→skill qua entity_relations teaches/assesses (127 node links kế thừa, 0 broken).

6. Shell, A11y & Design System (REQ-LAB-05)

Một LabShell trong @nemo12/design-system (patterns): nav, inquiry sheet, quiz renderer, accent theo subject. Sửa một lần cho cả 288: modal đúng role="dialog" + focus trap + Esc + focus restore; radiogroup cho options; aria-live cho kết quả; bỏ position:fixed inset:0 overflow:hidden (scroll được viewport ngắn); prefers-reduced-motion cho stepper; sàn 14px + contrast AA (DS-001 §3). Không dark-theme riêng của lab — theo tokens.

7. Công nghệ (REQ-LAB-06 — "mới nhất, dùng dài hạn")

  • React 19 + TS + Vite 8; SVG procedural là chuẩn render chính (giữ triết lý zero-asset — 288 labs trong 2MB).
  • three.js chỉ cho scene3d, lazy. Canvas/WebGPU cân nhắc per-engine khi cần.
  • Config schema versioned (zod) — validate lúc build content + runtime; engine version độc lập content version (SDD-006 §13).
  • Discussion per lab → Interaction System (SDD-005) qua target_type=lab — không xây LabDiscussion riêng.

8. Registry & Quality (REQ-LAB-07)

Labs qua Quality Engine như mọi content (SDD-003): rubric + deterministic checks (config validate, mapping tồn tại, mode đúng implementation) + learner evidence loop. Taxonomy subject/group/accent + quota grid (24 labs/math strand…) kế thừa làm coverage map trong Quality dashboard.

Trace

REQ-LAB-01→§2 · 02→§3 · 03→§4 · 04→§5 · 05→§6 · 06→§7 · 07→§8.