commit
This commit is contained in:
207
docs/permission-template-authorization-implementation.md
Normal file
207
docs/permission-template-authorization-implementation.md
Normal file
@@ -0,0 +1,207 @@
|
||||
# Permission Template Authorization Implementation
|
||||
|
||||
วันที่อัปเดต: 2026-07-07
|
||||
|
||||
## Scope ของเฟสแรก
|
||||
|
||||
เฟสแรกของงาน `permission-authorization` เน้นวาง foundation ให้ระบบย้ายจาก role-based authorization ไปสู่ permission-first model แบบค่อยเป็นค่อยไป โดยยังไม่บังคับเปลี่ยนทุก feature พร้อมกันในครั้งเดียว
|
||||
|
||||
สิ่งที่ทำในเฟสนี้:
|
||||
|
||||
- เพิ่ม permission catalog กลาง
|
||||
- เพิ่ม helper สำหรับเช็ก permission แบบ type-safe
|
||||
- ผูก default permission ของ membership เข้ากับ catalog กลาง
|
||||
- เพิ่ม session helper สำหรับ `requirePermission()` / `requireAnyPermission()` / `requireAllPermissions()`
|
||||
- เชื่อม `src/auth.ts` ให้ resolve effective permissions จาก template assignment และ override
|
||||
- ขยาย session payload ให้มี `effectivePermissions` และ `permissionTemplateIds`
|
||||
- เพิ่ม schema และ migration สำหรับ permission template, assignment, override, และ audit log
|
||||
|
||||
## โครงสร้าง Permission-first Model
|
||||
|
||||
โครงสร้างเป้าหมายของระบบ:
|
||||
|
||||
```text
|
||||
Organization
|
||||
-> Permission Template
|
||||
-> Template Permissions
|
||||
-> User Template Assignments
|
||||
-> User Permission Overrides
|
||||
-> Effective Permissions
|
||||
```
|
||||
|
||||
หลักการในเฟสนี้:
|
||||
|
||||
- `Permission` คือ source of truth ใหม่
|
||||
- `membership.role` ยังอยู่เพื่อ compatibility ระหว่าง migration
|
||||
- `businessRole`, `isHRD()`, `isIT()` ยังไม่ถูกลบทิ้ง แต่ไม่ควรเป็นฐานของ feature ใหม่
|
||||
- `super_admin` ยังเป็น system-level bypass ได้ตาม helper ปัจจุบัน
|
||||
|
||||
## Permission Catalog
|
||||
|
||||
ไฟล์หลัก:
|
||||
|
||||
- [src/lib/auth/permissions.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/lib/auth/permissions.ts)
|
||||
- [src/lib/auth/authorization.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/lib/auth/authorization.ts)
|
||||
|
||||
สิ่งที่เพิ่ม:
|
||||
|
||||
- `Permission` type แบบรวมค่า permission ทั้งระบบ
|
||||
- permission catalog แยกตาม module
|
||||
- default permission set สำหรับ `owner`, `admin`, `member`
|
||||
- helper:
|
||||
- `hasPermission()`
|
||||
- `hasAnyPermission()`
|
||||
- `hasAllPermissions()`
|
||||
- `normalizePermissions()`
|
||||
- `isPermission()`
|
||||
|
||||
## Default Permission Mapping
|
||||
|
||||
ไฟล์ที่ผูก default mapping:
|
||||
|
||||
- [src/lib/auth/roles.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/lib/auth/roles.ts)
|
||||
|
||||
สถานะปัจจุบัน:
|
||||
|
||||
- `getDefaultPermissionsForRole()` ถูกเปลี่ยนให้ดึงจาก catalog กลางแล้ว
|
||||
- ระบบเดิมยังสามารถสร้าง default permissions จาก membership role ได้เหมือนเดิม
|
||||
- ยังไม่ได้ย้ายไปใช้ seeded permission templates จริงในฐานข้อมูล
|
||||
|
||||
## Session และ Authorization Helper
|
||||
|
||||
ไฟล์หลัก:
|
||||
|
||||
- [src/auth.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/auth.ts)
|
||||
- [src/lib/auth/session.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/lib/auth/session.ts)
|
||||
- [src/types/next-auth.d.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/types/next-auth.d.ts)
|
||||
- [src/types/index.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/types/index.ts)
|
||||
|
||||
สิ่งที่เพิ่ม:
|
||||
|
||||
- `resolveEffectivePermissions()` ถูกใช้ใน session callback แล้ว
|
||||
- `requirePermission(permission)`
|
||||
- `requireAnyPermission(permissions)`
|
||||
- `requireAllPermissions(permissions)`
|
||||
- nav access metadata รองรับ `Permission` type มากขึ้น
|
||||
|
||||
ข้อสำคัญ:
|
||||
|
||||
- session จะพยายามอ่านสิทธิ์จาก:
|
||||
- active permission template assignments
|
||||
- active user permission overrides
|
||||
- fallback membership permissions หรือ default role permissions
|
||||
- `session.user.permissions` และ `session.user.effectivePermissions` ตอนนี้ชี้ไปที่ผลลัพธ์ effective permissions ชุดเดียวกัน
|
||||
- `requireOrganizationAccess()` และ `requirePermission()` เปลี่ยนมาอ้าง `session.user.effectivePermissions` เป็นหลักแล้ว
|
||||
|
||||
## Database / Schema ที่เพิ่ม
|
||||
|
||||
ไฟล์หลัก:
|
||||
|
||||
- [src/db/schema.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/db/schema.ts)
|
||||
- [drizzle/0015_permission_template_authorization.sql](/D:/WY-2569/HRD/training-system-minimal-refactor/drizzle/0015_permission_template_authorization.sql)
|
||||
|
||||
ตารางและ enum ที่เพิ่ม:
|
||||
|
||||
1. `permission_override_effect`
|
||||
ใช้เก็บค่า `allow` และ `deny`
|
||||
|
||||
2. `permission_templates`
|
||||
เก็บ template รายองค์กร
|
||||
|
||||
คอลัมน์สำคัญ:
|
||||
|
||||
- `organization_id`
|
||||
- `code`
|
||||
- `name`
|
||||
- `description`
|
||||
- `is_system`
|
||||
- `is_default`
|
||||
- `is_active`
|
||||
- `deleted_at`
|
||||
|
||||
3. `permission_template_permissions`
|
||||
เก็บรายการ permission ของแต่ละ template
|
||||
|
||||
4. `user_permission_template_assignments`
|
||||
เก็บการ assign template ให้ user แบบผูกกับ organization
|
||||
|
||||
หมายเหตุ:
|
||||
|
||||
- รองรับหลาย template ต่อ user ต่อ organization ได้
|
||||
- มี `is_active` สำหรับรองรับการปิด assignment โดยไม่ต้องลบทิ้ง
|
||||
|
||||
5. `user_permission_overrides`
|
||||
เก็บ override รายบุคคล
|
||||
|
||||
ความสามารถที่รองรับแล้วใน schema:
|
||||
|
||||
- `allow` override
|
||||
- `deny` override
|
||||
- `expires_at`
|
||||
- `revoked_at`
|
||||
- `revoked_by`
|
||||
|
||||
6. `permission_audit_logs`
|
||||
เก็บ audit trail สำหรับการเปลี่ยน template, assignment, override
|
||||
|
||||
## วิธีคำนวณ Effective Permissions
|
||||
|
||||
logic ที่ถูกต่อเข้ากับ session แล้วในรอบนี้:
|
||||
|
||||
```text
|
||||
effective permissions
|
||||
= permissions จาก template assignment ที่ active
|
||||
+ allow overrides ที่ยังไม่หมดอายุ
|
||||
- deny overrides ที่ active และยังไม่หมดอายุ
|
||||
```
|
||||
|
||||
กติกาที่ต้องใช้ในเฟสถัดไป:
|
||||
|
||||
- `deny` มี priority สูงกว่า `allow`
|
||||
- override ที่หมดอายุแล้วต้องไม่ถูกใช้
|
||||
- ทุกการคำนวณต้องผูกกับ `active organization`
|
||||
- ถ้า user ยังไม่มี active template assignment จะ fallback ไปที่ `memberships.permissions`
|
||||
- ถ้า membership ไม่มี permissions เลย จะ fallback ไปที่ default permissions ตาม role เดิม
|
||||
|
||||
## ไฟล์ที่แก้ในเฟสนี้
|
||||
|
||||
- [src/lib/auth/permissions.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/lib/auth/permissions.ts)
|
||||
- [src/lib/auth/authorization.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/lib/auth/authorization.ts)
|
||||
- [src/lib/auth/roles.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/lib/auth/roles.ts)
|
||||
- [src/auth.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/auth.ts)
|
||||
- [src/lib/auth/session.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/lib/auth/session.ts)
|
||||
- [src/types/next-auth.d.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/types/next-auth.d.ts)
|
||||
- [src/types/index.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/types/index.ts)
|
||||
- [src/db/schema.ts](/D:/WY-2569/HRD/training-system-minimal-refactor/src/db/schema.ts)
|
||||
- [drizzle/0015_permission_template_authorization.sql](/D:/WY-2569/HRD/training-system-minimal-refactor/drizzle/0015_permission_template_authorization.sql)
|
||||
|
||||
## สิ่งที่ยังไม่ได้ทำ
|
||||
|
||||
- seed default permission templates ลงฐานข้อมูล
|
||||
- helper `getEffectivePermissions(userId, organizationId)`
|
||||
- admin UI สำหรับจัดการ template
|
||||
- UI สำหรับ assign template และตั้ง override รายบุคคล
|
||||
- migration ของ feature guards จาก role-based เป็น permission-based แบบครบทุกหน้า
|
||||
- audit write logic ตอน create/update/assign/override
|
||||
|
||||
## ลำดับงานถัดไปที่แนะนำ
|
||||
|
||||
1. เพิ่ม permission template service และ effective permission resolver
|
||||
2. seed default permission templates และ assignment strategy สำหรับข้อมูลเดิม
|
||||
3. ทำ seed default templates ต่อ organization
|
||||
4. ย้าย page guards และ navigation ไปใช้ permission helper
|
||||
5. ย้าย route handlers สำคัญไปใช้ `requirePermission()`
|
||||
6. ค่อยทำ admin UI สำหรับ template และ user assignment
|
||||
|
||||
## Verification
|
||||
|
||||
ตรวจสอบแล้วในรอบนี้:
|
||||
|
||||
- `oxlint` ผ่านสำหรับไฟล์ auth/schema ที่แก้
|
||||
- `tsc --noEmit` ผ่านหลังเพิ่ม foundation ของ permission helper
|
||||
- `session.user.permissions` ถูกย้ายให้ใช้ผลจาก effective permission resolver แล้ว
|
||||
|
||||
หมายเหตุ:
|
||||
|
||||
- หลังเพิ่ม migration `0015` ควรรัน `npm run migrate` ในเครื่องก่อนเริ่มทำ service/UI เฟสถัดไป
|
||||
- ยังไม่ได้เพิ่ม snapshot ใหม่ใน `drizzle/meta` เพราะรอบนี้เพิ่ม migration SQL แบบ manual เพื่อคุมผลกระทบให้แคบที่สุด
|
||||
Reference in New Issue
Block a user