---
url: https://docs.nemo12.com/reference/course-build-order.md
description: >-
  Thứ tự dựng một Course theo thời gian: làm gì trước, gì sau, những chỗ người
  dựng hay vấp, bổ sung cho chuẩn CD-1..CD-12.
---

# Thứ tự dựng một Course (SRC-634)

[Chuẩn thiết kế Course](course-design-standard/index.md) nói **viết gì cho đúng** (CD-1..CD-12); trang này
nói **làm theo thứ tự nào**. Hai câu hỏi khác nhau: chuẩn đọc theo tầng, còn người dựng course thì
đi theo thời gian và luôn vấp cùng một chỗ — bắt đầu từ bài học trong khi chưa có unit để bám.

**Luật xuyên suốt: mỗi bước chỉ làm được khi bước trước đã xong.** Không phải quy ước cho gọn — nó
là ràng buộc thật của dữ liệu. Lesson `concepts` phải nằm trong key concepts của unit (CD-4.4), nên
key concepts phải có trước. Hiểu lầm của bài trỏ về mã M của unit (CD-9.6), nên Misconception Map
phải có trước. Xưởng nội dung ([SDD-027](../architecture/sdd-027-content-foundry/index.md)) **từ chối
chạy** khi bước trước còn thiếu, và nói rõ thiếu gì.

## Bản đồ một trang

```
Tầng 0  Chuẩn bị nguồn           bảng chuẩn phủ GDPT · cây Pearl B21 · AoPS · danh mục ngữ liệu
   ↓
Tầng 1  COURSE   (CD-10, CD-3)   slot (môn, mạch, bậc, seq) · tên · nguồn · spec · outcomes · prereqs
   ↓
Tầng 2  UNIT     (CD-9)   ×3-5   Big Idea · EQ · key concepts · ngữ liệu · khung tư duy
                                 outcomes · spec · prereq notes · Misconception Map · Performance Task
   ↓
Tầng 3  LESSON   (CD-8, CD-12)   tên bài + seq  ←── RANH GIỚI: người đặt tên, xưởng đổ nội dung
                          ×3-5   guiding question · concepts · outcomes
                                 story · hiểu lầm · lỗi · hướng gỡ · học liệu · câu kiểm
   ↓
Tầng 4  KHO CÂU + NÂNG LIVE      16 câu/bài · lab thật · audit ≥90 · draft → live
```

## Tầng 0 · Trước khi có course

| Bước | Làm gì | Vì sao phải trước |
| ---: | --- | --- |
| 0.1 | Chọn **môn** (`subject_id`: `math` · `vietnamese` · `informatics` · `english`) và **mạch** (`ladder`: `arithmetic` · `algebra` · `geometry` · `data` · `core`) | Đây là hai cột có `CHECK` trong `curriculum_courses`; sai giá trị là insert gãy |
| 0.2 | Tra **nguồn**: mã chủ đề GDPT trong [bảng chuẩn phủ](../quality/coverage/math.md), unit cây Pearl B21, unit AoPS, danh mục ngữ liệu | Course phải khai nguồn (CD-3); tra bằng lệnh, không nhớ mồm |
| 0.3 | Kiểm **bất biến phủ trọn**: chủ đề GDPT định đưa vào chưa thuộc course nào khác | Một chủ đề đúng một course. Phát hiện sau khi đã soạn xong là phải tháo cả course |

## Tầng 1 · COURSE

| Bước | Tạo gì | Bảng D1 | Chuẩn |
| ---: | --- | --- | --- |
| 1.1 | **Slot** `(subject_id, ladder, level 1-5, seq 1-3)` + `code` + tên nói được với phụ huynh | `curriculum_courses` (status `draft`) | CD-1, CD-2 |
| 1.2 | **Nguồn**: `gdpt` · `b21` · `aops` · `material` · `competency` (≥3) · `note` ✍️ cho ô trống có chủ | `curriculum_course_sources` | CD-3 |
| 1.3 | **Spec 4 trường**: purpose · progression (5 chặng) · assessment strategy · completion criteria | `curriculum_course_specs` | CD-10 |
| 1.4 | **Course Outcomes 2-4** + **prerequisites ≥1** | `curriculum_course_outcomes`, `curriculum_course_prereqs` | CD-10 |

Course sinh ra ở `status='draft'` và **ở đó cho tới tầng 4**. Trên trang Khoá học của learner, đó
chính là nhãn *"Đang soạn"*.

## Tầng 2 · UNIT (3-5 unit mỗi course)

