1298 lines
34 KiB
Markdown
1298 lines
34 KiB
Markdown
# TMS Phase 1 Architecture Remediation
|
||
## Complete Coding Prompt for Closing All Phase 1 Findings
|
||
|
||
---
|
||
|
||
# 1. บทบาทของ AI/Codex
|
||
|
||
คุณทำหน้าที่เป็น:
|
||
|
||
- Senior Software Architect
|
||
- Senior Full-Stack Engineer
|
||
- Database Migration Engineer
|
||
- Security Reviewer
|
||
- Code Reviewer
|
||
|
||
สำหรับระบบ TMS ที่พัฒนาด้วย:
|
||
|
||
- Next.js 16 App Router
|
||
- TypeScript
|
||
- Auth.js
|
||
- Drizzle ORM
|
||
- PostgreSQL
|
||
- TanStack Query
|
||
- shadcn/ui
|
||
- Tailwind CSS
|
||
|
||
ภารกิจนี้เป็น **Coding Phase สำหรับแก้ไขและปิดทุกประเด็นที่พบจาก Phase 1 — Architecture Audit**
|
||
|
||
ต้องแก้ไข Source Code, Database Schema, Migration, Tests, Scripts และเอกสารที่เกี่ยวข้องให้เสร็จสมบูรณ์ โดยห้ามแก้เฉพาะเอกสารเพื่อทำให้ดูเหมือนปิด Finding
|
||
|
||
---
|
||
|
||
# 2. เป้าหมายหลัก
|
||
|
||
เมื่อดำเนินการเสร็จ ระบบต้องมีคุณสมบัติดังนี้:
|
||
|
||
1. `users` และ `employees` มีขอบเขตความรับผิดชอบชัดเจน
|
||
2. ไม่มี Dual Source of Truth ที่คลุมเครือ
|
||
3. ความสัมพันธ์ระหว่างผู้ใช้งานระบบกับพนักงานมี Constraint และ Contract ชัดเจน
|
||
4. Production Dashboard ไม่มี Demo, Template, Placeholder หรือ Dead Route ปะปน
|
||
5. CTA และ Internal Link ทุกจุดมี Route Contract ที่ถูกต้อง
|
||
6. Page Authorization ใช้มาตรฐานเดียวกัน
|
||
7. API Authentication และ Authorization มี Boundary ที่ชัดเจน
|
||
8. Architecture Document ตรงกับ Implementation จริง
|
||
9. มี Automated Check เพื่อป้องกัน Architectural Drift
|
||
10. ระบบผ่าน Lint, Type Check, Test, Migration Verification และ Production Build
|
||
|
||
---
|
||
|
||
# 3. นิยาม Entity ที่ต้องยึดถือ
|
||
|
||
## 3.1 `users`
|
||
|
||
`users` หมายถึง **ผู้ใช้งานระบบ**
|
||
|
||
ใช้สำหรับ:
|
||
|
||
- Authentication
|
||
- Login identity
|
||
- Username / Login email
|
||
- Account status
|
||
- Session
|
||
- System role
|
||
- Organization membership
|
||
- Permission
|
||
- Permission template
|
||
- User-specific permission
|
||
- Audit actor
|
||
- ผู้สร้างรายการ
|
||
- ผู้แก้ไขรายการ
|
||
- ผู้อนุมัติรายการ
|
||
- ผู้เผยแพร่รายการ
|
||
- Notification recipient
|
||
|
||
## 3.2 `employees`
|
||
|
||
`employees` หมายถึง **พนักงานขององค์กร**
|
||
|
||
ใช้สำหรับ:
|
||
|
||
- รหัสพนักงาน
|
||
- ชื่อ–นามสกุลตาม HR Master
|
||
- บริษัท
|
||
- ฝ่าย
|
||
- แผนก
|
||
- ตำแหน่ง
|
||
- สถานะการเป็นพนักงาน
|
||
- วันที่เริ่มงาน
|
||
- Employee profile
|
||
- เจ้าของประวัติการอบรม
|
||
- Training target
|
||
- Training matrix assignment
|
||
- Compliance
|
||
- รายงานเชิงบุคลากร
|
||
|
||
## 3.3 หลักการสำคัญ
|
||
|
||
ห้ามสรุปว่า `users` และ `employees` ต้องรวมเป็น Entity เดียว
|
||
|
||
ต้องคงทั้งสอง Entity แต่ต้องกำหนดให้ชัดว่า:
|
||
|
||
```text
|
||
users = ผู้ใช้งานระบบ
|
||
employees = พนักงาน
|
||
```
|
||
|
||
ผู้ใช้งานระบบหนึ่งรายอาจ:
|
||
|
||
- เชื่อมกับพนักงานหนึ่งคน
|
||
- ไม่มี Employee Profile เช่น Super Admin, Service Account หรือ External Admin
|
||
|
||
พนักงานหนึ่งคนอาจ:
|
||
|
||
- มีบัญชีผู้ใช้งานหนึ่งบัญชี
|
||
- ยังไม่มีบัญชีผู้ใช้งาน
|
||
|
||
ค่าตั้งต้นที่แนะนำ:
|
||
|
||
```text
|
||
User 0..1 <-> 0..1 Employee
|
||
```
|
||
|
||
หาก Requirement จริงแตกต่างจากนี้ ต้องบันทึกใน ADR
|
||
|
||
---
|
||
|
||
# 4. เอกสารและไฟล์ที่ต้องอ่านก่อนเริ่ม
|
||
|
||
อ่านอย่างน้อย:
|
||
|
||
- `phase-1-architecture-audit.md`
|
||
- `docs/PROJECT_ARCHITECTURE.md`
|
||
- `docs/AI_DEVELOPMENT_GUIDE.md`
|
||
- `AGENTS.md`
|
||
- `src/db/schema.ts`
|
||
- `src/auth.ts`
|
||
- `src/proxy.ts`
|
||
- `src/lib/auth/session.ts`
|
||
- `src/lib/auth/page-guards.ts`
|
||
- `src/lib/auth/roles.ts`
|
||
- `src/app/dashboard/**`
|
||
- `src/app/api/**`
|
||
- `src/features/employees/**`
|
||
- `src/features/training-records/**`
|
||
- `src/features/reports/**`
|
||
- `src/features/overview/**`
|
||
- `src/features/training-policy/**`
|
||
- `src/features/training-matrix/**`
|
||
- Permission-related modules
|
||
- Migration files
|
||
- Seed files
|
||
- Test files
|
||
- Navigation config
|
||
- Route config
|
||
|
||
ห้ามเริ่มแก้ Schema ก่อนตรวจ Dependency ครบ
|
||
|
||
---
|
||
|
||
# 5. Findings ที่ต้องปิด
|
||
|
||
ต้องแก้ทุกประเด็นต่อไปนี้:
|
||
|
||
## Finding 1 — User/Employee Responsibility ไม่ชัดเจน
|
||
|
||
ปัจจุบันมีความเสี่ยงเกิดความสับสนระหว่าง:
|
||
|
||
- Runtime user identity
|
||
- Employee master data
|
||
- Employee linkage
|
||
- Training data ownership
|
||
- Audit actor
|
||
- Permission identity
|
||
|
||
ต้องปรับ Architecture ให้ชัดเจนโดยไม่ลบ `employees` ออกจาก Runtime Domain
|
||
|
||
## Finding 2 — Production Dashboard มี Demo/Template/Legacy Route
|
||
|
||
มี Route ที่ไม่ใช่ Production Business Feature อยู่ใต้ `/dashboard`
|
||
|
||
## Finding 3 — Page Authorization Guard ไม่เป็นมาตรฐานเดียวกัน
|
||
|
||
บางหน้าใช้ Shared Guard
|
||
บางหน้าใช้ `auth()` + role helper
|
||
บางหน้าพึ่ง Layout หรือ Proxy
|
||
|
||
## Finding 4 — Training Matrix มี Broken Route Contract
|
||
|
||
CTA ไปยัง:
|
||
|
||
```text
|
||
/dashboard/training-matrix/new
|
||
```
|
||
|
||
แต่ไม่มี Route ที่รองรับ
|
||
|
||
## Finding 5 — API Perimeter Strategy ไม่ชัดเจน
|
||
|
||
`proxy.ts` ป้องกัน API บางกลุ่ม แต่ API อื่นพึ่ง Handler Guard ทำให้ Boundary ไม่สม่ำเสมอ
|
||
|
||
---
|
||
|
||
# 6. ลำดับการดำเนินงาน
|
||
|
||
ทำตามลำดับนี้:
|
||
|
||
1. Architecture Inventory
|
||
2. User–Employee Data Ownership Decision
|
||
3. User–Employee Relationship Remediation
|
||
4. Runtime Query Remediation
|
||
5. Production Route Cleanup
|
||
6. Broken Route Contract Fix
|
||
7. Page Guard Standardization
|
||
8. API Guard and Perimeter Standardization
|
||
9. Architecture Enforcement
|
||
10. Test and Verification
|
||
11. Final Remediation Report
|
||
|
||
---
|
||
|
||
# 7. Workstream A — Architecture Inventory
|
||
|
||
ก่อนแก้ไข ให้ตรวจ Dependency ทั้งหมดของ `users` และ `employees`
|
||
|
||
## ตรวจสอบ
|
||
|
||
- ตารางที่ FK ไป `users.id`
|
||
- ตารางที่ FK ไป `employees.id`
|
||
- ตารางที่เก็บ `employeeId`
|
||
- ตาราง `user_employee_maps`
|
||
- Column `users.employeeId`
|
||
- Session fields
|
||
- Auth linking flow
|
||
- Registration flow
|
||
- Import employee flow
|
||
- Employee directory
|
||
- Training records
|
||
- Training targets
|
||
- Training matrix
|
||
- Reports
|
||
- Overview
|
||
- Audit log
|
||
- Notifications
|
||
- Approval workflow
|
||
- Permission resolution
|
||
- Organization membership
|
||
|
||
## สร้างเอกสาร
|
||
|
||
```text
|
||
docs/architecture/user-employee-domain-inventory.md
|
||
```
|
||
|
||
รูปแบบ:
|
||
|
||
| Domain | User Usage | Employee Usage | Current FK/Join | Data Owner | Issue | Required Change |
|
||
|---|---|---|---|---|---|---|
|
||
|
||
## ต้องระบุ
|
||
|
||
- ข้อมูลใดเป็น User Data
|
||
- ข้อมูลใดเป็น Employee Data
|
||
- ข้อมูลใดถูกเก็บซ้ำ
|
||
- ข้อมูลใดไม่มี Source of Truth
|
||
- Query ใด Join ผิด Domain
|
||
- Actor field ใดใช้ Employee แทน User
|
||
- Owner field ใดใช้ User แทน Employee
|
||
|
||
ห้ามเริ่ม Migration ก่อน Inventory เสร็จ
|
||
|
||
---
|
||
|
||
# 8. Workstream B — User–Employee Data Ownership
|
||
|
||
กำหนด Data Ownership อย่างเป็นทางการ
|
||
|
||
## Source of Truth ที่แนะนำ
|
||
|
||
| Data | Source of Truth |
|
||
|---|---|
|
||
| Login email | `users` |
|
||
| Username | `users` |
|
||
| Account status | `users` |
|
||
| System role | `users` |
|
||
| Permission | Permission/Membership tables |
|
||
| Audit actor | `users` |
|
||
| Created by | `users` |
|
||
| Approved by | `users` |
|
||
| Published by | `users` |
|
||
| Employee code | `employees` |
|
||
| Employee name | `employees` |
|
||
| Company | `employees` |
|
||
| Department | `employees` |
|
||
| Position | `employees` |
|
||
| Employment status | `employees` |
|
||
| Training record owner | `employees` |
|
||
| Training target | `employees` |
|
||
| Training compliance | `employees` |
|
||
| Training matrix assignment | `employees` |
|
||
|
||
## สร้าง ADR
|
||
|
||
สร้าง:
|
||
|
||
```text
|
||
docs/adr/ADR-XXX-user-employee-domain-boundary.md
|
||
```
|
||
|
||
ADR ต้องมี:
|
||
|
||
- Context
|
||
- Problem
|
||
- Definitions
|
||
- Data ownership
|
||
- Relationship cardinality
|
||
- Linking strategy
|
||
- Mapping strategy
|
||
- Non-employee user handling
|
||
- Employee without user handling
|
||
- Migration strategy
|
||
- Compatibility strategy
|
||
- Consequences
|
||
- Rollback strategy
|
||
|
||
ใช้หมายเลขต่อจาก ADR ล่าสุด
|
||
|
||
---
|
||
|
||
# 9. Workstream C — User–Employee Relationship Remediation
|
||
|
||
## เป้าหมาย
|
||
|
||
ทำให้ความสัมพันธ์ระหว่าง `users` และ `employees`:
|
||
|
||
- ชัดเจน
|
||
- ไม่ซ้ำซ้อน
|
||
- ตรวจสอบได้
|
||
- ปลอดภัยต่อข้อมูลเดิม
|
||
- รองรับ User ที่ไม่ใช่ Employee
|
||
- รองรับ Employee ที่ยังไม่มี User
|
||
|
||
## ตรวจโครงสร้างปัจจุบัน
|
||
|
||
ตรวจว่าระบบมีทั้ง:
|
||
|
||
```text
|
||
users.employeeId
|
||
user_employee_maps
|
||
```
|
||
|
||
หรือไม่
|
||
|
||
หากมีทั้งสองแบบ ต้องตัดสินใจว่าจะใช้แบบใดเป็น Canonical Link
|
||
|
||
## แนวทางที่แนะนำ
|
||
|
||
หาก Requirement เป็น 1:1:
|
||
|
||
```text
|
||
users.employee_id nullable
|
||
users.employee_id unique
|
||
users.employee_id -> employees.id
|
||
```
|
||
|
||
ข้อกำหนด:
|
||
|
||
- Nullable
|
||
- Unique
|
||
- Foreign Key
|
||
- รองรับ User ที่ไม่มี Employee
|
||
- ป้องกัน Employee ถูกผูกหลาย User
|
||
- พิจารณา `ON DELETE SET NULL` หรือ `RESTRICT`
|
||
|
||
## `user_employee_maps`
|
||
|
||
คงไว้ได้เฉพาะเมื่อมี Requirement เช่น:
|
||
|
||
- User หนึ่งรายดูแลหลาย Employee
|
||
- Employee หนึ่งรายมีหลาย Account
|
||
- Effective date
|
||
- Historical relationship
|
||
- Multi-source identity linking
|
||
- Multi-tenant mapping
|
||
|
||
หากไม่มี Requirement เหล่านี้:
|
||
|
||
- วางแผนเลิกใช้
|
||
- Backfill ไป Canonical Link
|
||
- ปิด Write Path เดิม
|
||
- ลบหลัง Verification
|
||
|
||
## Migration Strategy
|
||
|
||
ใช้:
|
||
|
||
```text
|
||
Expand -> Backfill -> Verify -> Switch -> Contract
|
||
```
|
||
|
||
### Expand
|
||
|
||
- เพิ่ม FK/Constraint ใหม่
|
||
- ยังไม่ลบของเดิม
|
||
- เพิ่ม Index
|
||
- เพิ่ม Compatibility Read ชั่วคราว
|
||
|
||
### Backfill
|
||
|
||
- เชื่อม User–Employee
|
||
- ตรวจ duplicate employee code
|
||
- ตรวจ duplicate mapping
|
||
- ตรวจ orphan
|
||
- ตรวจ conflict
|
||
|
||
### Verify
|
||
|
||
สร้าง Report:
|
||
|
||
- User ไม่มี Employee
|
||
- Employee ไม่มี User
|
||
- Employee ถูกผูกหลาย User
|
||
- User ถูกผูกหลาย Employee
|
||
- Mapping ไม่ตรงกับ `users.employeeId`
|
||
- Duplicate employee code
|
||
|
||
### Switch
|
||
|
||
- เปลี่ยน Runtime Read/Write ไป Canonical Link
|
||
- ปิด Legacy Write Path
|
||
- ปรับ Auth Flow
|
||
|
||
### Contract
|
||
|
||
- ลบ Mapping หรือ Column ที่ไม่ใช้
|
||
- ลบ Compatibility Code
|
||
- ลบ Index/Constraint เก่า
|
||
|
||
ห้าม Contract จนกว่า Test และ Verification ผ่าน
|
||
|
||
---
|
||
|
||
# 10. Workstream D — Auth และ Session Remediation
|
||
|
||
ตรวจ:
|
||
|
||
- `src/auth.ts`
|
||
- Session callback
|
||
- JWT callback
|
||
- User linking
|
||
- Employee linking
|
||
- Registration
|
||
- Login
|
||
- Organization resolution
|
||
- Permission resolution
|
||
|
||
## ข้อกำหนด
|
||
|
||
- Auth ใช้ `users` เป็น Identity
|
||
- Employee linking เป็น Optional
|
||
- Super Admin ไม่จำเป็นต้องมี Employee
|
||
- Service Account ไม่จำเป็นต้องมี Employee
|
||
- Employee User ต้อง Resolve Employee ได้อย่างถูกต้อง
|
||
- Linking ต้อง Idempotent
|
||
- ห้ามสร้าง duplicate mapping
|
||
- Multi-table write ต้องใช้ Transaction
|
||
- Login ไม่ควรทำ Heavy Sync ทุกครั้งหากไม่จำเป็น
|
||
- Session เก็บเฉพาะ ID และข้อมูลที่จำเป็น
|
||
- Employee Master Data ไม่ควรถูก Copy เข้า Session มากเกินไป
|
||
- Permission ต้อง Resolve จาก User/Membership
|
||
- Training Ownership ต้อง Resolve จาก Employee
|
||
|
||
## ตรวจ `syncUserEmployeeLink(...)`
|
||
|
||
ต้อง:
|
||
|
||
- ป้องกัน duplicate
|
||
- ป้องกัน race condition
|
||
- ตรวจ unique constraint
|
||
- มี error handling
|
||
- มี structured log
|
||
- ไม่มี sensitive data leak
|
||
- ไม่ทำให้ Login สร้างข้อมูลครึ่งหนึ่ง
|
||
|
||
---
|
||
|
||
# 11. Workstream E — Runtime Query Remediation
|
||
|
||
ตรวจทุก Domain ว่าใช้ Entity ถูกต้อง
|
||
|
||
## Training Records
|
||
|
||
ควรแยก:
|
||
|
||
```text
|
||
training_records.employee_id
|
||
training_records.created_by_user_id
|
||
training_records.updated_by_user_id
|
||
training_records.approved_by_user_id
|
||
```
|
||
|
||
หากชื่อ Column จริงต่างจากนี้ ให้คง Naming ตามมาตรฐานโครงการ แต่ Semantic ต้องชัด
|
||
|
||
## Reports
|
||
|
||
- Report ด้านบุคลากรอ้างอิง `employees`
|
||
- Actor / Operator อ้างอิง `users`
|
||
- Permission scope อ้างอิง User/Membership
|
||
- Employee filter อ้างอิง Employee Profile
|
||
|
||
## Overview Dashboard
|
||
|
||
- จำนวนพนักงานใช้ `employees`
|
||
- จำนวนผู้ใช้งานใช้ `users`
|
||
- ห้ามรวมสอง Metric โดยไม่ระบุความหมาย
|
||
|
||
## Training Policy / Target
|
||
|
||
- Target เป็นของ Employee
|
||
- ผู้สร้าง/แก้ไข Policy เป็น User
|
||
|
||
## Training Matrix
|
||
|
||
- Assignment เป็นของ Employee/Department/Position ตาม Business Rule
|
||
- ผู้สร้าง Rule เป็น User
|
||
|
||
## Audit Log
|
||
|
||
- Actor ต้องเป็น `users.id`
|
||
- Target อาจเป็น User, Employee หรือ Business Entity
|
||
- ต้องมี `targetType`/`entityType` ตามมาตรฐานถ้าระบบรองรับ
|
||
|
||
## Notifications
|
||
|
||
- Recipient เป็น User
|
||
- Employee ที่ไม่มี User อาจไม่มี In-App Notification
|
||
- Email Notification อาจ Resolve จาก Employee Contact ตาม Requirement แต่ต้องแยกจาก User Identity
|
||
|
||
---
|
||
|
||
# 12. Workstream F — Data Reconciliation Script
|
||
|
||
สร้าง:
|
||
|
||
```text
|
||
scripts/audit-user-employee-links.ts
|
||
```
|
||
|
||
ตรวจ:
|
||
|
||
- duplicate employee code
|
||
- user ไม่มี employee
|
||
- employee ไม่มี user
|
||
- duplicate link
|
||
- conflicting link
|
||
- orphan FK
|
||
- invalid mapping
|
||
- inactive employee linked to active user
|
||
- inactive user linked to active employee
|
||
- training record ไม่มี employee
|
||
- actor field อ้างอิง employee แทน user
|
||
- employee owner field อ้างอิง user แทน employee
|
||
|
||
เพิ่ม Command:
|
||
|
||
```json
|
||
{
|
||
"scripts": {
|
||
"audit:user-employee-links": "..."
|
||
}
|
||
}
|
||
```
|
||
|
||
Script ต้อง Default เป็น Read-only
|
||
|
||
หากมี Safe Fix:
|
||
|
||
```bash
|
||
pnpm audit:user-employee-links --fix-safe
|
||
```
|
||
|
||
ต้อง:
|
||
|
||
- แก้เฉพาะ deterministic case
|
||
- สร้าง log
|
||
- แสดง Before/After
|
||
- ห้าม merge record อัตโนมัติ
|
||
- ห้ามลบข้อมูลอัตโนมัติ
|
||
|
||
---
|
||
|
||
# 13. Workstream G — Production Route Cleanup
|
||
|
||
ตรวจ Route ใต้:
|
||
|
||
```text
|
||
src/app/dashboard
|
||
```
|
||
|
||
จัดประเภท:
|
||
|
||
- Production Business Module
|
||
- Internal Admin Module
|
||
- Demo
|
||
- Template
|
||
- Playground
|
||
- Deprecated
|
||
- Placeholder
|
||
- Unused
|
||
|
||
## Route ที่ต้องตรวจ
|
||
|
||
- `/dashboard/billing`
|
||
- `/dashboard/chat`
|
||
- `/dashboard/forms`
|
||
- `/dashboard/forms/advanced`
|
||
- `/dashboard/forms/basic`
|
||
- `/dashboard/forms/multi-step`
|
||
- `/dashboard/forms/sheet-form`
|
||
- `/dashboard/react-query`
|
||
- `/dashboard/kanban`
|
||
- `/dashboard/product`
|
||
- `/dashboard/workspaces`
|
||
- `/dashboard/elements/icons`
|
||
- `/dashboard/exclusive`
|
||
|
||
## แนวทาง
|
||
|
||
เลือกหนึ่งอย่าง:
|
||
|
||
1. ลบ Route
|
||
2. ย้ายไป Playground
|
||
3. Development-only
|
||
4. Feature Flag
|
||
5. Redirect
|
||
6. คงไว้เมื่อยืนยันว่าเป็น Business Feature จริง
|
||
|
||
## กฎ
|
||
|
||
- Demo Route ห้ามอยู่ Production Navigation
|
||
- Placeholder Route ห้ามเปิดให้ผู้ใช้ทั่วไป
|
||
- Route ที่ไม่รองรับต้องไม่อยู่ Sitemap
|
||
- Route ที่ถูกลบต้องลบ Import ที่ไม่ใช้
|
||
- ตรวจ Shared Component ก่อนลบ Feature Folder
|
||
- ห้ามลบ Business Feature ที่ใช้จริง
|
||
|
||
## สร้าง Route Registry
|
||
|
||
```text
|
||
docs/architecture/production-route-registry.md
|
||
```
|
||
|
||
รูปแบบ:
|
||
|
||
| Route | Module | Classification | Permission | Production Status | Action |
|
||
|---|---|---|---|---|---|
|
||
|
||
---
|
||
|
||
# 14. Workstream H — Training Matrix Route Contract
|
||
|
||
Finding:
|
||
|
||
```text
|
||
/dashboard/training-matrix
|
||
```
|
||
|
||
มี CTA ไป:
|
||
|
||
```text
|
||
/dashboard/training-matrix/new
|
||
```
|
||
|
||
แต่ไม่มี Route
|
||
|
||
## ให้ตรวจ Business Intent ก่อน
|
||
|
||
เลือก:
|
||
|
||
### Option A — Create Page
|
||
|
||
สร้าง:
|
||
|
||
```text
|
||
src/app/dashboard/training-matrix/new/page.tsx
|
||
```
|
||
|
||
ต้องมี:
|
||
|
||
- Shared Page Guard
|
||
- Permission Check
|
||
- Organization Scope
|
||
- Form
|
||
- Validation
|
||
- Duplicate Rule Check
|
||
- Submit API
|
||
- Audit Log
|
||
- Loading
|
||
- Error Handling
|
||
- Success Redirect
|
||
- Query Invalidation
|
||
|
||
### Option B — Modal/Sheet
|
||
|
||
หาก Design เดิมตั้งใจใช้ Modal:
|
||
|
||
- เปลี่ยน CTA ไม่ให้ใช้ Broken Link
|
||
- เปิด Form จริง
|
||
- Refresh List หลังบันทึก
|
||
- API Guard ต้องครบ
|
||
- รองรับ Deep Link หาก Requirement ต้องการ
|
||
|
||
### Option C — Feature ยังไม่พร้อม
|
||
|
||
- ซ่อน CTA
|
||
- ใช้ Feature Flag
|
||
- ห้ามปล่อยให้ไป 404
|
||
|
||
## ตรวจ Route Contract ทั้งระบบ
|
||
|
||
ค้นหา:
|
||
|
||
- `Link`
|
||
- `router.push`
|
||
- `router.replace`
|
||
- `redirect`
|
||
- Breadcrumb
|
||
- Navigation config
|
||
- Action menu
|
||
- Empty state CTA
|
||
- Quick action
|
||
|
||
ทุก Internal Link ต้องมีปลายทางจริง
|
||
|
||
---
|
||
|
||
# 15. Workstream I — Page Authorization Standardization
|
||
|
||
## เป้าหมาย
|
||
|
||
ทุก Production Dashboard Page ใช้ Shared Guard Convention เดียวกัน
|
||
|
||
## ใช้หรือปรับปรุง
|
||
|
||
```text
|
||
src/lib/auth/page-guards.ts
|
||
```
|
||
|
||
ตัวอย่าง:
|
||
|
||
- `requireAuthenticatedDashboardAccess`
|
||
- `requireEmployeeDashboardAccess`
|
||
- `requireHRDDashboardAccess`
|
||
- `requireITAdminDashboardAccess`
|
||
- `requireSuperAdminDashboardAccess`
|
||
- `requirePermissionDashboardAccess`
|
||
- `requireOrganizationDashboardAccess`
|
||
|
||
## แก้ Finding อย่างน้อยใน
|
||
|
||
- `src/app/dashboard/training-matrix/page.tsx`
|
||
- `src/app/dashboard/organizers/page.tsx`
|
||
- `src/app/dashboard/overview/page.tsx`
|
||
- `src/app/dashboard/layout.tsx`
|
||
|
||
## กฎ
|
||
|
||
- ห้ามเขียน `auth()` + `isHRD()` + `redirect()` ซ้ำ
|
||
- Page Entry ต้องอ่านแล้วรู้ Permission ที่ใช้
|
||
- Layout Guard ใช้ได้กับ Common Boundary
|
||
- Child Page ที่มี Permission เฉพาะต้องมี Guard เพิ่ม
|
||
- Proxy ไม่ใช่ Authorization Boundary
|
||
- UI Hidden ไม่ใช่ Security
|
||
- Direct URL ต้องถูกป้องกัน
|
||
- Organization Context ต้อง Validate
|
||
- Forbidden Behavior ต้องสม่ำเสมอ
|
||
|
||
## Permission-first
|
||
|
||
ลดการใช้:
|
||
|
||
- `isHRD()`
|
||
- `businessRole`
|
||
- hard-coded role checks
|
||
|
||
Role Check คงไว้ได้เฉพาะ:
|
||
|
||
- bootstrap
|
||
- Super Admin
|
||
- compatibility ที่มีเอกสาร
|
||
|
||
---
|
||
|
||
# 16. Workstream J — API Authorization และ Perimeter
|
||
|
||
## Architecture Strategy ที่ต้องใช้
|
||
|
||
แนะนำ:
|
||
|
||
```text
|
||
Proxy = Coarse Authentication / Routing Boundary
|
||
API Handler = Authoritative Authentication + Authorization Boundary
|
||
Service = Business Rule and Invariant Boundary
|
||
Database = Constraint Boundary
|
||
```
|
||
|
||
## ตรวจ API
|
||
|
||
อย่างน้อย:
|
||
|
||
- `/api/permission-templates`
|
||
- `/api/permission-audit-logs`
|
||
- `/api/user-permissions`
|
||
- `/api/permissions/catalog`
|
||
- `/api/training-records`
|
||
- `/api/reports`
|
||
- `/api/announcements`
|
||
- `/api/training-matrix`
|
||
- `/api/training-policy`
|
||
- `/api/users`
|
||
- `/api/employees`
|
||
- `/api/organizations`
|
||
|
||
## ทุก API ต้องมี
|
||
|
||
- Authentication
|
||
- Authorization
|
||
- Organization Scope
|
||
- Input Validation
|
||
- Standard Error Response
|
||
- Correct HTTP Status
|
||
- Sensitive Error Protection
|
||
- Audit Log สำหรับ Privileged Mutation
|
||
- Cross-organization Protection
|
||
- Disabled User Protection
|
||
|
||
## Proxy Strategy
|
||
|
||
เลือกหนึ่ง:
|
||
|
||
### Strategy A — Broad Matcher
|
||
|
||
ป้องกัน `/api/:path*` ยกเว้น Public Allowlist
|
||
|
||
### Strategy B — Handler-first
|
||
|
||
Proxy ป้องกันเฉพาะ Page Route
|
||
API ทุก Route ต้อง Guard ที่ Handler
|
||
|
||
หากใช้ Strategy B:
|
||
|
||
- ลบหรือปรับ `protectedApiPrefixes`
|
||
- Document ให้ชัด
|
||
- เพิ่ม Automated Check
|
||
|
||
## Public API Allowlist
|
||
|
||
ระบุ Explicit:
|
||
|
||
- Auth callback
|
||
- Health check
|
||
- Webhook
|
||
- Public invitation validation
|
||
- Public registration
|
||
- Public file ตาม Requirement
|
||
|
||
ห้ามมี Implicit Public Endpoint
|
||
|
||
---
|
||
|
||
# 17. Workstream K — Architecture Enforcement
|
||
|
||
ปรับปรุง:
|
||
|
||
- `docs/PROJECT_ARCHITECTURE.md`
|
||
- `docs/AI_DEVELOPMENT_GUIDE.md`
|
||
- `AGENTS.md`
|
||
|
||
เพิ่มกฎ:
|
||
|
||
- User vs Employee Definition
|
||
- Data Ownership
|
||
- User–Employee Relationship
|
||
- Actor vs Owner Convention
|
||
- Page Guard Convention
|
||
- API Guard Convention
|
||
- Production Route Policy
|
||
- Demo Route Policy
|
||
- Permission-first
|
||
- Route Contract
|
||
- Migration Strategy
|
||
|
||
## เพิ่ม Script
|
||
|
||
เช่น:
|
||
|
||
```text
|
||
scripts/check-architecture.ts
|
||
scripts/check-routes.ts
|
||
scripts/check-api-guards.ts
|
||
```
|
||
|
||
ตรวจ:
|
||
|
||
- Production Page ไม่มี Guard
|
||
- API Mutation ไม่มี Guard
|
||
- Demo Route อยู่ Production Navigation
|
||
- Broken Internal Link
|
||
- Raw `auth()` Pattern ใน Page
|
||
- Legacy Role Helper
|
||
- Client Component Import DB
|
||
- Direct DB Access จาก UI
|
||
- User/Employee FK ใช้ผิด Domain
|
||
|
||
เพิ่ม Scripts:
|
||
|
||
```json
|
||
{
|
||
"scripts": {
|
||
"check:architecture": "...",
|
||
"check:routes": "...",
|
||
"check:api-guards": "..."
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
# 18. Database Migration Safety
|
||
|
||
ทุก Schema Change ต้อง:
|
||
|
||
- มี Migration
|
||
- มี Index
|
||
- มี Constraint
|
||
- มี Backfill
|
||
- มี Verification
|
||
- มี Rollback หรือ Restore Plan
|
||
- ทดสอบกับฐานข้อมูลที่มีข้อมูลเดิม
|
||
- ห้าม Drop ทันที
|
||
- ห้ามแก้ Production Data แบบ Manual โดยไม่มี Script
|
||
|
||
ตรวจ:
|
||
|
||
- Foreign Key
|
||
- Unique Constraint
|
||
- Nullable
|
||
- Delete Behavior
|
||
- Update Behavior
|
||
- Duplicate
|
||
- Orphan
|
||
- Transaction Safety
|
||
|
||
---
|
||
|
||
# 19. Testing Requirements
|
||
|
||
## 19.1 User–Employee Tests
|
||
|
||
- User ที่เชื่อม Employee
|
||
- User ที่ไม่เชื่อม Employee
|
||
- Employee ที่ไม่มี User
|
||
- Super Admin ไม่มี Employee
|
||
- Duplicate Employee Link
|
||
- Duplicate Employee Code
|
||
- Inactive User
|
||
- Inactive Employee
|
||
- Idempotent Linking
|
||
- Concurrent Linking
|
||
- Orphan Prevention
|
||
- Training Owner Resolution
|
||
- Audit Actor Resolution
|
||
|
||
## 19.2 Page Authorization Tests
|
||
|
||
Role/Permission:
|
||
|
||
- Employee
|
||
- HRD Staff
|
||
- HRD Manager
|
||
- IT Admin
|
||
- Super Admin
|
||
- ไม่มี Permission
|
||
- ไม่มี Organization
|
||
- Disabled User
|
||
|
||
ทดสอบ:
|
||
|
||
- Navigation
|
||
- Direct URL
|
||
- Redirect
|
||
- Forbidden
|
||
- Organization Scope
|
||
|
||
## 19.3 API Tests
|
||
|
||
- 401
|
||
- 403
|
||
- Invalid Organization
|
||
- Invalid Payload
|
||
- Successful Request
|
||
- Audit Log Created
|
||
- Cross-organization Blocked
|
||
- Disabled User Blocked
|
||
|
||
## 19.4 Route Tests
|
||
|
||
- Training Matrix CTA
|
||
- Navigation Links
|
||
- Breadcrumbs
|
||
- Action Menus
|
||
- Empty State CTAs
|
||
- ไม่มี Demo Route ใน Production Nav
|
||
- ไม่มี Broken Internal Link
|
||
|
||
## 19.5 Migration Tests
|
||
|
||
- Empty Database
|
||
- Existing Database
|
||
- Backfill
|
||
- Duplicate Handling
|
||
- Orphan Handling
|
||
- Reconciliation Result
|
||
- Rollback/Restore Procedure
|
||
|
||
---
|
||
|
||
# 20. Commands ที่ต้องรัน
|
||
|
||
ตรวจ `package.json` และใช้คำสั่งจริงของโครงการ
|
||
|
||
ตัวอย่าง:
|
||
|
||
```bash
|
||
pnpm lint
|
||
pnpm typecheck
|
||
pnpm test
|
||
pnpm test:integration
|
||
pnpm audit:user-employee-links
|
||
pnpm check:architecture
|
||
pnpm check:routes
|
||
pnpm check:api-guards
|
||
pnpm build
|
||
```
|
||
|
||
ค้นหา Legacy Pattern:
|
||
|
||
```bash
|
||
rg -n "isHRD\(|businessRole|auth\(\)" src/app/dashboard src/app/api
|
||
rg -n "user_employee_maps|employeeId|employee_id" src
|
||
rg -n "/dashboard/training-matrix/new" src
|
||
rg -n "router\.push|router\.replace|href=" src/app src/features
|
||
```
|
||
|
||
ห้ามรายงานว่า Command ผ่านหากไม่ได้รันจริง
|
||
|
||
---
|
||
|
||
# 21. Acceptance Criteria
|
||
|
||
## User–Employee Boundary
|
||
|
||
- [ ] `users` และ `employees` มี Definition ชัดเจน
|
||
- [ ] มี ADR
|
||
- [ ] มี Data Ownership Matrix
|
||
- [ ] มี Canonical Linking Strategy
|
||
- [ ] ไม่มี Duplicate Mapping
|
||
- [ ] รองรับ Non-employee User
|
||
- [ ] รองรับ Employee Without User
|
||
- [ ] Actor ใช้ User
|
||
- [ ] Training Owner ใช้ Employee
|
||
- [ ] Runtime Query หลักใช้ Entity ถูกต้อง
|
||
- [ ] Reconciliation Script ผ่าน
|
||
|
||
## Production Routes
|
||
|
||
- [ ] Demo/Template/Placeholder ถูกลบ ย้าย หรือปิด
|
||
- [ ] Production Navigation ไม่มี Demo Route
|
||
- [ ] มี Production Route Registry
|
||
- [ ] ไม่มี Dead Route
|
||
|
||
## Route Contract
|
||
|
||
- [ ] Training Matrix CTA ใช้งานได้
|
||
- [ ] ไม่มี Internal Link ไป 404
|
||
- [ ] Breadcrumb และ Action Menu ถูกต้อง
|
||
- [ ] Route Verification ผ่าน
|
||
|
||
## Page Guard
|
||
|
||
- [ ] Production Page ทุกหน้ามี Guard ตามมาตรฐาน
|
||
- [ ] ไม่มี Custom Role Check ซ้ำซ้อน
|
||
- [ ] Direct URL ถูกป้องกัน
|
||
- [ ] Permission-first ถูกใช้
|
||
- [ ] Organization Scope ถูกตรวจ
|
||
|
||
## API Guard
|
||
|
||
- [ ] API ทุกตัวมี Handler Guard
|
||
- [ ] API Perimeter Strategy ชัดเจน
|
||
- [ ] Public API ใช้ Allowlist
|
||
- [ ] Cross-org Access ถูกป้องกัน
|
||
- [ ] Privileged Mutation มี Audit Log
|
||
|
||
## Quality Gate
|
||
|
||
- [ ] Lint ผ่าน
|
||
- [ ] Type Check ผ่าน
|
||
- [ ] Tests ผ่าน
|
||
- [ ] Build ผ่าน
|
||
- [ ] Migration Verification ผ่าน
|
||
- [ ] Architecture Check ผ่าน
|
||
- [ ] Route Check ผ่าน
|
||
- [ ] API Guard Check ผ่าน
|
||
- [ ] ไม่มี Critical/High Finding ค้าง
|
||
- [ ] Medium Finding ถูกแก้หรือมี ADR ยอมรับความเสี่ยง
|
||
|
||
---
|
||
|
||
# 22. สิ่งที่ห้ามทำ
|
||
|
||
- ห้ามรวม `users` กับ `employees` เป็นตารางเดียว
|
||
- ห้ามลบ `employees`
|
||
- ห้ามใช้ User เป็น Training Owner แทน Employee
|
||
- ห้ามใช้ Employee เป็น Audit Actor แทน User
|
||
- ห้ามมีทั้ง `users.employeeId` และ `user_employee_maps` โดยไม่มี Canonical Source
|
||
- ห้าม Drop Schema โดยไม่มี Backfill
|
||
- ห้ามซ่อนปุ่มอย่างเดียวโดยไม่ Guard API
|
||
- ห้ามใช้ Client-side Permission เป็น Security Boundary
|
||
- ห้ามเพิ่ม Hard-coded Role Check
|
||
- ห้ามเก็บ Demo Route ใน Production Nav
|
||
- ห้ามปล่อย CTA ไป 404
|
||
- ห้ามแก้เฉพาะเอกสาร
|
||
- ห้ามอ้างว่า Test ผ่านหากไม่ได้รัน
|
||
- ห้ามใช้ `any` เพื่อหลบปัญหา
|
||
- ห้าม Disable Lint แบบ Global
|
||
- ห้ามลบข้อมูลเพื่อให้ Migration ผ่าน
|
||
|
||
---
|
||
|
||
# 23. รูปแบบรายงานระหว่างทำ
|
||
|
||
หลังจบแต่ละ Workstream ให้รายงาน:
|
||
|
||
```markdown
|
||
## Workstream X — [ชื่อ]
|
||
|
||
### Root Cause
|
||
...
|
||
|
||
### Decision
|
||
...
|
||
|
||
### Files Changed
|
||
- ...
|
||
|
||
### Database Impact
|
||
...
|
||
|
||
### Compatibility Impact
|
||
...
|
||
|
||
### Tests Added / Updated
|
||
- ...
|
||
|
||
### Commands Executed
|
||
- `...` → Passed / Failed
|
||
|
||
### Remaining Risks
|
||
...
|
||
|
||
### Status
|
||
- Completed
|
||
- Partially Completed
|
||
- Blocked
|
||
```
|
||
|
||
หากพบ Critical Risk ให้รายงานทันที
|
||
|
||
---
|
||
|
||
# 24. Final Remediation Report
|
||
|
||
สร้าง:
|
||
|
||
```text
|
||
docs/reviews/phase-1-architecture-remediation-report.md
|
||
```
|
||
|
||
โครงสร้าง:
|
||
|
||
# Phase 1 Architecture Remediation Report
|
||
|
||
## Executive Summary
|
||
|
||
## Scope
|
||
|
||
## Architecture Decisions
|
||
|
||
## User and Employee Definitions
|
||
|
||
## Data Ownership Matrix
|
||
|
||
## User–Employee Relationship
|
||
|
||
## Findings Closure Matrix
|
||
|
||
| Finding | Severity | Resolution | Evidence | Status |
|
||
|---|---:|---|---|---|
|
||
|
||
## Schema and Migration Changes
|
||
|
||
## Auth and Session Changes
|
||
|
||
## Runtime Query Changes
|
||
|
||
## Production Route Cleanup
|
||
|
||
## Route Contract Fixes
|
||
|
||
## Page Guard Standardization
|
||
|
||
## API Guard and Perimeter Strategy
|
||
|
||
## Automated Checks
|
||
|
||
## Tests Executed
|
||
|
||
## Commands and Results
|
||
|
||
## Reconciliation Results
|
||
|
||
## Known Limitations
|
||
|
||
## Remaining Risks
|
||
|
||
## Rollback Plan
|
||
|
||
## Production Deployment Notes
|
||
|
||
## Final Status
|
||
|
||
Final Status ใช้ได้เพียง:
|
||
|
||
- `PASS — Phase 1 Closed`
|
||
- `CONDITIONAL PASS — Remaining Accepted Risks`
|
||
- `FAIL — Phase 1 Not Closed`
|
||
|
||
ห้ามใช้ PASS หาก:
|
||
|
||
- Build ไม่ผ่าน
|
||
- Test สำคัญไม่ผ่าน
|
||
- Migration ยังไม่ Verify
|
||
- Broken Route ยังมี
|
||
- Demo Route ยังปะปน
|
||
- Guard ยังไม่ครบ
|
||
- High Finding ยังเปิด
|
||
|
||
---
|
||
|
||
# 25. Definition of Done
|
||
|
||
งานนี้เสร็จเมื่อ:
|
||
|
||
1. ปิด Finding ทั้งหมดของ Phase 1
|
||
2. `users` และ `employees` มีขอบเขตชัดเจน
|
||
3. ความสัมพันธ์ User–Employee ปลอดภัยและตรวจสอบได้
|
||
4. Actor และ Owner ใช้ Entity ถูกต้อง
|
||
5. Production Route สะอาด
|
||
6. ไม่มี Broken CTA
|
||
7. Page Guard เป็นมาตรฐาน
|
||
8. API Boundary ชัดเจน
|
||
9. เอกสารตรงกับโค้ด
|
||
10. มี Automated Check
|
||
11. Migration ปลอดภัย
|
||
12. Lint, Type Check, Test และ Build ผ่าน
|
||
13. มี Final Remediation Report พร้อม Evidence
|
||
|
||
---
|
||
|
||
# 26. คำสั่งเริ่มต้นสำหรับ AI/Codex
|
||
|
||
เริ่มจากอ่าน `phase-1-architecture-audit.md` และเอกสาร Architecture ทั้งหมด
|
||
|
||
จากนั้นจัดทำ User–Employee Domain Inventory โดยยึดนิยาม:
|
||
|
||
```text
|
||
users = ผู้ใช้งานระบบ
|
||
employees = พนักงาน
|
||
```
|
||
|
||
ห้ามรวมสอง Entity นี้เข้าด้วยกัน
|
||
|
||
ให้กำหนด Data Ownership, Relationship Cardinality และ Canonical Linking Strategy ใน ADR ก่อนแก้ Schema
|
||
|
||
หลังจากนั้นดำเนินการตาม Workstream A–K ตามลำดับ แก้โค้ดจริง เพิ่ม Migration, Tests, Reconciliation Script, Architecture Check และเอกสารที่จำเป็น
|
||
|
||
เป้าหมายสุดท้ายคือปิดทุก Finding ของ Phase 1 อย่างมีหลักฐาน โดยไม่ทำลายข้อมูลเดิม ไม่สร้าง Dual Source of Truth ใหม่ และไม่สร้าง Compatibility Debt ถาวร
|