Files
lcbp3/docs/LCBP3-DMS_V1_4_0_Frontend_Development_Plan.md
2025-11-17 16:48:49 +07:00

25 KiB

📋 แผนการพัฒนา Frontend (NestJS) - LCBP3-DMS v1.4.0

📋 แผนการพัฒนา Frontend (Next.js) - LCBP3-DMS v1.4.0

🎯 ภาพรวมโครงการ

พัฒนา Frontend สำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System) ที่ทันสมัย responsive และใช้งานง่าย รองรับการจัดการเอกสารที่ซับซ้อน มี Dashboard แบบ Real-time และระบบ Workflow Visualization


📐 สถาปัตยกรรมระบบ

Technology Stack

  • Framework: Next.js 14+ (App Router, React 18+, TypeScript, ESM)
  • Styling: Tailwind CSS + PostCSS
  • Component Library: shadcn/ui (Radix UI)
  • State Management:
    • Server State: TanStack Query (React Query)
    • Global Client State: Zustand
    • Form State: React Hook Form + Zod
  • Data Fetching: Axios + TanStack Query
  • Authentication: NextAuth.js (JWT Strategy)
  • File Upload: React Dropzone
  • Tables: TanStack Table
  • Charts: Recharts
  • Date Picker: date-fns + shadcn/ui Calendar
  • Icons: Lucide React
  • Testing:
    • Unit/Integration: Vitest + React Testing Library
    • E2E: Playwright
    • API Mocking: Mock Service Worker (MSW)

โครงสร้างโปรเจกต์

app/
├── (public)/              # Public routes (Landing, Login)
│   ├── page.tsx          # Landing Page
│   └── login/            # Login Page
├── (protected)/          # Protected routes
│   ├── layout.tsx        # App Shell (Navbar + Sidebar)
│   ├── dashboard/        # Dashboard
│   ├── correspondences/  # Correspondence Management
│   ├── rfas/            # RFA Management
│   ├── drawings/        # Drawing Management
│   ├── circulations/    # Circulation Management
│   ├── transmittals/    # Transmittal Management
│   ├── search/          # Advanced Search
│   ├── reports/         # Reports
│   ├── admin/           # Admin Panel
│   └── profile/         # User Profile
├── api/                 # API Routes (if needed)
components/
├── ui/                  # shadcn/ui components
├── features/            # Feature-specific components
│   ├── auth/
│   ├── correspondence/
│   ├── rfa/
│   ├── drawing/
│   ├── circulation/
│   └── common/
└── layouts/             # Layout components
lib/
├── api/                 # API client & hooks
├── stores/              # Zustand stores
├── utils/               # Utility functions
├── hooks/               # Custom hooks
└── types/               # TypeScript types
public/
├── images/
└── fonts/

🗓️ แผนการพัฒนาแบบ Phase-Based

Phase 0: Setup & Infrastructure (สัปดาห์ที่ 1)

Milestone: สร้างโครงสร้างพื้นฐานและ Development Environment

Tasks:

