123 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # DMS Backend (ESM)
 | |
| 
 | |
| - Node 20+, ESM
 | |
| - No `.env` — ใช้ `environment:` จาก docker-compose / Container Station
 | |
| - พอร์ตภายใน: 3001 (สอดคล้องกับ Nginx upstream: `backend:3001`)
 | |
| 
 | |
| ## Endpoints
 | |
| - `GET /health` — DB ping
 | |
| - `POST /api/v1/auth/login` — {username, password} → {access_token, refresh_token}
 | |
| - `POST /api/v1/auth/refresh` — {refresh_token}
 | |
| - `GET /api/v1/users` — (Admin) List
 | |
| - `GET /api/v1/users/:id` — (Admin) Read
 | |
| - `POST /api/v1/users` — (Admin) Create
 | |
| - `PATCH /api/v1/users/:id` — (Admin) Update (+ password)
 | |
| - `DELETE /api/v1/users/:id` — (Admin) Delete
 | |
| 
 | |
| ## ENV example (ตั้งใน compose)
 | |
| - BACKEND_PORT=3001
 | |
| - DB_HOST=mariadb
 | |
| - DB_PORT=3306
 | |
| - DB_USER=center
 | |
| - DB_PASSWORD=Center2025
 | |
| - DB_NAME=dms_db
 | |
| - JWT_SECRET=CHANGE
 | |
| - JWT_REFRESH_SECRET=CHANGE
 | |
| - CORS_ALLOWLIST=https://dcs.mycloudnas.com,https://localhost,https://127.0.0.1
 | |
| 
 | |
| 
 | |
| ## RFA & Correspondence Endpoints
 | |
| - `GET /api/v1/rfas` (filters: q, project_id, status, page, page_size)
 | |
| - `GET /api/v1/rfas/:id`
 | |
| - `POST /api/v1/rfas` (Admin/Editor)
 | |
| - `PATCH /api/v1/rfas/:id` (Admin/Editor)
 | |
| - `DELETE /api/v1/rfas/:id` (Admin)
 | |
| - `GET /api/v1/rfas/:id/revisions`
 | |
| - `POST /api/v1/rfas/:id/revisions` (Admin/Editor)
 | |
| - `GET /api/v1/correspondences` (filters: q, project_id, status, page, page_size)
 | |
| - `GET /api/v1/correspondences/:id`
 | |
| - `POST /api/v1/correspondences` (Admin/Editor)
 | |
| - `PATCH /api/v1/correspondences/:id` (Admin/Editor)
 | |
| - `DELETE /api/v1/correspondences/:id` (Admin)
 | |
| - `GET /api/v1/correspondences/:id/versions`
 | |
| - `POST /api/v1/correspondences/:id/versions` (Admin/Editor)
 | |
| 
 | |
| 
 | |
| ## Drawings / Documents / Transmittals
 | |
| - `GET/POST/PATCH/DELETE /api/v1/drawings[/:id]` + `/drawings/:id/revisions`
 | |
| - `GET/POST/PATCH/DELETE /api/v1/documents[/:id]`
 | |
| - `GET/POST/PATCH/DELETE /api/v1/transmittals[/:id]` + items under `/transmittals/:id/items`
 | |
| - Mapping: `GET/POST/DELETE /api/v1/maps/rfa/:rfa_id/drawings/:drawing_id` and `/maps/correspondence/:corr_id/documents/:doc_id`
 | |
| 
 | |
| 
 | |
| ## Specialized Tables & File Uploads
 | |
| - Volumes: `/api/v1/volumes`
 | |
| - Sub Categories: `/api/v1/sub_categories`
 | |
| - Organizations: `/api/v1/organizations`
 | |
| - Upload file: `POST /api/v1/uploads/:module/:refId` field `file` (Admin/Editor)
 | |
|   - Allowed modules: rfa, correspondence, drawing, document, transmittal
 | |
|   - Default size limit 100MB; set `MAX_UPLOAD_BYTES` if needed
 | |
| - Download file: `GET /api/v1/files/:file_id?token=...` (Admin bypass token)
 | |
| - Mount host path `/share/dms-data` into the container at the same path
 | |
| 
 | |
| 
 | |
| ## Views (read-only)
 | |
| - `GET /api/v1/views/rfas` (q, project_id, status, page, page_size)
 | |
| - `GET /api/v1/views/correspondences` (q, project_id, status, page, page_size)
 | |
| - `GET /api/v1/views/drawings/latest` (q, project_id, discipline, status, page, page_size)
 | |
| - `GET /api/v1/views/transmittals` (q, project_id, status, page, page_size)
 | |
| - `GET /api/v1/views/files` (module, ref_id, page, page_size)
 | |
| 
 | |
