# 2026-08-07 — Sales Trainer build-out (M0–M7) ## Summary Built the first complete version of the Sales Trainer app — corporate multi-user sales-training simulator — in `~/Gitea/Sales Trainer` from the detailed plan in `docs/PLAN.md` (which records all user decisions from the planning discussion). ## Plan status - M0–M7 all complete (see `engineering-log.md` status table). ## What was built Backend (Flask + JWT + filesystem JSON): - `app/config.py` (env/.env, LLM resolve), `app/llm.py` (OpenAI-compatible client + JSON/conv helpers) - `app/storage/store.py` (durable JSON store, lock + atomic write) - `app/auth/users.py` (UserStore: password hash, JWT, roles, no self-reg bootstrap) - `app/services/`: `file_parser` (pdf/txt/md), `analyzer` (sales kit + initial pain-fit), `persona_prompts` + `persona_generator` (15 personas, 5/tier, wrong_text special), `store` (persona shape + revealable_view), `report`, `groups`, `sessions`, `simulator` (chat + judge), `trainee` (weak-areas, MyPersonaStore), `own_persona` - `app/api/`: auth, admin, groups, chat, me, analytics routes + JWT/RBAC helpers - `app/factory.py`: app factory, bootstrap admin, serves built Vue frontend (SPA fallback) - `run.py` entry Frontend (Vue 3 + Vite): login, dashboard (role-based), group builder, group edit (admin) , personas (trainee revealable-only + win/lose), chat (FB/LINE thread + seller-task + debrief overlay), my-sessions, weak-areas, gen-persona, admin users, analytics. EN+TH i18n. ## Verified commands / results ``` backend: uv venv --python 3.11 .venv uv pip install -r requirements.txt --python .venv/bin/python uv run python scripts/test_m0.py -> ALL M0 TESTS PASSED uv run python scripts/test_m1.py -> ALL M1/M2-IMPORT TESTS PASSED uv run python scripts/test_routes.py -> ALL ROUTE REGISTRATION TESTS PASSED uv run python scripts/test_e2e.py -> ALL E2E TESTS PASSED frontend: npm install && npm run build -> builds 11 route-split chunks (423ms) live HTTP (Flask dev on :5001): GET / -> 200 (SPA) POST /api/auth/register -> 404 (no self-reg) POST /api/auth/login -> 200 (JWT) POST /api/groups -> 201 (draft group) ``` Mock-LLM E2E covers: analyze→15 personas (+wrong_text)→revealable-only→customer/seller-initiated sessions→debrief(latent reveal+coaching)→one-shot→board→weak-areas→gen-persona→analytics. ## Engineering notes / issues 1. **Tooling**: the Hermes terminal life-cycle guard crashes ("embedded null byte") on direct `.venv/bin/python