T0.1 Initialize Next.js Project

  • สร้างโปรเจกต์ด้วย create-next-app:
    npx create-next-app@latest lcbp3-frontend --typescript --tailwind --app --src-dir=false
    
  • เลือก Options:
    • TypeScript
    • ESLint
    • Tailwind CSS
    • App Router
    • Import alias (@/*)
  • Setup .gitignore, README.md
  • Deliverable: โปรเจกต์เริ่มต้นพร้อม

T0.2 Install Core Dependencies

# State Management & Data Fetching
npm install @tanstack/react-query zustand
npm install axios
npm install react-hook-form @hookform/resolvers zod

# UI Components & Styling
npm install clsx tailwind-merge
npm install lucide-react
npm install date-fns

# File Upload
npm install react-dropzone

# Authentication
npm install next-auth

# Development Tools
npm install -D @types/node
  • Deliverable: Dependencies ติดตั้งสมบูรณ์

T0.3 Setup shadcn/ui

npx shadcn-ui@latest init
  • เลือก Style: Default
  • เลือก Base Color: Slate
  • ติดตั้ง Components เบื้องต้น:
    npx shadcn-ui@latest add button input label card table dropdown-menu
    npx shadcn-ui@latest add dialog sheet toast alert
    npx shadcn-ui@latest add form select textarea checkbox
    npx shadcn-ui@latest add calendar popover
    
  • Deliverable: shadcn/ui พร้อมใช้งาน

T0.4 Configure Tailwind CSS

  • แก้ไข tailwind.config.ts:
    • เพิ่ม Custom Colors (ตาม Brand)
    • เพิ่ม Custom Fonts (ภาษาไทย: Noto Sans Thai)
    • Configure Container, Spacing
  • สร้าง app/globals.css พร้อม Custom Styles
  • Deliverable: Tailwind พร้อมใช้

T0.5 Setup Development Environment

  • สร้าง .env.local:
    NEXT_PUBLIC_API_URL=http://backend.np-dms.work/api
    NEXTAUTH_URL=http://localhost:3000
    NEXTAUTH_SECRET=...
    
  • Setup ESLint Rules (ไทย Comments OK)
  • Setup Prettier
  • Setup VS Code Settings
  • Deliverable: Dev Environment พร้อม

T0.6 Setup Git & Docker

  • Push โปรเจกต์ไปยัง Gitea (git.np-dms.work)
  • สร้าง Dockerfile สำหรับ Next.js:
    FROM node:20-alpine
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    COPY . .
    RUN npm run build
    EXPOSE 3000
    CMD ["npm", "start"]
    
  • สร้าง docker-compose.yml (เชื่อม Network lcbp3)
  • Deliverable: Project อยู่ใน Git + Docker พร้อม

Phase 1: Authentication & App Shell (สัปดาห์ที่ 2-3)

Milestone: ระบบ Login และ Layout หลัก

Tasks:

T1.1 Setup API Client

  • สร้าง lib/api/client.ts:

    import axios from "axios";
    
    export const apiClient = axios.create({
      baseURL: process.env.NEXT_PUBLIC_API_URL,
      headers: {
        "Content-Type": "application/json",
      },
    });
    
    // Request Interceptor (Add JWT Token)
    apiClient.interceptors.request.use((config) => {
      const token = localStorage.getItem("access_token");
      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
      return config;
    });
    
    // Response Interceptor (Handle Errors)
    apiClient.interceptors.response.use(
      (response) => response,
      (error) => {
        if (error.response?.status === 401) {
          // Redirect to login
          window.location.href = "/login";
        }
        return Promise.reject(error);
      }
    );
    
  • Deliverable: API Client พร้อมใช้

T1.2 Setup TanStack Query

  • สร้าง app/providers.tsx:

    "use client";
    import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
    import { useState } from "react";
    
    export function Providers({ children }: { children: React.ReactNode }) {
      const [queryClient] = useState(
        () =>
          new QueryClient({
            defaultOptions: {
              queries: {
                staleTime: 60 * 1000, // 1 minute
                refetchOnWindowFocus: false,
              },
            },
          })
      );
    
      return (
        <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
      );
    }
    
  • Wrap ใน app/layout.tsx

  • Deliverable: React Query พร้อม

T1.3 Create Auth Store (Zustand)

  • สร้าง lib/stores/auth-store.ts:

    import { create } from "zustand";
    import { persist } from "zustand/middleware";
    
    interface User {
      user_id: number;
      username: string;
      email: string;
      first_name: string;
      last_name: string;
      primary_organization_id: number;
      permissions: string[];
    }
    
    interface AuthStore {
      user: User | null;
      token: string | null;
      setAuth: (user: User, token: string) => void;
      clearAuth: () => void;
      hasPermission: (permission: string) => boolean;
    }
    
    export const useAuthStore = create<AuthStore>()(
      persist(
        (set, get) => ({
          user: null,
          token: null,
          setAuth: (user, token) => {
            set({ user, token });
            localStorage.setItem("access_token", token);
          },
          clearAuth: () => {
            set({ user: null, token: null });
            localStorage.removeItem("access_token");
          },
          hasPermission: (permission) => {
            const user = get().user;
            return user?.permissions.includes(permission) || false;
          },
        }),
        {
          name: "auth-storage",
        }
      )
    );
    
  • Deliverable: Auth Store พร้อม

T1.4 Create Login Page

  • สร้าง app/(public)/login/page.tsx:

    "use client";
    import { useForm } from "react-hook-form";
    import { zodResolver } from "@hookform/resolvers/zod";
    import * as z from "zod";
    import { Button } from "@/components/ui/button";
    import { Input } from "@/components/ui/input";
    import { useRouter } from "next/navigation";
    import { useAuthStore } from "@/lib/stores/auth-store";
    import { apiClient } from "@/lib/api/client";
    
    const loginSchema = z.object({
      username: z.string().min(1, "กรุณากรอกชื่อผู้ใช้"),
      password: z.string().min(1, "กรุณากรอกรหัสผ่าน"),
    });
    
    export default function LoginPage() {
      const router = useRouter();
      const setAuth = useAuthStore((state) => state.setAuth);
      const form = useForm({
        resolver: zodResolver(loginSchema),
      });
    
      const handleLogin = async (data: z.infer<typeof loginSchema>) => {
        try {
          const response = await apiClient.post("/auth/login", data);
          const { access_token, user } = response.data;
          setAuth(user, access_token);
          router.push("/dashboard");
        } catch (error) {
          console.error("Login failed:", error);
          // แสดง Toast Error
        }
      };
    
      return (
        <div className="flex min-h-screen items-center justify-center">
          <form onSubmit={form.handleSubmit(handleLogin)} className="w-96">
            {/* Form Fields */}
          </form>
        </div>
      );
    }
    
  • Deliverable: หน้า Login พร้อม

