- Auth/roles (no self-reg), admin user provision, JWT - Analyze: sales kit + initial pain-fit from form/upload - Persona generator: 15 personas (5/tier) w/ pain variety, negotiation, init mode, channel, latent/revealable, wrong_text special - Chat simulator: per-mode initiation, one-shot, hidden signals, judge-LLM debrief+coaching - Trainee loop: win/lose board, weak-areas, user-generated personas - Admin analytics; EN+TH Vue SPA served by Flask - Deploy: Dockerfile, docker-compose, README, eng-log + HANDOFF - Tests (mock LLM): m0/m1/routes/e2e all pass
2.9 KiB
2.9 KiB
HANDOFF — Sales Trainer
Another AI should be able to resume without chat history.
Branch / repo
- Repo:
~/Gitea/Sales Trainer/(local git initialized; no remote yet). - Branch:
main(default).
What this is
Corporate multi-user sales-training simulator. Vue SPA + Flask API + filesystem JSON storage. Admins build persona groups from a product (form + upload); trainees chat one-shot against generated customer personas to practice closing; judge-LLM scores + coaches.
Current state — COMPLETE (M0–M7), prototype verified with mock LLM
All backend + frontend built. All 4 backend test suites pass. Frontend builds. Live HTTP smoke test passes (SPA served, login, group create, register->404).
Verified commands
# Backend tests (mock LLM, no key needed)
cd backend
uv run python scripts/test_m0.py # auth/roles/no-self-reg
uv run python scripts/test_m1.py # group create + role visibility
uv run python scripts/test_routes.py # 21 routes registered
uv run python scripts/test_e2e.py # full flow (analyze->personas->chat->debrief->one-shot->board->analytics)
# Run backend
cd backend && uv run python run.py # Flask :5001 (serves built frontend from frontend/dist)
# Frontend dev
cd frontend && npm install && npm run dev # Vite :3000 proxying /api -> :5001
# Frontend build
cd frontend && npm run build # outputs frontend/dist
Default account
- super_admin:
admin@salestrainer.local/admin123(bootstrap; change in prod).
Key gotchas
- Do NOT invoke
.venv/bin/python <script>directly — the tool lifecycle guard crashes ("embedded null byte"). Always:uv run python scripts/<name>.py. - LLM creds in
.env(backend/.env for local; root.envfor compose).LLM_API_KEY=replace_meis a placeholder → LLM is None → analyze/chat return 500 "LLM not configured". - SPA fallback in
app/factory._register_frontendaccepts all HTTP methods and 404s/api/*so no-self-registration holds.
Blockers / open items
- Real-LLM E2E not yet run (needs a live API key). This is the #1 item.
- Docker image not built locally (no Docker on this Mac). Validate on EasyPanel.
- No git remote set (Gitea).
Exact next actions
- Set real
LLM_PROVIDER+LLM_API_KEY(and optionally base/model) inbackend/.env. - Run a live smoke test: login → create group → analyze → pick persona → chat a few turns → finish → read debrief; confirm judge produces sane output (this exercises real analyzer/persona/chat/judge).
- Fix any real-model issues surfaced (prompt drift, JSON parsing).
- Add Gitea remote + push. Optionally wire Gitea Actions / EasyPanel deploy.
- If EasyPanel: build from root
Dockerfile, set env vars, map port 5001.
Docs
docs/PLAN.md— full design + all confirmed decisions & open questions.docs/engineering-log.md+docs/engineering-log/2026-08-07-build-out.md— milestone record.README.md— quick start, accounts, tests, LLM config.