# Bulk create — Link files to Contract and Incident

Mục đích
- Cho phép liên kết nhiều file đã upload với một `contract_id` hoặc `incident_id` trong một lần gọi API.

Endpoints
- `POST /api/v1/contract-files` — Link nhiều file với một hợp đồng.
- `POST /api/v1/incident-files` — Link nhiều file với một sự cố.

Xác thực & quyền
- `POST /api/v1/contract-files`: yêu cầu `Bearer` token (middleware: `verify`).
- `POST /api/v1/incident-files`: yêu cầu `Bearer` token và quyền Admin (middleware: `verify`, `requireAdmin`).

Request body (JSON)
- Contract:
  - `contract_id` (string, uuid) — Bắt buộc.
  - `file_ids` (array[string, uuid]) — Bắt buộc, tối thiểu 1 phần tử.

- Incident:
  - `incident_id` (string) — Bắt buộc.
  - `file_ids` (array[string]) — Bắt buộc, tối thiểu 1 phần tử.

Ví dụ request — Contract
```json
{
  "contract_id": "9fbbf51b-50a3-1aea-baa0-18596c0eebdf/i",
  "file_ids": [
    "9d9f1450-dd41-79d9-31f4-5b3903429ac3/i",
    "f47ac10b-58cc-4372-a567-0e02b2c3d480/i"
  ]
}
```

Ví dụ request — Incident
```json
{
  "incident_id": "9fbbf51b-50a3-1aea-baa0-18596c0eebdf/i",
  "file_ids": [
    "9d9f1450-dd41-79d9-31f4-5b3903429ac3/i"
  ]
}
```

Hành vi (Behavior)
- Với mỗi `file_id` trong `file_ids`, API sẽ tạo một bản ghi `ContractFile` hoặc `IncidentFile` tương ứng.
- Trường `created_by` được gán từ `req.user?.id` (người gọi API).
- Toàn bộ thao tác được thực hiện bằng `bulkCreate(...)` trong provider tương ứng (`ContractFileProvider.bulkCreate` hoặc `IncidentFileProvider.bulkCreate`) và chạy trong giao dịch — nếu một phần thất bại thì rollback cả nhóm (atomic).
- Controller trả về mảng các bản ghi vừa tạo (HTTP 201 cho contract-files, HTTP 200 cho incident-files theo controller hiện tại).

Ví dụ response
```json
{
  "data": [
    {
      "id": "bb5ea6d5-fcd7-d0ca-d7ad-8f25a94bedd3",
      "contract_id": "9fbbf51b-50a3-1aea-baa0-18596c0eebdf/i",
      "file_id": "9d9f1450-dd41-79d9-31f4-5b3903429ac3/i",
      "created_by": "user-uuid",
      "created_at": "2026-05-18T12:34:56.000Z",
      "updated_at": null,
      "deleted_at": null
    }
  ]
}
```

Schema validator & controller
- Contract schema: [src/contracts/contract-file/schema.ts](src/contracts/contract-file/schema.ts)
- Contract controller: [src/controllers/api/v1/contract-files/index.ts](src/controllers/api/v1/contract-files/index.ts)
- Incident schema: [src/contracts/incident-file/schema.ts](src/contracts/incident-file/schema.ts)
- Incident controller: [src/controllers/api/v1/incident-files/index.ts](src/controllers/api/v1/incident-files/index.ts)

Lưu ý & khuyến nghị
- `file_ids` là trường bắt buộc; `file_id` (đơn lẻ) không còn được dùng.
- Nếu cần tránh bản ghi trùng (duplicate) nên thực hiện dedupe trước khi gọi API hoặc thêm kiểm tra trong provider.
- Nếu database có ràng buộc khóa ngoại (FK) hoặc ràng buộc unique, lỗi có thể xuất hiện và toàn giao dịch sẽ rollback.
- Nếu muốn thay đổi mã trạng thái trả về cho consistency, cân nhắc trả `201 Created` cho cả hai endpoints.

Hành động tiếp theo (tuỳ chọn)
- Dọn dẹp: xóa hai file tài liệu cũ `contract-files-bulk-create.md` và `incident-files-bulk-create.md` nếu không cần giữ bản riêng.
- Commit thay đổi tài liệu vào repo.
