Files
lcbp3/docs/Markdown/LCBP3-DMS V1_1_1_FullStackJS.md
admin aaa5da3ec1
Some checks failed
Spec Validation / validate-markdown (push) Has been cancelled
Spec Validation / validate-diagrams (push) Has been cancelled
Spec Validation / check-todos (push) Has been cancelled
251217:1704 Docunment Number: Update to 1.6.2
2025-12-17 17:04:06 +07:00

32 KiB
Raw Permalink Blame History

แนวทางการพัฒนา FullStackJS

🧠 ปรัชญาทั่วไป

แนวทางปฏิบัติที่ดีที่สุดแบบครบวงจรสำหรับการพัฒนา NestJS Backend, NextJS Frontend และ Tailwind-based UI/UX ในสภาพแวดล้อม TypeScript มุ่งเน้นที่ ความชัดเจน (clarity), ความง่ายในการบำรุงรักษา (maintainability), ความสอดคล้องกัน (consistency) และ การเข้าถึงได้ (accessibility) ตลอดทั้งสแต็ก


⚙️ แนวทางทั่วไปสำหรับ TypeScript

หลักการพื้นฐาน

  • ใช้ ภาษาอังกฤษ สำหรับโค้ดและเอกสารทั้งหมด
  • กำหนดไทป์ (type) อย่างชัดเจนสำหรับตัวแปร, พารามิเตอร์ และค่าที่ส่งกลับ (return values) ทั้งหมด
  • หลีกเลี่ยงการใช้ any; ให้สร้างไทป์ (types) หรืออินเทอร์เฟซ (interfaces) ที่กำหนดเอง
  • ใช้ JSDoc สำหรับคลาส (classes) และเมธอด (methods) ที่เป็น public
  • ส่งออก (Export) สัญลักษณ์หลัก (main symbol) เพียงหนึ่งเดียว ต่อไฟล์
  • หลีกเลี่ยงบรรทัดว่างภายในฟังก์ชัน

ข้อตกลงในการตั้งชื่อ (Naming Conventions)

Entity (สิ่งที่ตั้งชื่อ) Convention (รูปแบบ) Example (ตัวอย่าง)
Classes PascalCase UserService
Variables & Functions camelCase getUserInfo
Files & Folders kebab-case user-service.ts
Environment Variables UPPERCASE DATABASE_URL
Booleans Verb + Noun isActive, canDelete, hasPermission

ใช้คำเต็ม — ไม่ใช้อักษรย่อ — ยกเว้นคำมาตรฐาน (เช่น API, URL, req, res, err, ctx)


🧩 ฟังก์ชัน (Functions)

  • เขียนฟังก์ชันให้สั้น และทำ หน้าที่เพียงอย่างเดียว (single-purpose) (< 20 บรรทัด)
  • ใช้ early returns เพื่อลดการซ้อน (nesting) ของโค้ด
  • ใช้ map, filter, reduce แทนการใช้ loops เมื่อเหมาะสม
  • ควรใช้ arrow functions สำหรับตรรกะสั้นๆ, และใช้ named functions ในกรณีอื่น
  • ใช้ default parameters แทนการตรวจสอบค่า null
  • จัดกลุ่มพารามิเตอร์หลายตัวให้เป็นอ็อบเจกต์เดียว (RO-RO pattern)
  • ส่งค่ากลับ (Return) เป็นอ็อบเจกต์ที่มีไทป์กำหนด (typed objects) ไม่ใช่ค่าพื้นฐาน (primitives)
  • รักษาระดับของสิ่งที่เป็นนามธรรม (abstraction level) ให้เป็นระดับเดียวในแต่ละฟังก์ชัน

🧱 การจัดการข้อมูล (Data Handling)

  • ห่อหุ้มข้อมูล (Encapsulate) ในไทป์แบบผสม (composite types)
  • ใช้ immutability (การไม่เปลี่ยนแปลงค่า) ด้วย readonly และ as const
  • ทำการตรวจสอบความถูกต้องของข้อมูล (Validations) ในคลาสหรือ DTOs ไม่ใช่ภายในฟังก์ชันทางธุรกิจ
  • ตรวจสอบความถูกต้องของข้อมูลโดยใช้ DTOs ที่มีไทป์กำหนดเสมอ

