This commit is contained in:
2026-07-16 09:53:14 +07:00
parent 0fc112a2e8
commit 29cec708a3
1236 changed files with 212848 additions and 0 deletions

343
plans/req.md Normal file
View File

@@ -0,0 +1,343 @@
# Training System Requirements Aligned With Project Stack
## 1. เป้าหมายของระบบ
ระบบนี้เป็นเว็บแอปสำหรับจัดเก็บและติดตามประวัติการอบรมของพนักงาน รวมถึงไฟล์ใบรับรองการอบรม และการตรวจสอบความครบถ้วนตาม Training Matrix ของแต่ละหน่วยงานหรือแต่ละตำแหน่งงาน
เอกสารฉบับนี้ปรับให้สอดคล้องกับ stack และสถาปัตยกรรมของโปรเจ็กต์ปัจจุบัน โดยไม่ใช้ Google Apps Script, Google Sheets หรือ Google Drive เป็นแกนหลักของระบบ
## 2. Stack ที่ต้องใช้ตามโปรเจ็กต์นี้
- Frontend: Next.js 16 App Router + React 19 + TypeScript
- UI: Tailwind CSS v4 + shadcn/ui
- Auth: Auth.js
- Database: PostgreSQL + Drizzle ORM
- Data fetching: TanStack React Query
- URL state: nuqs
- Forms: TanStack Form + Zod ผ่าน `useAppForm`
- API boundary: Next.js Route Handlers ภายใต้ `src/app/api/**`
- Icons: ใช้ผ่าน `@/components/icons` เท่านั้น
## 3. แนวทางสถาปัตยกรรมที่ต้องยึด
- ใช้ feature-based structure ภายใต้ `src/features/<feature>/`
- ใช้ data layer pattern ของโปรเจ็กต์:
- `types.ts`
- `service.ts`
- `queries.ts`
- `mutations.ts` เมื่อมี create/update/delete
- ฝั่ง client ต้องเรียกข้อมูลผ่าน `service.ts`
- `service.ts` ต้องเรียก Route Handlers ด้วย `apiClient`
- Route Handlers ต้องเป็น boundary หลักสำหรับ auth, authorization, validation ขั้นต้น และ database access
- หน้า dashboard ต้องใช้ `PageContainer` สำหรับ page header
- table/listing ที่มี filter, search, sort, pagination ต้องใช้ React Query + nuqs ตาม pattern ของหน้า `products` และ `users`
- form ต้องใช้ `useAppForm` และ field wrappers ของโปรเจ็กต์
## 4. Domain Model ที่ต้องใช้ในระบบ
ระบบนี้ควรใช้คำศัพท์โดเมนให้ชัดและสอดคล้องกับโครงสร้าง auth ปัจจุบัน
- `user`: ผู้ใช้งานที่ล็อกอินเข้าระบบ
- `organization`: หน่วยงานเจ้าของข้อมูล หรือ tenant ของระบบ
- `membership`: ความสัมพันธ์ระหว่าง user กับ organization พร้อม role
- `employee`: ข้อมูลพนักงานที่ถูกติดตามประวัติการอบรม
- `course`: หลักสูตรอบรมกลาง
- `training_record`: รายการประวัติการอบรมของพนักงานแต่ละครั้ง
- `certificate`: ข้อมูลไฟล์ใบรับรองที่ผูกกับ training record
- `training_matrix`: ข้อกำหนดว่าตำแหน่งหรือแผนกใดต้องผ่านหลักสูตรอะไร
- `department`: หน่วยงานภายในองค์กร
- `position`: ตำแหน่งงาน
หมายเหตุ:
- ถ้าผู้ใช้ระบบกับพนักงานเป็นคนละแนวคิด ต้องแยก `user` ออกจาก `employee`
- ข้อมูลทั้งหมดควรถูกผูกกับ `organizationId` เพื่อรองรับ multi-tenant
## 5. ขอบเขตข้อมูลหลักใน PostgreSQL
ตารางหลักที่ควรมีในระบบนี้:
- `users`
- ข้อมูลบัญชีผู้ใช้งานสำหรับ Auth.js
- `organizations`
- ข้อมูลองค์กรหรือ workspace
- `memberships`
- บทบาทของผู้ใช้งานในแต่ละ organization
- `employees`
- รหัสพนักงาน, ชื่อ, แผนก, ตำแหน่ง, บริษัท, สถานะ
- `departments`
- หน่วยงานภายใน organization
- `positions`
- ตำแหน่งงานภายใน organization
- `courses`
- ชื่อหลักสูตร, หมวดหมู่, ผู้จัดอบรม, จำนวนชั่วโมง, อายุใบรับรอง, บังคับหรือไม่
- `training_records`
- employee, course, วันที่อบรม, รูปแบบการอบรม, ชั่วโมง, หมายเหตุ, สถานะอนุมัติ
- `certificates`
- ชื่อไฟล์, path หรือ storage key, mime type, uploadedAt
- `training_matrices`
- mapping ระหว่าง department หรือ position กับ course ที่จำเป็น
แนวทางสำคัญ:
- ทุกตารางเชิงธุรกิจควรมี `organizationId`
- ใช้ foreign keys ชัดเจนระหว่าง employee, course, training_record, certificate
- เก็บ file metadata ใน database และเก็บไฟล์จริงใน app-owned storage
## 6. แนวทางจัดเก็บไฟล์ใบรับรอง
ไม่ใช้ Google Drive เป็น storage หลักของระบบนี้
รอบแรกของระบบควรใช้แนวทางใดแนวทางหนึ่ง:
- ทางเลือกแนะนำสำหรับโปรเจ็กต์นี้:
- เก็บ metadata ใน PostgreSQL
- เก็บไฟล์จริงผ่าน local uploads หรือ object storage ที่ต่อเพิ่มภายหลัง
ข้อกำหนดเชิงระบบ:
- certificate ต้องผูกกับ `training_record`
- ต้องสามารถเปิดดูไฟล์ย้อนหลังได้
- ต้องรองรับไฟล์อย่างน้อย `pdf`, `jpg`, `jpeg`, `png`
- ต้องมี field สำหรับ `fileName`, `fileType`, `fileSize`, `storageKey`, `uploadedAt`
## 7. บทบาทผู้ใช้งาน
ระบบต้องรองรับ role อย่างน้อย:
- `member`
- ดู dashboard ของตัวเอง
- เพิ่มและแก้ไขประวัติการอบรมของตัวเอง
- อัปโหลดใบรับรองของตัวเอง
- ดูสถานะการอนุมัติ
- `admin`
- จัดการ employee
- จัดการ course
- ตรวจสอบและอนุมัติ training record
- จัดการ training matrix
- ดูรายงานภาพรวมของ organization
- `owner`
- สิทธิ์ระดับสูงสุดใน organization
- จัดการสมาชิกและค่ากำหนดหลักของ organization
Authorization ต้องตรวจที่ server-side ผ่าน session + membership ไม่ใช่ตรวจเฉพาะ client
## 8. ฟีเจอร์หลักสำหรับผู้ใช้งานทั่วไป
### 8.1 User Dashboard
ผู้ใช้งานต้องเห็น dashboard ส่วนตัวที่ประกอบด้วย:
- จำนวนหลักสูตรที่เคยอบรมทั้งหมด
- จำนวนชั่วโมงอบรมสะสม
- จำนวนใบรับรองที่บันทึกแล้ว
- จำนวนหลักสูตรที่ยังขาดตาม training matrix
- กราฟสรุปการอบรมรายเดือนหรือรายปี
แนวทาง implementation:
- ใช้ Recharts สำหรับกราฟ
- ใช้ server prefetch + `HydrationBoundary` + `useSuspenseQuery`
### 8.2 บันทึกการอบรม
ผู้ใช้งานต้องสามารถเพิ่มรายการอบรมได้ โดยข้อมูลหลักประกอบด้วย:
- employee หรือข้อมูลผู้เข้าอบรม
- course
- training date
- training type: `online | onsite | internal | external`
- training hours
- organizer
- note
- certificate file
- approval status
แนวทาง implementation:
- ใช้ TanStack Form + Zod
- submit ผ่าน mutation ไปยัง Route Handler
- หลังบันทึกต้อง invalidate query ที่เกี่ยวข้อง
### 8.3 รายการอบรมของฉัน
ผู้ใช้งานต้องสามารถ:
- ค้นหาตามชื่อหลักสูตร
- กรองตามปี
- กรองตามหมวดหมู่
- กรองตามสถานะ
- เปิดดูรายละเอียด
- เปิดดูไฟล์ใบรับรอง
- แก้ไขรายการของตัวเอง
- ลบรายการที่ยังไม่ถูกอนุมัติ หรือเป็นไปตาม policy ที่กำหนด
แนวทาง implementation:
- ใช้ Data Table pattern เดียวกับ `products` หรือ `users`
- ใช้ React Query + nuqs
## 9. ฟีเจอร์หลักสำหรับ Admin
### 9.1 Admin Dashboard
Admin ต้องเห็น dashboard ภาพรวมของ organization:
- จำนวนพนักงาน
- จำนวนชั่วโมงอบรมรวม
- เปอร์เซ็นต์ความครบถ้วนตาม training matrix
- จำนวนรายการที่รออนุมัติ
- สถิติแยกตามแผนก หมวดหมู่ และช่วงเวลา
### 9.2 จัดการ Employee
Admin ต้องสามารถ:
- เพิ่ม employee
- แก้ไข employee
- ปิดการใช้งาน employee
- กำหนดแผนก
- กำหนดตำแหน่ง
### 9.3 จัดการ Course
Admin ต้องสามารถ:
- เพิ่ม course
- แก้ไข course
- ลบ course
- กำหนด category
- กำหนด standard training hours
- กำหนด certificate validity
- ระบุว่าเป็น required course หรือไม่
### 9.4 ตรวจสอบและอนุมัติ Training Record
Admin ต้องสามารถ:
- เปิดดูไฟล์ใบรับรอง
- ตรวจสอบรายละเอียดการอบรม
- approve
- reject
- request changes
- ใส่หมายเหตุประกอบการตรวจสอบ
สถานะที่ควรใช้:
- `pending`
- `approved`
- `rejected`
- `needs_revision`
### 9.5 จัดการ Training Matrix
Admin ต้องสามารถ:
- กำหนดหลักสูตรบังคับตาม department
- กำหนดหลักสูตรบังคับตาม position
- กำหนดหลักสูตรเฉพาะรายบุคคลในอนาคตได้
- กำหนด minimum required hours เมื่อจำเป็น
- ดูสถานะครบหรือไม่ครบของแต่ละ employee
## 10. รายงานที่ระบบควรมี
อย่างน้อยควรมีรายงานต่อไปนี้:
- ประวัติการอบรมรายบุคคล
- การอบรมแยกตามแผนก
- ชั่วโมงอบรมสะสม
- หลักสูตรที่ยังขาดตาม matrix
- ใบรับรองใกล้หมดอายุ
- สรุป training matrix ของ organization
รูปแบบการแสดงผล:
- แสดงบนหน้า dashboard/table
- รองรับ export ใน phase ถัดไป
## 11. แนวทาง UI/UX ที่ต้องสอดคล้องกับโปรเจ็กต์
- ใช้ shadcn/ui และ component patterns ที่มีอยู่แล้ว
- ใช้ `PageContainer` สำหรับ page title, description, action
- ใช้ `@/components/icons` แทนการ import icon ตรงจาก package ภายนอก
- ใช้ Card, Table, Dialog, Sheet, Tabs ตามแนวทางเดิมของโปรเจ็กต์
- รองรับ desktop และ mobile
- ไม่ใช้ SweetAlert2 หรือระบบ popup ภายนอกเป็นค่าเริ่มต้น
- ใช้ toast/alert/dialog ที่มีในโปรเจ็กต์แทน
## 12. Visual Direction
โทนสีจาก requirement เดิมสามารถตีความเป็น theme ของระบบได้ แต่ต้อง implement ผ่าน theme/token ของโปรเจ็กต์นี้ ไม่ใช่เขียนเป็นระบบ CSS แยกใหม่
สีที่ต้องการ:
- เขียวเข้ม: `#336b4a`
- เทา: `#808285`
- ส้ม: `#e26631`
- ม่วงเข้ม: `#413b60`
แนวทางใช้งาน:
- primary actions: เขียวเข้ม
- warning/highlight states: ส้ม
- supporting accents/charts: ม่วงเข้ม
- muted text/borders: เทา
ถ้าต้องทำ theme จริง ให้เพิ่มผ่านระบบ theme ของโปรเจ็กต์ ไม่ทำแยกนอก `src/styles/themes` และ `theme.config.ts`
## 13. แนวทางแบ่ง feature ในรีโปนี้
ฟีเจอร์ที่ควรสร้างใน `src/features/`:
- `employees`
- `courses`
- `training-records`
- `certificates`
- `training-matrix`
- `reports`
แต่ละ feature ควรมี:
- `api/types.ts`
- `api/service.ts`
- `api/queries.ts`
- `api/mutations.ts` เมื่อมี mutation
- `components/`
- `schemas/`
- `constants/` เมื่อจำเป็น
และมี route ใต้ `src/app/dashboard/<feature>/page.tsx`
## 14. ลำดับการพัฒนาที่แนะนำ
เพื่อให้เข้ากับโครงสร้างของโปรเจ็กต์ ควรพัฒนาเป็นลำดับดังนี้:
1. Auth + organization + membership foundation
2. Employee management
3. Course management
4. Training record CRUD + certificate upload metadata
5. Training matrix
6. Dashboard summaries and reports
## 15. สิ่งที่ไม่ควรใช้ใน requirement ฉบับนี้
เพื่อให้ตรงกับโปรเจ็กต์นี้ ไม่ควรออกแบบระบบโดยอิงสิ่งต่อไปนี้เป็นแกนหลัก:
- Google Apps Script
- Google Sheets เป็น database หลัก
- Google Drive เป็น storage หลัก
- HTML/CSS/JavaScript แบบแยก standalone app
- SweetAlert2 เป็น UI feedback หลัก
- FontAwesome เป็น icon source หลัก
## 16. สรุป
ระบบ Training System ฉบับนี้ต้องถูกออกแบบให้เป็น multi-tenant web application บน stack ของโปรเจ็กต์ปัจจุบัน โดยใช้:
- Next.js App Router
- Auth.js
- PostgreSQL + Drizzle
- React Query + nuqs
- TanStack Form + Zod
- shadcn/ui + Tailwind CSS
และต้องจัดวางฟีเจอร์ตาม feature architecture ของรีโป เพื่อให้สามารถพัฒนาต่อจากฐานโค้ดนี้ได้จริง