# 🎯 Sales Trainer A **corporate, multi-user sales-training simulator**. Admins upload/describe a product; the app analyzes it and generates **15 realistic customer personas** (5 per buying-intent tier) with real, varied pains. Trainees **chat one-on-one** with each persona to practice closing a sale — customers negotiate, stall, and refuse unless their pain is genuinely resolved. Debrief reveals + coaches. Built on patterns from the **CrowdSight / MiroFish** swarm engine and clean-room Hermes Brain & Tools plugin. --- ## Features - **Login + roles** (no self-registration): `super_admin` / `admin` / `user`. - Admin builds & edits **persona groups** (product + 15 personas), hand-edits personas, sees analytics. - User (trainee) **can't create** — only selects a group and practices; sees own results. - **Input** via form (product / segment / description) **and/or file upload** (.pdf/.md/.txt). Product data is used mainly to extract **pains**; personas are reusable across similar products. - **15 personas** (5 × tier A/B/C): - A = ready to buy · B = unsure · C = not interested but has pain (hardest). - Varied demographics, income, occupation, lifestyle, personality — consistent with product. - **Pain variety** (directly-solvable / partial / unrelated red-herring). - **Negotiation levers** (price, freebies, delivery time, scope, payment). - **Initiation mode**: customer opens OR seller must open the sale (outbound, e.g. insurance). - **Channel**: Facebook / LINE. - Special tier-C **"wrong_text"** persona (appears to buy, loses interest, but still has pain). - **One-shot rule**: a persona is chatted **once per user** (final); shared across other users. - **Chat realism**: all tiers can lose; everything negotiates; hidden internal signals + latent fields (pain/income/personality/budget) revealed only after the result. - **Debrief**: short summary + **coaching** (how to answer better on weak-score messages), scored by a **separate judge LLM** (no speed factor). - **Training loop**: win/lose board, **weak-area analysis**, and **user-generated personas** (weak-area "lock" or manual form). - **Admin analytics**: close rate, avg score, hardest personas. - **EN + TH** UI. --- ## Quick start ### Local (dev) ```bash # backend (Python 3.11) cd backend uv venv --python 3.11 .venv uv pip install -r requirements.txt --python .venv/bin/python cp .env.example .env # edit LLM keys + JWT_SECRET uv run python run.py # Flask on :5001 # frontend (separate terminal) cd frontend npm install npm run dev # Vite on :3000 -> proxies /api to :5001 ``` The first run creates a default super-admin: **`admin@salestrainer.local` / `admin123`** (change it!). ### Docker / EasyPanel ```bash cp .env.example .env # set LLM_API_KEY + a strong JWT_SECRET docker compose up -d # single container serving frontend + API on :5001 ``` --- ## LLM config Any OpenAI-compatible endpoint (OpenAI, DeepSeek, or custom base URL): ```env LLM_PROVIDER=deepseek # deepseek | openai | custom LLM_BASE_URL= # optional override LLM_MODEL_NAME=deepseek-chat # optional override LLM_API_KEY=sk-... ``` --- ## Architecture ``` frontend/ Vue 3 + Vite SPA (login, dashboard, group builder, personas, chat, debrief, gen-persona, weak-areas, analytics). Built to dist/ and served by Flask. backend/ Flask API (JWT auth, roles, groups, analyzer, persona generator, chat simulator, judge, trainee loop, analytics). Filesystem JSON persistence (no external DB). app/services/ analyzer · persona_generator · simulator (+ judge) · report · trainee · groups · sessions docs/PLAN.md full design & decisions record ``` - **Storage**: `backend/data/` — JSON files per entity (users, orgs, groups, sessions, my_personas). - **LLM calls**: analyzer (sales kit + pain-fit), persona generator, persona chat, judge. --- ## Tests Run with the built-in deterministic **mock LLM** (no external key needed): ```bash cd backend uv run python scripts/test_m0.py # auth/roles/no-self-registration uv run python scripts/test_m1.py # group create + failure handling + role visibility uv run python scripts/test_routes.py # all API routes registered uv run python scripts/test_e2e.py # full flow: analyze→personas→chat→debrief→one-shot→board→analytics ``` Real-model verification requires a live `LLM_API_KEY` in `.env`. --- ## Default accounts | Role | Email | Password | |------|-------|----------| | super_admin | `admin@salestrainer.local` | `admin123` (change after first login) | Admins create additional users (users/login has no self-registration).