🧰 คลาส (Classes)

  • ปฏิบัติตามหลักการ SOLID
  • ควรใช้ composition มากกว่า inheritance (Prefer composition over inheritance)
  • กำหนด interfaces สำหรับสัญญา (contracts)
  • ให้คลาสมุ่งเน้นการทำงานเฉพาะอย่างและมีขนาดเล็ก (< 200 บรรทัด, < 10 เมธอด, < 10 properties)

🚨 การจัดการข้อผิดพลาด (Error Handling)

  • ใช้ Exceptions สำหรับข้อผิดพลาดที่ไม่คาดคิด
  • ดักจับ (Catch) ข้อผิดพลาดเพื่อแก้ไขหรือเพิ่มบริบท (context) เท่านั้น; หากไม่เช่นนั้น ให้ใช้ global error handlers
  • ระบุข้อความข้อผิดพลาด (error messages) ที่มีความหมายเสมอ

🧪 การทดสอบ (ทั่วไป) (Testing (General))

  • ใช้รูปแบบ ArrangeActAssert
  • ใช้ชื่อตัวแปรในการทดสอบที่สื่อความหมาย (inputData, expectedOutput)
  • เขียน unit tests สำหรับ public methods ทั้งหมด
  • จำลอง (Mock) การพึ่งพาภายนอก (external dependencies)
  • เพิ่ม acceptance tests ต่อโมดูลโดยใช้รูปแบบ GivenWhenThen

🏗️ แบ็กเอนด์ (NestJS) (Backend (NestJS))

หลักการ

  • สถาปัตยกรรมแบบโมดูลาร์ (Modular architecture):
    • หนึ่งโมดูลต่อหนึ่งโดเมน
    • โครงสร้างแบบ Controller → Service → Repository (Model)
  • DTOs ที่ตรวจสอบความถูกต้องด้วย class-validator
  • ใช้ MikroORM (หรือ TypeORM/Prisma) สำหรับการคงอยู่ของข้อมูล (persistence) ซึ่งสอดคล้องกับสคีมา MariaDB
  • ห่อหุ้มโค้ดที่ใช้ซ้ำได้ไว้ใน common module (@app/common):
    • Configs, decorators, DTOs, guards, interceptors, notifications, shared services, types, validators

ฟังก์ชันหลัก (Core Functionalities)

  • Global filters สำหรับการจัดการ exception
  • Middlewares สำหรับการจัดการ request
  • Guards สำหรับการอนุญาต (permissions) และ RBAC
  • Interceptors สำหรับการแปลงข้อมูล response และการบันทึก log

ข้อจำกัดในการ Deploy (QNAP Container Station)

  • ห้ามใช้ไฟล์ .env ในการตั้งค่า Environment Variables
  • การตั้งค่าทั้งหมด (เช่น Database connection string, JWT secret) จะต้องถูกกำหนดผ่าน Environment Variable ใน docker-compose.yml โดยตรง ซึ่งจะจัดการผ่าน UI ของ QNAP Container Station

โครงสร้างโมดูลตามโดเมน (Domain-Driven Module Structure)

