An AI-powered sales / customer-service training & evaluation platform built on Next.js 15 + React 19 + Prisma + MySQL + Redis + VolcEngine RTC/ASR/TTS.
yw-aida provides real-time voice training rooms (RTC + ASR + TTS), scenario-based AI coaches, batch evaluation, admin workstation and organizational management โ all in a single full-stack Next.js application.
- Real-time voice training via VolcEngine RTC, streaming ASR and TTS
- Scenario/agent-based AI coaches with configurable prompts
- Batch evaluation pipeline (BullMQ + Redis + cron scheduler)
- Organization / user / invite / bonus-minute management
- Object storage via VolcEngine TOS (private + public buckets)
- JWT-based auth, phone-number SMS login (Aliyun SMS)
- WebSocket + SSE push, Prisma 7 data layer, Pino structured logs
A full end-to-end product tour, told through one fictional company โ YunQi Tech (ไบๅฏ็งๆ), a SaaS vendor whose sales team trains on AIDA. The four scenarios below map to AIDA's closed loop: author โ practice โ evaluate โ manage, each from the point of view of the person who lives that step.
The UI is Simplified Chinese. A shot-by-shot script, the buyer-facing talking points, and a one-command script to generate this exact demo data (
scripts/seed-demo-data.ts) all live indocs/DEMO_SCENARIOS.md.
A training lead drops in a plain sales-playbook document; AIDA's LLM auto-extracts the scene setup, customer persona, and scoring rubric and publishes a ready-to-practice scenario in minutes โ no scripting, no engineering. Content cost drops from person-days to minutes, and non-technical staff can ship new courses themselves.
Reps rehearse against an AI customer that balks at price, stalls, and probes for specifics โ by real-time voice (VolcEngine RTC + streaming ASR + TTS) or text โ available 24/7 with zero risk to real leads. Pick a coach (Sam / Anna) and go; the AI plays a budget-sensitive procurement manager who keeps pushing on "too expensive".
| Text mode โ live LLM conversation | Voice mode โ RTC + ASR + TTS |
|---|---|
Every session produces a multi-dimension scorecard: an overall score, per-skill ratings (needs discovery, value framing, objection handling, โฆ), turn-by-turn coaching with model answers, and a score trend over time โ turning soft skills into measurable, comparable data instead of gut feel.
Bulk-import the org tree, allocate per-team quotas (voice/text minutes, KB & training storage), and track adoption and consumption on a dashboard โ internal training at scale that stays deployable, governable, and cost-controlled.
| Adoption dashboard | Org tree & quota management |
|---|---|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Next.js App (SSR) โ
โ Pages / App Router / API Routes / WebSocket โ
โโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโผโโโโโโโ โโโโโโโโผโโโโโโโ
โ Prisma โ โ BullMQ โ
โ (MySQL) โ โ Workers โ
โโโโโโโโโฌโโโโโโโ โโโโโโโโฌโโโโโโโ
โ โ
โโโโโโโโโผโโโโโโโ โโโโโโโโผโโโโโโโ
โ MySQL DB โ โ Redis โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
External: VolcEngine RTC/ASR/TTS/TOS/Ark ยท Aliyun SMS ยท ipinfo.io ยท Zhipu LLM
- Node.js 24+ (the project uses Next.js 15 features that assume Node 20+; CI runs on Node 24. Node 22 has been seen to work locally but is not officially supported.)
- MySQL 8.x
- Redis 6+
- (Optional) a private
rtc-serverrepository for RTC signaling, cloned into the project root asrtc-server/
git clone <your-fork-or-repository-url>
cd yw-aida
cp .env.example .env.local
# edit .env.local and fill in real values (see "Environment Variables" below)
npm install
npx prisma generate
npx prisma migrate deploy # or: npm run migrate:db
npm run dev # day-to-day dev
# or, first-time bootstrap (also tries to clone rtc-server if RTC_SERVER_REPO_URL is set):
npm run initThe first render will fail fast if required env vars (JWT keys, DB, Redis, RTC/ASR tokens, SMS keys) are missing. Fill them in
.env.localfirst. This repository is open for GitHub-based source collaboration. The application package remains"private": true, so cloning the source and publishing an npm package are intentionally separate workflows.
| Command | Purpose |
|---|---|
npm run init |
First-time init + start |
npm run dev |
Start Next.js dev server (HTTPS) |
npm run build |
Production build |
npm start |
Run the custom Node server (WebSocket) |
npm run lint |
ESLint |
npm test |
Vitest |
npm run migrate:db |
Migrate DB schema |
Organizations get account authorizations and resource quotas (message / voice training minutes, KB storage, training storage) through a super-admin only recharge flow. Two entry points:
| Entry point | Use case |
|---|---|
Web UI โ /training/workstation/recharge (no menu, direct URL) |
One-off, interactive |
CLI script โ scripts/recharge-authorization.ts |
Batch / scripted / CI |
- Platform-admin permission on the caller user:
UPDATE users SET platform_admin_type = 1 WHERE phone = '<your-phone>';
- Auth token (JWT) โ log in as that user in the browser, then copy the
auth_token_admincookie value (DevTools โ Application โ Cookies). - A running app โ
npm run devonhttps://localhost:3000/(default), or a deployed instance.
# 1. Put the token in .env (or export in shell). Do NOT wrap the value in
# non-ASCII quotes โ only the raw JWT, no spaces:
echo 'RECHARGE_AUTH_TOKEN=eyJhbGciOi...your-jwt...' >> .env
# Optional: override the target host (defaults to https://localhost:3000/)
# echo 'RECHARGE_API_BASE_URL=https://staging.example.com/' >> .env
# 2. Edit the RECHARGE_LIST array at the top of the script with your orgIds
# and the amounts you want to top up:
# scripts/recharge-authorization.ts
# 3. Run it:
npx tsx scripts/recharge-authorization.tsThe API (POST /api/org/authorization/recharge) accepts user-facing units
(minutes / GB / days); the backend handles the minuteโsecond conversion before
persistence. Never pre-multiply by 60 on the client side.
| Field | Unit | Max per request |
|---|---|---|
authorization.quantity |
count | 100 |
authorization.validityDays |
days | 730 |
quotas[quotaType=1] โ message training |
minutes | 5000 |
quotas[quotaType=2] โ voice training |
minutes | 5000 |
quotas[quotaType=3] โ knowledge base |
GB | 100 |
quotas[quotaType=4] โ training storage |
GB | 100 |
The script validates the HTTP status and the business-layer
success / code fields, so a silent failure on a 200 response will still be
surfaced as ไธๅกๅคฑ่ดฅ code=400: ....
-- Authorization coupons
SELECT * FROM b_org_authorization_transaction
WHERE transaction_type = 1 ORDER BY create_time DESC LIMIT 20;
-- Quota top-ups
SELECT * FROM b_org_quota_transaction
WHERE transaction_type = 1 ORDER BY create_time DESC LIMIT 20;See docs/RECHARGE_GUIDE.md for the full permission
model, Web-UI walkthrough, warning thresholds and operational safety notes.
All configuration lives in .env.local (loaded by Next.js + dotenv).
Start from .env.example โ it lists every variable used across the codebase with <your-xxx> placeholders.
Major groups:
- App / runtime:
APP_ENV,NODE_ENV,PORT,NEXT_PUBLIC_BASE_PATH, โฆ - MySQL / Prisma:
DATABASE_URL,MYSQL_HOST,MYSQL_USER, โฆ - Redis:
REDIS_URLorREDIS_HOST/REDIS_PORT/REDIS_PASSWORD - JWT:
JWT_PRIVATE_KEY,JWT_PUBLIC_KEY(base64) - Aliyun SMS:
ALIYUN_ACCESS_KEY_ID,ALIYUN_ACCESS_KEY_SECRET,ALIYUN_SMS_SIGN_NAME,ALIYUN_SMS_TEMPLATE_CODE - VolcEngine (RTC / ASR / TTS / TOS / Ark):
NEXT_PUBLIC_RTC_APP_ID,NEXT_PUBLIC_ASR_APP_ID,NEXT_PUBLIC_ASR_TOKEN,VOLC_TOS_*,NEXT_PUBLIC_VOLC_ARK_ENDPOINT_ID, โฆ
ย ย TOS ไธไผ /CORS ๆ้ไธๆกถ้ ็ฝฎ่งdocs/TOSๅฏน่ฑกๅญๅจๅฎ็ฐๆป็ป.md - LLM:
ZHIPU_KEY,ZHIPU_MODEL,OPENAI_API_KEY, โฆ - IP geolocation:
IPINFO_TOKEN - Batch evaluation:
BATCH_EVALUATION_API_KEY,DIFY_EVALUATION_BASE_URL
The RTC signaling server lives in a separate private repository.
Set RTC_SERVER_REPO_URL in your environment before running npm run init, or clone it yourself into ./rtc-server and run npm ci inside. If the directory is absent at runtime the main app will still build and start, but real-time voice training will be degraded.
- Docker: build from the included
Dockerfile(node:24-alpine) - CI: GitHub Actions โ see
.github/workflows/ci.yml
This project was extracted from an internal codebase. A few rough edges remain โ contributions that progressively clean them up are very welcome:
- ESLint warnings/errors:
npm run lintcurrently reports a number of pre-existing violations (no-require-imports,no-empty-object-type,prefer-const, a few hook-dependency issues). They do not affectnpm run build. CI runs lint for visibility but does not fail the build on them. - Node version: CI pins Node 24. Older versions may work but are untested.
rtc-server: lives in a separate private repo. Without it the app still builds and non-RTC features work, but real-time voice training is degraded.- Translations / copy: some user-facing strings are Simplified Chinese only.
See CONTRIBUTING.md if you want to help.
See CONTRIBUTING.md and our Code of Conduct.
Please do not file public GitHub issues for security vulnerabilities. See SECURITY.md for our responsible disclosure policy.
MIT ยฉ yw-aida contributors