# ĐẶC TẢ HỆ THỐNG KHO LƯU TRỮ — v2 (Brain)

> Mô hình mới của Founder. Thay bản cũ (kho chỉ theo vai). Tài liệu do BA AtoZ soạn.

## 0. Khái niệm & phân biệt

| Thuật ngữ | Ý nghĩa | Ghi chú |
|---|---|---|
| **DEMO** | Nơi **xem bản demo** sản phẩm/mẫu | Không phải kho lưu trữ, không quản hồ sơ |
| **KHO** | Nơi **lưu trữ** tài liệu/hồ sơ cho bộ phận | Có phân quyền, nhật ký, phân bổ theo dự án/ticket/bộ phận |
| **KHO TỔNG HỢP** | Kho chung, **ai cũng xem** | Không thuộc dự án nào |

## 1. Mô hình dữ liệu

### Thực thể chính

| Thực thể | Trường chính | Mô tả |
|---|---|---|
| **Kho (Warehouse)** | id, loại (`du-an` \| `ticket` \| `bo-phan` \| `tong-hop`), chủ_thể_id | 1 kho gắn với 1 dự án / ticket / bộ phận, hoặc kho tổng hợp |
| **ThưMục (Muc)** | id, kho_id, tên (`marketing`,`ho-so`,`tong-hop`...), đường_dẫn | Đường dẫn: `Kho/<du-an>/<muc>` |
| **File** | id, muc_id, tên, url, **loại** (`ho-so`,`kinh-doanh`...), **tag[]**, người_upload, ngày, mô_tả_text | Tag/loại phục vụ sort & tìm theo text |
| **LiênKếtFile** | file_id, dự_án_id?, ticket_id?, bộ_phận_id? | Liên kết file ↔ dự án/ticket/bộ phận (phục vụ union 3 nguồn) |
| **Quyền (Permission)** | bộ_phận_id, kho_id \| loại_kho, mức (`xem`\|`quản`) | Bộ phận nào xem/quản kho nào |
| **NhậtKýChuyển (MoveLog)** | id, file_id, người, thời_điểm, từ_kho, đến_kho, ghi_chú | **Bắt buộc** mỗi lần chuyển kho |

### Quan hệ

```
Kho 1─* ThưMục 1─* File
File *─* {DựÁn, Ticket, BộPhận}   (qua LiênKếtFile)
BộPhận *─* Kho                     (qua Permission)
File 1─* NhậtKýChuyển
```

## 2. Luồng UPLOAD (chọn mục)

| Bước | Hành động |
|---|---|
| 1 | Chọn tệp |
| 2 | Chọn **đích**: (a) Dự án → Mục (`marketing`/`ho-so`/`tong-hop`), HOẶC (b) Kho tổng hợp |
| 3 | Gắn **Loại** (`ho-so`,`kinh-doanh`...) + **Tag** tự do |
| 4 | (Tùy) mô tả text để tìm sau |
| 5 | Lưu → tạo File + LiênKếtFile tương ứng |

**Quy tắc:** upload không bắt buộc quyền quản; ai upload được thì chọn đích trong phạm vi kho mình có quyền xem/góp.

## 3. Luồng CHUYỂN KHO (nhật ký bắt buộc)

| Bước | Hành động | Kiểm soát |
|---|---|---|
| 1 | Chọn file cần chuyển | — |
| 2 | Chọn kho/mục đích | Chỉ **Quản Kho / Quản Dự Án** mới thao tác được |
| 3 | Nhập ghi chú | — |
| 4 | Xác nhận → ghi **1 dòng NhậtKýChuyển** (ai, khi nào, chuyển gì, từ đâu→vào đâu) | **Chặn** nếu thiếu log |

> Không có nhật ký ⇒ không cho chuyển (ràng buộc cứng).

## 4. Truy vấn "Kho của bộ phận X" = UNION 3 nguồn

| Nguồn | Nội dung |
|---|---|
| (a) | Kho các **DỰ ÁN** mà bộ phận X tham gia |
| (b) | Kho các **TICKET** mà bộ phận X xử lý |
| (c) | Kho **RIÊNG** của bộ phận X |

```
KhoBoPhan(X) = files(dự-án X tham gia)
             ∪ files(ticket X xử lý)
             ∪ files(kho riêng X)
```
Kết quả trả về đã **khử trùng** theo file_id, kèm nguồn gốc mỗi file.

## 5. Phân quyền

| Vai | Xem | Upload | Chuyển kho | Quản mục |
|---|---|---|---|---|
| Nhân viên bộ phận | Kho được cấp + Tổng hợp | ✔ | ✘’ | ✘ |
| Quản Kho / Quản Dự Án | Kho phụ trách | ✔ | ✔ | ✔ |
| Tổng hợp (mọi người) | ✔ (chỉ đọc) | theo cấu hình | ✘ | ✘ |

- Quyền xem gắn theo **bộ phận**, không theo cá nhân.
- Tìm kiếm cũng lọc theo bộ phận (chỉ thấy phạm vi được phép).

## 6. Tìm / Sort

| Tiêu chí | Cách |
|---|---|
| Theo **text** | tên + mô tả + tag + loại (full-text) |
| Theo **loại/tag** | filter `ho-so`,`kinh-doanh`... |
| Theo **bộ phận** | lọc trong phạm vi quyền của bộ phận |
| Sort | ngày, loại, tag, dự án |

## 7. Route Brain đề xuất

| Route | Chức năng |
|---|---|
| `GET /kho/:duan/:muc` | Xem mục của dự án |
| `GET /kho/tong-hop` | Kho tổng hợp |
| `POST /kho/upload` | Upload (chọn dự án+mục/tổng hợp, loại, tag) |
| `POST /kho/chuyen` | Chuyển kho (ghi nhật ký bắt buộc) |
| `GET /kho/bo-phan/:id` | **Union 3 nguồn** của bộ phận |
| `GET /kho/ticket/:id` | Kho riêng của ticket |
| `GET /kho/search?q=&loai=&bophan=` | Tìm/sort theo text + bộ phận |
| `GET /kho/nhat-ky?file=` | Xem nhật ký chuyển |

## 8. Tiêu chí nghiệm thu

- [ ] Phân biệt rõ DEMO vs KHO trong UI.
- [ ] Tạo được `Kho/<du-an>/<muc>` và 1 Kho Tổng Hợp ai cũng xem.
- [ ] Upload cho chọn dự án+mục HOẶC tổng hợp; gắn được loại + tag.
- [ ] Tìm theo text/tag/loại trả đúng kết quả trong phạm vi bộ phận.
- [ ] Chuyển kho **chỉ** Quản Kho/Quản Dự Án làm được; **bắt buộc** sinh 1 dòng nhật ký (ai/khi nào/chuyển gì/vào đâu); thiếu log ⇒ bị chặn.
- [ ] Ticket có kho riêng, upload & phân bổ theo task.
- [ ] `GET /kho/bo-phan/:id` trả **union 3 nguồn** (dự án + ticket + kho riêng), khử trùng, kèm nguồn gốc.
- [ ] Quyền xem theo bộ phận đúng: không thấy kho ngoài phạm vi.
