265 lines
12 KiB
Markdown
265 lines
12 KiB
Markdown
# Role Permission Matrix
|
|
|
|
วันที่จัดทำ: 2026-07-07
|
|
|
|
## Summary
|
|
|
|
เอกสารนี้กำหนดโครงสร้าง role และ permission model ใหม่สำหรับระบบ Training Management System เพื่อใช้แทนแนวทางเดิมที่พึ่งพา:
|
|
|
|
- `systemRole`
|
|
- `membership.role`
|
|
- `businessRole`
|
|
|
|
แบบกระจายหลายชั้นและ 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
|
|
|
|
1. เพิ่ม permission catalog กลางใน `src/lib/auth`
|
|
2. เพิ่ม helper:
|
|
- `hasPermission()`
|
|
- `hasAnyPermission()`
|
|
- `requirePermission()`
|
|
3. เปลี่ยน route handlers ให้เช็ก permission ก่อน
|
|
4. เปลี่ยน nav/page visibility ให้ใช้ permission matrix
|
|
5. คง `businessRole` ไว้ชั่วคราวเพื่อไม่ให้ feature เดิมพัง
|
|
6. ค่อยทยอย refactor feature ให้ใช้ permission-first model เต็มรูปแบบ
|