T1.5 Create Landing Page

  • สร้าง app/(public)/page.tsx:
    • Hero Section พร้อมข้อมูลโครงการ
    • Feature Highlights
    • CTA Button → Login
  • ใช้ Tailwind + Animations
  • Deliverable: Landing Page สวยงาม

T1.6 Create Protected Layout (App Shell)

  • สร้าง app/(protected)/layout.tsx:

    "use client";
    import { useEffect } from "react";
    import { useRouter } from "next/navigation";
    import { useAuthStore } from "@/lib/stores/auth-store";
    import Navbar from "@/components/layouts/navbar";
    import Sidebar from "@/components/layouts/sidebar";
    
    export default function ProtectedLayout({
      children,
    }: {
      children: React.ReactNode;
    }) {
      const router = useRouter();
      const user = useAuthStore((state) => state.user);
    
      useEffect(() => {
        if (!user) {
          router.push("/login");
        }
      }, [user, router]);
    
      if (!user) return null;
    
      return (
        <div className="flex h-screen">
          <Sidebar />
          <div className="flex flex-1 flex-col">
            <Navbar />
            <main className="flex-1 overflow-y-auto p-6">{children}</main>
          </div>
        </div>
      );
    }
    
  • Deliverable: App Shell พร้อม

T1.7 Create Navbar Component

  • สร้าง components/layouts/navbar.tsx:
    • แสดงชื่อระบบ
    • แสดงชื่อผู้ใช้ + Avatar
    • Dropdown Menu:
      • Profile
      • Settings
      • Logout
  • Responsive (Mobile Hamburger Menu)
  • Deliverable: Navbar พร้อม

T1.8 Create Sidebar Component

  • สร้าง components/layouts/sidebar.tsx:
    • เมนูหลัก:
      • Dashboard
      • Correspondences
      • RFAs
      • Drawings (Shop & Contract)
      • Circulations
      • Transmittals
      • Search
      • Reports
    • เมนู Admin (แสดงตามสิทธิ์):
      • Users
      • Roles & Permissions
      • Master Data
      • Document Numbering
  • Collapsible Sidebar
  • Active State Highlighting
  • Deliverable: Sidebar พร้อม

Phase 2: Dashboard & Common Components (สัปดาห์ที่ 4)

Milestone: Dashboard และ Reusable Components

Tasks:

T2.1 Create Reusable Components

  • components/features/common/data-table.tsx:
    • ใช้ TanStack Table
    • รองรับ Pagination, Sorting, Filtering
    • Responsive
  • components/features/common/file-upload.tsx:
    • ใช้ React Dropzone
    • รองรับ Multi-file Upload
    • Drag & Drop
    • Progress Bar
  • components/features/common/status-badge.tsx:
    • แสดง Status แบบสีสัน (Draft, Submitted, Approved)
  • components/features/common/permission-guard.tsx:
    • ซ่อน/แสดง Component ตามสิทธิ์
  • Deliverable: Reusable Components พร้อม