Đây là tầng quyết định chất lượng cả course, và là tầng **chưa có workflow nào sinh được**. Theo
[QG-014 (đã gỡ, SRC-672)](../quality/quality-gates.md) đó là **nợ nên trả bằng một workflow**, không phải giấy phép
gõ tay: chạm tới tầng này thì dừng và báo chủ dự án.

| Bước | Tạo gì | Bảng D1 | Chuẩn |
| ---: | --- | --- | --- |
| 2.1 | **Big Idea** (câu khẳng định) + **Essential Question** (câu hỏi mở, không chứa thuật ngữ sắp dạy) | `curriculum_units` | CD-4.1, CD-4.2 |
| 2.2 | **Key concepts 3-5** (danh từ, dùng lại được) | `curriculum_unit_elements` kind `key_concept` | CD-2, CD-4.4 |
| 2.3 | **Ngữ liệu ≥2** (tác phẩm/bộ bài có thật) + **khung tư duy 2-3** | `curriculum_unit_elements` kind `material` / `framework`… | CD-4.5, CD-4.6 |
| 2.4 | **Unit Outcomes 2-4** ("Tôi có thể…" + động từ quan sát được) | `curriculum_unit_outcomes` | CD-6.1 |
| 2.5 | **Spec 3 trường**: purpose · progression · mastery criteria | `curriculum_unit_specs` | CD-9 |
| 2.6 | **Prerequisites 2-4 dòng** | `curriculum_unit_prereq_notes` | CD-9 |
| 2.7 | **Misconception Map 3-5**, mã `M1..Mn` | `curriculum_unit_misconceptions` | CD-9 |
| 2.8 | **Đúng 1 Performance Task**: đề + sản phẩm nộp + **3-5 tiêu chí**, mỗi tiêu chí nối một Unit Outcome | `curriculum_unit_tasks`, `curriculum_task_criteria` | CD-6.3, CD-9 |

**Bước 2.2 và 2.7 là hai cái chốt của cả dây chuyền.** Thiếu key concepts thì mọi bài phía sau
không có gì để chọn khái niệm; thiếu Misconception Map thì hiểu lầm của từng bài không trỏ về đâu
được, và engine mất địa chỉ để định tuyến remediation.

## Tầng 3 · LESSON (3-5 bài mỗi unit)

**Ranh giới người / máy nằm giữa 3.1 và 3.2.**

| Bước | Tạo gì | Ai làm | Chuẩn |
| ---: | --- | --- | --- |
| 3.1 | **Tên bài + seq** trong kế hoạch unit | **Người.** Đặt tên bài là chia nhỏ Big Idea — việc thiết kế, không phải việc sinh chữ | CD-1 |
| 3.2 | **Guiding Question** + **concepts** (⊆ key concepts của unit) | **xưởng** (WF-19) | CD-4.3, CD-4.4 |
| 3.3 | **Lesson Outcomes 1-2**, mức HIỂU (dễ hơn Unit Outcome) | **xưởng** | CD-6.2 |
| 3.4 | **Story SCQA**: tình huống → chỗ vướng → câu hỏi → lối thoát | **xưởng** | CD-12 |
| 3.5 | **Hiểu lầm 3-5** (trỏ mã M khi trùng) · **lỗi hay mắc 2-4** · **hướng gỡ ≥3** | **xưởng** | CD-8 |
| 3.6 | **Học liệu 1-3** + reflection. **Cấm bịa URL** | xưởng soạn tiêu đề + reflection; **người** gắn nguồn thật (lab id / URL) | CD-7 |
| 3.7 | **Câu kiểm 2-4**, dạng máy chấm được, mỗi câu khai đo outcome nào | **xưởng** | CD-7.4, CD-8 |

**Bất biến đếm chỗ (hay hỏng nhất):** chỉ câu `mcq` mới mang phương án nhiễu, mỗi câu 3 chỗ — nên
**số hiểu lầm ≤ số câu mcq × 3**. Khai 4 hiểu lầm mà chỉ có 1 mcq là hở 1 chỗ, và không cách nào
chữa bằng cách viết khéo hơn: phải hạ số hiểu lầm hoặc thêm câu mcq.

## Tầng 4 · Kho câu hỏi và nâng `live`

| Bước | Làm gì | Chuẩn |
| ---: | --- | --- |
| 4.1 | **16 câu/bài** = 10 cho luyện tập + 6 để dành cho bài đo | CD-1, CS-05 |
| 4.2 | Học liệu trỏ **nguồn thật**: lab id có trong D1, hoặc trang Pearl có file tương ứng | CD-7.2 |
| 4.3 | `node scripts/audit-course.mjs <course_id>` đạt **≥90/100** | [rubric audit course](../quality/course-audit.md) |
| 4.4 | Nâng `status` `draft` → `live` khi **mọi lesson có ≥16 câu published** | CD-5 |

