Commit Graph

6 Commits

Author SHA1 Message Date
Macky
0b92430aab feat(idea): create group auto-generates personas; channel removed; product->product/idea
Per product-idea focus:
- GroupBuilder: 'สินค้า/บริการ/ไอเดีย' label; removed the channel select (channel is now
  chosen at chat time as a scenario, not at persona create). Create now auto-runs analyze
  so personas are generated immediately (no separate Analyze button).
- GroupEdit: analyze button becomes 'สร้างบุคคลต้นแบบเพิ่มเติม' which APPENDS more personas
  (backend analyze?append=true reuses sales kit + keeps existing instead of replacing).
- i18n product label updated.
- User-journey test asserts append adds personas (15->30) and existing kept.
All 9 backend suites pass. Rebuilt dist.
2026-08-09 10:12:40 +07:00
Macky
e1d61e1e1e feat(ip): protect persona 'formula' — secret fields only super_admin sees/edits
IP protection so casual copying yields inferior results:
- SECRET_PERSONA_FIELDS (pains/objections/negotiation_levers/opener/tolerance +
  pain rootCause/resolutionConditions): only super_admin can view/edit them.
- list_personas/get_persona/update_persona/get_group strip these for role=admin (and
  hide sales_kit + pain-fit report from admins too).
- update_persona rejects admin attempts to set secret fields (403).
- PersonaForm hides the 'การขาย' recipe section for non-super-admin (shows locked note);
  auth.isSuperAdmin getter added.
Rebuilt dist. Added test_ip_protection.
2026-08-09 07:22:50 +07:00
Macky
55759a3a50 fix(api): group create read product from multipart form (bug: 'provide product info' when no file attached)
The GroupBuilder sends the create form as multipart/form-data (FormData). The code
decided JSON vs form by checking  — when no file was attached,
request.files was empty/falsy, so it tried get_json() on a multipart body and lost the
product field -> 400 'provide product info' even though the user filled the product name.

Fix: branch on the Content-Type (multipart/form-data -> request.form) instead of
request.files. Added a regression test (multipart create with product only -> 201).
Verified live: multipart product-only create now returns 201.
2026-08-08 09:49:24 +07:00
Macky
ce6076f7f4 [verified] Apply independent-reviewer suggestions: mask sales_kit/report to trainees, ready-gate get_persona
Responding to the requesting-code-review independent reviewer (passed:true, zero blocking issues):
- get_group: hide sales_kit + report from trainees (they contain latent pain analysis)
- get_persona: add status==ready gate for trainees (parity with list_personas)
- Extend test_security.py with latent-leak + non-ready-gate assertions; all suites pass
2026-08-07 16:09:42 +07:00
Macky
ff0f680090 [verified] Security hardening + UX/UI polish
Security (requesting-code-review pipeline + independent reviewer):
- Fix path traversal on file upload (basename sanitize + resolve-containment)
- Fix IDOR: org + owner scoping on all group/chat routes (_authorize_group/_get_owned_group),
  hide other users' personal groups in listings
- Remove XSS via v-html in Chat task (text interpolation)
- Add test_security.py (traversal + cross-user denial) — all pass

UX/UI (ui-ux-pro-max + frontend-dev-verification):
- Global: focus rings, 44px touch targets, hover/press transitions, input focus glow,
  prefers-reduced-motion, skeleton loaders, empty states, back links, spinner
- Login: password toggle, autocomplete, spinner, disabled-when-empty
- Cards lift on hover; dashboard skeleton + empty state; analyze button spinner

All backend tests pass (m0/m1/routes/security/e2e); frontend builds; served SPA verified via curl.
2026-08-07 16:00:43 +07:00
Macky
c3d31c06e2 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
2026-08-07 15:31:06 +07:00