A multi-tenant AI chatbot SaaS with knowledge base grounding, embeddable chat widget, human handoff to agents, API key management, subscriptions, and analytics.
ai-agent-frontend/
backend/ // Node.js/Express API, MongoDB (Mongoose), Socket.IO, Stripe webhooks
frontend/ // React (Vite) app with Tailwind UI, routing, and widget
README.md
test-suite.sh
- Multi-tenant auth (owners, admins, agents) with JWT
- API keys with permissions and usage tracking
- Knowledge base (Q&A) with simple embeddings and similarity search
- Chat API + embeddable widget (KB grounding + LLM)
- Human handoff (assign to agents, agent chat via Socket.IO)
- Tenant usage limits/rate limits
- Stripe subscriptions (checkout + webhook handlers)
- Analytics dashboard
- Install dependencies
# from repo root (recommended run per package)
cd backend && npm install && cd ../frontend && npm install- Configure environment
Create
backend/.envwith at least:
# backend/.env
PORT=5001
FRONTEND_URL=http://localhost:5173
MONGO_URI=mongodb://localhost:27017/ai-agent-frontend
JWT_SECRET=change-me-please
# LLM (SambaNova-compatible; falls back to stub without a key)
SAMBANOVA_API_KEY=
LLM_BASE_URL=https://api.sambanova.ai/v1
# Optional Stripe (for subscriptions)
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_PRICE_STARTER=price_xxx
STRIPE_PRICE_PROFESSIONAL=price_xxx
STRIPE_PRICE_ENTERPRISE=price_xxxStart a local MongoDB (choose one):
- Homebrew:
brew services start mongodb-community - Docker:
docker run -d -p 27017:27017 --name mongodb mongo:7
- Run the stack
# Terminal A
cd backend
npm run dev
# Terminal B
cd frontend
npm run dev- Backend: http://localhost:5001
- Frontend: http://localhost:5173
- Runtime: Node.js (ESM), Express, Mongoose, Socket.IO, Stripe
- Entry:
backend/src/index.js - Config:
backend/src/config/env.js(loadsbackend/.env),backend/src/config/db.js
routes/authRoutes.js: register/login/me, profile updatestenantRoutes.js: tenant settings, analytics, team, billing checkout, subscription statusapiKeyRoutes.js: CRUD + usage for API keyskbRoutes.js: KB CRUD + search (embeddings)chatRoutes.js: chat start/message/history/end, handoff, agent endpointswebhookRoutes.js: Stripe webhook handlers
models/:User.js,Tenant.js,Conversation.js,Message.js,KBItem.js,ApiKey.jsservices/:llmProvider.js,embedding.js,handoff.jsmiddleware/:auth.js,tenant.js(API key auth, permissions, usage limits)
- Start conversation:
POST /api/chat/start(X-API-Key) - Send message:
POST /api/chat/message(X-API-Key)- Detects handoff keywords; if enabled, attempts agent assignment
- Agent actions (JWT auth):
- Accept handoff:
POST /api/chat/:conversationId/agent/accept - Send message:
POST /api/chat/:conversationId/agent/message
- Accept handoff:
- History:
GET /api/chat/:sessionId/history - End conversation:
POST /api/chat/:sessionId/end
- Create checkout session:
POST /api/tenant/billing/create-checkout-session - Subscription status:
GET /api/tenant/billing/subscription - Webhook:
POST /api/webhook/stripe(configure Stripe endpoint to this route)
PORT: API port (default 3000; dev script uses 5001)FRONTEND_URL: CORS allow origin (e.g., http://localhost:5173)MONGO_URI: Mongo connection stringJWT_SECRET: JWT signing secretSAMBANOVA_API_KEY,LLM_BASE_URL: optional LLM providerSTRIPE_SECRET_KEY,STRIPE_PRICE_*: Stripe billing
npm run dev: start with nodemon on PORT=5001npm start: start Node (uses PORT or 3000)
- Stack: React 18, Vite, Tailwind, React Router
- Entry:
frontend/src/main.jsx,frontend/src/App.jsx - Public routes:
/(Landing),/login,/signup - App (protected):
/app,/dashboard,/api-keys,/knowledge-base,/prompt-tuner,/chat-tester,/handoff-center
Landing.jsx: marketing landing pageDashboard.jsx: usage, analytics, recent conversations, billing linkApiKeys.jsx: manage API keysKnowledgeBase.jsx: CRUD and searchChatTester.jsx: interact with the botHandoffCenter.jsx: agents accept handoffs and reply to users
Use within your site/app:
import ChatWidget from '@/components/ChatWidget.jsx';
<ChatWidget apiKey="YOUR_API_KEY" config={{ primaryColor: '#3B82F6' }} />- Starts via
POST /api/chat/start - Sends user messages via
POST /api/chat/message - Reads history, handles errors, and displays responses
npm run dev: Vite dev servernpm run build: production buildnpm run preview: preview production build
- Health check:
GET /api/health - Manual E2E: register → login → create API key → add KB items → Chat Tester → send "human" to trigger handoff → accept in Handoff Center → reply as agent.
- Hosted smoke-test script:
test-suite.sh(targets a sample deployment); adapt endpoints if needed.
- Provide environment variables on your platform (Render, Railway, Fly, etc.)
- Point Stripe webhook to
/api/webhook/stripe - Serve the frontend build and set
FRONTEND_URL
- LLM and embeddings gracefully fall back to stubbed responses without API keys (for local dev).
- For production, replace stubbed embedding logic with a proper vector DB or embedding service.