Module · WS đào tạo · 07/7/2026

lms — Lý thuyết đạt chuẩn giám sát v1.5

Dạy – học lý thuyết đạt chuẩn giám sát học từ xa: lớp/buổi học, điểm danh khuôn mặt, ngân hàng 600 câu (config), thi thử và kết quả xét điều kiện. Terminal khuôn mặt mua ngoài — chỉ viết tích hợp.

⚠️ Chưa có trong code — scaffold ở v1.5.
1

Feature / BO / Action

FeatureBO chínhAction
classLớp / buổi học lý thuyếtviewcreateedit
attendanceĐiểm danh khuôn mặt (log hợp lệ)viewexportcheckin
question-bankNgân hàng 600 câu (config theo bộ đề)viewimportconfigure
mock-examThi thử + kết quảviewcreatescore
resultKết quả học lý thuyết (xét điều kiện)viewapprovereport
2

Dữ liệu chính

BOTrường chính
Lớp/buổi họcKhóa · môn (ref catalog) · GV · phòng · lịch · hình thức (tập trung / từ xa)
Điểm danhBuổi × học viên · phương thức (khuôn mặt/RFID) · ảnh chụp · thời điểm vào/ra — log sinh dữ liệu hợp lệ theo chuẩn giám sát
Ngân hàng câu hỏi600 câu theo bộ đề hiện hành · chương/mục · câu điểm liệt · phiên bản bộ đề (đổi đề = cập nhật config)
Kết quảHọc viên × môn · số giờ đã học · điểm thi thử · trạng thái đạt/chưa đạt
3

Quy tắc & liên kết

Quy tắc nghiệp vụ

  • Học từ xa một phần được phép nhưng phải sinh dữ liệu hợp lệ: log thời gian học + điểm danh khuôn mặt
  • Ngân hàng 600 câu là dữ liệu cấu hình — bộ đề đổi thì cập nhật, không sửa code
  • Kết quả lý thuyết đạt là điều kiện trong hồ sơ xét hoàn thành (student/report)
  • Câu điểm liệt xử lý đúng luật thi (sai điểm liệt = trượt thi thử)

Liên kết chéo

  • student — kết quả lý thuyết vào hồ sơ
  • catalog — môn học, bộ đề
  • rfcard — điểm danh kết hợp
  • report — số giờ học vào báo cáo
  • portal — ôn tập/thi thử trên app

⚠ Câu hỏi mở

  • Chuẩn giám sát học từ xa chi tiết theo TT 17/2026-BXD (log gì, lưu bao lâu)?
  • Terminal khuôn mặt chọn hãng nào — API tích hợp?
Quyền

Ma trận phân quyền — ốp vào manifest & seed role

Khối permissions[] dán vào manifest.json; bảng dưới là gán quyền theo vai trò (seed rt_role). Permission key đầy đủ: lms.main.<feature>.<action>.

▸ permissions[] — manifest.json

[ { "group": "main", "feature": "class", "label": "Lớp/buổi lý thuyết", "actions": [ "view", "create", "edit" ] }, { "group": "main", "feature": "attendance", "label": "Điểm danh", "actions": [ "view", "export", "checkin" ] }, { "group": "main", "feature": "question-bank", "label": "Ngân hàng 600 câu", "actions": [ "view", "import", "configure" ] }, { "group": "main", "feature": "mock-exam", "label": "Thi thử", "actions": [ "view", "create", "score" ] }, { "group": "main", "feature": "result", "label": "Kết quả lý thuyết", "actions": [ "view", "approve", "report" ] } ]

⚠️ Action đặc thù (checkin, score) cần bổ sung vào validator manifest — xem plan data-scope P1.

▸ Ma trận vai trò × feature

FeatureQTHTGIAM_DOCQL_DAO_TAOGIAO_VUGIAO_VIENHOC_VIEN
classRRWWR¹
attendanceRRRRR¹
question-bankRRW
mock-examRRRWR²
resultRRRARR²

R xem · W tạo/sửa · A duyệt · không có quyền · ¹ dữ liệu phân công · ² của chính mình · ³ theo trạng thái hồ sơ. Vai trò không liệt kê = không có quyền.

Đặc thù: attendance +checkin (GIAO_VIEN, HOC_VIEN) · mock-exam score = hệ thống chấm tự động

▸ Quyền mức record (row-level)

(a) Manifest bổ sung fields + scopeVars cho feature bị scope (mở rộng schema — plan data-scope P1; manifest chỉ khai "cái gì scope được", không chứa rule):

[ { "group": "main", "feature": "class", "fields": [ "giao_vien_id" ], "scopeVars": [ "current_giao_vien_id" ] }, { "group": "main", "feature": "attendance", "fields": [ "giao_vien_id", "nguoi_lxid" ], "scopeVars": [ "current_giao_vien_id", "current_nguoi_lxid" ] }, { "group": "main", "feature": "mock-exam", "fields": [ "nguoi_lxid" ], "scopeVars": [ "current_nguoi_lxid" ] }, { "group": "main", "feature": "result", "fields": [ "nguoi_lxid" ], "scopeVars": [ "current_nguoi_lxid" ] } ]

(b) Điều kiện record theo vai trò:

Vai tròFeature (action)Điều kiện record
GIAO_VIENclass, attendance (view)giao_vien_id = ctx.current_giao_vien_id (lớp mình dạy)
HOC_VIENmock-exam, result (view)nguoi_lxid = ctx.current_nguoi_lxid

(c) Seed rt_role.grants (kind rule — nhiều rule cùng resource+action = OR):

[ { "kind": "rule", "module": "lms", "feature": "class", "actions": [ "view" ], "predicate": { "op": "cmp", "field": "giao_vien_id", "cmp": "=", "value": { "ctx": "current_giao_vien_id" } } }, { "kind": "rule", "module": "lms", "feature": "attendance", "actions": [ "view" ], "predicate": { "op": "cmp", "field": "giao_vien_id", "cmp": "=", "value": { "ctx": "current_giao_vien_id" } } }, { "kind": "rule", "module": "lms", "feature": "result", "actions": [ "view" ], "predicate": { "op": "cmp", "field": "nguoi_lxid", "cmp": "=", "value": { "ctx": "current_nguoi_lxid" } } } ]

Biến ngữ cảnh: current_user_id — engine có sẵn · current_giao_vien_id/current_ma_gv — module teacher tra từ user đăng nhập (ctxVars, plan P3) · current_nguoi_lxid/current_ma_dk_list — module student tra (1 người nhiều lượt đăng ký) · current_assigned_* — danh sách phụ trách/được phân công.