# QUY TRÌNH WORKFLOW: TỪ LỊCH BẢO TRÌ ĐẾN CÔNG VIỆC VÀ BÁO CÁO

## MỤC LỤC
1. [Tổng quan](#tổng-quan)
2. [Giai đoạn 1: Lịch Bảo trì (PM Schedule)](#giai-đoạn-1-lịch-bảo-trì-pm-schedule)
3. [Giai đoạn 2: Tự động tạo Công việc (Work Order)](#giai-đoạn-2-tự-động-tạo-công-việc-work-order)
4. [Giai đoạn 3: Thực hiện Công việc](#giai-đoạn-3-thực-hiện-công-việc)
5. [Giai đoạn 4: Báo cáo](#giai-đoạn-4-báo-cáo)
6. [Luồng dữ liệu và API](#luồng-dữ-liệu-và-api)
7. [Các trạng thái và chuyển đổi](#các-trạng-thái-và-chuyển-đổi)

---

## TỔNG QUAN

Quy trình workflow quản lý bảo trì định kỳ (Preventive Maintenance) được thiết kế để tự động hóa việc lập kế hoạch, thực hiện và báo cáo các công việc bảo trì. Quy trình bao gồm 4 giai đoạn chính:

```
Lịch Bảo trì (PM Schedule) 
    ↓ [Tự động chạy scheduler]
Công việc (Work Order) 
    ↓ [Thực hiện và hoàn thành]
Báo cáo (Report)
```

---

## GIAI ĐOẠN 1: LỊCH BẢO TRÌ (PM SCHEDULE)

### 1.1. Mục đích
Lịch bảo trì định kỳ (PM Schedule) là kế hoạch chi tiết cho các công việc bảo trì cần được thực hiện theo chu kỳ nhất định.

### 1.2. Thông tin cơ bản

#### Các trường dữ liệu:
- **projectId** (Bắt buộc): ID của dự án
- **contractId** (Bắt buộc): ID của hợp đồng (chỉ chấp nhận O&M, EPC, hoặc PPA)
- **assetId** (Tùy chọn): ID của tài sản cần bảo trì
- **title** (Bắt buộc): Tiêu đề công việc bảo trì
- **description** (Tùy chọn): Mô tả chi tiết
- **frequency** (Bắt buộc): Tần suất thực hiện
  - `Daily` - Hàng ngày
  - `Weekly` - Hàng tuần
  - `Monthly` - Hàng tháng
  - `Quarterly` - Hàng quý
  - `Semi-Annually` - Nửa năm
  - `Annually` - Hàng năm
- **nextDue** (Bắt buộc): Ngày đến hạn tiếp theo
- **lastPerformed** (Tự động): Ngày thực hiện lần cuối
- **assignedTo** (Tùy chọn): Danh sách ID người được phân công (có thể nhiều người, phân cách bằng dấu phẩy)
- **status** (Mặc định: Active): Trạng thái
  - `Active` - Đang hoạt động
  - `Paused` - Tạm dừng
  - `Inactive` - Không hoạt động

### 1.3. Quy trình tạo lịch bảo trì

#### Bước 1: Kiểm tra hợp đồng
- Hệ thống kiểm tra `contractId` có tồn tại không
- Xác minh loại hợp đồng phải là O&M, EPC, hoặc PPA
- Nếu không hợp lệ, trả về lỗi: "Chỉ có thể tạo lịch bảo trì cho hợp đồng O&M, EPC hoặc PPA"

#### Bước 2: Tạo lịch bảo trì
- Người dùng cung cấp thông tin: title, description, frequency, nextDue, assignedTo
- Hệ thống tự động gán projectId từ hợp đồng
- Lưu vào database với status mặc định là `Active`

#### Bước 3: Xác nhận
- Trả về thông báo: "Tạo lịch bảo trì thành công"
- Trả về đối tượng PMSchedule đã tạo

### 1.4. API Endpoints

#### GET `/api/pm-schedules?projectId={projectId}`
- **Mục đích**: Lấy danh sách lịch bảo trì theo dự án
- **Response**: Danh sách PMSchedule được sắp xếp theo `nextDue` tăng dần

#### POST `/api/pm-schedules`
- **Mục đích**: Tạo lịch bảo trì mới
- **Body**: 
  ```json
  {
    "contractId": "contract_id",
    "projectId": "project_id",
    "assetId": "asset_id (optional)",
    "title": "Kiểm tra và vệ sinh tấm pin",
    "description": "Vệ sinh định kỳ tấm pin năng lượng mặt trời",
    "frequency": "Monthly",
    "nextDue": "2024-02-01T00:00:00Z",
    "assignedTo": "user_id1,user_id2",
    "status": "Active"
  }
  ```

#### PUT `/api/pm-schedules/:id`
- **Mục đích**: Cập nhật lịch bảo trì
- **Validation**: Kiểm tra contractId mới (nếu có) phải là O&M, EPC, hoặc PPA

#### DELETE `/api/pm-schedules/:id`
- **Mục đích**: Xóa lịch bảo trì

---

## GIAI ĐOẠN 2: TỰ ĐỘNG TẠO CÔNG VIỆC (WORK ORDER)

### 2.1. Mục đích
Hệ thống tự động tạo Work Order từ các PM Schedule đã đến hạn, đảm bảo công việc bảo trì được thực hiện đúng thời gian.

### 2.2. Quy trình Scheduler

#### Bước 1: Chạy Scheduler
- **API**: `POST /api/pm-schedules/run-scheduler`
- **Tần suất**: Nên chạy định kỳ (ví dụ: hàng ngày hoặc theo cron job)
- **Logic**: Tìm tất cả PM Schedule có:
  - `status = 'Active'`
  - `nextDue <= (hôm nay + 7 ngày)`

#### Bước 2: Xử lý từng Schedule

Với mỗi schedule đã đến hạn:

**2.2.1. Xác định Asset:**
- Ưu tiên 1: Sử dụng `schedule.assetId` nếu có và hợp lệ
- Ưu tiên 2: Tìm Asset loại `Plant` trong project
- Ưu tiên 3: Lấy Asset đầu tiên của project
- Lưu ý: `assetId` là tùy chọn, Work Order có thể được tạo mà không cần assetId

**2.2.2. Xác định người được phân công:**
- Copy toàn bộ `assignedTo` từ schedule sang Work Order
- Nếu `assignedTo` chứa nhiều user ID (phân cách bằng dấu phẩy), tất cả sẽ được copy
- `assignedTechnicianId` được set bằng user ID đầu tiên (để tương thích ngược)

**2.2.3. Tạo Work Order:**
```javascript
{
  woCode: "WO-{timestamp}-{random}", // Mã tự động
  projectId: schedule.projectId,
  contractId: schedule.contractId,
  assetId: assetId || undefined, // Tùy chọn
  workOrderType: "PM", // Loại bảo trì định kỳ
  title: "Bảo trì định kỳ: {schedule.title}",
  description: schedule.description || "Được tạo tự động từ lịch bảo trì KHĐK.",
  priority: "Medium",
  status: "Draft", // Trạng thái ban đầu
  scheduledStart: schedule.nextDue,
  scheduledEnd: schedule.nextDue + 2 giờ, // Mặc định 2 giờ
  assignedTechnicianId: user_id_đầu_tiên,
  assignedTo: "user_id1,user_id2", // Tất cả user IDs
  costLabor: 0,
  costMaterial: 0,
  costExternal: 0
}
```

**2.2.4. Cập nhật Schedule:**
- `lastPerformed` = ngày hiện tại
- `nextDue` = tính toán ngày đến hạn tiếp theo dựa trên `frequency`:
  - Daily: +1 ngày
  - Weekly: +7 ngày
  - Monthly: +1 tháng
  - Quarterly: +3 tháng
  - Semi-Annually: +6 tháng
  - Annually: +1 năm

#### Bước 3: Xử lý lỗi
- Nếu một schedule gặp lỗi, hệ thống ghi log và tiếp tục xử lý các schedule khác
- Không dừng toàn bộ quá trình vì lỗi của một schedule

#### Bước 4: Trả kết quả
```json
{
  "success": true,
  "message": "Scheduler executed successfully",
  "data": {
    "createdCount": 5 // Số lượng Work Order đã tạo
  }
}
```

### 2.3. Cấu hình Scheduler

**Khuyến nghị:**
- Chạy scheduler mỗi ngày vào lúc 00:00 hoặc 06:00
- Sử dụng cron job hoặc task scheduler
- Ví dụ cron: `0 6 * * *` (chạy lúc 6 giờ sáng mỗi ngày)

---

## GIAI ĐOẠN 3: THỰC HIỆN CÔNG VIỆC

### 3.1. Mục đích
Work Order được tạo từ PM Schedule sẽ trải qua các bước thực hiện để hoàn thành công việc bảo trì.

### 3.2. Các trạng thái Work Order

#### Luồng trạng thái:
```
Draft → Approved → InProgress → Completed → Verified
                                    ↓
                                Cancelled
```

**Chi tiết các trạng thái:**

1. **Draft** (Nháp)
   - Work Order vừa được tạo tự động hoặc thủ công
   - Chưa được phê duyệt
   - Có thể chỉnh sửa, xóa

2. **Approved** (Đã phê duyệt)
   - Đã được supervisor/manager phê duyệt
   - Sẵn sàng để thực hiện
   - Có thể bắt đầu công việc

3. **InProgress** (Đang thực hiện)
   - Công việc đã bắt đầu
   - `actualStart` được ghi nhận
   - Kỹ thuật viên đang thực hiện

4. **Completed** (Đã hoàn thành)
   - Công việc đã hoàn tất
   - `actualEnd` được ghi nhận
   - Chờ xác nhận/kiểm tra

5. **Verified** (Đã xác nhận)
   - Đã được supervisor xác nhận chất lượng
   - Công việc chính thức kết thúc
   - Dữ liệu được sử dụng cho báo cáo

6. **Cancelled** (Đã hủy)
   - Công việc bị hủy bỏ
   - Có thể hủy từ bất kỳ trạng thái nào

### 3.3. Thông tin Work Order

#### Các trường dữ liệu:
- **woCode** (Bắt buộc, Unique): Mã công việc tự động
- **projectId** (Bắt buộc): ID dự án
- **contractId** (Tùy chọn): ID hợp đồng
- **assetId** (Tùy chọn): ID tài sản
- **workOrderType** (Bắt buộc): Loại công việc
  - `PM` - Bảo trì định kỳ
  - `CM` - Bảo trì sửa chữa
  - `Cleaning` - Vệ sinh
  - `Inspection` - Kiểm tra
  - `Upgrade` - Nâng cấp
- **title** (Bắt buộc): Tiêu đề
- **description** (Tùy chọn): Mô tả
- **status** (Mặc định: Draft): Trạng thái
- **priority** (Mặc định: Medium): Độ ưu tiên
  - `Low` - Thấp
  - `Medium` - Trung bình
  - `High` - Cao
- **scheduledStart** (Tùy chọn): Thời gian dự kiến bắt đầu
- **scheduledEnd** (Tùy chọn): Thời gian dự kiến kết thúc
- **actualStart** (Tùy chọn): Thời gian thực tế bắt đầu
- **actualEnd** (Tùy chọn): Thời gian thực tế kết thúc
- **assignedTechnicianId** (Tùy chọn): ID kỹ thuật viên chính
- **assignedTo** (Tùy chọn): Danh sách ID người được phân công (nhiều người)
- **supervisorId** (Tùy chọn): ID người giám sát
- **costLabor** (Mặc định: 0): Chi phí nhân công
- **costMaterial** (Mặc định: 0): Chi phí vật tư
- **costExternal** (Mặc định: 0): Chi phí dịch vụ bên ngoài
- **totalCost** (Tự động): Tổng chi phí = costLabor + costMaterial + costExternal
- **checklistProgress** (0-100): Tiến độ checklist

### 3.4. Quy trình thực hiện

#### Bước 1: Phê duyệt (Draft → Approved)
- Supervisor/Manager xem xét Work Order
- Cập nhật `status = 'Approved'`
- Có thể điều chỉnh `priority`, `scheduledStart`, `scheduledEnd`

#### Bước 2: Bắt đầu công việc (Approved → InProgress)
- Kỹ thuật viên nhận công việc
- Cập nhật `status = 'InProgress'`
- Ghi nhận `actualStart = new Date()`
- Bắt đầu thực hiện công việc

#### Bước 3: Hoàn thành công việc (InProgress → Completed)
- Kỹ thuật viên hoàn tất công việc
- Cập nhật `status = 'Completed'`
- Ghi nhận `actualEnd = new Date()`
- Nhập chi phí:
  - `costLabor`: Chi phí nhân công
  - `costMaterial`: Chi phí vật tư
  - `costExternal`: Chi phí dịch vụ bên ngoài
- Cập nhật `checklistProgress` (nếu có checklist)

#### Bước 4: Xác nhận (Completed → Verified)
- Supervisor kiểm tra chất lượng công việc
- Cập nhật `status = 'Verified'`
- Work Order chính thức kết thúc
- Dữ liệu sẵn sàng cho báo cáo

### 3.5. API Endpoints

#### GET `/api/work-orders?projectId={projectId}`
- **Mục đích**: Lấy danh sách Work Order theo dự án
- **Response**: Danh sách Work Order sắp xếp theo `createdAt` giảm dần

#### POST `/api/work-orders`
- **Mục đích**: Tạo Work Order thủ công (không từ PM Schedule)
- **Body**: Tương tự như Work Order được tạo tự động

#### PUT `/api/work-orders/:id`
- **Mục đích**: Cập nhật Work Order
- **Sử dụng**: 
  - Chuyển trạng thái
  - Cập nhật chi phí
  - Cập nhật thời gian thực tế
  - Cập nhật tiến độ

#### DELETE `/api/work-orders/:id`
- **Mục đích**: Xóa Work Order (chỉ khi status = Draft)

---

## GIAI ĐOẠN 4: BÁO CÁO

### 4.1. Mục đích
Hệ thống báo cáo tổng hợp dữ liệu từ Work Orders, Tickets, KPIs, và Financial để tạo các báo cáo chi tiết.

### 4.2. Các loại báo cáo

#### 4.2.1. Báo cáo Hàng ngày (Daily Report)

**Mục đích**: Tổng hợp hoạt động trong một ngày

**Dữ liệu bao gồm:**
- **Thông tin dự án**: Tên, mã dự án
- **Tickets**:
  - Tổng số tickets
  - Phân loại theo trạng thái
  - Phân loại theo độ ưu tiên
  - Phân loại theo danh mục
  - Danh sách chi tiết tickets
- **Work Orders**:
  - Tổng số work orders
  - Số lượng đã hoàn thành
  - Số lượng đang thực hiện
  - Tổng chi phí
- **Tóm tắt**:
  - Số tickets đang mở
  - Số tickets đã giải quyết
  - Số work orders đã hoàn thành

**API**: `POST /api/reports/generate`
```json
{
  "type": "Daily",
  "title": "Báo cáo ngày 01/02/2024",
  "projectId": "project_id"
}
```

#### 4.2.2. Báo cáo Hàng tháng (Monthly Report)

**Mục đích**: Tổng hợp hoạt động và hiệu suất trong một tháng

**Dữ liệu bao gồm:**
- **Thông tin dự án**: Tên, mã, công suất (MWp)
- **KPI**:
  - PR trung bình (Performance Ratio)
  - Tỷ lệ sẵn sàng trung bình (Availability)
  - Tổng sản lượng (kWh)
  - Specific Yield trung bình
  - Bức xạ trung bình (Irradiation)
- **Tickets**:
  - Tổng số tickets
  - Số tickets đã giải quyết
  - Thời gian giải quyết trung bình (giờ)
  - Phân loại theo danh mục
- **Work Orders**:
  - Tổng số work orders
  - Số lượng đã hoàn thành
  - Tổng chi phí
  - Phân tích chi phí:
    - Chi phí nhân công
    - Chi phí vật tư
    - Chi phí dịch vụ bên ngoài
- **Tài chính**:
  - Doanh thu
  - Chi phí vận hành (OPEX)
  - Lợi nhuận ròng

**API**: `POST /api/reports/generate`
```json
{
  "type": "Monthly",
  "title": "Báo cáo tháng 01/2024",
  "projectId": "project_id"
}
```

#### 4.2.3. Báo cáo Tài chính (Financial Report)

**Mục đích**: Phân tích tài chính trong khoảng thời gian (mặc định 12 tháng)

**Dữ liệu bao gồm:**
- **Thông tin dự án**: Tên, mã dự án
- **Dữ liệu tài chính theo tháng**:
  - Doanh thu
  - OPEX
  - Lợi nhuận ròng
  - ROI tích lũy
- **Tóm tắt**:
  - Tổng doanh thu
  - Tổng OPEX
  - Tổng lợi nhuận ròng
  - ROI trung bình
  - ROI hiện tại
  - Tỷ suất lợi nhuận (Profit Margin %)
- **Phân tích chi phí**:
  - Nhân sự O&M (35%)
  - Vật tư thay thế (20%)
  - Vệ sinh tấm pin (15%)
  - Bảo hiểm (10%)
  - Thuê đất (10%)
  - Khác (10%)

**API**: `POST /api/reports/generate`
```json
{
  "type": "Financial",
  "title": "Báo cáo tài chính 12 tháng",
  "projectId": "project_id",
  "financialData": {
    "financialData": [...],
    "costBreakdown": [...],
    "totals": {...}
  }
}
```

#### 4.2.4. Báo cáo Kiểm toán (Audit Report)

**Mục đích**: Theo dõi các hoạt động và thay đổi trong hệ thống

**Dữ liệu bao gồm:**
- **Thông tin dự án**: Tên, mã (nếu có)
- **Nhật ký hoạt động**:
  - Thời gian
  - Người thực hiện
  - Hành động (Create, Update, Delete)
  - Bộ sưu tập đích (tickets, workOrders, assets)
  - Chi tiết
- **Tóm tắt**:
  - Tổng số hành động
  - Phân loại theo hành động
  - Phân loại theo bộ sưu tập

**API**: `POST /api/reports/generate`
```json
{
  "type": "Audit",
  "title": "Báo cáo kiểm toán tháng 01/2024",
  "projectId": "project_id"
}
```

### 4.3. Quy trình tạo báo cáo

#### Bước 1: Yêu cầu tạo báo cáo
- Người dùng chọn loại báo cáo, nhập tiêu đề, chọn dự án
- Gửi request đến API `/api/reports/generate`

#### Bước 2: Tạo bản ghi Report
- Hệ thống tạo bản ghi Report với:
  - `status = 'Processing'`
  - `generatedDate = new Date()`
  - `createdBy = user_id`
- Trả về ngay lập tức để người dùng biết báo cáo đang được xử lý

#### Bước 3: Thu thập dữ liệu (Async)
- Sau 2 giây, hệ thống bắt đầu thu thập dữ liệu:
  - **Daily**: Lấy tickets và work orders trong ngày
  - **Monthly**: Lấy KPIs, tickets, work orders, financial trong tháng
  - **Financial**: Lấy financial data trong 12 tháng gần nhất
  - **Audit**: Lấy audit logs trong khoảng thời gian

#### Bước 4: Tạo PDF
- Sử dụng `PDFGenerator` để tạo file PDF từ dữ liệu
- Validate PDF (kiểm tra header `%PDF` và marker `%%EOF`)
- Lưu PDF dưới dạng base64 vào `downloadUrl`

#### Bước 5: Cập nhật trạng thái
- Nếu thành công: `status = 'Ready'`, lưu `downloadUrl` và `size`
- Nếu thất bại: `status = 'Failed'`

### 4.4. API Endpoints

#### GET `/api/reports?projectId={projectId}`
- **Mục đích**: Lấy danh sách báo cáo theo dự án
- **Response**: Danh sách báo cáo sắp xếp theo `generatedDate` giảm dần
- **Lưu ý**: Tự động populate thông tin người tạo (name/email)

#### POST `/api/reports/generate`
- **Mục đích**: Tạo báo cáo mới
- **Body**:
  ```json
  {
    "type": "Daily" | "Monthly" | "Financial" | "Audit",
    "title": "Tiêu đề báo cáo",
    "projectId": "project_id",
    "financialData": { ... } // Chỉ cho Financial report
  }
  ```
- **Response**: Trả về ngay với `status = 'Processing'`
- **Lưu ý**: PDF được tạo bất đồng bộ, cần kiểm tra lại sau

#### GET `/api/reports/:id/download`
- **Mục đích**: Tải xuống file PDF báo cáo
- **Validation**: 
  - Kiểm tra `status = 'Ready'`
  - Kiểm tra `downloadUrl` tồn tại
- **Response**: File PDF với headers phù hợp

#### DELETE `/api/reports/:id`
- **Mục đích**: Xóa báo cáo

### 4.5. Định dạng báo cáo

- **Format**: PDF (mặc định)
- **Encoding**: Base64 trong database
- **Download**: Data URL hoặc file download trực tiếp

---

## LUỒNG DỮ LIỆU VÀ API

### Sơ đồ luồng dữ liệu

```
┌─────────────────┐
│  PM Schedule    │
│  (Lịch bảo trì) │
└────────┬────────┘
         │
         │ [POST /api/pm-schedules/run-scheduler]
         │ Tự động tạo Work Order khi đến hạn
         ▼
┌─────────────────┐
│  Work Order     │
│  (Công việc)     │
└────────┬────────┘
         │
         │ [PUT /api/work-orders/:id]
         │ Cập nhật trạng thái, chi phí
         │
         │ [Status: Draft → Approved → InProgress → Completed → Verified]
         ▼
┌─────────────────┐
│  Report         │
│  (Báo cáo)      │
└─────────────────┘
         │
         │ Thu thập dữ liệu từ:
         │ - Work Orders (đã Verified)
         │ - Tickets
         │ - KPIs
         │ - Financial Data
         │ - Audit Logs
         ▼
    [PDF File]
```

### Các API chính

#### PM Schedules
- `GET /api/pm-schedules?projectId={id}` - Lấy danh sách
- `POST /api/pm-schedules` - Tạo mới
- `PUT /api/pm-schedules/:id` - Cập nhật
- `DELETE /api/pm-schedules/:id` - Xóa
- `POST /api/pm-schedules/run-scheduler` - Chạy scheduler

#### Work Orders
- `GET /api/work-orders?projectId={id}` - Lấy danh sách
- `POST /api/work-orders` - Tạo mới
- `PUT /api/work-orders/:id` - Cập nhật
- `DELETE /api/work-orders/:id` - Xóa

#### Reports
- `GET /api/reports?projectId={id}` - Lấy danh sách
- `POST /api/reports/generate` - Tạo báo cáo
- `GET /api/reports/:id/download` - Tải xuống
- `DELETE /api/reports/:id` - Xóa

---

## CÁC TRẠNG THÁI VÀ CHUYỂN ĐỔI

### PM Schedule Status

```
Active ──→ Paused ──→ Active
  │
  └──→ Inactive (Kết thúc)
```

- **Active**: Đang hoạt động, scheduler sẽ tạo Work Order
- **Paused**: Tạm dừng, scheduler bỏ qua
- **Inactive**: Không hoạt động, không tạo Work Order

### Work Order Status

```
Draft ──→ Approved ──→ InProgress ──→ Completed ──→ Verified
  │          │             │              │
  └──────────┴─────────────┴──────────────┴──→ Cancelled
```

**Quy tắc chuyển đổi:**
- `Draft` → `Approved`: Cần phê duyệt
- `Approved` → `InProgress`: Bắt đầu công việc, ghi `actualStart`
- `InProgress` → `Completed`: Hoàn thành, ghi `actualEnd`, nhập chi phí
- `Completed` → `Verified`: Xác nhận chất lượng
- Bất kỳ trạng thái nào → `Cancelled`: Hủy bỏ

### Report Status

```
Processing ──→ Ready
     │
     └──→ Failed
```

- **Processing**: Đang thu thập dữ liệu và tạo PDF
- **Ready**: Đã sẵn sàng, có thể tải xuống
- **Failed**: Lỗi trong quá trình tạo báo cáo

---

## LƯU Ý QUAN TRỌNG

### 1. Scheduler
- **Chạy định kỳ**: Nên cấu hình cron job để chạy scheduler hàng ngày
- **Thời gian**: Scheduler tìm các schedule có `nextDue` trong vòng 7 ngày tới
- **Xử lý lỗi**: Lỗi của một schedule không ảnh hưởng đến các schedule khác

### 2. Work Order
- **AssetId**: Có thể tạo Work Order mà không cần assetId (liên kết với contractId)
- **AssignedTo**: Hỗ trợ nhiều người được phân công (phân cách bằng dấu phẩy)
- **Chi phí**: `totalCost` được tính tự động từ costLabor + costMaterial + costExternal

### 3. Báo cáo
- **Bất đồng bộ**: Quá trình tạo PDF diễn ra bất đồng bộ (2 giây delay)
- **Validation**: PDF được validate trước khi lưu
- **Financial Report**: Có thể nhận dữ liệu từ frontend để đảm bảo tính chính xác

### 4. Dữ liệu
- **ProjectId**: Hệ thống hỗ trợ cả ObjectId và string ID (tương thích với demo data)
- **Timestamps**: Tất cả timestamps được lưu dưới dạng Date trong MongoDB
- **Indexes**: Các collection đã được index để tối ưu truy vấn

---

## KẾT LUẬN

Quy trình workflow từ Lịch bảo trì đến Công việc và Báo cáo được thiết kế để:
- **Tự động hóa**: Giảm thiểu công việc thủ công
- **Theo dõi**: Quản lý toàn bộ vòng đời công việc bảo trì
- **Báo cáo**: Cung cấp dữ liệu chi tiết cho quản lý và ra quyết định
- **Linh hoạt**: Hỗ trợ nhiều loại hợp đồng, tài sản, và người dùng

Hệ thống đảm bảo tính nhất quán dữ liệu và cung cấp các công cụ cần thiết để quản lý hiệu quả hoạt động bảo trì định kỳ.

---

**Tài liệu này được tạo tự động dựa trên phân tích mã nguồn hệ thống.**
**Ngày cập nhật: 2024**