เพื่อให้สอดคล้องกับสคีมา SQL (LCBP3-DMS) เราจะใช้โครงสร้างโมดูลแบบ Domain-Driven (แบ่งตามขอบเขตธุรกิจ) แทนการแบ่งตามฟังก์ชัน:

  1. CoreModule / CommonModule:
    • เก็บ Services ที่ใช้ร่วมกัน เช่น DatabaseModule, FileStorageService (จัดการไฟล์ใน QNAP), AuditLogService, และ NotificationService
  2. AuthModule / UserModule:
    • จัดการ users, roles, permissions และการยืนยันตัวตน (JWT, Guards)
    • (สำคัญ) ต้องรับผิดชอบการตรวจสอบสิทธิ์ 3 ระดับ: สิทธิ์ระดับระบบ (Global Role), สิทธิ์ระดับโปรเจกต์ (Project Role), และ สิทธิ์ระดับสัญญา (Contract Role)
    • (สำคัญ) ต้องมี API สำหรับ Admin เพื่อ สร้างและจัดการ Role และการจับคู่ Permission แบบไดนามิก (ไม่ใช่แค่ seed ข้อมูลเริ่มต้น)
  3. ProjectModule:
    • จัดการ projects, organizations, contracts, project_parties, contract_parties
  4. CorrespondenceModule (โมดูลศูนย์กลาง):
    • จัดการ correspondences, correspondence_revisions
    • จัดการ correspondence_attachments (ตารางเชื่อมไฟล์แนบ)
    • รับผิดชอบเวิร์กโฟลว์ "Correspondence Routings" (correspondence_routings) สำหรับการส่งต่อเอกสารทั่วไประหว่างองค์กร
  5. RfaModule:
    • จัดการ rfas, rfa_revisions, rfa_items
    • รับผิดชอบเวิร์กโฟลว์ "RFA Workflows" (rfa_workflows) สำหรับการอนุมัติเอกสารทางเทคนิค
  6. DrawingModule:
    • จัดการ shop_drawings, shop_drawing_revisions, contract_drawings และหมวดหมู่ต่างๆ
    • จัดการ shop_drawing_revision_attachments (ตารางเชื่อมไฟล์แนบ)
  7. CirculationModule:
    • จัดการ circulations, circulation_templates, circulation_assignees
    • จัดการ circulation_attachments (ตารางเชื่อมไฟล์แนบ)
    • รับผิดชอบเวิร์กโฟลGว์ "Circulations" สำหรับการเวียนเอกสาร ภายในองค์กร
  8. TransmittalModule:
    • จัดการ transmittals และ transmittal_items
  9. SearchModule:
    • (สำหรับ V1) ให้บริการค้นหาขั้นสูง (Advanced Search) โดยต้องรองรับการกรองจาก ชื่อเรื่อง (LIKE), ประเภท, วันที่, และ Tags (ผ่านการ Join ตาราง) โดยค้นหาผ่าน Views (v_current_rfas, v_current_correspondences)

🔐 Authentication & Authorization

  • @nestjs/passport
  • @nestjs/jwt
  • casl สำหรับ RBAC (Role-Based Access Control)

🗃️ Database & ORM

  • @nestjs/typeorm ORM สำหรับ SQL (หรือ Prisma เป็นทางเลือก)
  • typeorm-seeding สำหรับสร้างข้อมูลจำลอง (seeding)

📦 Validation & Transformation

  • class-validator
  • class-transformer

📁 File Upload & Storage

  • @nestjs/platform-express
  • multer สำหรับจัดการไฟล์

🔍 Search

  • (สำหรับ V1) เน้นการค้นหาขั้นสูงตาม Requirement 6.2 (Full-text search/Elasticsearch จะพิจารณาใน V2)

📬 Notification

  • nodemailer สำหรับส่งอีเมล
  • @nestjs/schedule สำหรับ cron job หรือแจ้งเตือนตามเวลา

📊 Logging & Monitoring

  • winston หรือ nestjs-pino ระบบ log ที่ยืดหยุ่น
  • @nestjs/terminus สำหรับ health check

🧪 Testing

  • @nestjs/testing
  • jest สำหรับ unit/integration test

🌐 API Documentation

  • @nestjs/swagger (สำคัญมาก) สร้าง Swagger UI อัตโนมัติ ต้องใช้ DTOs อย่างเคร่งครัดเพื่อความชัดเจนของ API สำหรับทีม Frontend

🛡️ Security

  • helmet ป้องกันช่องโหว่ HTTP
  • rate-limiter-flexible ป้องกัน brute force

การทดสอบ (Testing)

  • ใช้ Jest สำหรับการทดสอบ
  • ทดสอบทุก controller และ service
  • เพิ่ม endpoint admin/test เพื่อใช้เป็น smoke test

🖥️ ฟรอนต์เอนด์ (NextJS / React / UI) (Frontend (NextJS / React / UI))

โปรไฟล์นักพัฒนา (Developer Profile)

วิศวกร TypeScript + React/NextJS ระดับ Senior เชี่ยวชาญ TailwindCSS, Shadcn/UI, และ Radix สำหรับการพัฒนา UI

