Sales Trainer v0.1: corporate sales-training simulator (Flask+Vue, 15 personas, chat simulator, judge, analytics)

- 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
This commit is contained in:
Macky
2026-08-07 15:31:06 +07:00
commit c3d31c06e2
70 changed files with 6135 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
# 2026-08-07 — Sales Trainer build-out (M0M7)
## 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
- M0M7 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 <script>` invocation. Workaround: run scripts via `uv run python scripts/x.py`.
2. **Static serving path**: initially pointed at `backend/frontend/dist` (wrong) → `GET /` 404.
Fixed to repo-root `frontend/dist`, and made the SPA fallback accept all HTTP methods so
`/api/*` returns 404 (not 405), preserving no-self-registration.
3. **Mock vs real LLM**: tests use `scripts/mock_llm.py` (deterministic). Real model path
requires a live `LLM_API_KEY` in `.env` — NOT yet exercised live.
## Current state / runtime
- Backend runs via `cd backend && uv run python run.py`; frontend dev via `cd frontend && npm run dev` (proxies /api -> :5001).
- Default super-admin: `admin@salestrainer.local` / `admin123` (bootstrap; change in prod).
- Deploy files: root `Dockerfile`, `docker-compose.yml`, `.env.example`; repo-root `frontend/dist` build.
## Risks / remaining
- **Real-LLM end-to-end not verified** (needs a live key). Next: run analyze + persona + chat +
judge against the configured provider (DeepSeek/OpenAI/custom).
- Docker build not run locally (no Docker on this Mac — per environment note). Dockerfile follows
the EasyPanel single-container pattern; remote build+run should be validated on EasyPanel.
## Next action
1. Set a real `LLM_API_KEY` (and provider) in `.env`, run a live smoke test of analyze→personas→chat→debrief.
2. Push to Gitea remote (repo currently local git, no remote yet).
3. Validate Docker image build on EasyPanel.