Spaces:
Runtime error
Runtime error
| # Smart Chatbot β Project Navigation | |
| **What it is:** A chatbot-as-a-service (CaaS) microservice for SMEs. Tenants embed the widget on their site; the chatbot answers domain questions grounded in the tenant's knowledge base (RAG). Sold as prepaid token credits or monthly subscription. | |
| --- | |
| ## Current Focus | |
| **Next:** Phase 3 release gate β Simulated Tenant QA Pipeline (all prior gates including Qdrant migration are complete). | |
| Full task spec: `current_state/project_status.md` | |
| --- | |
| ## Tech Stack | |
| | Layer | Technology | | |
| |---|---| | |
| | Backend | FastAPI, Python, SQLAlchemy, Alembic | | |
| | Database | PostgreSQL (dev/prod), SQLite (HuggingFace Spaces) | | |
| | Vector DB | Qdrant β shared collection with required `tenant_id` payload filter; ChromaDB legacy fallback code only | | |
| | Embeddings | Google Gemini Embedding 2 (`gemini-embedding-2`, 3072-dim) | | |
| | LLM | LiteLLM Router β provider-agnostic, model aliases in env vars, auto-fallback chains | | |
| | Frontend | Preact + Shadow DOM widget, Vite build | | |
| | Auth | API key (widget) + Google OAuth + TOTP 2FA + JWT (admin) | | |
| | Infra | Docker multi-env, Nginx, Redis/Celery workers, Qdrant, HuggingFace Spaces | | |
| | CI/CD | GitHub Actions | | |
| --- | |
| ## Project Structure | |
| ``` | |
| app/ | |
| routers/ # Route handlers (knowledge_base, system_prompt) | |
| schemas/ # Pydantic request/response models | |
| middleware/ # TenantAuthMiddleware (API key β tenant_id) | |
| models/ # SQLAlchemy models | |
| services/ # Business logic (EmbeddingService, VectorStore, RetrievalService, LLMService, CreditService, WordPress sync, kb_reindex) | |
| workers/ # Celery background workers (wordpress_sync, kb_reindex) | |
| utils/ # api_key, token_counter, seeding | |
| dependencies/ # FastAPI dependencies (admin_auth) | |
| alembic/ # DB migrations | |
| tests/ # 469 tests, organized by domain | |
| auth/ # Admin + super-admin auth, JWT, TOTP, OAuth | |
| knowledge_base/ # KB CRUD, chunking, pagination, reindex, sync | |
| chat/ # Conversations, RAG context, input limits, history | |
| billing/ # Credits, billing modes, concurrency | |
| vector_store/ # Qdrant, ChromaDB, embedding service | |
| workers/ # Summarization worker, WP sync jobs | |
| llm/ # LLM service, retrieval, AI verdict, RAG | |
| infra/ # Middleware, rate limiter, seeding, widget, system prompt | |
| frontend/ # Preact chat widget (Vite build β chatbot-widget.js) | |
| current_state/ # Architecture and status documents (see below) | |
| archive/ # Historical notes and discussion logs (never retroactively edited) | |
| docs/ # Specs and error logs | |
| ``` | |
| --- | |
| ## Key Architecture Decisions | |
| **Multi-tenancy:** API key β `tenant_id` extracted in middleware. All DB queries and vector store operations are scoped to `tenant_id`. Qdrant uses one shared collection with required `tenant_id` payload filters inside the adapter; PostgreSQL remains the source of truth and Qdrant is a rebuildable search index. | |
| **RAG pipeline:** `/chat` β `RetrievalService.retrieve(query, tenant_id)` β top-k KB docs injected into system message β LLM response grounded in KB. | |
| **User auth model:** Two modes β `anonymous` (most SMEs: no end-user login, visitors are anonymous) and `authenticated` (SaaS/e-commerce: host page passes authenticated user identity). Toggle via admin panel config. | |
| **LLM provider abstraction:** `LLMService` wraps LiteLLM Router. Model aliases (`chat-model`, `summarization-model`, `judge-llm`) declared in env vars β swapping providers requires only an env var change, no code change. Auto-fallback chains configured per alias. `complete_with_usage()` returns `LLMResult` with token counts for billing. | |
| **API versioning:** All public endpoints prefixed `/api/v1/` β in place before first client embeds widget (one-way door). | |
| **Widget embedding:** Preact + Shadow DOM β 3KB bundle, fully isolated from host-site CSS/JS, works on any tech stack (WordPress, Vue, React, plain HTML). Admin console generates per-tenant snippet: `<script src="widget.js" data-api-key="tenant_abc123"></script>`. Widget reads `data-api-key` at runtime. | |
| **Per-tenant customization:** All theme/branding/chatbot identity settings stored as `customization JSONB` on `tenants` table β zero schema migrations for new settings. Only fields that need filtering (e.g. `credits`, `is_active`) get proper columns. | |
| **Multi-tenant secrets:** Shared secrets (`GROQ_API_KEY`, `DATABASE_URL`) live in backend env. Per-tenant config (system prompt, KB, theme) lives in DB. BYOK tenants store their own LLM API key encrypted in `customization JSONB`. | |
| **Credit deduction atomicity:** Single SQL `UPDATE tenants SET balance_usd = balance_usd - :amount WHERE id = :tenant_id AND balance_usd >= :amount` β check rows affected (1 = success, 0 = insufficient balance). No race condition possible without application-level locking. | |
| --- | |
| ## Key Files | |
| | File | Purpose | | |
| |---|---| | |
| | `app/main.py` | Entry point β router registration, middleware, startup | | |
| | `app/models/conversation_manager.py` | LLM call lives here β chat logic, context assembly | | |
| | `app/models/nlp_engine.py` | Analytics and routing only β keep as-is | | |
| | `app/utils/config.py` | Singleton config β safe to defer refactor | | |
| | `.env` / `.env.staging` / `.env.production` | Environment-specific values | | |
| --- | |
| ## Business Model | |
| | Tier | Best for | How it works | | |
| |---|---|---| | |
| | Prepaid credits | Informational sites, low-volume SMEs | Buy credits upfront, deducted per message | | |
| | Monthly subscription | E-commerce, SaaS, high-volume SMEs | Fixed fee, predictable revenue | | |
| Gifted accounts (V1 only): Monireach tops up manually via super-admin; no Stripe needed. Full payment integration is post-V1. | |
| --- | |
| ## Deployment Roadmap | |
| | Stage | Tenants | Stack | Monthly cost | | |
| |---|---|---|---| | |
| | Now | 0β10 | HuggingFace Spaces (demo/portfolio) | Free | | |
| | Early | 10β100 | Railway or Fly.io (managed, zero DevOps) | $10β30 | | |
| | Growth | 100β1000 | Hetzner VPS + Docker Compose | β¬10β20 | | |
| | Scale | 1000+ | Hetzner + K3s (lightweight Kubernetes) | β¬30β80 | | |
| Target: Hetzner CAX31 ARM (4 vCPU, 8GB RAM, β¬14.10/month). PostgreSQL: Supabase managed at small scale β self-hosted at large scale. Admin panels: Cloudflare Pages (free). HF Space kept as public demo proxy only. | |
| **K3s local practice (after V1 stable):** Deploy the full stack to a local K3s cluster in parallel with Docker Compose β not a replacement for the dev workflow, but a learning environment for writing real K8s manifests (`Deployment`, `Service`, `Ingress`, `ConfigMap`, `Secret`) against a real multi-service app. Makes the eventual Hetzner β K3s production migration familiar ground. | |
| --- | |
| ## Where to Find Things | |
| | What you need | File | | |
| |---|---| | |
| | Task status, V1 checklist, current progress | `current_state/project_status.md` | | |
| | Full details on completed tasks (sub-tasks, bugs, decisions) | `current_state/milestone.md` | | |
| | Auth model, tenant isolation, API key design | `docs/security_architecture.md` | | |
| | Frontend widget architecture, embedding, theming | `docs/frontend_architecture.md` | | |
| | Khmer language strategy, LLM provider selection | `docs/khmer_llm_strategy.md` | | |
| | Admin console scope and integration status | `~/projects/smart_chatbot_admin_console/PROJECT.md` | | |
| | Super-admin console scope and task status | `~/projects/smart_chatbot_super_admin/current_state/project_status.md` | | |
| | Docker setup, env vars, service topology | `DOCKER_SETUP.md` | | |
| | Historical discussions (system expansion, billing design) | `archive/` | | |
| --- | |
| ## Live Deployments | |
| | Environment | URL | | |
| |---|---| | |
| | HuggingFace Spaces (public API) | `https://huggingface.co/spaces/monireach88/smart-chatbot-api` | | |
| | Portfolio (widget embedded) | `https://monireach.com` | | |