แนวทางการพัฒนาโค้ด (Code Implementation Guidelines)

  • ใช้ early returns เพื่อความชัดเจน
  • ใช้คลาสของ TailwindCSS ในการกำหนดสไตล์เสมอ
  • ควรใช้ class: syntax แบบมีเงื่อนไข (หรือ utility clsx) มากกว่าการใช้ ternary operators ใน class strings
  • ใช้ const arrow functions สำหรับ components และ handlers
  • Event handlers ให้ขึ้นต้นด้วย handle... (เช่น handleClick, handleSubmit)
  • รวมแอตทริบิวต์สำหรับการเข้าถึง (accessibility) ด้วย: tabIndex="0", aria-label, onKeyDown, ฯลฯ
  • ตรวจสอบให้แน่ใจว่าโค้ดทั้งหมด สมบูรณ์, ผ่านการทดสอบ, และ ไม่ซ้ำซ้อน (DRY)
  • ต้อง import โมดูลที่จำเป็นต้องใช้อย่างชัดเจนเสมอ

UI/UX ด้วย React

  • ใช้ semantic HTML
  • ใช้คลาสของ Tailwind ที่รองรับ responsive (sm:, md:, lg:)
  • รักษาลำดับชั้นของการมองเห็น (visual hierarchy) ด้วยการใช้ typography และ spacing
  • ใช้ Shadcn components (Button, Input, Card, ฯลฯ) เพื่อ UI ที่สอดคล้องกัน
  • ทำให้ components มีขนาดเล็กและมุ่งเน้นการทำงานเฉพาะอย่าง
  • ใช้ utility classes สำหรับการจัดสไตล์อย่างรวดเร็ว (spacing, colors, text, ฯลฯ)
  • ตรวจสอบให้แน่ใจว่าสอดคล้องกับ ARIA และใช้ semantic markup

การตรวจสอบฟอร์มและข้อผิดพลาด (Form Validation & Errors)

  • ใช้ไลบรารีฝั่ง client เช่น zod และ react-hook-form
  • แสดงข้อผิดพลาดด้วย alert components หรือข้อความ inline
  • ต้องมี labels, placeholders, และข้อความ feedback

🔗 แนวทางการบูรณาการ Full Stack (Full Stack Integration Guidelines)

Aspect (แง่มุม) Backend (NestJS) Frontend (NextJS) UI Layer (Tailwind/Shadcn)
API REST / GraphQL Controllers API hooks ผ่าน fetch/axios/SWR Components ที่รับข้อมูล
Validation (การตรวจสอบ) class-validator DTOs zod / react-hook-form สถานะของฟอร์ม/input ใน Shadcn
Auth (การยืนยันตัวตน) Guards, JWT NextAuth / cookies สถานะ UI ของ Auth (loading, signed in)
Errors (ข้อผิดพลาด) Global filters Toasts / modals Alerts / ข้อความ feedback
Testing (การทดสอบ) Jest (unit/e2e) Vitest / Playwright Visual regression
Styles (สไตล์) Scoped modules (ถ้าจำเป็น) Tailwind / Shadcn Tailwind utilities
Accessibility (การเข้าถึง) Guards + filters ARIA attributes Semantic HTML

🗂️ ข้อตกลงเฉพาะสำหรับ DMS (LCBP3-DMS)

ส่วนนี้ขยายแนวทาง FullStackJS ทั่วไปสำหรับโปรเจกต์ LCBP3-DMS โดยมุ่งเน้นไปที่เวิร์กโฟลว์การอนุมัติเอกสาร (Correspondence, RFA, Drawing, Contract, Transmittal, Circulation)

🧱 โมดูลโดเมนฝั่งแบ็กเอนด์ (Backend Domain Modules)

ใช้โครงสร้างโดเมนแบบโมดูลาร์ที่สะท้อนสคีมา SQL โดย correspondences จะทำหน้าที่เป็นศูนย์กลาง (โครงสร้างนี้จะอยู่ภายใต้ "Functional Modules" ที่กล่าวถึงข้างต้น)

