Skip to content

SDD-010 · Nguyên tắc, archetype, Lab là Experience, migrate, evidence, shell và công nghệ ​

Một phần của SDD-010.

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.

3b. Một Unit — một lab (REQ-LAB-08, SRC-208) ​

Lab gắn vào Unit, không phải vào bài: labs.unit là chỗ neo, và một unique index từng phần trên (subject_id, unit) WHERE status='live' AND unit IS NOT NULL (migration 0048) giữ luật "tối đa 1 lab / unit". Đặt ở DB chứ không ở script vì đợt import lab sau này phải fail ngay lúc ghi, thay vì âm thầm sinh ra unit hai lab rồi vài tuần sau mới lộ ra ở giao diện.

Ba hệ quả trong thiết kế:

  • Thứ tự trải nghiệm trong Unit thành cố định: các bài → lab → ô đo. Nhờ đó thẻ Unit ở Toàn cảnh (REQ-UX-14) vẽ được mà không phải hỏi "unit này lấy lab nào".
  • Lab dôi ra chuyển draft, không xoá và không retired: chúng không hỏng, chỉ thừa so với luật mới — retired đọc như "đã khai tử" và sẽ khiến người sau tưởng lab có vấn đề chất lượng.
  • Lab chưa có unit tương ứng vẫn live (unit NULL được index miễn trừ) nên vẫn vào được Thư viện Lab (SRC-166): 70 lab Nghe/Nói tiếng Anh và Làm văn đang ở diện này, chờ chương trình mở thêm unit.

3c. Lab yêu thích của learner (REQ-LAB-09, SRC-212) ​

lab_favorites (learner_id, lab_id) — bảng riêng, không phải cột trên labs: đây là dữ liệu của từng learner, để lên labs thì hai learner đánh dấu là ghi đè nhau. Bỏ thích thì xoá dòng, không có cột trạng thái: lịch sử "đã từng thích rồi bỏ" không ai dùng, giữ lại chỉ khiến mọi truy vấn sau này phải nhớ lọc thêm một điều kiện.

Đọc qua GET /v1/learners/{id}/lab-favorites, tách khỏi GET /v1/subjects/{id}/labs: thư viện là tài nguyên CHUNG của môn (không phụ thuộc ai đang xem, cache được); nhét cờ "đã thích" vào đó là biến nó thành tài nguyên riêng của từng người. Client lấy hai thứ rồi ghép.

Ghi bằng PUT/DELETE theo labId nên bấm mấy lần cũng ra một kết quả; PUT kiểm lab có thật trước khi ghi, DELETE một lab chưa từng thích vẫn trả 200 vì kết quả learner muốn đã đúng.

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 (chưa dựng tính tới 2026-08-20; hiện nội dung lab nằm trong lab_content.content_json) — 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_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).

5.1 inquiry_answer thành bằng chứng thật (REQ-LRN-41 — SRC-478, SRC-479) ​

Hợp đồng trên khai từ đầu nhưng chưa từng chạy: learner nghịch xong một lab thì hồ sơ năng lực im lặng, và chủ dự án báo đúng triệu chứng đó ("vừa làm xong một lesson mà không thấy ghi nhận"). POST /v1/labs/{labId}/evidence khép lại:

  • Độ tin cậy 0,45, thấp hơn hẳn bài đo: lab là chỗ thử và đoán, không phải chỗ chấm. Cho nó cùng trọng số với Assessment là làm hỏng thước đo.
  • event_id = lab:{labId}:{learnerId}:{ngày} — một bằng chứng mỗi lab mỗi ngày, để nghịch đi nghịch lại một lab trong một buổi không tự bơm mastery lên.
  • Lab không gắn được vào node nào thì không ghi được gì. Vì vậy 70 lab mồ côi phải trỏ về Unit (SRC-479): 61 gắn được, 9 để trống có chủ đích vì cây Pearl chưa có Unit nào phủ (kỹ năng nghe, yếu tố kịch, xung đột, bối cảnh, nhạc tính thơ, điện phân). Chín cái đó là tín hiệu thiếu nội dung, không phải rác: gắn xấp xỉ cho đủ số sẽ làm hồ sơ nói dối về một kỹ năng learner chưa chạm.

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.