Appearance
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)
| Engine | Archetype legacy | Labs | Dạng |
|---|---|---|---|
picker | A1 chip picker → swap stage + note (+A4 static) | 187 | JSON config, zero code/lab |
parametric | A2 slider → SVG/numeric viz | 58 | declarative {params[], formula, viz} |
stepper | A3 animated/stepped simulation (rAF) | 9 | config + tick function đăng ký |
sim | A5 multi-scene domain simulator | 29 | React components trên shared shell |
scene3d | A6 three.js | 1 (anatomy) | lazy-load cô lập (734KB không đè lên lab khác) |
inquiry | cross-cutting: predict → observe → checks + quiz | 288/288 | mộ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)
- Script reverse-parse
.tsx→ JSON (ITEMS,INQUIRY,SCENARIOSlà top-level literals;~highlight~syntax giữ nguyên) — 186 picker labs tự động 100%. - 58 parametric: trích
{params, formula, viz-spec}bán tự động. - 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.
- Toàn bộ 288 inquiry blocks vào bảng
inquiries— lần đầu tiên bespoke labs có correctness signal. - 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_completelab_complete và inquiry_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.