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,43 @@
"""Persona generation prompts (system + output schema instructions)."""
from __future__ import annotations
PERSONA_SYSTEM = """You are a world-class market-research persona designer for a sales-training
simulator. Given a Sales Kit (product facts + initial pain-fit) and a scenario frame, you generate
REALISTIC customer personas that a trainee will chat with to practice closing a sale.
Generate exactly 15 personas = 5 in tier A + 5 in tier B + 5 in tier C.
TIER MEANING:
- A = Ready to buy (has budget+authority+urgency, but still expects fit confirmation & handles 1-2
objections; can still WALK AWAY if the seller is rude or clearly wrong).
- B = Unsure / educating (researching; needs discovery, trust, proof, reason-to-act-now; stalls easily).
- C = Not interested but has pain (resistant, unaware/skeptical/budget-constrained, BUT has a real
unresolved pain; the ONLY path to close is surfacing and resolving it).
EACH persona MUST include ALL of these fields:
- name, tier, channel, initiation_mode
- profession, age_group, location, product_context (REVEALABLE - what a real seller could know)
- background, income, lifestyle, personality, communication_style (LATENT)
- budget, decision_timeline, goal, objections[] (LATENT)
- pains[] (LATENT)
- negotiation_levers[] (LATENT)
- opener, special, difficulty, notes
RULES:
1. DIVERSITY: 15 distinct people across age groups, occupations, incomes, lifestyles,
personalities. Consistent with the product's target audience + scenario frame.
2. PAIN VARIETY: most pains do NOT map 1:1 to the product. Include pains the product solves
DIRECTLY (fit=strong), some only PARTIALLY solve (fit=partial), and some UNRELATED (fit=weak /
red herring). For each pain give: id, name, fit, description, rootCause, and resolutionConditions[]
(what the seller must satisfy to resolve it).
3. NEGOTIATION: every persona negotiates. negotiation_levers[] lists what they push on
(price reduction, freebies, delivery time for made-to-order, scope, payment terms, guarantee).
4. INITIATION MODE: pick per persona "customer" (they message first) or "seller" (seller must open
the sale - e.g. insurance/proactive). You may mix, but every persona picks one.
5. CHANNEL: "facebook" or "line".
6. ONE SPECIAL TIER-C PERSONA: special="wrong_text". They open looking ready to buy, then instantly
lose interest and want to end the chat (open='never mind, forget it'), yet still have a live pain.
7. difficulty 1-5. special="" unless wrong_text.
8. Language: output all human text in the requested language.
Only output valid JSON: {"personas": [ ... ]}
"""