src/
 ├─ modules/
 │   ├─ correspondences/ (Core: Master documents, Revisions, correspondence_attachments)
 │   ├─ rfas/             (RFA logic, Revisions, Workflows, Items)
 │   ├─ drawings/         (ShopDrawings, Revisions, shop_drawing_revision_attachments)
 │   ├─ circulations/     (Internal circulation, Templates, circulation_attachments)
 │   ├─ transmittals/     (Transmittal logic, Items)
 │   ├─ projects-contracts/ (Projects, Contracts, Organizations, Parties)
 │   ├─ users-auth/       (Users, Roles, Permissions, Auth)
 │   ├─ audit-log/
 │   └─ common/

ข้อตกลงการตั้งชื่อ (Naming Convention)

Entity (สิ่งที่ตั้งชื่อ) Example (ตัวอย่างจาก SQL)
Table correspondences, rfa_revisions, contract_parties
Column correspondence_id, created_by, is_current
DTO CreateRfaDto, UpdateCorrespondenceDto
Controller rfas.controller.ts
Service correspondences.service.ts

🧩 RBAC และการควบคุมสิทธิ์ (RBAC & Permission Control)

ใช้ Decorators เพื่อบังคับใช้สิทธิ์การเข้าถึง โดยอ้างอิงสิทธิ์จากตาราง permissions

@RequirePermission('rfas.respond') // ต้องตรงกับ 'permission_code'
@Put(':id')
updateRFA(@Param('id') id: string) {
  return this.rfaService.update(id);
}

Roles (บทบาท)

  • Superadmin: ไม่มีข้อจำกัดใดๆ
  • Admin: มีสิทธิ์เต็มที่ในองค์กร
  • Document Control: เพิ่ม/แก้ไข/ลบ เอกสารในองค์กร
  • Editor: สามารถ เพิ่ม/แก้ไข เอกสารที่กำหนด
  • Viewer: สามารถดู เอกสาร

ตัวอย่าง Permissions (จากตาราง permissions)

  • rfas.view, rfas.create, rfas.respond, rfas.delete
  • drawings.view, drawings.upload, drawings.delete
  • corr.view, corr.manage
  • transmittals.manage
  • cirs.manage
  • project_parties.manage

การจับคู่ระหว่าง roles และ permissions เริ่มต้น จะถูก seed ผ่านสคริปต์ (ดังที่เห็นในไฟล์ SQL) อย่างไรก็ตาม AuthModule/UserModule ต้องมี API สำหรับ Admin เพื่อสร้าง Role ใหม่และกำหนดสิทธิ์ (Permissions) เพิ่มเติมได้ในภายหลัง


🧾 มาตรฐาน AuditLog (AuditLog Standard)

บันทึกการดำเนินการ CRUD และการจับคู่ทั้งหมดลงในตาราง audit_logs

Field (ฟิลด์) Type (จาก SQL) Description (คำอธิบาย)
audit_id BIGINT Primary Key
user_id INT ผู้ใช้ที่ดำเนินการ (FK -> users)
action VARCHAR(100) rfa.create, correspondence.update, login.success
entity_type VARCHAR(50) ชื่อตาราง/โมดูล เช่น 'rfa', 'correspondence'
entity_id VARCHAR(50) Primary ID ของระเบียนที่ได้รับผลกระทบ
details_json JSON ข้อมูลบริบท (เช่น ฟิลด์ที่มีการเปลี่ยนแปลง)
ip_address VARCHAR(45) IP address ของผู้ดำเนินการ
user_agent VARCHAR(255) User Agent ของผู้ดำเนินการ
created_at TIMESTAMP Timestamp (UTC)

ตัวอย่างการใช้งาน:

await this.auditLogService.log({
  userId: user.id,
  action: 'rfa.update_status',
  entityType: 'rfa_revisions',
  entityId: rfaRevision.id,
  detailsJson: { from: 'DFT', to: 'FAP' },
  ipAddress: req.ip,
});

📂 การจัดการไฟล์ (File Handling) (ปรับปรุงใหม่)

