- Given Có quyền
curriculum.managevà một trình độ trong danh mục (PRD 03) - When Tạo giáo trình với tên, mã, trình độ, phạm vi chi nhánh, rồi thêm đơn vị và bài học bằng cách nhập tay hoặc dán danh sách tên bài (mỗi dòng một bài)
- Then Giáo trình được tạo với phiên bản 1 ở trạng thái
draft; đơn vị và bài học cópositionliên tiếp; kéo thả để sắp xếp lại được lưu ngay; mã trùng trong trung tâm bị từ chối và biểu mẫu đề nghị mở giáo trình đã có.
PRD 14 · Giáo trình, bài học và tài nguyên số
Giáo trình dạng cây có thứ tự (giáo trình, đơn vị, bài học) được quản lý phiên bản theo trung tâm và dùng chung giữa các chi nhánh; khoá học tham chiếu một phiên bản giáo trình và các buổi học của lớp được gắn sẵn với bài học theo thứ tự; sổ đầu bài của giáo viên theo từng buổi và báo cáo tiến độ theo lớp; thư viện tài nguyên số có thư mục, hạn mức dung lượng và phân quyền. Tệp lưu trên dịch vụ tệp hiện có của FLYER.
Xuất xứ / Prompt / Giới hạn
Tài liệu do trợ lý AI soạn trong một phiên làm việc ngày 16/09/2026, mở rộng bộ PRD theo yêu cầu gốc được trích nguyên văn ở trang mục lục. Đây là bản đề xuất để đội thảo luận, chưa phải quyết định của đội sản phẩm.
Nguồn
- Nghiên cứu công khai về đối thủ cạnh tranh (PSE ONE, pse4.one), mã nguồn
center-crm-frontendvà đặc tả OpenAPI/v3trên staging (182 endpoint), tính đến ngày 10/09/2026. - Nhãn existing / extend / new trong trang được xác định bằng cách đối chiếu với đặc tả
/v3trên staging tại thời điểm trên. - Đợt quét thứ hai các nguồn công khai của PSE ONE ngày 16/09/2026 (trang tính năng, bảng phí dịch vụ, mục hướng dẫn sử dụng).
- Tham chiếu đối thủ cạnh tranh (pse4.one, khảo sát công khai ngày 16/09/2026): đối thủ có mô-đun "Quản lý giáo trình" nằm trong phần quản trị cơ sở dữ liệu; giáo trình được tổ chức bằng thư mục trong tab tài nguyên số, bài học được tạo từ mẫu tài nguyên "Bài học" với loại ứng dụng HTML và có thể nhúng video YouTube; phần dạy trực tuyến chỉ có ở gói Enterprise.
Giới hạn
- Cần xác minh khi khảo sát trực tiếp trong ứng dụng, vì đăng nhập tự động vào sản phẩm tham chiếu chưa được cấp phép trong phiên soạn:
- Đối thủ có khái niệm phiên bản giáo trình hay không, hay mọi sửa đổi áp dụng ngay cho lớp đang học.
- Bài học của đối thủ có gắn vào buổi học cụ thể trong thời khoá biểu hay chỉ nằm trong thư mục để giáo viên tự tra cứu.
- Có sổ đầu bài theo buổi hay không, và giáo viên ghi trên di động hay chỉ trên web.
- Hạn mức dung lượng theo gói và loại tệp được phép; các mẫu tài nguyên ngoài "Bài học" và loại ứng dụng ngoài "HTML".
- Ứng dụng học viên hiển thị "tài liệu học tập" theo buổi học, theo lớp hay theo toàn bộ giáo trình, và phụ huynh có thấy trước bài chưa dạy không.
- Quyền "Quản trị dữ liệu" của đối thủ cấp theo toàn mô-đun hay theo từng thư mục.
Thiết kế đề xuất
Giáo trình là một cây có thứ tự và có phiên bản; bài học được gắn sẵn vào từng buổi của lớp để sinh ra tiến độ, còn giáo viên chỉ cần xác nhận "Đã dạy" trên điện thoại sau mỗi buổi. Các màn hình dưới đây cho thấy trạng thái quan trọng nhất: một lớp chậm 3 bài vì một buổi huỷ chưa dồn bài và hai buổi chưa ghi sổ.










