12 KiB
12 KiB
Role Permission Matrix
วันที่จัดทำ: 2026-07-07
Summary
เอกสารนี้กำหนดโครงสร้าง role และ permission model ใหม่สำหรับระบบ Training Management System เพื่อใช้แทนแนวทางเดิมที่พึ่งพา:
systemRolemembership.rolebusinessRole
แบบกระจายหลายชั้นและ hard-code ตาม feature
เป้าหมายของโมเดลใหม่คือ:
- แยก
system-level accessออกจากorganization-level access - ใช้
permissionsเป็นตัวตัดสินสิทธิ์จริงที่ระดับ API/server - รองรับ workflow ที่ซับซ้อนขึ้น เช่น approve, publish, schedule, archive, revision
- ลดการพึ่งพา
businessRoleให้เหลือ compatibility layer ชั่วคราว
Access Model
ระบบใหม่ควรมี 3 ชั้น:
| Layer | Purpose | Example |
|---|---|---|
system_role |
สิทธิ์ระดับ platform | super_admin, support, standard |
organization_role |
บทบาทหลักในแต่ละองค์กร | owner, org_admin, hrd_manager, hrd_staff, employee |
permissions[] |
สิทธิ์ละเอียดระดับ feature/action | announcement:publish, users:manage |
System Roles
| System Role | Meaning |
|---|---|
super_admin |
เข้าถึงทุกองค์กรและทุกฟังก์ชันได้ |
support |
เข้าถึงเพื่อ support หรือ diagnose ได้ตาม policy ที่กำหนด |
standard |
ใช้สิทธิ์ตาม role ในองค์กรเป็นหลัก |
Organization Roles
| Organization Role | Meaning |
|---|---|
owner |
เจ้าขององค์กร จัดการทุกอย่างในองค์กร |
org_admin |
ผู้ดูแลองค์กร จัดการ users, master data, reports, workflow ได้ |
hrd_manager |
อนุมัติ, publish, schedule, archive workflow ฝั่ง HRD ได้ |
hrd_staff |
สร้าง, แก้ draft, submit ได้ แต่อนุมัติและ publish ไม่ได้ |
employee |
ผู้ใช้ทั่วไป เห็นเฉพาะข้อมูล public และข้อมูลของตัวเอง |
Permission Catalog
Platform / Organization
| Permission | Meaning |
|---|---|
organization:manage |
จัดการข้อมูลองค์กร |
organization:switch |
สลับ active organization |
membership:manage |
จัดการสมาชิกในองค์กร |
roles:assign |
เปลี่ยน role ให้สมาชิก |
permissions:assign |
กำหนด permission รายคนหรือราย role |
Users / Employee Directory
| Permission | Meaning |
|---|---|
users:read |
ดูรายการผู้ใช้ |
users:create |
สร้างผู้ใช้ |
users:update |
แก้ผู้ใช้ |
users:delete |
ลบหรือปิดผู้ใช้ |
users:manage |
จัดการผู้ใช้ทั้งหมด |
employee_directory:read |
ดู employee directory |
employee_directory:write |
แก้ employee directory |
employee_import:run |
import พนักงาน |
employee_master_review:approve |
อนุมัติ master data จาก import |
Courses / Training Policy / Training Matrix
| Permission | Meaning |
|---|---|
courses:read |
ดูหลักสูตร |
courses:write |
จัดการหลักสูตร |
training_policy:read |
ดูนโยบาย |
training_policy:write |
จัดการนโยบาย |
training_matrix:read |
ดู training matrix |
training_matrix:write |
จัดการ training matrix |
Training Records
| Permission | Meaning |
|---|---|
training_record:self_read |
ดูประวัติอบรมของตัวเอง |
training_record:self_write |
สร้างหรือแก้ draft ของตัวเอง |
training_record:read_all |
ดูข้อมูลทั้งองค์กร |
training_record:write_all |
สร้างหรือแก้แทนคนอื่นในองค์กร |
training_record:submit |
ส่งตรวจสอบ |
training_record:review |
อนุมัติหรือขอแก้ไข |
training_record:delete_draft |
ลบ draft |
training_record:manage_attachments |
จัดการไฟล์แนบ |
Announcements
| Permission | Meaning |
|---|---|
announcement:read_public |
ดูประกาศที่เผยแพร่แล้ว |
announcement:read_all |
ดูประกาศทุกสถานะ |
announcement:create |
สร้างประกาศ |
announcement:edit_draft |
แก้ draft หรือ revision |
announcement:delete_draft |
ลบ draft |
announcement:submit |
ส่งอนุมัติ |
announcement:approve |
อนุมัติ |
announcement:reject |
ตีกลับ |
announcement:publish |
เผยแพร่ทันที |
announcement:schedule |
ตั้งเวลาเผยแพร่ |
announcement:unpublish |
ยกเลิกการเผยแพร่ |
announcement:archive |
เก็บถาวร |
announcement:revision |
สร้าง draft revision จาก version ที่เผยแพร่แล้ว |
announcement:preview |
preview ได้ |
Online Lessons
| Permission | Meaning |
|---|---|
online_lesson:read_public |
ดูบทเรียนที่เผยแพร่แล้ว |
online_lesson:read_all |
ดูบทเรียนทุกสถานะ |
online_lesson:create |
สร้างบทเรียน |
online_lesson:edit_draft |
แก้ draft หรือ revision |
online_lesson:delete_draft |
ลบ draft |
online_lesson:submit |
ส่งอนุมัติ |
online_lesson:approve |
อนุมัติ |
online_lesson:reject |
ตีกลับ |
online_lesson:publish |
เผยแพร่ทันที |
online_lesson:schedule |
ตั้งเวลาเผยแพร่ |
online_lesson:unpublish |
ยกเลิกการเผยแพร่ |
online_lesson:archive |
เก็บถาวร |
online_lesson:revision |
สร้าง draft revision |
online_lesson:preview |
preview ได้ |
Reports / Audit / Notifications
| Permission | Meaning |
|---|---|
reports:self_read |
ดูรายงานของตัวเอง |
reports:organization_read |
ดูรายงานทั้งองค์กร |
reports:export |
export รายงาน |
audit_logs:read |
ดู audit logs |
notifications:read |
ดู notifications |
notifications:manage |
จัดการ notification flows หรือ templates |
Recommended Role-Permission Matrix
| Permission Group | owner | org_admin | hrd_manager | hrd_staff | employee |
|---|---|---|---|---|---|
organization:* |
Y | Y | N | N | N |
membership:manage |
Y | Y | N | N | N |
roles:assign |
Y | Y | N | N | N |
permissions:assign |
Y | Y | N | N | N |
users:* |
Y | Y | N | N | N |
employee_directory:read |
Y | Y | Y | Y | N |
employee_directory:write |
Y | Y | Y | Y | N |
employee_import:run |
Y | Y | Y | N | N |
employee_master_review:approve |
Y | Y | Y | N | N |
courses:read |
Y | Y | Y | Y | N |
courses:write |
Y | Y | Y | Y | N |
training_policy:read |
Y | Y | Y | N | N |
training_policy:write |
Y | Y | Y | N | N |
training_matrix:read |
Y | Y | Y | Y | N |
training_matrix:write |
Y | Y | Y | Y | N |
training_record:self_* |
Y | Y | Y | Y | Y |
training_record:read_all |
Y | Y | Y | Y | N |
training_record:write_all |
Y | Y | Y | Y | N |
training_record:submit |
Y | Y | Y | Y | Y |
training_record:review |
Y | Y | Y | N | N |
announcement:create/edit_draft/delete_draft/submit/preview |
Y | Y | Y | Y | N |
announcement:approve/reject/publish/schedule/unpublish/archive/revision |
Y | Y | Y | N | N |
online_lesson:create/edit_draft/delete_draft/submit/preview |
Y | Y | Y | Y | N |
online_lesson:approve/reject/publish/schedule/unpublish/archive/revision |
Y | Y | Y | N | N |
reports:self_read |
Y | Y | Y | Y | Y |
reports:organization_read |
Y | Y | Y | N | N |
reports:export |
Y | Y | Y | N | N |
audit_logs:read |
Y | Y | N | N | N |
notifications:read |
Y | Y | Y | Y | Y |
notifications:manage |
Y | Y | Y | N | N |
Page Access Matrix
| Page / Module | owner | org_admin | hrd_manager | hrd_staff | employee |
|---|---|---|---|---|---|
| Dashboard Overview | Y | Y | Y | Y | Y |
| Notifications | Y | Y | Y | Y | Y |
| Training Records | Y | Y | Y | Y | Y |
| Pending Review | Y | Y | Y | N | N |
| Announcements | Y | Y | Y | Y | Y, public-only content |
| Online Lessons | Y | Y | Y | Y | Y, public-only content |
| Users | Y | Y | N | N | N |
| Employee Directory | Y | Y | Y | Y | N |
| Courses | Y | Y | Y | Y | N |
| Training Policy | Y | Y | Y | N | N |
| Training Matrix | Y | Y | Y | Y | N |
| Reports | Y | Y | Y | N | Y, self-only |
| Audit Logs | Y | Y | N | N | N |
Special Rules
Employee visibility
Employee-facing queries ต้องถูกจำกัดที่ server-side เสมอ:
- content ต้องใช้
status = published - versioned content ต้องใช้
is_current = true - training records ต้อง self-scope หรือผ่าน employee mapping ที่อนุญาต
HRD staff
HRD staff ต้อง:
- สร้าง content ได้
- แก้ draft ได้
- submit ได้
แต่ต้องไม่มีสิทธิ์:
- approve
- publish
- schedule publish
- unpublish
- archive
HRD manager
HRD manager ต้อง:
- approve / reject ได้
- publish ได้
- schedule ได้
- archive ได้
- preview ได้
Super admin
super_admin เป็น system override:
- bypass organization-level permission checks ได้
- แต่ควรยังใช้ organization context เดิมในการ query/write เพื่อให้ audit trail ชัดเจน
Design Notes For Current Repo
สำหรับ repo ปัจจุบัน:
systemRoleยังควรเก็บไว้memberships.roleควรถูกย้ายจากowner/admin/memberไปสู่ role model ใหม่ หรือเพิ่ม layer mapping ใหม่businessRoleควรถูกลดบทบาทเหลือ compatibility layer ระหว่าง migration- server-side checks ต้องย้ายจาก
isHRD()/isIT()ไปเป็นhasPermission()/requirePermission()
Recommended Rollout
- เพิ่ม permission catalog กลางใน
src/lib/auth - เพิ่ม helper:
hasPermission()hasAnyPermission()requirePermission()
- เปลี่ยน route handlers ให้เช็ก permission ก่อน
- เปลี่ยน nav/page visibility ให้ใช้ permission matrix
- คง
businessRoleไว้ชั่วคราวเพื่อไม่ให้ feature เดิมพัง - ค่อยทยอย refactor feature ให้ใช้ permission-first model เต็มรูปแบบ