# 🚀 DOING: User Simulator — Hoàn thiện cơ chế giả lập User

## 📁 Folders & Files liên quan
```
backend/
├── agent/
│   ├── persona_generator.py          ← ❌ DELETE (duplicate 261 lines, 0 imports)
│   └── simulate_agent/
│       ├── persona_generator.py      ← ✅ Bản chính (235 lines)
│       ├── simulation_runner.py      ← MODIFY (thêm save to SQLite)
│       └── evaluator.py             ← OK (không đổi)
├── api/
│   └── user_simulator/
│       ├── user_simulator_route.py   ← MODIFY (thêm history/compare endpoints)
│       └── simulator_db.py           ← 🆕 NEW (SQLite helpers)
└── database/
    └── simulator.db                  ← 🆕 NEW (SQLite database)
```

## 📌 Context
- **Status:** 🚧 In Progress

## 🎯 Goal
Hoàn thiện hệ thống User Simulator để có thể tự động tạo persona giả lập, chat với chatbot, đánh giá chất lượng conversion, **lưu kết quả vào SQLite**, và so sánh giữa các phiên bản prompt.

## ⚠️ Active Trade-offs
- Storage: SQLite local (không dùng MongoDB/external service)
- Prompt source: đọc trực tiếp từ `agent/prompt_module/*.txt` (7 files có sẵn)

---

## 🔍 Hiện trạng

### ✅ Backend logic — DONE:
- `agent/simulate_agent/persona_generator.py` → LLM generate N personas (10 archetypes)
- `agent/simulate_agent/simulation_runner.py` → Full loop: persona → chat → evaluate
- `agent/simulate_agent/evaluator.py` → 5-criteria scoring + conversion + synthesis
- `api/user_simulator/user_simulator_route.py` → 7 endpoints đầy đủ

### ❌ Thiếu:
1. **Duplicate file** — `agent/persona_generator.py` (261 lines) trùng `agent/simulate_agent/persona_generator.py` (235 lines)
2. **Không lưu kết quả** — simulation results chỉ trả JSON, mất khi restart
3. **Không so sánh** — không A/B test prompt versions
4. **Không schedule** — không tự chạy định kỳ

---

## 🛠 Tao sẽ làm gì & làm như nào

### 🏗️ Kiến trúc:

```
┌─────────────────────────────────────────────────┐
│  database/simulator.db  (SQLite mới)            │
│                                                 │
│  ┌──────────────────┐  ┌────────────────────┐   │
│  │ simulation_runs  │  │ simulation_details │   │
│  │ ───────────────  │  │ ──────────────────  │  │
│  │ run_id (PK)      │  │ id (PK)            │   │
│  │ timestamp        │  │ run_id (FK)        │   │
│  │ persona_count    │  │ persona_name       │   │
│  │ turns            │  │ archetype          │   │
│  │ prompt_version   │◄─┤ conversion_status  │   │
│  │ model_name       │  │ scores_json        │   │
│  │ conversion_rate  │  │ conversation_json  │   │
│  │ avg_score        │  │ key_wins           │   │
│  │ summary_json     │  │ key_fails          │   │
│  └──────────────────┘  │ prompt_fix         │   │
│                        └────────────────────┘   │
└─────────────────────────────────────────────────┘
```

### 📐 Pattern theo project:
- DB file: `database/simulator.db` (cùng thư mục với `autotrain.db`)
- Init: `init_db()` tự tạo bảng khi import (pattern y hệt `autotrain_route.py` line 36-98)
- Connection: `sqlite3.connect()` sync (pattern giống `autotrain_route.py`, không cần aiosqlite vì data nhỏ)

---

## 📋 Execution Checklist

### Phase 1: Cleanup duplicate (~5m)
- [x] Task 1.1: Grep confirm `from agent.persona_generator` không ai dùng
- [x] Task 1.2: Xóa `agent/persona_generator.py` (file orphan 261 lines)

### Phase 2: SQLite storage cho simulation results (~25m)
- [x] Task 2.1: Tạo `database/simulator.db` với 2 bảng:
  - `simulation_runs`: run_id, timestamp, persona_count, turns, prompt_version, model_name, chatbot_url, conversion_rate, interest_rate, avg_score, summary_json, errors_json
  - `simulation_details`: id, run_id (FK), persona_name, archetype, age, gender, budget, shopping_for, conversion_status, conversion_reason, scores_json, conversation_json, key_wins, key_fails, prompt_fix, products_json
- [x] Task 2.2: Tạo helper functions trong `api/user_simulator/simulator_db.py`:
  - `init_simulator_db()` — tạo bảng
  - `save_simulation_run(run_data)` → insert run + details, return run_id
  - `get_simulation_runs(limit)` → list runs
  - `get_simulation_run(run_id)` → chi tiết 1 run + all persona results
  - `compare_runs(run_id_1, run_id_2)` → conversion rate delta
- [x] Task 2.3: Hook `save_simulation_run()` vào cuối `simulation_runner.run_simulation()` — auto-save khi chạy xong

### Phase 3: API endpoints mới (~15m)
- [x] Task 3.1: `GET /api/user-simulator/history` → list all past runs (from SQLite)
- [x] Task 3.2: `GET /api/user-simulator/history/{run_id}` → chi tiết 1 run + persona results
- [x] Task 3.3: `GET /api/user-simulator/compare?run1=xxx&run2=yyy` → so sánh 2 runs
- [x] Task 3.4: Thêm `prompt_version` param vào `POST /run-simulation` → lưu kèm run

### Phase 4: Prompt version tracking (~10m)
- [x] Task 4.1: Đọc prompt version từ `agent/prompt_module/` — hash nội dung 7 files → tạo version string (VD: `v-a3f2b1`)
- [x] Task 4.2: Auto-attach prompt_version vào mỗi simulation run
- [x] Task 4.3: Compare endpoint hiển thị prompt diff nếu version khác nhau

### Phase 5: Testing (~10m)
- [x] Task 5.1: Test run-simulation → verify data saved vào simulator.db
- [x] Task 5.2: Test history + detail endpoints
- [x] Task 5.3: Test compare endpoint

## 🔄 Sub-Doings
_None yet_

## ✅ Completion Gate
- [x] All tasks [x] | [x] Sub-Doings resolved | [x] Smoke test passed | [x] Trade-offs confirmed

---
_Started: 2026-05-10 | Updated: 2026-05-10_
