# Review — Cách chia module hiện tại (`ws_suns/modules/`)

> Cập nhật: 06/7/2026 · Thuộc [Kế hoạch giai đoạn 1](README.md) · Liên quan: [Schema](schema-du-lieu-2026-07-06.md) · [Plan data-scope](plan-data-scope-2026-07-06.md)
>
> Review dựa trên đọc trực tiếp manifest + migrations của các module trong `ws_suns/modules/`:
> `catalog, student, course, teacher, vehicle, dat(-device), rfcard, account, base`.
>
> **Trạng thái: đã chốt cả 2 quyết định (06/7)** — (A) `account` giữ trong repo, không cài, không dùng; (B) tách module `tuition` ngay từ đầu (schema đã cập nhật).

---

## 1. ✅ Hợp lý — giữ nguyên

| Module | Nhận xét |
|---|---|
| `catalog` | Chuẩn — danh mục dùng chung tách riêng, các module khác `depends: ["catalog@>=1.0"]`. Đúng chỗ để thêm checklist giấy tờ (`catalog_loai_giay_to`, `catalog_hang_giay_to`) |
| `student` / `course` / `teacher` / `vehicle` | Chia theo subsystem legacy → migrate 1:1 từ QLHS V2, ranh giới rõ |
| `dat` | Đúng khi tách riêng — thiết bị có vòng đời riêng (bàn giao, hết hạn); roadmap v2 sẽ tự phát triển DAT |
| `rfcard` | Chấp nhận được — thẻ có vòng đời cấp/thu, dùng chung cho cả GV lẫn HV nên không nhét vào `student` |

---

## 2. ⚠️ Có vấn đề — cần sửa

### 2.1 Module `account` — lỗi copy-paste từ template (3 chỗ)
1. Migration comment ghi *"Prefix bắt buộc: base_"* nhưng bảng là `account_items`.
2. Index đặt tên `idx_base_items_*` — sai prefix (phải là `idx_account_items_*`).
3. **Nghiêm trọng nhất:** nav trong `manifest.json` khai `"module": "base"`, route `/base` — **đè nav của module `base` thật** khi cài cùng nhau.

→ `account` và `base` đều là **demo items, không phải domain** — **không cài vào workspace Vĩnh An**. Nếu sau này dùng `account` làm module thật thì phải sửa cả 3 lỗi trên trước.

### 2.2 Denormalize trong `student_nguoi_lx`
`ma_kh, ten_kh, ma_xe_tap, ma_xe_tap_phu` là bản copy từ `course`/`vehicle`. Chấp nhận được vì bám legacy để migrate, nhưng:
- `ten_kh` sẽ lệch khi đổi tên khóa học;
- **Quy tắc từ nay: không thêm cột denormalize mới** — cột mới đi qua khóa tham chiếu.

### 2.3 Tham chiếu chéo module không nhất quán
`vehicle_xe_tap_lai` có cả `dat_device_id` (id cứng) lẫn `seri_dat` (khóa nghiệp vụ) trỏ sang module `dat`.

→ **Chốt quy ước:** vì module cài/gỡ độc lập, tham chiếu **chéo module dùng khóa nghiệp vụ** (`seri_dat`, `ma_kh`, `ma_gv`, `rfid`); id cứng (FK int) chỉ dùng **nội bộ trong một module**.

### 2.4 Ngữ nghĩa bảng `student_nguoi_lx` — gọi đúng tên
`UNIQUE (ma_dk, ma_kh, ma_csdt)` ⇒ 1 dòng = **1 lượt đăng ký theo khóa**, không phải "1 con người" (1 người học 2 khóa = 2 dòng).
- Thuận lợi: khớp tự nhiên với lớp hồ sơ WS1 (hồ sơ theo khóa).
- Lưu ý: app học viên (v1.5) cần định danh **người** qua `so_cmt`/`user_id` — liên quan P3 của [plan data-scope](plan-data-scope-2026-07-06.md) (thêm cột `user_id`).

---

## 3. ❌ Thiếu module cho phạm vi GĐ1 — đề xuất bổ sung

| Đề xuất | Hình thức | Lý do |
|---|---|---|
| Hồ sơ workflow | **Feature `hoso` trong `student`** (không tách module) | Cùng vòng đời học viên; bảng `student_ho_so_lichsu`, `student_ho_so_giayto` như [Schema §2](schema-du-lieu-2026-07-06.md) |
| **`tuition` (module mới)** — công nợ đợt | Tách **ngay từ đầu**: bảng `tuition_hoc_phi_dot` | **Sửa đề xuất schema trước** ("tạm ở student, chuyển sau"): quy tắc prefix bảng theo key ⇒ chuyển module sau = đổi tên bảng, đau migrate. Kế toán/HĐĐT v1.5 mở rộng module này |
| Phiên học DAT (đối soát km/giờ) | **Feature `session` trong `dat`** — bảng `dat_phien_hoc` | Painkiller MVP; nằm cạnh `dat_device`/`dat_log` là đúng chỗ |
| **`report` (module mới)** — báo cáo Sở XD | Module riêng, đọc chéo student/course/dat | Bản chất là consumer nhiều module, không thuộc module nào; permission `report.main.so-xd.{view,export}` |

### Bản đồ module mục tiêu GĐ1

```
catalog   ── danh mục (hạng GPLX, trình độ…) + NEW: loại giấy tờ, checklist theo hạng
student   ── học viên + NEW feature hoso (trạng thái, lịch sử, giấy tờ)
course    ── khóa học            teacher ── giáo viên
vehicle   ── xe tập lái          rfcard  ── thẻ RFID
dat       ── thiết bị + log + NEW feature session (phiên học, đối soát km/giờ)
tuition   ── NEW: công nợ học phí theo đợt (→ v1.5: kế toán, HĐĐT)
report    ── NEW: báo cáo tuân thủ Sở XD (đọc chéo, xuất mẫu)
account/base ── demo — KHÔNG cài vào workspace Vĩnh An
```

---

## 4. Việc cần làm sau khi chốt

- [x] **(A)** `account`: **đã chốt (06/7)** — giữ nguyên trong repo (không xóa) nhưng **không cài vào workspace**, chưa có tác dụng gì. 3 lỗi (prefix comment, tên index `idx_base_items_*`, nav `module:"base"`/route `/base`) để nguyên — chỉ sửa nếu sau này module được dùng thật.
- [x] **(B)** Tách `tuition` — **đã cập nhật** [Schema §2.4](schema-du-lieu-2026-07-06.md) (06/7): `tuition_hoc_phi_dot`, tham chiếu học viên bằng khóa nghiệp vụ `(ma_dk, ma_kh, ma_csdt)`.
- [x] Schema đã bổ sung `dat_phien_hoc` (feature `session` module `dat`) + `report_mau`/`report_da_lap` (module `report`) — xem [Schema §2.6–2.7](schema-du-lieu-2026-07-06.md).
- [ ] Ghi quy ước tham chiếu chéo module (khóa nghiệp vụ) vào `HUONG_DAN.md` của `ws_suns`.
- [ ] Scaffold 2 module mới `tuition`, `report` (theo template warehouse) khi bắt đầu code MVP.
