3 Commits

Author SHA1 Message Date
Macky
3c22d88bcd feat: demo SaaS + training flow security hardening (8/8 review gate passed)
- Demo accounts: super_admin-only provisioning into isolated DEMO_ORG_ID tenant,
  30-day UTC trial on first login, revocable, one-time credential delivery via
  optional SES/webhook (never persisted). Adds boto3 dependency.
- Analytics/report/export/privacy: shared bounded scan budget across users/groups/
  sessions, tenant-consistent session/user/group joins, scalar-only CSV export
  (no nested persisted-value stringification).
- Ownership/tenant isolation: canonical owner-tenant predicate for list/read/chat;
  client sees is_owned only, never owner_user_id.
- Lifecycle/races: status transition validation, analyzing is an in-progress gate
  (no duplicate reanalysis), structured-ready publication, stale-variant revalidation.
- Auth/setup/consent/JWT/OAuth/config: fail-closed consent, bounded JWT lifetime,
  provider-subject atomic OAuth identity, repeated-secret rejection, strict Persona
  trait validation.
- Chat/session/privacy: pre-seller opener redaction, corrupt-session recovery,
  role-aware completed-chat dashboard routing.
- Frontend: Training→product→personas→practice flow, demo/role/demo guards,
  is_owned-based ownership display, 320×568 and 500×768 responsive E2E.
- 8 independent exact-five-key review scopes passed; backend 509, frontend 26,
  production build 1775 modules, isolated E2E 15.
2026-08-25 06:39:06 +07:00
Macky
4b5a14079b [verified] all roles train for real: remove preview, 1 persona = 1 chat per user
- listPersonas: compute per-user my_outcome for ALL roles; always set the
  key (default 'not_tried') so the all-roles UI never sees undefined
  (fixes global super_admin without org showing every persona as trained)
- start_session/mode lookups (send/finish/resume/authorize): no preview
  mode; every role creates one-shot 'trainee' sessions. The one-shot lock
  (1 persona chat per user; many users per persona) now applies to all roles
- Chat.vue: always start in trainee mode, remove preview label
- Personas.vue: unified branches - show 'แชท' when untrained, 'สรุปผล'+variant
  when trained, for all roles
- Rewrite test_admin_preview.py to assert the new no-preview one-shot behavior
2026-08-19 08:32:33 +07:00
Macky
dbfce9aa54 [verified] harden Sales Trainer and add PostgreSQL foundation 2026-08-16 02:41:10 +07:00