Giao diện
SSD — System/Solution Design
TL;DR — A static, data-driven single-page app (Vite + Tailwind) reads one shared curriculum dataset, renders one idea per screen, and stores evidence in the browser. Docs are generated from the same dataset. Phase 2 adds a Cloudflare Worker API with D1 (records) and R2 (files) behind the same evidence schema.
1. Kiến trúc tổng thể
shared/curriculum/ (nguồn dữ liệu duy nhất, ESM)
framework · courses · pedagogy · brand · lessons/* → dsl.js (kiểm tra) → index.js
│ │
▼ ▼
learning-experience/ (Vite + Tailwind) docs-aiteen-learning-experience/ (VitePress)
SPA hash-router · views · store scripts/gen-curriculum.mjs → trang Markdown
│ evidence (localStorage) │
▼ ▼
Cloudflare Pages aiteen-learning-experience Cloudflare Pages docs-aiteen-learning-experience
Giai đoạn 2: SPA ──POST /api/evidence──▶ Worker ──▶ D1 (bản ghi) · R2 (ảnh/file)2. Mô hình nội dung
Mỗi buổi học là một đối tượng được dựng bằng lesson() (file shared/curriculum/dsl.js):
| Trường | Ý nghĩa |
|---|---|
id, n, course | Định danh, thứ tự, khóa |
title, gq | Tên buổi, Guiding Question (Compelling) — cặp [vi, en] |
lo[], supporting[] | LO được đánh giá; LO hỗ trợ |
ib | Key concepts, Global context, ATL, Learner profile |
task, materials, plan | Performance Task, vật liệu, hoạt động mentor theo 6 chặng |
steps[] | Màn hình của học viên theo thứ tự chặng |
Loại bước: info, choice, text, link, scale. Bước có assess: true và lo là bước đánh giá tổng kết.
Kiểm tra bắt buộc khi nạp dữ liệu (nếu sai, build dừng và báo lỗi tiếng Việt): đủ 6 chặng đúng thứ tự; mọi LO của buổi có ít nhất một bước assess; mỗi khóa đúng 10 LO và 12 buổi; mọi LO của khóa được đánh giá ở ít nhất một buổi; tổng thời gian 6 chặng = 120 phút.
3. Ứng dụng học viên
| Thành phần | Trách nhiệm |
|---|---|
main.js | Router theo hash: #/, #/c/:course, #/c/:course/l/:n, #/portfolio[/:course[/:lo]] |
views/lesson.js | Máy trạng thái của buổi học: màn dẫn dắt (-2), mục tiêu (-1), các bước (0…n-1), tổng kết (n) |
lib/store.js | Tiến độ và evidence (localStorage), bộ gửi evidence lên API khi có VITE_API_BASE |
lib/mastery.js | Tính trạng thái LO: none, progress, secure |
lib/i18n.js | Chuỗi giao diện VI/EN và hàm tx([vi,en]) |
Máy trạng thái một bước choice: answer → feedback (đúng: kết thúc; sai lần 1: thử lại; sai lần 2: hiện đáp án và đi tiếp). Bước text/link: answer → rubric → tiếp. Mỗi lần kiểm tra/gửi tạo một bản ghi evidence.
4. Mô hình evidence
| Trường / Field | Ý nghĩa / Meaning |
|---|---|
courseId | Khóa học / Course |
lessonId | Buổi học / Lesson |
stepId | Màn hình (bước) / Step |
phase | Chặng của learning cycle / Learning-cycle phase |
cra | C, R hoặc A / C, R or A |
loId | Learning Outcome liên quan / Related Learning Outcome |
type | Loại evidence / Evidence type |
assess | Là bước đánh giá tổng kết hay không / Whether it is a summative step |
response | Câu trả lời của learner / The learner’s response |
correct | Đúng/sai nếu chấm tự động, ngược lại null / Right/wrong if auto-graded, else null |
attempt | Lần thử thứ mấy / Attempt number |
ts | Thời điểm ghi (ISO 8601) / Timestamp (ISO 8601) |
prediction— Dự đoán / Predictionchoice— Lựa chọn có lý do / Choice with reasonresponse— Câu trả lời tự luận / Written responseartifact— Sản phẩm / liên kết / Artifact / linkreflection— Phản tư / Reflectionconfidence— Mức tự tin / Confidence
Quy tắc "đã vững" cho một LO: mọi bước assess của LO đó đều có evidence và (a) câu chọn đáp án đã trả lời đúng, (b) câu tự luận/liên kết có tự kiểm tra đủ tiêu chí. Trạng thái luôn kèm "Chờ mentor xác nhận" cho đến khi giai đoạn 2 có bước mentor duyệt.
5. Thiết kế API giai đoạn 2 (Cloudflare Workers + D1 + R2)
| Phương thức | Đường dẫn | Mô tả |
|---|---|---|
POST | /api/evidence | Ghi một bản ghi evidence (đã có trong client) |
PATCH | /api/evidence/:id | Cập nhật selfCheck |
POST | /api/uploads | Xin URL tải lên R2 (presigned) cho ảnh/file |
GET | /api/learners/:id/progress | Tiến độ và trạng thái LO |
POST | /api/mentor/verify | Mentor xác nhận một LO |
sql
-- D1
CREATE TABLE learners (id TEXT PRIMARY KEY, display_name TEXT, created_at TEXT NOT NULL);
CREATE TABLE evidence (
id TEXT PRIMARY KEY, learner_id TEXT NOT NULL REFERENCES learners(id),
course_id TEXT NOT NULL, lesson_id TEXT NOT NULL, step_id TEXT NOT NULL,
phase TEXT NOT NULL, cra TEXT NOT NULL, lo_id TEXT, type TEXT NOT NULL,
assess INTEGER NOT NULL DEFAULT 0, response TEXT, correct INTEGER,
self_check TEXT, attempt INTEGER NOT NULL DEFAULT 1, file_key TEXT,
ts TEXT NOT NULL, updated_at TEXT
);
CREATE INDEX idx_evidence_learner_lo ON evidence(learner_id, lo_id);
CREATE TABLE lo_verification (
learner_id TEXT NOT NULL, course_id TEXT NOT NULL, lo_id TEXT NOT NULL,
mentor_id TEXT NOT NULL, verified_at TEXT NOT NULL, note TEXT,
PRIMARY KEY (learner_id, course_id, lo_id)
);Khóa đối tượng R2: evidence/<learnerId>/<lessonId>/<stepId>-<timestamp>.<ext>.
6. Bảo mật & quyền riêng tư (học sinh dưới 18)
- Giai đoạn 1: không thu họ tên, email, số điện thoại; ID học viên ngẫu nhiên; dữ liệu chỉ ở trình duyệt.
- Giai đoạn 2: cần đồng ý của phụ huynh, chính sách lưu trữ và xóa, mã hóa khi truyền, phân quyền theo vai trò, giới hạn kích thước/loại file tải lên, quét nội dung. Cần tư vấn pháp lý về Nghị định 13/2023/NĐ-CP.
- Toàn bộ chuỗi do người dùng nhập được escape trước khi hiển thị (
esc()tronglib/dom.js); không dùnginnerHTMLvới dữ liệu thô của người dùng. - Buổi học dạy học viên không đưa thông tin nhạy cảm cho AI; trang xuất bản của học sinh không chứa dữ liệu cá nhân (buổi 9).
7. Truy cập & quốc tế hóa
Màu tương phản cao trên nền cát; aria-live cho vùng phản hồi; nút có nhãn; phím tắt (Enter tiếp tục, 1–9 chọn đáp án); giảm chuyển động theo cài đặt hệ điều hành; ngôn ngữ lưu theo thiết bị và đặt lang cho <html>.
8. Quyết định thiết kế
| Quyết định | Lý do |
|---|---|
| SPA thuần JS thay vì framework | Nội dung tĩnh, ít trạng thái; build nhẹ, dễ học và bảo trì |
| Một nguồn dữ liệu cho cả hai site | Tránh lệch giữa tài liệu và trải nghiệm |
| Hash router | Cloudflare Pages không cần cấu hình rewrite |
| Evidence ghi tại mỗi tương tác, kể cả lần thử sai | Có dấu vết quá trình học, không chỉ kết quả |
| Tự kiểm tra rubric + mentor duyệt | Cân bằng khả năng mở rộng và độ tin cậy |