มาตรฐานการอัปโหลดไฟล์ (File Upload Standard)

  • ตรรกะใหม่: การอัปโหลดไฟล์ทั้งหมดจะถูกจัดการโดย FileStorageService และบันทึกข้อมูลไฟล์ลงในตาราง attachments (ตารางกลาง)
  • ไฟล์จะถูกเชื่อมโยงไปยัง Entity ที่ถูกต้องผ่าน ตารางเชื่อม (Junction Tables) เท่านั้น:
    • correspondence_attachments (เชื่อม Correspondence กับ Attachments)
    • circulation_attachments (เชื่อม Circulation กับ Attachments)
    • shop_drawing_revision_attachments (เชื่อม Drawing Revision กับ Attachments)
  • (สำคัญ) คอลัมน์ file_path ถูกลบออกจาก shop_drawing_revisions แล้ว ต้องใช้ระบบตารางเชื่อมใหม่นี้เท่านั้น
  • เส้นทางจัดเก็บไฟล์ (Upload path): อ้างอิงจาก Requirement 2.1 คือ /share/dms-data โดย FileStorageService จะสร้างโฟลเดอร์ย่อยแบบรวมศูนย์ (เช่น /share/dms-data/uploads/{YYYY}/{MM}/[stored_filename])
    • (หมายเหตุ): โครงสร้างนี้ แทนที่ โครงสร้างแบบแยกโมดูลที่ระบุใน Requirement 3.9 เนื่องจากการออกแบบใหม่ได้รวมศูนย์ไฟล์ไว้ที่ตาราง attachments กลางแล้ว
  • ประเภทไฟล์ที่อนุญาต: pdf, dwg, docx, xlsx, zip
  • ขนาดสูงสุด: 50 MB
  • จัดเก็บนอก webroot
  • ให้บริการไฟล์ผ่าน endpoint ที่ปลอดภัย /files/:attachment_id/download

การควบคุมการเข้าถึง (Access Control)

การเข้าถึงไฟล์ไม่ใช่การเข้าถึงโดยตรง endpoint /files/:attachment_id/download จะต้อง:

  1. ค้นหาระเบียน attachment
  2. ตรวจสอบว่า attachment_id นี้ เชื่อมโยงกับ Entity ใด (เช่น correspondence, circulation, shop_drawing_revision) ผ่านตารางเชื่อม
  3. ตรวจสอบว่าผู้ใช้มีสิทธิ์ (permission) ในการดู Entity ต้นทางนั้นๆ หรือไม่

📊 การรายงานและการส่งออก (Reporting & Exports)

วิวสำหรับการรายงาน (Reporting Views) (จาก SQL)

การรายงานควรสร้างขึ้นจาก Views ที่กำหนดไว้ล่วงหน้าในฐานข้อมูลเป็นหลัก:

  • v_current_correspondences: สำหรับ revision ปัจจุบันทั้งหมดของเอกสารที่ไม่ใช่ RFA
  • v_current_rfas: สำหรับ revision ปัจจุบันทั้งหมดของ RFA และข้อมูล master
  • v_contract_parties_all: สำหรับการตรวจสอบความสัมพันธ์ของ project/contract/organization

Views เหล่านี้ทำหน้าที่เป็นแหล่งข้อมูลหลักสำหรับการรายงานฝั่งเซิร์ฟเวอร์และการส่งออกข้อมูล

กฎการส่งออก (Export Rules)

  • Export formats: CSV, Excel, PDF.
  • จัดเตรียมมุมมองสำหรับพิมพ์ (Print view).
  • รวมลิงก์ไปยังต้นทาง (เช่น /rfas/:id).

🧮 ฟรอนต์เอนด์: รูปแบบ DataTable และฟอร์ม (Frontend: DataTable & Form Patterns)

DataTable (ServerSide)

  • Endpoint: /api/{module}?page=1&pageSize=20&sort=...&filter=...
  • ต้องรองรับ: การแบ่งหน้า (pagination), การเรียงลำดับ (sorting), การค้นหา (search), การกรอง (filters)
  • แสดง revision ล่าสุดแบบ inline เสมอ (สำหรับ RFA/Drawing)