T2.2 Create Dashboard Page

  • สร้าง app/(protected)/dashboard/page.tsx:
    • KPI Cards Section:
      • จำนวนเอกสารทั้งหมด
      • งานที่รอดำเนินการ
      • เอกสารที่เกินกำหนด
      • RFA ที่รออนุมัติ
    • My Tasks Table:
      • ดึงข้อมูลจาก /api/circulations/my-tasks (ใช้ v_user_tasks)
      • แสดงรายการงานที่ต้องทำ (Pending, In Progress)
      • Columns: Document Number, Title, Type, Status, Deadline, Actions
      • คลิกแถวแล้วไปยังหน้า Detail
    • Recent Activity Feed:
      • ดึงข้อมูลจาก /api/audit-logs/user/:userId
      • แสดง 10 รายการล่าสุด
  • Deliverable: Dashboard ครบถ้วน

T2.3 Create API Hooks

  • สร้าง lib/api/hooks/use-my-tasks.ts:

    import { useQuery } from "@tanstack/react-query";
    import { apiClient } from "../client";
    
    export function useMyTasks() {
      return useQuery({
        queryKey: ["my-tasks"],
        queryFn: async () => {
          const response = await apiClient.get("/circulations/my-tasks");
          return response.data;
        },
      });
    }
    
  • สร้าง Hooks เพิ่มเติม:

    • use-dashboard-stats.ts
    • use-recent-activity.ts
  • Deliverable: API Hooks พร้อม


Phase 3: Correspondence Management (สัปดาห์ที่ 5-6)

Milestone: ระบบจัดการเอกสารโต้ตอบ

Tasks:

T3.1 Create Correspondence List Page

  • สร้าง app/(protected)/correspondences/page.tsx:
    • Data Table แสดงรายการเอกสาร
    • Columns:
      • Document Number (คลิกไปยัง Detail)
      • Title
      • Type
      • Status (Badge)
      • Originator
      • Date
      • Actions (View, Edit, Delete)
    • Filters:
      • ประเภทเอกสาร (Dropdown)
      • สถานะ (Dropdown)
      • วันที่ (Date Range Picker)
      • องค์กร (Dropdown)
    • Pagination (Server-side)
    • Search Box
    • Create Button (ตรวจสิทธิ์)
  • Deliverable: หน้ารายการเอกสาร

T3.2 Create Correspondence Detail Page

  • สร้าง app/(protected)/correspondences/[id]/page.tsx:
    • Header Section:
      • Document Number (ใหญ่)
      • Status Badge
      • Action Buttons: Edit, Delete, Export PDF
    • Metadata Section:
      • Title, Description
      • Document Date, Issued Date, Received Date
      • Originator, Recipients (TO/CC)
      • Due Date (ถ้ามี)
    • Revision History:
      • แสดง Revisions ทั้งหมดเป็น Timeline
      • แต่ละ Revision แสดง: Revision Number, Date, Changes, User
    • Attachments:
      • แสดงไฟล์แนบทั้งหมด
      • กำหนดไฟล์หลัก (Main Document) ด้วยไอคอน
      • ปุ่ม Download
    • References:
      • แสดงเอกสารที่อ้างถึง (Links)
    • Tags:
      • แสดง Tags แบบ Chips
    • Activity Log:
      • แสดง Audit Log ของเอกสารนี้
  • Deliverable: หน้า Detail ครบถ้วน

T3.3 Create Correspondence Form (Create/Edit)

  • สร้าง app/(protected)/correspondences/create/page.tsx:
  • สร้าง app/(protected)/correspondences/[id]/edit/page.tsx:
  • Form Fields:
    • Basic Info:
      • Correspondence Type (Dropdown)
      • Title (Text)
      • Description (Textarea)
      • Document Date (Date Picker)
    • Recipients:
      • TO: Multi-select Organizations
      • CC: Multi-select Organizations
    • References:
      • Search & Select เอกสารอื่นๆ
    • Tags:
      • Autocomplete Tag Input
    • Attachments:
      • File Upload (Multi-file)
      • กำหนด Main Document (Radio)
    • Deadline:
      • Due Date (Date Picker)
  • Validation ด้วย Zod
  • Submit → API → Redirect to Detail
  • Deliverable: ฟอร์มสร้าง/แก้ไข