1Mục đích
Một trung tâm vận hành ổn định khi mọi lớp cùng trình độ dạy cùng một nội dung theo cùng một nhịp, bất kể giáo viên nào đứng lớp. Hiện nay giáo trình của phần lớn trung tâm nằm trong file Word, thư mục Google Drive và trí nhớ của giáo viên; giáo viên dạy thay không biết lớp đã học đến đâu và giáo vụ không biết lớp đang chậm so với kế hoạch. Mô-đun này đưa giáo trình vào hệ thống dưới dạng một cây có thứ tự, gắn bài học vào từng buổi học ngay khi lớp được tạo, cho giáo viên ghi sổ đầu bài trong một phút sau mỗi buổi, và cho quản lý một báo cáo tiến độ theo lớp.
Trong phạm vi
- Giáo trình dạng cây có thứ tự: giáo trình → đơn vị (unit) → bài học; quản lý phiên bản theo trung tâm; dùng chung cho tất cả chi nhánh hoặc giới hạn theo chi nhánh.
- Bài học: tên, mục tiêu, thời lượng dự kiến, nội dung (văn bản định dạng, nhúng HTML, video YouTube, tệp đính kèm), tài liệu cho giáo viên tách khỏi tài liệu cho học viên, bài tập về nhà gợi ý liên kết đến bài tập FLYER hiện có.
- Gắn giáo trình vào khoá học (PRD 03); khi tạo lớp, buổi thứ N được gắn sẵn bài thứ N; gắn lại thủ công, bỏ qua, dạy bù.
- Sổ đầu bài của giáo viên theo từng buổi học và báo cáo tiến độ theo lớp.
- Thư viện tài nguyên số: thư mục, loại tệp, hạn mức dung lượng theo trung tâm (liên kết hạn mức lưu trữ ở PRD 19), phân quyền sửa và xem, tìm kiếm.
- Cờ hiển thị cho phụ huynh và học viên theo từng bài học; tài liệu đưa lên cổng phụ huynh (PRD 07).
Ngoài phạm vi
- Học trực tuyến: khoá học online, luyện thi, trò chơi giáo dục, tài khoản học viên gắn với khoá học online. Phần này thuộc PRD 18; PRD này chỉ để lại điểm nối là cờ hiển thị và bài tập FLYER.
- Soạn bài kiểm tra và chấm điểm (đã có trong bài tập FLYER).
- Kho sách in và phát tài liệu vật lý (PRD 08).
- Chợ giáo trình dùng chung giữa các trung tâm (ứng viên cho giai đoạn 3).
2Hiện trạng
Trong center-crm-frontend chưa có màn hình nào cho giáo trình hay tài nguyên. Phía FLYER /v3 đã có khái niệm "lesson" gắn với ClassSchedule (lộ trình học trên ứng dụng FLYER, dùng để nhắc bài) và có mẫu tải tệp cho hồ sơ khách hàng CRM.
| Năng lực hiện có | Endpoint | Giữ lại? |
|---|---|---|
| Bài học của lộ trình FLYER gắn vào lịch lớp (study_unit, book, trạng thái nhắc) | DELETE /v3/teacher/class-schedules/{id}/lessons/{lesson_id} | existing giữ; bài học FLYER là nguồn nội dung có thể tham chiếu từ bài học của giáo trình, không phải thực thể thay thế |
| Danh sách bài tập đã giao cho một lớp (lọc theo trạng thái, trình độ, kỹ năng, ngày) | GET /v3/teacher/classes/{class_id}/assign-tests | existing giữ; nguồn chọn bài tập về nhà gợi ý và bài tập đã giao trong sổ đầu bài |
| Tải tệp cho hồ sơ khách hàng (file_id, file_name, file_type; tệp nằm trên dịch vụ tệp FLYER) | GET/POST /v3/crm/customer-files, DELETE /v3/crm/customer-files/{id} | existing tái sử dụng mẫu tải tệp; bản ghi tài nguyên là thực thể mới |
| Giáo trình, đơn vị, bài học, phiên bản, ánh xạ buổi học với bài học, sổ đầu bài, thư viện tài nguyên, hạn mức dung lượng | không có | new |
Trường Số chọn hướng riêng ở hai điểm: giáo trình là thực thể có phiên bản và có thứ tự thay vì cây thư mục, và bài học được gắn trực tiếp vào buổi học của lớp để sinh ra tiến độ mà không cần giáo viên nhập lại.
3User story và tiêu chí chấp nhận
- Given Phiên bản giáo trình ở trạng thái
draft - When Mở bài học và nhập mục tiêu, thời lượng dự kiến, các khối nội dung (văn bản định dạng, nhúng HTML, video YouTube, tệp đính kèm), đánh dấu khối nào chỉ dành cho giáo viên, và chọn bài tập về nhà gợi ý từ bài tập FLYER
- Then Nội dung được lưu theo khối có thứ tự; tệp được tải lên dịch vụ tệp FLYER theo mẫu customer-files và tạo bản ghi tài nguyên trong thư mục hệ thống của giáo trình; URL YouTube được kiểm tra; nhúng HTML được lọc theo quy tắc 13.
- Given Phiên bản 1 đã phát hành và đang được ba lớp sử dụng
- When Chọn Tạo phiên bản mới, sửa nội dung, rồi Phát hành
- Then Phiên bản 2 được sao chép từ phiên bản 1, chuyển sang
publishedvà bị khoá nội dung; ba lớp đang học vẫn gắn phiên bản 1; khoá học có tuỳ chọn "Lớp mới dùng phiên bản mới nhất"; giáo vụ có thể chuyển một lớp sang phiên bản 2 với bản đối chiếu theo mã bài, các bài không khớp được liệt kê để gắn tay.
- Given Khoá học (PRD 03) tham chiếu một phiên bản giáo trình đã phát hành có 24 bài
- When Tạo lớp từ khoá học đó với 24 buổi học sinh ra từ lịch học
- Then Buổi thứ N được gắn bài thứ N; tab Giáo trình của lớp hiển thị bảng buổi học và bài tương ứng; nếu số buổi khác số bài, phần dư được đánh dấu "Chưa gắn bài" hoặc "Bài chưa có buổi" và giáo vụ được cảnh báo ở bước xem trước khi tạo lớp. Khoá học không có giáo trình vẫn tạo lớp bình thường; tab Giáo trình hiển thị hành động "Gắn giáo trình".
- Given Buổi 5 bị huỷ vì nghỉ lễ và một buổi bù được thêm ở cuối
- When Mở tab Giáo trình của lớp và chọn "Dồn bài học xuống"
- Then Bài 5 và các bài sau lần lượt dời sang buổi kế tiếp, buổi bù cuối nhận bài 24; ánh xạ ghi lại thao tác và người thực hiện.
- Given Buổi 12 chỉ dạy được nửa bài 12, hoặc giáo viên thấy bài 9 không phù hợp
- When Ghi sổ đầu bài "Dạy một phần", hoặc đánh dấu bài 9 là Bỏ qua kèm lý do
- Then Hệ thống đề nghị gắn phần còn lại của bài 12 vào buổi 13 (buổi 13 có hai bài) hoặc dồn toàn bộ; bài Bỏ qua không tính vào mẫu số tiến độ và buổi tương ứng nhận bài kế tiếp nếu chọn dồn, hoặc giữ trống để dạy nội dung tự do.
- Given Buổi học vừa kết thúc và giáo viên đã lưu điểm danh (PRD 04)
- When Màn hình sau khi lưu điểm danh hiển thị phần Sổ đầu bài với bài học đã gắn sẵn
- Then Giáo viên xác nhận "Đã dạy" bằng một lần chọn, hoặc đổi thành "Dạy một phần" / "Chưa dạy" / "Dạy bài khác" (chọn bài trong giáo trình), thêm ghi chú và bài tập về nhà đã giao; bản ghi được lưu trong một yêu cầu; nếu ngoại tuyến, được xếp hàng cùng phiếu điểm danh; buổi quá 24 giờ chưa ghi sổ được nhắc lúc 21:00 và xuất hiện trong danh sách "Chưa ghi sổ" của giáo vụ.
- Given Các lớp có giáo trình và sổ đầu bài trong chi nhánh
- When Mở Đào tạo → Tiến độ
- Then Mỗi lớp hiển thị số bài đã dạy trên tổng số bài có hiệu lực, số bài theo kế hoạch tính đến hôm nay, độ lệch, và chip Đúng tiến độ / Chậm 1–2 bài / Chậm từ 3 bài; lọc theo chi nhánh, giáo trình, giáo viên; xuất xlsx.
- Given Có quyền
resources.manage - When Tạo thư mục, tải nhiều tệp cùng lúc, đặt quyền cho thư mục (ai được sửa, ai được xem: theo vai trò hoặc nhân sự cụ thể, theo chi nhánh)
- Then Tệp lưu trên dịch vụ tệp FLYER; bản ghi tài nguyên ghi kích thước, loại, người tải, thư mục; dung lượng đã dùng của trung tâm được cập nhật; vượt 90% hạn mức thì thanh dung lượng chuyển màu cảnh báo, đạt 100% thì tải lên bị từ chối với thông báo rõ và liên kết đến gói lưu trữ (PRD 19).
- Given Bài học có cờ "Hiển thị cho phụ huynh" và có tài liệu cho học viên; sổ đầu bài của buổi học đã ghi "Đã dạy"
- When Phụ huynh mở buổi học đó trên cổng phụ huynh (PRD 07)
- Then Thấy tên bài, mục tiêu, tài liệu cho học viên, ghi chú dành cho phụ huynh và bài tập về nhà đã giao; không bao giờ thấy tài liệu cho giáo viên hay ghi chú nội bộ; bài chưa dạy không hiển thị trừ khi trung tâm bật "Cho xem trước lộ trình".
4Màn hình
Tab: Đang dùng (N) · Bản nháp (N) · Lưu trữ. Bộ lọc: tìm kiếm, trình độ, chi nhánh. Cột: tên và mã, trình độ, phiên bản mới nhất đã phát hành (kèm "nháp v3" nếu có), số đơn vị / số bài / tổng thời lượng, chi nhánh, số khoá học và lớp đang gắn, thao tác (Sửa, Tạo phiên bản mới, Nhân bản, Lưu trữ). Hành động: + Tạo giáo trình, Nhập từ Excel (cột: đơn vị, bài, mục tiêu, thời lượng). Trạng thái rỗng: "Chưa có giáo trình. Tạo giáo trình đầu tiên hoặc nhập từ Excel để gắn bài học vào buổi học của lớp."
Cột trái là cây có kéo thả; cột phải là trình soạn của bài đang chọn, mỗi khối có công tắc "chỉ giáo viên thấy". Thanh trên: trạng thái phiên bản, số lớp đang dùng, nút Lưu, Phát hành, Xem trước như phụ huynh. Trạng thái rỗng của bài: "Bài học chưa có nội dung."
Đầu trang: giáo trình và phiên bản đang gắn, tiến độ (đã dạy / có hiệu lực, chênh lệch so với kế hoạch), nút Đổi phiên bản và Dồn bài học xuống. Bảng: buổi (số thứ tự, ngày, giờ), bài học được gắn (chọn bài khác từ danh sách), trạng thái sổ đầu bài (Chưa ghi / Đã dạy / Một phần / Bỏ qua / Bài khác), giáo viên ghi, ghi chú rút gọn. Buổi đã huỷ hiển thị gạch ngang và bài được đánh dấu "Cần dời". Trạng thái rỗng: "Lớp chưa gắn giáo trình" kèm hành động Gắn giáo trình.
Hiển thị ngay dưới phiếu tổng hợp sau khi lưu điểm danh (PRD 04) và có thể mở riêng. Trường: bài học được gắn, mức hoàn thành (Đã dạy / Dạy một phần / Chưa dạy / Dạy bài khác), bài học thay thế, ghi chú nội bộ, ghi chú cho phụ huynh (tuỳ chọn), bài tập về nhà đã giao (chọn từ bài tập của lớp hoặc nhập tự do). Nút Lưu cố định; sau khi lưu có thể sửa trong 7 ngày, sau đó cần quyền teaching_log.edit_any.
Bộ lọc: chi nhánh, giáo trình, giáo viên, trạng thái lớp. Bảng: lớp, giáo trình và phiên bản, giáo viên chính, đã dạy / có hiệu lực, theo kế hoạch đến hôm nay, độ lệch, buổi chưa ghi sổ, chip tiến độ. Chọn một dòng mở tab Giáo trình của lớp. Xuất xlsx. Trạng thái rỗng: "Chưa có lớp nào gắn giáo trình trong phạm vi lọc."
Cột trái: cây thư mục (thư mục hệ thống "Giáo trình" không xoá được; thư mục do người dùng tạo). Cột phải: bảng tệp với tên, loại, kích thước, người tải lên, ngày, số bài học tham chiếu, thao tác (Xem trước, Tải xuống, Đổi tên, Di chuyển, Xoá). Thanh dung lượng đã dùng / hạn mức ở đầu trang; ô tìm kiếm chung cho tệp và bài học trong phạm vi được phép xem; kéo thả tệp để tải lên. Trạng thái rỗng: "Thư mục trống. Kéo thả tệp hoặc chọn Tải lên."
5Quy tắc nghiệp vụ
- Giáo trình thuộc trung tâm (center). Phạm vi chi nhánh là danh sách school_id hoặc rỗng (tất cả chi nhánh); khoá học của một chi nhánh chỉ chọn được giáo trình có phạm vi bao gồm chi nhánh đó.
- Một giáo trình có nhiều phiên bản; tối đa một phiên bản
drafttại một thời điểm. Phiên bảnpublishedlà bất biến; sửa nội dung yêu cầu tạo phiên bản mới. Sửa lỗi chính tả trong tên bài được phép trên phiên bản đã phát hành và được ghi nhật ký. - Khoá học tham chiếu đúng một
curriculum_version_idhoặc cờuse_latest_published; lớp tham chiếu đúng một phiên bản tại thời điểm tạo và không tự đổi khi có phiên bản mới; lớp mới không bao giờ dùng draft. - Ánh xạ mặc định khi tạo lớp: buổi thứ N nhận bài thứ N theo
positiontoàn giáo trình (bỏ qua ranh giới đơn vị), thứ tự buổi theo thời gian bắt đầu. Bài của buổi bị huỷ được đánh dấu "Cần dời" cho đến khi giáo vụ dồn bài hoặc gắn tay. - Một buổi có thể gắn 0, 1 hoặc nhiều bài; một bài có thể gắn với nhiều buổi. Tiến độ tính theo bài, không theo buổi: tỷ lệ = số bài "Đã dạy" (bài "Dạy một phần" tính 0,5) / số bài có hiệu lực (tổng bài trừ bài Bỏ qua); kế hoạch đến hôm nay = số bài gắn với các buổi không huỷ có ngày nhỏ hơn hoặc bằng hôm nay; độ lệch = đã dạy trừ kế hoạch.
- Sổ đầu bài chỉ được ghi bởi giáo viên chính hoặc giáo viên dạy thay của buổi học, hoặc người có
teaching_log.edit_any; mỗi buổi có tối đa một bản ghi, sửa đổi được lưu lịch sử; sau cửa sổ 7 ngày cần lý do. - Tài liệu cho giáo viên không bao giờ được trả về trong endpoint dành cho phụ huynh hoặc học viên; kiểm tra ở tầng API, không chỉ ở giao diện.
- Cờ hiển thị cho phụ huynh mặc định tắt; khi bật, nội dung chỉ hiển thị sau khi buổi tương ứng có sổ đầu bài "Đã dạy" hoặc "Dạy một phần", trừ khi trung tâm bật "Cho xem trước lộ trình" (PRD 10).
- Tệp cho phép: pdf, doc/docx, ppt/pptx, xls/xlsx, png, jpg, mp3, mp4, zip; tối đa 200 MB mỗi tệp; hạn mức tổng theo trung tâm lấy từ gói lưu trữ (PRD 19), mặc định 5 GB; tải lên khi đã đủ hạn mức bị từ chối với mã
STORAGE_QUOTA_EXCEEDED. - Xoá tệp đang được bài học tham chiếu yêu cầu xác nhận và liệt kê các bài đó; tệp bị xoá vào thùng rác 30 ngày trước khi xoá vật lý và vẫn tính vào dung lượng cho đến lúc đó.
- Quyền thư mục kế thừa từ thư mục cha trừ khi được ghi đè; quyền của tệp thuộc giáo trình đi theo giáo trình.
- Lưu trữ giáo trình chỉ được phép khi không còn lớp đang hoạt động gắn với bất kỳ phiên bản nào; lớp đã kết thúc vẫn giữ tham chiếu để xem lịch sử.
- Nhúng HTML được lọc theo danh sách cho phép: không script, không form, iframe chỉ từ miền trong danh sách cấu hình của trung tâm (mặc định youtube.com, docs.google.com, canva.com).
6Mô hình dữ liệu
| Thực thể | Trường | Ghi chú |
|---|---|---|
| curriculum | id uuid; center_id; code (unique trong center); name; level_code; description; school_ids uuid[] null (null = tất cả chi nhánh); status enum(active, archived); latest_published_version_id null; created_by; created_at | new; phạm vi tenant |
| curriculum_version | id uuid; curriculum_id; version_no int; status enum(draft, published, retired); published_at null; published_by null; source_version_id null; lesson_count; total_duration_min; change_note | unique (curriculum_id, version_no); tối đa một draft |
| curriculum_unit | id uuid; version_id; position int; name; description | unique (version_id, position) |
| lesson | id uuid; version_id; unit_id; position int (toàn phiên bản); lesson_code (ổn định qua các phiên bản, dùng để đối chiếu); name; objectives; duration_min; parent_visible bool; parent_note null; suggested_assign_test_ids int64[]; flyer_book_lesson_id null; tags text[] | unique (version_id, position) |
| lesson_block | id uuid; lesson_id; position int; kind enum(rich_text, html_embed, youtube, file); audience enum(all, teacher_only, student); body null; url null; resource_file_id null | audience=teacher_only không bao giờ trả cho phụ huynh |
| course (PRD 03) | + curriculum_id null; curriculum_version_id null; use_latest_published bool | extend |
| class_syllabus | class_id PK; school_id; curriculum_version_id; bound_at; bound_by; effective_lesson_count; taught_count; planned_to_date_count | new; phạm vi chi nhánh; số đếm là cache |
| session_lesson_map | id uuid; class_id; session_id; lesson_id; position_in_session int; status enum(planned, taught, partial, skipped, moved); skip_reason null; source enum(auto, manual, shift); updated_by; updated_at | unique (session_id, lesson_id) |
| teaching_log | id uuid; session_id (unique); class_id; school_id; staff_id; completion enum(taught, partial, not_taught, other_lesson); actual_lesson_id null; note; parent_note null; homework_text null; homework_assign_test_ids int64[]; logged_at; version int | new; lịch sử ở teaching_log_history (before, after, actor_id, reason) |
| resource_folder | id uuid; center_id; parent_id null; name; kind enum(user, curriculum_system); curriculum_id null; school_ids uuid[] null; permissions jsonb [{principal_type: role|staff, principal_id, access: view|edit}]; created_by | new; thư mục hệ thống gắn giáo trình |
| resource_file | id uuid; center_id; folder_id; flyer_file_id; file_name; mime_type; size_bytes; tags text[]; uploaded_by; uploaded_at; deleted_at null (thùng rác); ref_count int | new; tệp vật lý ở dịch vụ tệp FLYER |
| storage_usage | center_id PK; used_bytes; quota_bytes (đồng bộ từ gói lưu trữ PRD 19); warned_at null; recalculated_at | cache, tính lại hằng đêm |
| curriculum_policy (cấu hình tenant) | allow_preview_for_parents bool; log_edit_window_days (7); log_reminder_hour (21); max_file_mb (200); allowed_embed_domains text[]; behind_schedule_threshold (3) | lưu trong cấu hình trung tâm (PRD 10) |
7Hợp đồng API
| Method | Path | Mục đích | Trạng thái |
|---|---|---|---|
| GET/POST · GET/PATCH/DELETE | /v3/crm/curricula · /v3/crm/curricula/{id} | danh sách lọc level_code, school_id, status; tạo kèm phiên bản 1 draft; chi tiết kèm phiên bản; DELETE = lưu trữ, chặn khi còn lớp hoạt động | new |
| POST | /v3/crm/curricula/{id}/versions | tạo draft mới sao chép từ phiên bản chỉ định; 409 nếu đã có draft | new |
| GET · POST · PUT | /v3/crm/curriculum-versions/{id}/tree · /publish · /import · /order | toàn bộ cây (lọc audience theo vai trò); draft → published; nhập xlsx theo wizard PRD 11; {units: [{id, lessons: [id]}]} sắp xếp lại cả cây | new |
| POST/PATCH/DELETE | /v3/crm/curriculum-units/{id} · /v3/crm/lessons/{id} | thêm, sửa, xoá đơn vị và bài học (chỉ trên draft); PATCH bài học nhận toàn bộ blocks theo thứ tự | new |
| GET | /v3/teacher/classes/{class_id}/assign-tests | nguồn chọn bài tập về nhà gợi ý và bài tập đã giao trong sổ đầu bài | existing |
| DELETE | /v3/teacher/class-schedules/{id}/lessons/{lesson_id} | gỡ bài học FLYER khỏi lịch lớp khi trung tâm chuyển sang giáo trình riêng; không thay đổi | existing |
| GET/PUT | /v3/crm/classes/{class_id}/syllabus | {curriculum_version_id, strategy: sequential | manual} → class_syllabus + session_lesson_map[]; dry_run=true trả xem trước và cảnh báo lệch số buổi | new |
| PATCH · POST | /v3/crm/classes/{class_id}/syllabus/map · /shift · /rebind | {changes: [{session_id, lesson_ids[]}], skips: [{lesson_id, reason}]}; {from_session_id} dồn bài; {curriculum_version_id} đổi phiên bản, đối chiếu theo lesson_code, trả bài không khớp | new |
| GET/PUT | /v3/crm/sessions/{id}/teaching-log | đọc và ghi sổ đầu bài; PUT idempotent theo version; 409 STALE_VERSION; reason bắt buộc sau cửa sổ sửa | new |
| GET | /v3/crm/teaching-logs?school_id&from&to&missing=true | buổi chưa ghi sổ theo giáo viên | new |
| GET | /v3/crm/curriculum/progress | school_id, curriculum_id, staff_id → tiến độ theo lớp; format=xlsx | new |
| GET/POST · DELETE | /v3/crm/customer-files · /v3/crm/customer-files/{id} | mẫu tải tệp hai bước (file_id từ dịch vụ tệp, rồi tạo bản ghi) được tái sử dụng cho resource-files; không thay đổi | existing |
| GET/POST/PATCH/DELETE | /v3/crm/resource-folders · /v3/crm/resource-folders/{id} | cây thư mục; quyền theo thư mục qua PATCH {permissions[]} | new |
| GET/POST · PATCH/DELETE | /v3/crm/resource-files · /v3/crm/resource-files/{id} | danh sách theo folder_id, tìm kiếm q; tạo {folder_id, flyer_file_id, file_name, mime_type, size_bytes, tags}, 413 STORAGE_QUOTA_EXCEEDED; đổi tên, di chuyển, xoá vào thùng rác, restore=true; GET .../download-url trả URL có chữ ký 15 phút | new |
| GET | /v3/crm/storage-usage | used_bytes, quota_bytes, phân bổ theo thư mục | new |
| GET | /v3/parent/learner/{id}/sessions/{session_id}/lesson | nội dung bài cho phụ huynh: chỉ khối audience all hoặc student, chỉ khi parent_visible và đã dạy | new |
| GET/PUT | /v3/teacher/school-config | thêm khối curriculum_policy | extend |
8Phân quyền
| Mã quyền | owner | branch_manager | academic_admin | teacher | accountant | parent |
|---|---|---|---|---|---|---|
curriculum.view | tất cả | chi nhánh | chi nhánh | giáo trình của lớp được phân công | không | bài đã dạy của con (chỉ khối cho phụ huynh) |
curriculum.manage (tạo, sửa draft, sắp xếp) | có | chi nhánh (giáo trình có phạm vi chỉ chi nhánh đó) | chi nhánh | chỉ khi được cấp theo giáo trình cụ thể | không | không |
curriculum.publish, curriculum.archive | có | chỉ publish, chi nhánh | không | không | không | không |
syllabus.bind (gắn giáo trình cho khoá học, lớp; đổi phiên bản) | có | chi nhánh | chi nhánh | không | không | không |
syllabus.remap (gắn lại, dồn bài, bỏ qua) | có | chi nhánh | chi nhánh | lớp được phân công | không | không |
teaching_log.write | có | chi nhánh | chi nhánh | buổi được phân công | không | không |
teaching_log.edit_any | có | chi nhánh | chi nhánh | không | không | không |
curriculum.progress, curriculum.export | có | chi nhánh | chi nhánh | lớp được phân công | không | không |
resources.view | tất cả | chi nhánh | chi nhánh | thư mục được cấp | thư mục được cấp | không |
resources.manage (thư mục, tải lên, quyền) | có | chi nhánh | chi nhánh | thư mục được cấp quyền sửa | không | không |
resources.delete | có | chi nhánh | chi nhánh | tệp do bản thân tải lên trong 24 giờ | không | không |
curriculum.policy | có | không | không | không | không | không |
9Sự kiện phân tích
| Sự kiện | Thuộc tính |
|---|---|
| curriculum_created | level_code, branch_scope (all|subset), source (manual|import|duplicate) |
| curriculum_published | version_no, unit_count, lesson_count, total_duration_min, days_in_draft |
| lesson_saved | block_kinds[], has_teacher_material, has_student_material, parent_visible, suggested_assign_test_count |
| syllabus_bound | class_id, strategy, session_count, lesson_count, mismatch |
| syllabus_remapped | action (manual|shift|skip|rebind), affected_sessions, by_role |
| teaching_log_saved | completion, minutes_after_session_end, device, offline_queued, has_parent_note, homework_count |
| teaching_log_edited | days_after_log, by_role, reason_given |
| progress_report_viewed | filters, behind_count, on_track_count, exported |
| resource_uploaded | mime_type, size_bytes, folder_kind, quota_ratio_after |
| resource_quota_warning | ratio (0.9|1.0), used_bytes, quota_bytes |
| parent_lesson_viewed | learner_id, lesson_code, has_student_material, homework_count |
10Trường hợp biên
- Lớp có 30 buổi nhưng giáo trình chỉ có 24 bài: sáu buổi cuối "Chưa gắn bài", giáo vụ dùng cho ôn tập hoặc kiểm tra; tiến độ vẫn tính trên 24 bài. Trường hợp ngược lại (20 buổi, 24 bài): bốn bài cuối "Bài chưa có buổi", xem trước khi tạo lớp đề nghị tăng số buổi hoặc chọn giáo trình khác.
- Giáo viên dạy thay ghi "Dạy bài khác": chỉ chọn được bài trong cùng phiên bản giáo trình của lớp; nội dung ngoài giáo trình ghi vào ghi chú.
- Hai buổi trong cùng ngày của một lớp: ánh xạ theo thứ tự thời gian bắt đầu, không theo ngày.
- Phạm vi chi nhánh của giáo trình bị thu hẹp sau khi một lớp ở chi nhánh bị loại đã gắn: lớp giữ nguyên tham chiếu; chi nhánh đó không chọn được giáo trình này cho lớp mới.
- Tệp được nhiều bài ở nhiều giáo trình tham chiếu: một bản ghi resource_file với ref_count; xoá bị chặn cho đến khi gỡ hết tham chiếu hoặc chọn "Xoá và gỡ khỏi N bài học".
- Video YouTube bị đặt riêng tư sau khi nhúng: khối vẫn tồn tại, xem trước hiển thị "Video không khả dụng"; kiểm tra hằng tuần đánh dấu các khối lỗi để giáo vụ xem lại.
- Buổi học bị huỷ sau khi đã có sổ đầu bài: huỷ buổi yêu cầu xoá sổ đầu bài trước (cùng quy tắc với phiếu điểm danh ở PRD 04).
- Sổ đầu bài được lưu ngoại tuyến hai lần: bản có
client_saved_atmuộn hơn thắng, giống hàng đợi điểm danh.
11Câu hỏi còn mở
- Có cần cho giáo viên tự tạo giáo trình cá nhân (không phát hành cho trung tâm) để dùng cho lớp kèm riêng không? Đề xuất: không trong P1; giáo viên dùng bài tự do qua ghi chú sổ đầu bài.
- Đơn vị (unit) có nên có mục tiêu và bài kiểm tra cuối đơn vị riêng, hay để ở cấp bài học? Đề xuất: đơn vị chỉ là nhóm có tên trong P1.
- "Dạy một phần" tính 0,5 bài có đủ để quản lý chấp nhận không, hay cần phần trăm?
- Bài học FLYER (flyer_book_lesson_id) có nên được tự động đề xuất theo trình độ khi soạn bài không, và ai duy trì ánh xạ này?
Trường Số (truongso.net) · Nội bộ FLYER