มาตรฐานฟอร์ม (Form Standards)

  • ต้องมีการใช้งาน Dropdowns แบบขึ้นต่อกัน (Dependent dropdowns) (ตามที่สคีมารองรับ):
    • Project → Contract Drawing Volumes
    • Contract Drawing Category → Sub-Category
    • RFA (ประเภท Shop Drawing) → Shop Drawing Revisions ที่เชื่อมโยงได้
  • การอัปโหลดไฟล์: ต้องมี preview + validation (ผ่านตรรกะของ attachments และตารางเชื่อมใหม่)
  • ส่ง (Submit) ผ่าน API พร้อม feedback แบบ toast

ข้อกำหนด Component เฉพาะ (Specific UI Requirements)

  • Dashboard - My Tasks: ต้องพัฒนา Component ตาราง "งานของฉัน" (My Tasks) ซึ่งดึงข้อมูลงานที่ผู้ใช้ล็อกอินอยู่ต้องรับผิดชอบ (Main/Action) จากโมดูล Circulations
  • Workflow Visualization: ต้องพัฒนา Component สำหรับแสดงผล Workflow (โดยเฉพาะ RFA) ที่แสดงขั้นตอนทั้งหมดเป็นลำดับ โดยขั้นตอนปัจจุบัน (active) เท่านั้นที่ดำเนินการได้ และขั้นตอนอื่นเป็น disabled ต้องมีตรรกะสำหรับ Admin ในการ override หรือย้อนกลับขั้นตอนได้

🧭 แดชบอร์ดและฟีดกิจกรรม (Dashboard & Activity Feed)

การ์ดบนแดชบอร์ด (Dashboard Cards)

  • แสดง Correspondences, RFAs, Circulations ล่าสุด
  • รวมสรุป KPI (เช่น "RFAs ที่รอการอนุมัติ")
  • รวมลิงก์ด่วนไปยังโมดูลต่างๆ

ฟีดกิจกรรม (Activity Feed)

  • แสดงรายการ audit_logs ล่าสุด (10 รายการ) ที่เกี่ยวข้องกับผู้ใช้
// ตัวอย่าง API response
[
  { user: 'editor01', action: 'Updated RFA (LCBP3-RFA-001)', time: '2025-11-04T09:30Z' }
]

มาตรฐานที่นำไปใช้แล้ว (จาก SQL v1.1.0) (Implemented Standards (from SQL v1.1.0))

ส่วนนี้ยืนยันว่าแนวทางปฏิบัติที่ดีที่สุดต่อไปนี้เป็นส่วนหนึ่งของการออกแบบฐานข้อมูลอยู่แล้ว และควรถูกนำไปใช้ประโยชน์ ไม่ใช่สร้างขึ้นใหม่

  • Soft Delete: นำไปใช้แล้วผ่านคอลัมน์ deleted_at ในตารางสำคัญ (เช่น correspondences, rfas, project_parties) ตรรกะการดึงข้อมูลต้องกรอง deleted_at IS NULL
  • Database Indexes: สคีมาได้มีการทำ index ไว้อย่างหนักหน่วงบน foreign keys และคอลัมน์ที่ใช้ค้นหาบ่อย (เช่น idx_rr_rfa, idx_cor_project, idx_cr_is_current) เพื่อประสิทธิภาพ
  • โครงสร้าง RBAC: มีระบบ users, roles, permissions, user_roles, และ user_project_roles ที่ครอบคลุมอยู่แล้ว
  • Data Seeding: ข้อมูล Master (roles, permissions, organization_roles, initial users, project parties) ถูกรวมอยู่ในสคริปต์สคีมาแล้ว
  • (V2) นำ Fulltext search หรือ Elasticsearch มาใช้กับฟิลด์เช่น correspondence_revisions.title หรือ details
  • สร้าง Background job (โดยใช้ n8n เพื่อเชื่อมต่อกับ Line และ/หรือใช้สำหรับการแจ้งเตือน RFA ที่ใกล้ถึงกำหนด due_date)
  • เพิ่ม job ล้างข้อมูลเป็นระยะสำหรับ attachments ที่ไม่ถูกเชื่อมโยงกับ Entity ใดๆ เลย (ไฟล์กำพร้า)