6.8 KiB
6.8 KiB
HANDOFF — Sales Trainer
Another AI should be able to resume without chat history.
Branch / repo / deploy
- Repo:
~/Gitea/Sales Trainer/— git repo, remote = Gitea. - Remote:
https://git.moreminimore.com/kunthawat/sales-trainer.git(GITEA_TOKEN via credential helper; never committed). - Live deploy:
https://moreminimoreapps-saletrainer.ahkhwd.easypanel.host— EasyPanel, auto-redeploys from Gitea on push tomainvia webhook (≈3 min). Dockerfile ships prebuiltfrontend/dist/(no npm in image). LLM vars set in EasyPanel env.
What this is
Corporate multi-user sales-training simulator: admins create persona groups from a product/service/idea (โฟกัส "สินค้า/บริการ/ไอเดีย"), app auto-generates 15 customer personas (5/tier A/B/C) via LLM; trainees pick a scenario (social / พบหน้า), chat 1:1 one-shot to close a sale; a per-turn + final judge LLM evaluates feelings and scores/coaches. Vue SPA + Flask API + filesystem JSON storage (no SQL). i18n TH/EN. No self-registration (admin provisions).
Roles
- super_admin (bootstrap
admin) — full recipe (secret persona fields) + tenant admin. - admin — manages groups/users, sees personas with secret fields stripped (IP protection).
- user (trainee) — trains against personas, own board.
Current state — COMPLETE core + hardened
All backend + frontend built. 11 test suites green (mock LLM):
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_setup.py # first-time admin setup (email+password+ToS)
uv run python scripts/test_security.py # path traversal / IDOR / XSS
uv run python scripts/test_scenario.py # 2 scenarios (social/f2f_call), recontact default
uv run python scripts/test_e2e.py # full flow -> won via judge
uv run python scripts/test_ip_protection.py # secret fields hidden from admin
uv run python scripts/test_saas_tenant.py # tenant isolation + rate-limit + audit
uv run python scripts/test_user_journey.py # idea-flow end-to-end
uv run python scripts/test_variant.py # clone-persona-from-persona
uv run python scripts/test_resume_decision.py # resume + per-turn LLM decision
# run backend (serves SPA from frontend/dist)
cd backend && uv run python run.py # Flask :5001
Key behaviors (implemented)
- One-shot: 1 persona = 1 chat per user; result final (won/lost).
SessionStoreenforces. - Resume: unfinished session resumes on re-entry — no scenario re-pick (same session+scenario).
- Win/loss = per-turn LLM judge (
Simulator.evaluate_turn): every customer reply is evaluated →{mood, decision(buy|walk|pending), score_delta, reason}; session ends when decision = buy/walk. Not fixed keywords. - 2 scenarios only:
social,f2f_call. Unknown → social. - Recontact = persona trait (not a scenario): chats normally, then at turn ≥ 2 a time-lapse system note ("⏳ ผ่านไป 2-3 สัปดาห์…"), then re-engages warmer.
- Persona variant:
POST /api/groups/<gid>/personas/<pid>/variant— new persona (new id) that locks pains/objections/levers/tolerance/special/recontact/goal/budget/difficulty/tier/product but varies identity (name/profession/age/location/background/personality/opener). Lets a trainee re-practice the same challenge (one-shot is per-persona). UI button on finished personas. - Auto 15 personas on create; no "เพิ่มเติม" button (TARGET=15, retry up to 3× + accept ≥ 8 so real LLM under-count doesn't 500).
- IP protection:
SECRET_PERSONA_FIELDS(pains, objections, negotiation_levers, opener, tolerance, rootCause, resolutionConditions) stripped foradmin; full only forsuper_admin. - SaaS Phase 1–3 done: tenant isolation (
g.org_id+assert_tenant), login/chat rate-limit, audit log (data/audit/audit.jsonl), org plan/seats/active model +PATCH /api/admin/orgs/<id>, ToS consent on setup, org-scoped signed expiring CSV export (5-min HMAC). - Reduce raw JSON in UI:
list_groupsreturns lightweight summary (persona_count, no full array); persona detail rendered as readable form/cards (pain = line-by-line, not[object Object]).
Credentials / data (testing)
- Bootstrap super-admin
admin/1234→ first login forces email + new password + ToS consent. - Live test users:
testadmin/1234(admin),testuser/1234(user). - A test group "CRM ระบบจัดการลูกค้า" exists on live (user keeps it; will delete it themselves).
- LLM key is a placeholder on local
.env(replace_me). Real analyze/chat needs a realLLM_API_KEY(+LLM_PROVIDER/LLM_MODEL/LLM_BASE_URL) in EasyPanel env then redeploy.
Environment / gotchas
- Python 3.11 only (system default 3.14 incompatible). Use
backend/.venvorcd backend && uv run python …. - Tooling guard crash: commands whose first token is
./.venv/bin/pythontrip a lifecycle guard → always useuv run python. PrefixPYTHONPATH=when needed. - Frontend build:
cd frontend && npm run build(works even with allowScripts restrictions). Commitfrontend/dist/withgit add -f(it's gitignored otherwise); the Dockerfile needs it. - Deploy pattern: commit + push → webhook auto-deploys in ~3 min. Cannot run Docker locally
(no Docker on this Mac) → test with nginx/
python http.serveroruv run python run.py. - No remote push without asking unless it's the established auto-deploy cadence.
search_files/read_filesometimes misdetect files as binary (e.g.users.py, some.vue); useterminal+sed -n 'N,Mp' <file>orawkfor those.
Wire-authorized / known-limits
- Chrome/Vivaldi drivable via computer-use; current model (DeepSeek V4 Flash) reads screenshots
imperfectly, and window-edge resize to a 320px viewport didn't land — mobile visual QA at
320/500px still needs the user's eyes (open live URL on phone, or DevTools device toolbar).
Responsive CSS (640px, single-column,
flex-wrap,.btn-back) is present + deployed.
Next actions / backlog (also docs/FUTURE_WORK.md)
- Real
/legalpage (setup links to it), billing/payments, per-tenant storage volume, compressed persona recipe, export-token polish. - Mobile visual polish per user feedback on real device.
- Deeper: letting admins bulk-import personas, analytics drill-down per persona variant.
Related docs
docs/PLAN.md,docs/SAAS_PLAN.md,docs/FUTURE_WORK.md.docs/engineering-log.md+docs/engineering-log/2026-08-09-idea-flow-qa-deploy.md(this session: idea-flow UX, 2-scenario + recontact trait, live QA + auto-deploy, per-turn LLM judge, persona variant, 15-persona auto-gen).