DMS Backend (ESM)
- Node 20+, ESM
- No
.env— ใช้environment:จาก docker-compose / Container Station - พอร์ตภายใน: 3001 (สอดคล้องกับ Nginx upstream:
backend:3001)
Endpoints
GET /health— DB pingPOST /api/v1/auth/login— {username, password} → {access_token, refresh_token}POST /api/v1/auth/refresh— {refresh_token}GET /api/v1/users— (Admin) ListGET /api/v1/users/:id— (Admin) ReadPOST /api/v1/users— (Admin) CreatePATCH /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/:idPOST /api/v1/rfas(Admin/Editor)PATCH /api/v1/rfas/:id(Admin/Editor)DELETE /api/v1/rfas/:id(Admin)GET /api/v1/rfas/:id/revisionsPOST /api/v1/rfas/:id/revisions(Admin/Editor)GET /api/v1/correspondences(filters: q, project_id, status, page, page_size)GET /api/v1/correspondences/:idPOST /api/v1/correspondences(Admin/Editor)PATCH /api/v1/correspondences/:id(Admin/Editor)DELETE /api/v1/correspondences/:id(Admin)GET /api/v1/correspondences/:id/versionsPOST /api/v1/correspondences/:id/versions(Admin/Editor)
Drawings / Documents / Transmittals
GET/POST/PATCH/DELETE /api/v1/drawings[/:id]+/drawings/:id/revisionsGET/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_idand/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/:refIdfieldfile(Admin/Editor)- Allowed modules: rfa, correspondence, drawing, document, transmittal
- Default size limit 100MB; set
MAX_UPLOAD_BYTESif needed
- Download file:
GET /api/v1/files/:file_id?token=...(Admin bypass token) - Mount host path
/share/dms-datainto 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, membersGET/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/rolesGET/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)
- ถ้ามี permission
- ถ้าส่ง
project_id→ ต้องเป็นสมาชิกของโปรเจ็กต์นั้นหรือมี<module>:view
ABAC for Mutations (Create/Update/Delete)
- ทุกโมดูลที่มี
project_idถูกตรวจสอบ การเป็นสมาชิกโปรเจ็กต์ แล้ว- Create → ต้องส่ง
project_idใน body และต้องเป็นสมาชิก - Update/Delete → ระบบจะดึงเรคคอร์ดเดิมเพื่อหาระบุ
project_idแล้วตรวจสมาชิก
- Create → ต้องส่ง
- 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— ตัวอย่างการผูกผู้ใช้เข้ากับโปรเจ็กต์