1. Overview
My Chat Buddy Server lets a business upload its own content and expose a controlled AI assistant through APIs or a hosted website widget. The assistant is designed to answer from business-provided documents, track usage, and capture verified leads when the assistant flow is enabled.
- Customers create isolated projects with their own API keys and model settings.
- Visitors get fast answers from uploaded business knowledge.
- Developers integrate through REST endpoints or
GET /widget.js. - When useful context is missing, the assistant should return
I don't know.
2. Current Features
- Fastify TypeScript API server with PostgreSQL, Drizzle ORM, Chroma, and Docker support.
- Dashboard registration, login, email OTP verification, refresh token rotation, and roles.
- Project CRUD, API key rotation, widget snippets, integration helpers, and token limits.
- Document upload, chunking, embeddings, Chroma indexing, reindexing, and deletion.
- RAG chat with hybrid reranking, conversation history, token tracking, and sources.
- Assistant lead capture with name, email, OTP verification, and per-lead message limits.
- Usage and analytics endpoints for documents, conversations, messages, endpoints, and recent usage.
3. Architecture
Website / frontend
-> Fastify route
-> auth or API key middleware
-> controller validation
-> service logic
-> PostgreSQL / Chroma / AI provider
-> response| Layer | Responsibility |
|---|---|
| src/server.ts | Starts the Fastify server. |
| src/app.ts | Configures CORS, health routes, and route registration. |
| src/routes/* | Maps HTTP endpoints to controllers. |
| src/controllers/* | Validates input, sends responses, and delegates logic. |
| src/services/* | Contains core business logic. |
| src/db/schema/* | Defines Drizzle database tables. |
| src/middleware/* | Handles dashboard auth, API keys, and rate limiting. |
| src/utils/* | Contains reusable helpers. |
Document upload
-> store document in PostgreSQL
-> chunk text
-> create embeddings
-> store vectors in Chroma
-> store chunk metadata in PostgreSQL
User chat
-> embed question
-> retrieve matching chunks from Chroma
-> hybrid rerank
-> build prompt from retrieved context
-> call selected AI provider
-> save conversation and usage4. Database Schema
The backend separates dashboard identity, project configuration, knowledge storage, chat history, usage, and assistant lead state.
| Table | Purpose |
|---|---|
| users | Dashboard users with role, status, email verification, and profile fields. |
| otps | Dashboard email verification OTP codes. |
| refresh_tokens | Stored refresh tokens with expiry and rotation support. |
| projects | Tenant projects with owner, API key hash, provider config, and token limits. |
| documents | Original uploaded document content and metadata. |
| document_chunks | Chunk metadata linked to Chroma vector IDs. |
| conversations | Chat sessions for runtime and assistant flows. |
| conversation_messages | User, assistant, and system messages. |
| usage_logs | Token and endpoint usage events. |
| assistant_leads | Visitor leads with name, email, verification state, and message limits. |
| assistant_lead_otps | OTP records for assistant lead verification. |
| assistant_sessions | Assistant onboarding state: awaiting_name, awaiting_email, awaiting_otp, ready. |
5. Authentication APIs
Dashboard endpoints use bearer tokens.
Authorization: Bearer <accessToken>| Endpoint | Purpose |
|---|---|
| POST /auth/register | Register a dashboard user and send email OTP. |
| POST /auth/login | Login and return access plus refresh tokens. |
| POST /auth/verify-otp | Verify dashboard account email. |
| POST /auth/resend-otp | Resend dashboard email OTP. |
| POST /auth/refresh | Rotate refresh token and issue a new access token. |
| GET /auth/me | Return the current dashboard user. |
| GET /me | Return the logged-in user. |
6. Project APIs
Projects are tenant boundaries. The full API key is returned only when a project is created or rotated; the database stores the hashed key and a visible prefix.
| Endpoint | Purpose |
|---|---|
| GET /projects | List projects available to the dashboard user. |
| POST /projects | Create a project and return the plaintext API key once. |
| GET /projects/:projectId | Fetch one accessible project. |
| PATCH /projects/:projectId | Update project settings. |
| DELETE /projects/:projectId | Delete project data and Chroma collection. |
| POST /projects/:projectId/rotate-key | Rotate the runtime API key. |
| GET /projects/:projectId/widget | Return widget script details and snippet template. |
| GET /projects/:projectId/integration | Return integration details without exposing the full key. |
POST /projects
Authorization: Bearer <accessToken>
Content-Type: application/json
{
"name": "Acme Support Bot",
"modelProvider": "groq",
"tokenLimit": 100000,
"modelConfig": {
"model": "llama-3.1-8b-instant",
"temperature": 0.2,
"assistantMessageLimit": 5
}
}7. Document And Knowledge APIs
Runtime document APIs use the project API key.
x-api-key: <project-api-key>| Endpoint | Purpose |
|---|---|
| GET /projects/:projectId/documents | Dashboard-safe document list. |
| POST /projects/:projectId/documents/:documentId/reindex | Dashboard-safe document reindex. |
| POST /upload-doc | Upload raw text using x-api-key. |
| POST /upload-doc/file | Upload text or base64 file-like content. |
| GET /documents | List documents for the API-key project. |
| PUT /documents/:documentId | Replace document content and reindex it. |
| POST /documents/:documentId/reindex | Rebuild chunks and vectors. |
| DELETE /documents/:documentId | Delete a document and its vectors. |
POST /upload-doc
x-api-key: <project-api-key>
Content-Type: application/json
{
"content": "Your product docs, FAQ, pricing, policy, or support content.",
"metadata": {
"source": "pricing-page",
"category": "pricing"
}
}8. RAG Chat And Conversations
The chat endpoint validates the project key, enforces rate and token limits, retrieves relevant chunks, reranks them, calls the selected model provider, stores messages, and returns usage plus sources.
| Endpoint | Purpose |
|---|---|
| POST /chat | Run RAG chat and return reply, conversationId, usage, and sources. |
| GET /conversations | List project conversations. |
| GET /conversations/:conversationId/messages | Return one conversation and its messages. |
POST /chat
x-api-key: <project-api-key>
Content-Type: application/json
{
"message": "What is your refund policy?",
"conversationId": "optional-existing-conversation-id"
}Older conversation messages can be summarized before model calls, while recent history is kept for follow-up questions.
9. Assistant Lead Flow
The assistant flow is for business websites that want lead capture before normal chat. It asks for name, asks for email, validates the email, sends OTP, verifies the lead, then unlocks project chat with a message limit.
| Step | Runtime action |
|---|---|
| Start session | POST /assistant/chat with an empty body. |
| Collect name | POST /assistant/chat with sessionId and the visitor name. |
| Collect email | POST /assistant/chat with sessionId and email address. |
| Verify OTP | POST /assistant/verify-otp with sessionId and six-digit OTP. |
| Ready chat | POST /assistant/chat with sessionId and visitor question. |
POST /assistant/chat
x-api-key: <project-api-key>
Content-Type: application/json
{}
POST /assistant/verify-otp
x-api-key: <project-api-key>
Content-Type: application/json
{
"sessionId": "<sessionId>",
"otp": "123456"
}10. Usage, Analytics, And Providers
Usage is stored in usage_logs and total tokens used are updated on the project. Analytics can include document count, conversation count, message count, endpoint usage, and recent daily usage.
GET /usage
GET /analytics
GET /debug/provider-health # non-production only| Provider | Embedding behavior |
|---|---|
| groq | Uses Groq for generation and Gemini embeddings. |
| openai | Uses OpenAI generation and OpenAI embeddings. |
| gemini | Uses Gemini generation and Gemini embeddings. |
| ollama | Uses Ollama generation and Ollama embeddings. |
| fallback | If embeddings fail, uses a local 128-dimension character-hash embedding. |
11. Embeddable Widget
The backend serves a hosted widget script at GET /widget.js. A customer can paste the snippet into a website and configure title, color, position, welcome text, API URL, and project API key.
<script
src="http://localhost:5000/widget.js"
data-api-url="http://localhost:5000"
data-api-key="YOUR_PROJECT_API_KEY"
data-title="My Project Assistant"
data-primary-color="#0f766e"
data-position="right"
data-welcome="Ask me anything about this project."
></script>12. Developer Setup
Create the environment file, start local dependencies, install packages, migrate, and run the server.
PORT=5000
APP_BASE_URL=http://localhost:5000
FRONTEND_ORIGIN=http://localhost:3000
AUTH_SECRET=change-me-in-production
ACCESS_SECRET=change-me-in-production
REFRESH_SECRET=change-me-in-production
DB_URL=postgres://postgres:postgres@localhost:5432/chat
CHROMA_URL=http://localhost:8000
CHROMA_TENANT=default_tenant
CHROMA_DATABASE=default_database
OLLAMA_BASE_URL=http://localhost:11434
GROQ_API_KEY=
OPENAI_API_KEY=
GEMINI_API_KEY=
RESEND_API_KEY=
RESEND_FROM_EMAIL=docker compose up -d
npm install
npm run push
npm run dev- Register a dashboard user with
POST /auth/register. - Verify the OTP with
POST /auth/verify-otp. - Create a project and store the returned API key securely.
- Upload training content with
POST /upload-doc. - Test grounded answers with
POST /chat. - Add the widget script to the customer website.
13. Customer And Visitor Guides
Customers should understand what to upload, how to create projects, how API keys work, and how to review conversations and analytics.
- Upload FAQs, pricing, policies, product docs, support docs, and website content.
- Rotate an API key immediately if it is exposed.
- Expect the assistant to say
I don't knowwhen uploaded context is not enough. - Use analytics and conversations to improve training content.
Website visitors should know the assistant answers using business-provided content, may ask for name and email, may require OTP in lead-capture mode, has message limits, and should not be used for sensitive account-specific requests.
14. Roadmap
- Dashboard pages for leads, CSV export, CRM sync, source citations, and train-bot flows.
- Better parsers for PDF, DOCX, HTML, CSV, sitemap crawling, and URL crawling.
- Custom system prompts, branding, team roles, billing, and multi-language support.
- Retrieval evaluation tests, confidence scores, reranking providers, and document enable or disable status.
- Password reset, audit logs, API key scopes, domain allowlists, and encrypted provider keys.
- OpenAPI schema, Postman or Bruno collection, seed script, structured logs, and error catalog.
15. Known Limitations
- No automated test suite is currently implemented.
- Rate limiting is in-memory and is not ideal for multi-instance production deployments.
- Local fallback embeddings are low quality and should be replaced with setup warnings or errors in production.
- Widget UI is basic and can be improved.
- Provider API key storage should be hardened before production.
- Assistant OTP resend, lead list/export APIs, billing, and subscriptions are not yet present.
- Production deployment requires careful PostgreSQL, Chroma, email, and AI provider configuration.
Short pitch: My Chat Buddy turns business documents into a controlled website assistant with APIs, widget delivery, verified leads, usage tracking, and isolated project knowledge bases.