# Kiến trúc AI Stylist: Mapping Cứng theo `Product Line` & `Màu Sắc`

## Vấn Đề Hiện Tại
Hệ thống AI đang đọc các Tag Text NLP (`phong_cach`, `dip_mac`) trong `ultra_descriptions`. Do data nhập liệu tay lộn xộn, AI Recommend bị nhiễu tĩnh, gợi ý sai hoàn toàn các Set đồ so với Logic chuẩn.

## Giải Pháp Mới
- **BỎ hòan toàn quét NLP Tags.**
- Chỉ quét duy nhất cột **Danh Mục Sản Phẩm (Product Line)**. Hệ thống sẽ có Hard-coded Mappings chỉ định rõ Danh Mục A khi ở Dịp B thì ĐƯỢC PHÉP đi với Danh Mục C.
- **Tiêu chí Màu sắc** dùng làm "Trọng tài Cuối cùng" để tính điểm và Rank Top hiển thị.

---

## 1. Ma Trận Dịp Mặc (Occasions) × Danh Mục (Product Line)
Map cứng trực tiếp vào Logic của Engine (Hoặc DB `chatbot_fashion_rules`).

| Dịp (Occasion) | Nếu Khách Chọn (Anchor) | Thì Gợi Ý Phối Cùng (Targets) |
| :--- | :--- | :--- |
| **💼 Đi làm công sở** | `Áo Sơ mi`, `Áo Polo`, `Blouse` | `Quần khaki`, `Quần âu`, `Chân váy`, `Blazer/Vest` |
| | `Quần khaki`, `Quần âu` | `Áo Sơ mi`, `Áo Polo`, `Cardigan` |
| **🛍️ Đi chơi / dạo phố** | `Áo phông`, `Áo kiểu`, `Áo nỉ` | `Quần jean`, `Quần soóc`, `Chân váy ngắn`, `Áo khoác gió` |
| | `Quần jean`, `Quần soóc` | `Áo phông`, `Áo nỉ`, `Áo kiểu` |
| **🏠 Ở nhà / mặc ngủ** | `Áo phông`, `Áo hai dây` | `Quần mặc nhà`, `Quần đùi cotton` |
| **🏖️ Du lịch** | `Áo phông`, `Váy liền` | `Chân váy maxi`, `Quần soóc`, `Mũ/Kính râm` |

*(Chỉ có các sản phẩm thỏa mãn mảng Target Line này mới được đưa vào phễu tính điểm màu sắc).*

---

## 2. Lưới Lọc "Hòa Sắc" (Color Synergy) Điểm Vòng 2

Sau khi có danh sách Target Product Line hợp quy:
- **Áo Màu Trắng/Đen/Trung Tính:** Buff `+30đ` cho Quần Trắng/Đen (An toàn). Buff `+25đ` cho Quần Dark (Cá tính).
- **Áo Màu Nổi (Cam/Hồng):** Ép `+30đ` cho các Quần Đen/Trắng để tiết chế lại. Các quần cùng màu Hồng sẽ bị trừ điểm nặng hoặc chỉ cho `+5đ` nếu là Tone-sur-tone.
- **Lưới Nhân khẩu học:** Nam auto trừ điểm nhóm Pastel/Hồng. Bé Gái auto buff điểm nhóm Nhạt/Bèo nhún.

## 3. Checklist Nhiệm vụ cho AI Agent (Claude Code)
_(Claude Code vui lòng thực hiện tuần tự các bước sau và check `[x]` khi hoàn thành)_

- [x] **Bước 1:** Đọc file `backend/worker/fashion_rules.json` và `backend/worker/stylist_engine.py` (hàm `_score`, `compute_dynamic_rule_matches`) để hiểu code base hiện tại đang chấm điểm bừa bãi theo Tags thế nào.
- [x] **Bước 2:** Đọc file DB gốc tại `backend/database/canifa_ai_dump.sqlite`. Xem schema của bảng `chatbot_fashion_rules` (gồm `anchor_category`, `target_category`, `match_role`, `occasion_tag`, `ai_reason`).
- [x] **Bước 3:** Tạo 1 script Python tại `backend/scripts/seed_product_line_matrix.py`. Script này kết nối vào SQLite, chạy lệnh dọn dẹp `DELETE FROM chatbot_fashion_rules;` và insert hàng loạt các record ứng với Ma trận Mapping ở Mục 1 (Ví dụ: `anchor='Áo sơ mi'`, `target='Quần âu'`, `occasion='di_lam_cong_so'`).
- [x] **Bước 4:** Chạy script tạo dữ liệu thành công. (Đã insert 51 rules: di_lam 21, di_choi 18, mac_nha 4, du_lich 8)
- [x] **Bước 5:** Refactor lại tệp `backend/worker/stylist_engine.py`:
  - Thêm `_fetch_allowed_mappings()` và `_fetch_rules_with_reason()` để lấy rules từ DB.
  - Sửa `_compute_matches()`: chỉ cho phép target nếu target_category nằm trong DB rules cho occasion đó.
  - Cắt bỏ hoàn toàn `_occasion_score` và `_style_score` trong `_score()`.
  - Sửa `_score()` chỉ còn color + role + material.
  - Sửa `compute_dynamic_rule_matches()` để dùng DB rules filter và `_score()` mới.
- [x] **Bước 6:** Sửa lại `_color_score` đã có sẵn logic Color Synergy (dùng color_group_matrix). Cập nhật `fashion_rules.json` weights về `{"color": 50, "role": 30, "material": 20}`.
- [x] **Bước 7:** Test lại bằng cách kích hoạt `run_batch()` hoặc request POST đến `/api/fashion-matches/batch`, đảm bảo hệ thống render thành công toàn bộ `ai_matches` mà không sập.