| > หมายเหตุ: ชื่อตาราง view ต้องตรงกับ SQL ใน `04_*_views.sql`. หากต่าง ให้แก้ชื่อในไฟล์ models/vw_*.js ให้ตรงสคีมา
 | |
| 
 | |
| 
 | |
| ## MVP Endpoints Added
 | |
| - Auth: GET /api/v1/auth/me
 | |
| - Users: PATCH /api/v1/users/:id/password
 | |
| - Projects: CRUD /api/v1/projects + membership endpoints
 | |
| - Files alias: GET /api/v1/{rfas|correspondences|drawings|documents|transmittals}/:id/files
 | |
| - Lookups: statuses, disciplines, categories, organizations
 | |
| - Ops: GET /ready, /live, /version (from package.json v0.5.0)
 | |
| 
 | |
| 
 | |
| ## MVP Endpoints Added
 | |
| - Auth: `GET /api/v1/auth/me`, `POST /api/v1/auth/logout`
 | |
| - Users: `PATCH /api/v1/users/:id/password`, `GET /api/v1/users/search?q=`
 | |
| - User projects: `GET /api/v1/users/me/projects`
 | |
| - Projects: `GET/POST/PATCH/DELETE /api/v1/projects`, members `GET/POST/DELETE /api/v1/projects/:id/members/:user_id`
 | |
| - Files: `HEAD /api/v1/files/:file_id`, `DELETE /api/v1/files/:file_id`, `POST /api/v1/files/:file_id/rename`, `POST /api/v1/files/:file_id/refresh-url`
 | |
| - Module file aliases: `GET /api/v1/{rfas|correspondences|drawings|documents|transmittals}/:id/files`
 | |
| - Lookups: `GET /api/v1/lookups/statuses|disciplines|categories|organizations`
 | |
| - Ops: `GET /ready`, `GET /live`, `GET /version`
 | |
| 
 | |
| 
 | |
| ## RBAC / Permission Granularity
 | |
| - `GET /api/v1/rbac/effective` — roles + permissions ของผู้ใช้ปัจจุบัน
 | |
| - `GET/POST/DELETE /api/v1/rbac/roles`
 | |
| - `GET/POST/DELETE /api/v1/rbac/permissions`
 | |
| - bind/unbind: `POST/DELETE /api/v1/rbac/roles/:role_id/permissions/:permission_id`
 | |
| - assign/unassign: `POST/DELETE /api/v1/rbac/users/:user_id/roles/:role_id`
 | |
| - Helper middleware: `requirePerm('rfa:create')` (ไฟล์ `middleware/permGuard.js`)
 | |
| 
 | |
| 
 | |
| ## ABAC (Project-scoped) on Views
 | |
| - ทุก endpoint ใน `/api/v1/views/*` ถูกครอบด้วย `requirePerm('<module>:view')` และ `projectScopedView('<module>')` แล้ว
 | |
| - ถ้าไม่ส่ง `project_id` และผู้ใช้ไม่ใช่ Admin:
 | |
|   - ถ้ามี permission `<module>:view` → เห็นทุกโปรเจ็กต์
 | |
|   - ถ้าไม่มี → ระบบจะจำกัดผลลัพธ์ให้เฉพาะโปรเจ็กต์ที่ผู้ใช้เป็นสมาชิก (`user_project_roles`)
 | |
| - ถ้าส่ง `project_id` → ต้องเป็นสมาชิกของโปรเจ็กต์นั้นหรือมี `<module>:view`
 | |
| 
 | |
| 
 | |
| ## ABAC for Mutations (Create/Update/Delete)
 | |
| - ทุกโมดูลที่มี `project_id` ถูกตรวจสอบ **การเป็นสมาชิกโปรเจ็กต์** แล้ว
 | |
|   - Create → ต้องส่ง `project_id` ใน body และต้องเป็นสมาชิก
 | |
|   - Update/Delete → ระบบจะดึงเรคคอร์ดเดิมเพื่อหาระบุ `project_id` แล้วตรวจสมาชิก
 | |
| - Uploads/Files/Mapping ก็ตรวจ project membership ตามเอนทิตีอ้างอิง
 | |
| 
 | |
| ## Views: Require project_id (ยกเว้น Admin)
 | |
| - `/api/v1/views/*` **ต้องส่ง** `?project_id=` เสมอ (ถ้าไม่ใช่ Admin)
 | |
| - ใช้ร่วมกับ `requirePerm('<module>:view')` และ `projectScopedView('<module>')`
 | |
| 
 | |
| ## Seeds เพิ่มเติม
 | |
| - `seed/09_user_project_roles_seed.sql` — ตัวอย่างการผูกผู้ใช้เข้ากับโปรเจ็กต์
 |