T3.4 Create Status Management

  • ใน Detail Page เพิ่มปุ่ม Status Actions:
    • Draft → Submit (Document Control)
    • Submit → Close (Admin)
    • Submit → Cancel (Admin + Dialog ให้กรอกเหตุผล)
  • แสดง Confirmation Dialog ก่อนเปลี่ยนสถานะ
  • Deliverable: เปลี่ยนสถานะได้

Phase 4: RFA & Workflow Visualization (สัปดาห์ที่ 7-8)

Milestone: ระบบ RFA และ Workflow

Tasks:

T4.1 Create RFA List Page

  • สร้าง app/(protected)/rfas/page.tsx:
    • คล้าย Correspondence List
    • Columns เพิ่มเติม:
      • RFA Type (DWG, DOC, MAT)
      • Approval Status (Badge)
      • Approval Code (1A, 3R, etc.)
    • Filters:
      • RFA Type
      • Status
      • Approval Code
  • Deliverable: หน้ารายการ RFA

T4.2 Create RFA Detail Page

  • สร้าง app/(protected)/rfas/[id]/page.tsx:
    • คล้าย Correspondence Detail
    • เพิ่ม Section:
      • Shop Drawings (สำหรับ RFA_DWG):
        • แสดงรายการ Shop Drawings ที่เชื่อมโยง
        • แสดง Revision ของแต่ละแบบ
        • Link ไปยัง Shop Drawing Detail
      • Workflow Visualization (ดูรายละเอียดใน T4.3)
  • Deliverable: หน้า Detail RFA

T4.3 Create Workflow Visualization Component

  • สร้าง components/features/rfa/workflow-visualizer.tsx:
    • Layout: Steps แนวนอน (Timeline)
    • Step States:
      • Completed: สีเขียว, ไอคอน Check
      • Active: สีฟ้า, ปุ่ม Action เปิดใช้งาน
      • ⏸️ Pending: สีเทา, ปุ่ม disabled
      • Rejected: สีแดง
    • Step Info Card (เมื่อคลิก):
      • Organization
      • Assigned User
      • Action Type (Review, Approve)
      • Status
      • Comments
      • Completed Date
    • Actions (สำหรับ Active Step):
      • ปุ่ม "อนุมัติ" (Approve)
      • ปุ่ม "ปฏิเสธ" (Reject)
      • Dialog ให้กรอก Comments
    • Admin Override:
      • ปุ่ม "ไปยังขั้นตอนต่อไป" (Skip Step)
      • ปุ่ม "ย้อนกลับ" (Previous Step)
  • Deliverable: Workflow Component พร้อม

T4.4 Create RFA Form (Create/Edit)

  • สร้าง app/(protected)/rfas/create/page.tsx:
  • Form Fields:
    • RFA Type (Dropdown)
    • Title, Description
    • Document Date
    • Shop Drawings Section (สำหรับ RFA_DWG):
      • Search & Select Shop Drawings
      • แสดง Revisions ที่มี (Dropdown)
      • เพิ่มได้หลายแบบ
    • Attachments
    • Workflow Template (Dropdown)
  • Submit → สร้าง RFA + Start Workflow
  • Deliverable: ฟอร์ม RFA พร้อม

T4.5 Implement Workflow Actions API

  • สร้าง lib/api/hooks/use-rfa-workflow.ts:

    import { useMutation, useQueryClient } from "@tanstack/react-query";
    import { apiClient } from "../client";
    
    export function useCompleteWorkflowStep() {
      const queryClient = useQueryClient();
    
      return useMutation({
        mutationFn: async ({ rfaId, stepNumber, action, comments }) => {
          const response = await apiClient.post(
            `/rfas/${rfaId}/workflow/steps/${stepNumber}/complete`,
            { action, comments }
          );
          return response.data;
        },
        onSuccess: (_, variables) => {
          queryClient.invalidateQueries(["rfa", variables.rfaId]);
          queryClient.invalidateQueries(["my-tasks"]);
        },
      });
    }
    
  • Hooks เพิ่มเติม:

    • use-reject-workflow-step.ts
    • use-start-workflow.ts
  • Deliverable: Workflow Actions ทำงานได้