**Chưa có bước nào tự nâng `live`** — đó là lý do mọi khoá hiện vẫn hiện *"Đang soạn"*.

## Xưởng nội dung cắm vào chỗ nào

[SDD-027](../architecture/sdd-027-content-foundry/index.md) chỉ làm được **từ bước 3.2 tới 3.7**, và chỉ
cho những bài đã qua 3.1. Trước khi chạy, xưởng chấm đầu vào và **chặn** nếu thiếu:

| Thiếu | Xưởng làm gì |
| --- | --- |
| Chưa có unit (tầng 2 chưa làm) | **Từ chối**, báo "phải soạn unit trước — xưởng không tự đẻ ra unit" |
| Thiếu Big Idea / Essential Question / key concepts | **Từ chối**, chỉ đúng ô còn trống |
| Chưa có tên bài (3.1) | **Từ chối** — đặt tên bài là việc thiết kế |
| Thiếu Misconception Map / Unit Outcomes | Chạy, nhưng **nhắc**: hiểu lầm sẽ không trỏ về mã M nào |

Vì vậy **9 khoá Toán đang có 0 unit** (A9, A10, D2, D3, D4, G6–G10) chưa sinh được bài nào cho tới
khi tầng 2 của chúng có nội dung — và cách tốt nhất để có nội dung ấy vẫn là **dựng workflow
sinh Unit**, không phải mở file JSON ra viết.

## Ai được làm bước nào

Từ 2026-09-03 (SRC-672) KHÔNG còn cấm tạo nội dung learner đọc trực tiếp từ
Claude Code: nội dung phải do **workflow + engine sinh ra lúc chạy**, rồi người duyệt.

| Tầng | Ai làm | Đường đi |
| --- | --- | --- |
| 0-1 · nguồn, slot course, spec | người (cấu trúc, không phải nội dung learner đọc) | file JSON → `course-content-to-sql.mjs` → migration |
| 2 · Unit | **chưa có workflow** — xem cảnh báo dưới | — |
| 3.1 · tên bài | người (việc thiết kế: chia nhỏ Big Idea) | như trên |
| 3.2-3.7 · nội dung bài | **xưởng** (WF-19) | Coral → Xưởng nội dung → *Sinh cả bài* / *Chỉ vá phần X* |
| 4.1 · kho 16 câu | **chưa có workflow** | — |
| 4.2 · lab | **chưa có workflow** | — |
| 4.3-4.4 · audit, nâng live | người | `audit-course.mjs` ≥90 |

**Ba tầng chưa có workflow là nợ, không phải giấy phép gõ tay.** Chạm tới Unit, kho câu hỏi hay
lab thì việc cần làm là **dựng workflow cho tầng đó** rồi mới sinh nội dung — không phải mở file
JSON ra viết. Gặp tình huống ấy thì dừng và báo chủ dự án (luật ghi trong `CLAUDE.md`).

Đường nạp cuối cùng vẫn là **migration**, kể cả với nội dung máy sinh: bản thảo ở R2 được người
duyệt ghép vào file JSON của course (kèm `run_id` làm provenance) rồi mới thành migration
([SDD-027 §7](../architecture/sdd-027-content-foundry/pipeline.md)). Provenance ấy là thứ đáng giữ kể cả khi QG-014 đã gỡ (SRC-672):
mỗi mẩu nội dung trong production truy được về một lượt chạy.

## Sau khi có nội dung: ba vòng kiểm

| Vòng | Ai chấm | Kết quả |
| --- | --- | --- |
| 1 · rubric máy | máy, ngay trong workflow | điểm L1-L16, chỗ chưa đạt → tự vá một vòng |
| 2 · sổ việc tắc | máy, khi một bài trượt nhiều lượt | chẩn đoán bệnh lặp lại → **dừng**, chờ người chỉnh thuật toán ([SDD-027 §15](../architecture/sdd-027-content-foundry/review-loops.md)) |
| 3 · review của người | chủ dự án, trên Coral | nhận xét prompt và content → vá ngay, hoặc gom thành hồ sơ nâng prompt rồi sinh lại ([SDD-027 §16](../architecture/sdd-027-content-foundry/review-loops.md)) |

## Trace

SRC-634 → trang này. Luật từng tầng: [CD-1..CD-12](course-design-standard/index.md); quy trình soạn tay:
skill `/course-design`; chấm course đã nạp: [rubric audit](../quality/course-audit.md); máy sinh nội
dung bài: [SDD-027](../architecture/sdd-027-content-foundry/index.md); chỉ tiêu gom về
[CS-10](../quality/content-standards.md).
