A multi-tenant, AI-powered backend platform for mental health counselor training built with NestJS. It connects counselors and learners through real-time voice communication, scenario-based simulations, AI-driven feedback, and comprehensive analytics.
Ally Backend is the core API and event-processing service that:
- Powers scenario-based learning with simulated client conversations and learning pathways
- Provides real-time communication via WebSocket gateways and LiveKit voice/video rooms
- Processes audio and transcriptions through an async pipeline using AWS SQS and S3
- Delivers AI-driven insights including call summaries, live nudges, and session reports via LLM integration
- Enforces conversational guardrails to detect boundary violations in real time
- Manages multi-tenant access with role-based permissions, groups, and tenant isolation
- Supports gamification through a badge and community leaderboard system
- Integrates with AWS (S3, SQS, SES, CloudWatch) for storage, messaging, email, and audit logging
- Exposes a versioned REST API with Swagger/OpenAPI documentation
The system is organized as a modular NestJS monolith with the following key layers:
- REST API (
src/*/controllers) - Versioned endpoints (/api/v1/) with JWT and API key authentication - WebSocket Gateways - Real-time communication for microphone chat (
/microphone-chat), audio ingestion (/audio-ingest), and scenario reporting (/scenario-report) - LiveKit Integration (
src/livekit/) - Voice/video room lifecycle, participant tracking, agent dispatch, and webhook handling - Audio Pipeline (
src/audio/,src/audio-ingest/) - Multipart S3 upload, SQS-based transcription requests, and DLQ handling - AI / LLM Service (
src/ai/,src/ai-chat/) - Streaming LLM responses via OpenAI, session summarization, and event analysis - Conversational Guardrails (
src/conversational-guardrails/) - Real-time boundary detection with multi-language support - Prompt Management (
src/prompt/,src/prompts/) - Versioned system prompts with dashboard sync and external override resolution - Scenario Engine (
src/learn/,src/scenario-path/) - Scenarios, learning pathways, and session management - Review Systems (
src/scenario-session-review/,src/scribe-session-review/) - Threaded comments, reactions, and badge awards on sessions - Message Broker (
src/message-broker/) - Redis pub/sub for inter-service events - Scheduler (
src/scheduler/) - Periodic background jobs via@nestjs/schedule - Analytics (
src/analytics/) - Metabase integration for dashboards and tenant-specific reporting
| Component | Tech Used |
|---|---|
| Backend | NestJS (Node.js v24) |
| Database | PostgreSQL + TypeORM |
| Caching | Redis |
| Real-time Comm | WebSocket (Socket.io) + LiveKit |
| Authentication | JWT, OTP, Google OAuth, Magic Link |
| AI / LLM | OpenAI (streaming), Deepgram (STT) |
| TTS | ElevenLabs, Deepgram, Sarvam, Google, Hume |
| Cloud Storage | AWS S3 (multipart, presigned URLs) |
| Messaging | AWS SQS + Redis message broker |
| AWS SES | |
| Audit Logging | AWS CloudWatch (HIPAA-compliant) |
| Analytics | PostgreSQL + Metabase |
| Observability | Winston Logger + Slack alerts |
| Documentation | Swagger/OpenAPI |
ally-be/
βββ src/
β βββ ai/ # LLM integration (OpenAI), session summarization, event analysis
β βββ ai-chat/ # AI chat interfaces and provider abstraction
β βββ analytics/ # Metabase integration and tenant analytics dashboards
β βββ app-version/ # App version management
β βββ audio/ # Audio file storage and processing utilities
β βββ audio-ingest/ # SQS-based async transcription pipeline and DLQ handling
β βββ audit/ # Audit logging (AWS CloudWatch, HIPAA-compliant)
β βββ auth/ # JWT, OTP, Google OAuth, Magic Link authentication
β βββ authorization/ # RBAC guards and permission decorators
β βββ aws/ # AWS S3, SQS, SES service wrappers
β βββ badge/ # Badge definitions, award logic, bulk and auto awarding
β βββ case/ # Case management and tenant-isolated case items
β βββ chat/ # Chat session tracking
β βββ common/ # Shared utilities, interceptors, and decorators
β βββ community/ # Leaderboard and user ranking
β βββ config/ # Application configuration
β βββ conversational-guardrails/ # Real-time boundary detection with multi-language support
β βββ database/ # TypeORM data source, migrations, and seed scripts
β βββ exception/ # Global exception filters
β βββ factory/ # Factory classes for testing
β βββ health/ # Health check endpoint
β βββ language/ # Language settings and translation service
β βββ learn/ # Scenario engine, learning pathways, and session management
β βββ livekit/ # LiveKit room lifecycle, participant tracking, and webhooks
β βββ logger/ # Winston logger configuration
β βββ message-broker/ # Redis pub/sub for inter-service events
β βββ notification/ # Email and push notification delivery (AWS SES)
β βββ place/ # Location and place data
β βββ prompt/ # Prompt management and dashboard sync
β βββ prompts/ # Versioned system prompt definitions
β βββ queue/ # SQS queue setup and configuration
β βββ rate-limit/ # Request rate limiting
β βββ redis/ # Redis client configuration
β βββ reference-document/ # Reference materials associated with scenarios or pathways
β βββ review/ # Shared review utilities
β βββ scenario-character/ # Scenario NPC/character (client persona) definitions
β βββ scenario-cover-image-library/ # Scenario cover image management
β βββ scenario-path/ # Learning pathway composition
β βββ scenario-report/ # Real-time scenario reporting WebSocket gateway
β βββ scenario-session-review/ # Threaded comments, reactions, and badge awards on sessions
β βββ scheduler/ # Periodic background jobs (@nestjs/schedule)
β βββ scribe-session-review/ # Transcript-based feedback with threaded comments
β βββ session-event/ # Session event tracking and storage
β βββ settings/ # Application settings management
β βββ tenant/ # Multi-tenant management and isolation
β βββ user/ # User profiles and management
β βββ voice-preview/ # TTS voice preview (ElevenLabs, Sarvam, Google, Hume)
βββ docs/ # Additional documentation (prompts API, folder conventions)
βββ test/ # End-to-end tests
βββ .env.example # Local development environment template
βββ docker.env.example # Docker Compose environment template
βββ docker-compose.yml # Infrastructure services (Postgres, Redis, LocalStack, SQS)
βββ Makefile # Convenience make targets
βββ nest-cli.json # NestJS CLI configuration
βββ tsconfig.json # TypeScript configuration
βββ package.json # Dependencies and npm scripts
Before you begin, ensure you have the following installed:
- Node.js (v24) - Download
- npm - Comes with Node.js
- Docker (v20.10 or higher) - Download
- Docker Compose (v2.0 or higher) - Usually included with Docker Desktop
- PostgreSQL (v14 or higher) - For local development (optional, Docker recommended)
- Redis - For local development (optional, Docker recommended)
- LiveKit Account - For WebRTC audio/video calls (Sign up)
- OpenAI Account - For LLM-powered summaries, guardrail detection, and translations
- Deepgram Account - For speech-to-text transcription
- AWS Account (optional) - For S3, SQS, SES, CloudWatch (LocalStack can be used for local dev)
- Metabase (optional) - For analytics dashboards
- Slack (optional) - For exception alerts
git clone <repository-url>
cd ally-beCopy the sample environment files:
cp docker.env.example docker.env
cp .env.example .envEdit docker.env and .env with your credentials. See Environment Configuration for details.
Start PostgreSQL, Redis, LocalStack, and SQS using Docker Compose:
docker-compose upMake sure the SQS URLs in your .env file match the ones shown in the Docker output.
Note: The app service in Docker requires manual execution. Follow the steps below to run it.
npm run migration:runnpm run start:devThe application will be available at:
- Swagger Docs: http://localhost:8001/api-docs
- Health Check: http://localhost:8001/api/health
npm run build
npm run start:prodThe application uses two environment files:
.env- For local development (running without Docker)docker.env- For Docker Compose setup
Refer to .env.example and docker.env.example for all available configuration options.
Note: The
docker.envfile is used by Docker Compose services. The.envfile is used when running the app directly withnpm run start:dev.
# Generate a new migration
npm run migration:generate --name=YourMigrationName
# Create an empty migration file
npm run migration:create --name=YourMigrationName
# Run pending migrations
npm run migration:run
# Revert last migration
npm run migration:revert
# Show migration status
npm run migration:show- Host:
localhost(orpostgresin Docker) - Port:
5477(mapped from container's5432) - Database: Value from
DB_DATABASEindocker.env - Username: Value from
DB_USERNAMEindocker.env - Password: Value from
DB_PASSWORDindocker.env
Seeds live in src/database/seeds/ and insert the minimum dataset needed for local development directly via TypeORM (no running server required). The fixture data is inline TypeScript in fixtures.ts β edit it there if you need to add/change seeded records.
What gets seeded:
- 1 tenant (
ally) - 4 test users:
[email protected](SUPER_ADMIN),[email protected](ADMIN),[email protected](LEARNER+COUNSELOR),[email protected](MULTI_TENANT_ADMIN) - One scenario voice per active language (13 by default), 3 session events, 2 scenarios, 1 pathway, 1 case, 4 badges
- 3 scenario sessions (2 completed with sample transcripts, 1 active) so scribe-reviewer and admin dashboards have data to read
# Seed the DB (idempotent β safe to re-run; existing rows are matched by unique key and skipped)
npm run seed
# Truncate all seeded tables, then re-seed from scratch
npm run seed:reset -- --confirm && npm run seedseed:reset refuses to run without --confirm (or SEED_RESET_CONFIRM=1) and refuses entirely when NODE_ENV=production. It uses TRUNCATE ... CASCADE across the 14 seeded tables, so rows in other tables with foreign keys to these will also be deleted β run against a dev DB only.
All seeded users share the same password and OTP:
- Password:
Password123!(override withSEED_DEFAULT_PASSWORD) - OTP:
1234(override withSEED_DEFAULT_OTP; also needs matching entry inTEST_ACCOUNTSin.envfor OTP login to work)
Set AUTO_SEED=true in .env to run npm run seed once after migrations on container start (see docker-compose.yml). Or run manually:
docker compose exec app npm run seedOnce the application is running, access the interactive API documentation:
The API is versioned and accessible at:
- v1:
http://localhost:8001/api/v1/...
Most endpoints require JWT authentication:
Authorization: Bearer <your-access-token>
The platform supports multiple authentication methods:
- JWT - Standard access/refresh token flow
- OTP - Email-based one-time password (v2)
- Google OAuth - Sign in with Google
- Magic Link - Email-based passwordless authentication
- API Key -
X-API-Keyheader for service-to-service calls
| Endpoint | Description |
|---|---|
POST /api/v1/auth/login |
User login |
POST /api/v1/auth/refresh |
Refresh access token |
POST /api/v1/auth/generate-otp |
Generate OTP (v2) |
POST /api/v1/auth/verify-otp |
Verify OTP (v2) |
POST /api/v1/auth/google |
Google OAuth sign-in |
POST /api/v1/auth/magic-link/verify |
Magic link verification |
GET /api/v1/users/me |
Get current user profile |
GET /api/v1/health |
Health check endpoint |
GET /api/v1/badges/me |
Get current user's badges |
GET /api/v1/community |
Community leaderboard |
GET /api/v1/community/my-rank |
Current user's rank |
GET /api/analytics/* |
Analytics dashboards |
GET /api/tenant-analytics/* |
Tenant-specific analytics |
Prompts API (dashboard and sync): See docs/prompts-api.md. Prompt folder (naming, meta JSON): docs/prompts-folder.md.
- Learning Pathways - Compose ordered sets of scenarios into guided learning paths
- Scenario Characters - Define client personas (NPCs) for realistic simulations
- Session Management - Track learner progress through scenario sessions
- Trigger Warnings - Content warning system for sensitive scenario content
- Reference Documents - Associate supporting materials with scenarios or pathways
- Voice Preview - Text-to-speech preview for scenario voices (ElevenLabs, Deepgram, Sarvam, Google Cloud, Hume)
- LLM Integration - Streaming responses via OpenAI for session summaries and analysis
- Audio Processing - Multipart S3 upload with presigned URLs; SQS-based async transcription pipeline with DLQ support
- Conversational Guardrails - Real-time boundary detection using binary classification, with multi-language support and automatic agent redirect
- Session Reports - AI-generated post-session analysis and scoring
- WebSocket Gateways
/microphone-chat- Live audio chat with message streaming/audio-ingest- Cloud telephony integration/scenario-report- Real-time scenario reporting
- LiveKit Integration - Voice/video room creation, participant lifecycle, agent dispatch, and webhook handling
- Redis Message Broker - Pub/sub for inter-service event delivery
- Scenario Session Review - Threaded comments, emoji reactions, read status tracking, and badge awards
- Scribe Session Review - Transcript-based feedback with comment threads and reactions
- Case Management - Case creation, session tracking, and tenant-isolated case items
- Badge System - Achievement badges with bulk and automatic awarding for milestones
- Leaderboards - Global and scenario-specific leaderboards with user ranking
- Versioned Prompts - Store and version system prompts used across AI services
- Dashboard Sync - Sync prompts from external sources
- Per-Tenant Overrides - Resolve tenant-specific prompt variants at runtime
- Tenant Isolation - Cases, scenarios, dashboards, and analytics scoped per tenant
- Role-Based Access Control - Fine-grained permissions via groups and permission guards
- Tenant Analytics - Metabase integration with tenant-specific dashboard views
- Translation Service - OpenAI-powered translations for session events and guardrail content
- Language Module - Configurable language settings per tenant or scenario
- Sarvam STT/TTS - Indian language support
# Run all tests
npm run test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:cov
# Run end-to-end tests
npm run test:e2e
# Run tests inside Docker
npm run test:docker# Check for linting errors
npm run lint
# Auto-fix linting errors
npm run lint:fix
# Format code with Prettier
npm run format- Winston - Structured logging with multiple transports
- CloudWatch - HIPAA-compliant audit logging (optional)
- Console Logging - Configurable log levels
Configure log level via LOG_LEVEL environment variable:
| Level | Description |
|---|---|
error |
Only errors |
warn |
Warnings and errors (default) |
info |
Info, warnings, and errors |
debug |
All logs including debug messages |
- Health Checks - Built-in health check endpoints (
/api/health) - Slack Alerts - Exception and error notifications
- CloudWatch Logs - Audit trail for HIPAA compliance
# Check if PostgreSQL is running
docker-compose ps postgres
# Check PostgreSQL logs
docker-compose logs postgres
# Verify DB_HOST=postgres (for Docker) or localhost (for local) in docker.env# Check if Redis is running
docker-compose ps redis
# Test Redis connection
docker-compose exec redis redis-cli ping# Check LocalStack logs
docker-compose logs localstack
# Verify SQS queues are created
docker-compose logs sqs-setup
# Recreate queues if needed
docker-compose restart sqs-setup# Find process using port 8001
lsof -i :8001
# Kill the process or change PORT in docker.env# Check migration status
npm run migration:show
# Ensure all required environment variables are set before retrying
npm run migration:runLOG_LEVEL=debug
NODE_ENV=developmentFor contributing guidelines, refer to CONTRIBUTING.md.
For issues, questions, or contributions:
- Open an issue on GitHub
- Contact the development team
- Check the API documentation at
/api-docs