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

portal — Backend app học viên v1.5

Backend cho app học viên (iOS/Android) — công cụ tuyển sinh khác biệt: tra tiến độ km/giờ DAT thời gian thực, lịch học, đặt lịch bổ túc, ôn 600 câu, thông báo Zalo OA.

⚠️ Chưa có trong code — scaffold ở v1.5. App mobile là client riêng; module này là API + dữ liệu phía WS.
1

Feature / BO / Action

FeatureBO chínhAction
accountTài khoản học viên trên appviewcreatereset
progressTra cứu tiến độ km/giờview
bookingĐặt lịch bổ túc với GVviewapprovebook
practiceÔn 600 câu, thi thử trên appview
2

Dữ liệu chính

BOTrường chính
Tài khoản appHọc viên (ref ma_dk/CCCD) · SĐT đăng nhập · thiết bị · trạng thái
BookingHọc viên × GV × khung giờ · loại (bổ túc sa hình/đường trường) · trạng thái (đặt → GV/giáo vụ duyệt → hoàn thành/hủy)
Tiến độ (view)Đọc từ dat.reconcile: % km/giờ, còn thiếu, cảnh báo — chỉ dữ liệu của chính mình
3

Quy tắc & liên kết

Quy tắc nghiệp vụ

  • Học viên self-scope: chỉ thấy hồ sơ/tiến độ/công nợ của mình
  • Booking phải được GV hoặc giáo vụ duyệt; lịch trùng bị chặn
  • Thông báo đẩy qua notify (Zalo OA/push) — portal không tự gửi
  • Mapping tài khoản ↔ học viên qua SĐT/CCCD (plan data-scope P3)

Liên kết chéo

  • student — hồ sơ của tôi
  • dat — tiến độ km/giờ
  • tuition — công nợ của tôi
  • lms — 600 câu, thi thử
  • notify — Zalo OA/push
  • booking/chip (v2) — đặt phiên xe chip

⚠ Câu hỏi mở

  • Đặt lịch bổ túc tính phí ngay (nối tuition) hay miễn phí?
  • App dùng chung nhiều trung tâm (multi-tenant client) — chọn trung tâm thế nào?
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 đủ: portal.main.<feature>.<action>.

▸ permissions[] — manifest.json

[ { "group": "main", "feature": "account", "label": "Tài khoản app", "actions": [ "view", "create", "reset" ] }, { "group": "main", "feature": "progress", "label": "Tiến độ km/giờ", "actions": [ "view" ] }, { "group": "main", "feature": "booking", "label": "Đặt lịch bổ túc", "actions": [ "view", "approve", "book" ] }, { "group": "main", "feature": "practice", "label": "Ôn tập & thi thử", "actions": [ "view" ] } ]

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

▸ Ma trận vai trò × feature

FeatureQTHTGIAO_VUGIAO_VIENHOC_VIEN
accountWW
progressR²
bookingRARA¹W²
practiceR²

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ù: account +reset · booking +book (HOC_VIEN) · hủy lịch = bước workflow

▸ 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": "progress", "fields": [ "nguoi_lxid" ], "scopeVars": [ "current_nguoi_lxid" ] }, { "group": "main", "feature": "booking", "fields": [ "nguoi_lxid", "giao_vien_id" ], "scopeVars": [ "current_nguoi_lxid", "current_giao_vien_id" ] }, { "group": "main", "feature": "practice", "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
HOC_VIENprogress, practice (view) · booking (view, book)nguoi_lxid = ctx.current_nguoi_lxid
GIAO_VIENbooking (view, approve)giao_vien_id = ctx.current_giao_vien_id (lịch của mình)

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

[ { "kind": "rule", "module": "portal", "feature": "progress", "actions": [ "view" ], "predicate": { "op": "cmp", "field": "nguoi_lxid", "cmp": "=", "value": { "ctx": "current_nguoi_lxid" } } }, { "kind": "rule", "module": "portal", "feature": "booking", "actions": [ "view", "book" ], "predicate": { "op": "cmp", "field": "nguoi_lxid", "cmp": "=", "value": { "ctx": "current_nguoi_lxid" } } }, { "kind": "rule", "module": "portal", "feature": "booking", "actions": [ "view", "approve" ], "predicate": { "op": "cmp", "field": "giao_vien_id", "cmp": "=", "value": { "ctx": "current_giao_vien_id" } } } ]

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.