# Prompt: Refactor Authorization เป็น Permission Template + Permission-first Model ## Context โปรเจกต์นี้คือระบบ Training Management System (TMS) ที่ปัจจุบันยังมีการตรวจสอบสิทธิ์จาก `systemRole`, `membership.role`, `businessRole` และ helper เช่น `isHRD()` / `isIT()` ต้องการปรับระบบสิทธิ์ใหม่ให้เป็น **Permission-first Authorization Model** โดยตัดแนวคิดว่า “Role คือสิทธิ์” ออก และเปลี่ยนมาใช้ **Permission Template** เป็นชุดสิทธิ์ต้นแบบแทน อ้างอิงจากแผนเดิมใน `role-permission-migration-plan.md` ที่ระบุว่าควรย้ายระบบจาก role/helper เดิมไปสู่ permission-based model และให้ API/server ใช้ permission เป็นตัวตัดสินสิทธิ์จริง --- ## Final Direction ให้เปลี่ยนแนวคิดจากเดิม: ```text User -> Role -> Permission ``` เป็น: ```text Organization -> Permission Template -> Permissions -> User Assignment -> User Permission Override -> Effective Permissions ``` หลักการสำคัญ: - Permission คือ source of truth - Permission Template เป็นเพียงชุดสิทธิ์ต้นแบบ - User ได้รับสิทธิ์จาก Template - User สามารถมี Permission Override รายบุคคลได้ - ระบบต้องรองรับหลายองค์กร - UI ซ่อน/แสดงได้ตาม Permission - API/server ต้องตรวจ Permission เสมอ - ห้ามใช้ Role เป็นตัวตัดสินสิทธิ์หลักอีกต่อไป --- ## Required Work ### 1. Audit Existing Authorization ตรวจสอบโค้ดทั้งหมดก่อนแก้ไข ค้นหาการใช้งาน: ```ts systemRole membership.role businessRole isHRD() isIT() requireHRD() requireIT() requireUserManagementAccess() role === ... ``` ตรวจสอบในส่วน: - API routes - Server actions - Page guards - Navigation - Feature components - Data helpers - Auth/session helpers - User management - Middleware ให้สรุปก่อนว่าไฟล์ใดยังใช้ role-based authorization อยู่ --- ### 2. Create Permission Catalog สร้าง permission catalog กลาง เช่น: ```text src/lib/auth/permissions.ts ``` ต้องมี permission constants และ type-safe permission list ตัวอย่างกลุ่ม permission: ```ts organization:manage organization:switch permission_template:read permission_template:create permission_template:update permission_template:clone permission_template:delete permission_template:assign user_permission:read user_permission:update user_permission:override user_permission:remove_override users:read users:create users:update users:delete users:manage employee_directory:read employee_directory:write employee_import:run employee_master_review:approve training_record:self_read training_record:self_write training_record:read_all training_record:write_all training_record:submit training_record:review training_record:approve training_record:reject training_record:delete_draft training_record:manage_attachments announcement:read_public announcement:read_all announcement:create announcement:edit_draft announcement:delete_draft announcement:submit announcement:approve announcement:reject announcement:publish announcement:schedule announcement:unpublish announcement:archive announcement:restore announcement:revision announcement:preview announcement:view_history online_lesson:read_public online_lesson:read_all online_lesson:create online_lesson:edit_draft online_lesson:delete_draft online_lesson:submit online_lesson:approve online_lesson:reject online_lesson:publish online_lesson:schedule online_lesson:unpublish online_lesson:archive online_lesson:restore online_lesson:revision online_lesson:preview online_lesson:view_history reports:self_read reports:organization_read reports:export reports:export_excel reports:export_pdf audit_logs:read audit_logs:export notifications:read notifications:manage ``` --- ### 3. Add Permission Template Data Model ตรวจสอบ schema เดิมก่อนแก้ไข ให้เพิ่มหรือปรับ database model ให้รองรับ: ```text organizations permission_templates permission_template_permissions user_permission_template_assignments user_permission_overrides permission_audit_logs ``` โครงสร้างต้องรองรับ: - หลายองค์กร - แต่ละองค์กรมี Permission Template ของตัวเอง - Template สร้างได้ - Template แก้ไขได้ - Template Clone ได้ - Template ลบได้ - Template ที่ถูกใช้งานอยู่ต้องห้ามลบ หรือให้ soft delete เท่านั้น - User 1 คนสามารถถูก assign template ได้อย่างน้อย 1 template ต่อ organization - User สามารถมี permission override รายบุคคลได้ - Override ต้องรองรับทั้ง `allow` และ `deny` - Override สามารถมี optional expiration date ได้ ถ้าออกแบบได้โดยไม่กระทบระบบมาก - ทุกการเปลี่ยนแปลงต้องมี audit log --- ### 4. Default Permission Templates สร้าง default templates เป็น seed data ไม่ใช่ hard-code role ต้องมี template เริ่มต้นอย่างน้อย: ```text Employee HRD Staff HRD Manager Org Admin IT Admin Super Admin ``` ตัวอย่างสิทธิ์: #### Employee ```text notifications:read announcement:read_public online_lesson:read_public training_record:self_read training_record:self_write training_record:submit reports:self_read ``` #### HRD Staff ได้ Employee permissions และเพิ่ม: ```text employee_directory:read employee_directory:write courses:read courses:write training_matrix:read training_matrix:write training_record:read_all training_record:write_all announcement:read_all announcement:create announcement:edit_draft announcement:delete_draft announcement:submit announcement:preview online_lesson:read_all online_lesson:create online_lesson:edit_draft online_lesson:delete_draft online_lesson:submit online_lesson:preview ``` ห้ามมี: ```text announcement:approve announcement:publish announcement:schedule announcement:archive online_lesson:approve online_lesson:publish online_lesson:schedule online_lesson:archive ``` #### HRD Manager ได้ HRD Staff permissions และเพิ่ม: ```text training_record:review training_record:approve training_record:reject announcement:approve announcement:reject announcement:publish announcement:schedule announcement:unpublish announcement:archive announcement:restore announcement:revision announcement:view_history online_lesson:approve online_lesson:reject online_lesson:publish online_lesson:schedule online_lesson:unpublish online_lesson:archive online_lesson:restore online_lesson:revision online_lesson:view_history reports:organization_read reports:export reports:export_excel reports:export_pdf notifications:manage ``` #### Org Admin ```text organization:manage organization:switch users:read users:create users:update users:delete users:manage employee_directory:read employee_directory:write permission_template:read permission_template:assign user_permission:read reports:organization_read audit_logs:read ``` #### IT Admin / Super Admin ```text permission_template:read permission_template:create permission_template:update permission_template:clone permission_template:delete permission_template:assign user_permission:read user_permission:update user_permission:override user_permission:remove_override users:manage audit_logs:read audit_logs:export organization:manage organization:switch ``` --- ### 5. Permission Helper สร้าง helper กลาง เช่น: ```text src/lib/auth/authorization.ts ``` ต้องมี function: ```ts getEffectivePermissions(userId, organizationId) hasPermission(user, permission, context?) hasAnyPermission(user, permissions, context?) hasAllPermissions(user, permissions, context?) requirePermission(user, permission, context?) requireAnyPermission(user, permissions, context?) requireAllPermissions(user, permissions, context?) ``` Effective permissions ต้องคำนวณจาก: ```text Template permissions + user allow overrides - user deny overrides - expired overrides ``` เงื่อนไข: - `deny` ต้องมี priority สูงกว่า `allow` - expired permission ต้องไม่ถูกนำมาใช้ - ต้อง scope ตาม organization - ต้อง cache ได้ถ้าเหมาะสม - ต้อง clear cache เมื่อมีการแก้ template หรือ override --- ### 6. Session / Auth Update ปรับ session ให้รองรับ permission-first model Session ควรมี: ```ts userId; organizationId; organizationIds; activeOrganizationId; permissionTemplateIds; effectivePermissions; ``` คง field เดิม เช่น `businessRole`, `systemRole`, `membership.role` ไว้ชั่วคราวเพื่อ compatibility เท่านั้น ห้ามใช้ field เดิมเป็น source of truth ใหม่ --- ### 7. Permission Template Management UI เพิ่มหน้าจัดการ Permission Template ใน Admin ต้องรองรับ: - ดูรายการ Template - สร้าง Template - แก้ไข Template - Clone Template - ลบ Template - Soft delete Template ที่เคยถูกใช้งาน - ดู Permission ภายใน Template - ค้นหา Permission - Group Permission ตาม module - แสดงจำนวนผู้ใช้งาน Template - บันทึกเหตุผลเมื่อแก้ไข - เก็บ audit log ทุกครั้ง --- ### 8. User Permission Assignment UI เพิ่มหรือปรับหน้า User Management ให้รองรับ: - เลือก Organization - เลือก User - Assign Permission Template ให้ User - เปลี่ยน Template - แสดง Effective Permissions - เพิ่ม Permission เฉพาะราย - Deny Permission เฉพาะราย - Remove Override - กำหนดวันหมดอายุ Override ถ้ารองรับ - บันทึกเหตุผล - แสดงประวัติการเปลี่ยนสิทธิ์ Effective Permission Viewer ต้องแสดง: ```text Template permissions Allow overrides Deny overrides Expired overrides Final effective permissions ``` --- ### 9. Multi-Organization Support ระบบต้องรองรับหลายองค์กร หลักการ: - Permission Template ต้องผูกกับ organization - User assignment ต้องผูกกับ organization - User override ต้องผูกกับ organization - Effective permissions ต้องคำนวณตาม active organization - การ query/write ข้อมูลต้องมี organization context - Super Admin / IT Admin อาจ switch organization ได้ตาม permission ต้องตรวจสอบ: - organization switcher - membership - session - API scope - audit logs - user management - reports --- ### 10. Replace Server-Side Authorization เปลี่ยน API/server guard จาก role-based เป็น permission-based ตัวอย่าง: เดิม: ```ts if (!isHRD(user)) { return forbidden(); } ``` ใหม่: ```ts await requirePermission(user, "announcement:create", { organizationId, }); ``` ต้องปรับอย่างน้อย: - Announcements API - Online Lessons API - Training Records API - Users API - Employee Directory API - Employee Import API - Courses API - Training Policy API - Training Matrix API - Reports API - Audit Logs API - Notifications API สำคัญ: Employee-facing API ต้อง enforce server-side scope เสมอ ```text announcement / online lesson: - status = published - is_current = true training records: - self-scope เท่านั้น เว้นแต่มี training_record:read_all ``` --- ### 11. Replace Page Guards And Navigation ปรับ page guard และ navigation ให้ใช้ permission ตัวอย่าง: ```ts canViewUsers = hasPermission(user, "users:read"); canViewPendingReview = hasAnyPermission(user, [ "training_record:review", "announcement:approve", "online_lesson:approve", ]); ``` ห้ามใช้: ```ts businessRole === "HRD"; isHRD(); isIT(); ``` เป็นตัวตัดสินหลักอีกต่อไป --- ### 12. Feature UI Permission Visibility ปรับ component ให้รับ permission context หรือ effective permissions ตัวอย่าง: - ปุ่ม Create แสดงเมื่อมี `announcement:create` - ปุ่ม Submit แสดงเมื่อมี `announcement:submit` - ปุ่ม Approve แสดงเมื่อมี `announcement:approve` - ปุ่ม Publish แสดงเมื่อมี `announcement:publish` - ปุ่ม Schedule แสดงเมื่อมี `announcement:schedule` - ปุ่ม Archive แสดงเมื่อมี `announcement:archive` แต่ต้องจำไว้ว่า UI visibility ไม่ใช่ security Server/API ต้องตรวจ permission ซ้ำเสมอ --- ### 13. Audit Log ทุก action ต่อไปนี้ต้องมี audit log: - Create template - Update template - Clone template - Delete template - Assign template to user - Change user template - Add user permission override - Deny user permission - Remove override - Organization switch ที่สำคัญ - Permission-based workflow actions เช่น approve, publish, archive Audit payload ควรเก็บ: ```text actor_user_id organization_id target_user_id target_template_id action before after reason timestamp ``` --- ### 14. Backward Compatibility ห้ามลบ logic เดิมทันที ให้ทำ compatibility layer เช่น: ```ts mapLegacyRoleToPermissionTemplate(); resolveEffectivePermissionsFromLegacyRole(); ``` เป้าหมายคือ: - ระบบเดิมไม่พัง - migration ทำเป็น phase ได้ - ค่อย ๆ ลดการใช้ `businessRole`, `systemRole`, `membership.role` - ห้ามเขียน feature ใหม่โดยใช้ role-based authorization --- ### 15. Testing Checklist ต้องทดสอบอย่างน้อย: #### Employee - เห็นเฉพาะข้อมูลตัวเอง - เห็นเฉพาะ published content - เข้า draft ผ่าน URL ตรงไม่ได้ - approve ไม่ได้ - publish ไม่ได้ #### HRD Staff Template - สร้าง draft ได้ - แก้ draft ได้ - submit ได้ - preview ได้ - approve ไม่ได้ - publish ไม่ได้ - schedule ไม่ได้ - archive ไม่ได้ #### HRD Manager Template - approve ได้ - reject ได้ - publish ได้ - schedule ได้ - archive ได้ - revision ได้ - export report ได้ #### IT Admin - สร้าง template ได้ - แก้ template ได้ - clone template ได้ - ลบ template ได้ตามเงื่อนไข - assign template ให้ user ได้ - override permission รายบุคคลได้ - ดู effective permissions ได้ - audit log ถูกบันทึกครบ #### Multi-Organization - User คนเดียวมีสิทธิ์ต่างกันในแต่ละ organization ได้ - active organization เปลี่ยนแล้ว permission เปลี่ยนตาม - API ไม่ดึงข้อมูลข้าม organization - audit log ระบุ organization ถูกต้อง --- ### 16. Documentation หลังแก้ไขเสร็จ ให้สร้างเอกสารไว้ที่: ```text docs/permission-template-authorization-implementation.md ``` เอกสารต้องมี: - สรุปสิ่งที่แก้ไข - โครงสร้าง Permission-first model - Permission catalog - Default permission templates - Database/schema ที่เพิ่มหรือแก้ไข - วิธีคำนวณ effective permissions - วิธี assign template ให้ user - วิธี override permission รายบุคคล - วิธีรองรับหลายองค์กร - API/page ที่เปลี่ยนแล้ว - compatibility layer ที่ยังเหลือ - test checklist - known issues - next steps --- ## Acceptance Criteria งานนี้ถือว่าเสร็จเมื่อ: - Permission เป็น source of truth - Role ไม่ใช่ตัวกำหนดสิทธิ์หลักอีกต่อไป - มี permission catalog กลาง - มี Permission Template ที่จัดการผ่าน Admin ได้ - สร้าง/แก้ไข/Clone/ลบ Template ได้ - Assign Template ให้ User ได้ - Override Permission รายบุคคลได้ - รองรับหลายองค์กร - Effective permissions คำนวณถูกต้อง - API/server ใช้ `requirePermission()` เป็นหลัก - Navigation/page guard ใช้ permission - Employee เห็นเฉพาะข้อมูลที่ควรเห็น - HRD Staff publish/approve ไม่ได้ - HRD Manager publish/approve ได้ - IT Admin จัดการ Template และ Permission ได้ - ทุกการเปลี่ยนสิทธิ์มี audit log - มีเอกสารสรุปใน `docs` - ระบบเดิมไม่พังระหว่าง migration --- ## Important Notes - ห้ามใช้ Role เป็น source of truth - ห้าม hard-code role ใน feature ใหม่ - ห้ามตรวจสิทธิ์เฉพาะ UI - Server/API ต้องตรวจ permission เสมอ - Permission Template คือชุดสิทธิ์ต้นแบบ ไม่ใช่ตัวตัดสินสิทธิ์ - User Permission Override ต้องมีผลต่อ effective permissions - Multi-Organization ต้องไม่ทำให้ข้อมูลข้ามองค์กรรั่ว - ต้อง reuse pattern เดิมของโปรเจกต์ก่อนสร้างของใหม่ - ต้องทำ migration แบบปลอดภัยและมี compatibility layer