Phase 5: Drawing Management (สัปดาห์ที่ 9)

Milestone: ระบบจัดการแบบ

Tasks:

T5.1 Create Shop Drawing List Page

  • สร้าง app/(protected)/drawings/shop/page.tsx:
    • Data Table:
      • Drawing Number
      • Title
      • Main Category
      • Sub Category
      • Current Revision
      • Actions
    • Filters:
      • Category (Dropdown)
      • Sub Category (Dropdown)
    • Create Button
  • Deliverable: หน้ารายการ Shop Drawings

T5.2 Create Shop Drawing Detail Page

  • สร้าง app/(protected)/drawings/shop/[id]/page.tsx:
    • Header: Drawing Number, Title
    • Current Revision Info:
      • Revision Number, Date
      • Description
      • Attachments (PDF, DWG)
    • Contract Drawing References:
      • แสดง Contract Drawings ที่อ้างถึง
      • Links ไปยัง Contract Drawing Detail
    • Revision History:
      • แสดง Revisions ทั้งหมดเป็น Timeline
    • Related RFAs:
      • แสดง RFAs ที่เชื่อมโยงกับแบบนี้
  • Deliverable: หน้า Detail Shop Drawing

T5.3 Create Shop Drawing Form

  • สร้าง app/(protected)/drawings/shop/create/page.tsx:
  • Form Fields:
    • Drawing Number (Auto-generate หรือ Manual)
    • Title
    • Main Category (Dropdown)
    • Sub Category (Dropdown, dependent on Main)
    • Contract Drawing References:
      • Search & Select Contract Drawings (Multi-select)
    • Revision Info:
      • Revision Number (Auto)
      • Revision Label (A, B, C)
      • Description
    • Attachments:
      • Upload PDF (Main)
      • Upload DWG (Optional)
      • Upload Other Files
  • Deliverable: ฟอร์ม Shop Drawing

T5.4 Create Contract Drawing List & Detail

  • สร้าง app/(protected)/drawings/contract/page.tsx:
    • Data Table:
      • Drawing Number
      • Title
      • Volume
      • Category
      • Sub Category
    • Filters:
      • Volume (Dropdown)
      • Category (Dropdown)
  • สร้าง app/(protected)/drawings/contract/[id]/page.tsx:
    • แสดง Metadata
    • Attachments
    • Referenced By:
      • แสดง Shop Drawings ที่อ้างถึงแบบนี้
  • Deliverable: Contract Drawing Pages

Phase 6: Circulation & Transmittal (สัปดาห์ที่ 10)

Milestone: ระบบใบเวียนและเอกสารนำส่ง

Tasks:

T6.1 Create Circulation List Page

  • สร้าง app/(protected)/circulations/page.tsx:
    • Data Table:
      • Circulation Number
      • Subject
      • Status (Badge)
      • Created By
      • Created Date
    • Filters:
      • Status
      • Date Range
  • Deliverable: หน้ารายการใบเวียน

T6.2 Create Circulation Detail & Workflow

  • สร้าง app/(protected)/circulations/[id]/page.tsx:
    • Header: Circulation Number, Subject, Status
    • Linked Correspondence:
      • Link ไปยังเอกสารต้นทาง
    • Workflow Visualization:
      • คล้าย RFA Workflow
      • แสดง Steps:
        • Organization
        • Assigned Users (Main, Action, Information)
        • Status
        • Comments
        • Deadline
    • Actions (สำหรับ Assigned User):
      • ปุ่ม "ดำเนินการเสร็จสิ้น" (Complete)
      • Dialog ให้กรอก Comments
    • Close Circulation (Document Control):
      • ปุ่ม "ปิดใบเวียน" (เมื่อตอบกลับองค์กรผู้ส่งแล้ว)
  • Deliverable: หน้า Detail ใบเวียน