Initial commit

This commit is contained in:
belviskhoremk
2026-02-22 21:59:37 +00:00
commit 5bd496d355
27 changed files with 4172 additions and 0 deletions

462
README.md Normal file
View File

@@ -0,0 +1,462 @@
# Contexta — AI Chatbot SaaS Platform
A full-stack SaaS platform that lets businesses build custom AI chatbots from their documents, publish them to a marketplace, and optionally export self-hostable code.
---
## Architecture at a Glance
```
contexta_be/ → FastAPI backend (Python 3.11)
contexta_fe/ → React + TypeScript frontend (Vite)
```
**Key tech stack:**
- **Backend**: FastAPI, Supabase (auth + DB), Qdrant (vectors), LangChain
- **Frontend**: React 18, TypeScript, Tailwind CSS, TanStack Query, Zustand
- **AI**: Fireworks AI (free tier), OpenAI, Anthropic, Google Gemini
- **Payments**: Stripe
- **Infra**: Docker, Railway/Vercel-ready
---
## Prerequisites
| Tool | Version | Purpose |
|------|---------|---------|
| Python | 3.11+ | Backend runtime |
| Node.js | 18+ | Frontend build |
| Git | any | Version control |
**External services you need to set up (all have free tiers):**
| Service | What for | Free tier? |
|---------|----------|------------|
| [Supabase](https://supabase.com) | Database + Auth | ✅ Yes |
| [Qdrant Cloud](https://cloud.qdrant.io) | Vector search | ✅ Yes (1GB) |
| [Fireworks AI](https://fireworks.ai) | LLM (free models) | ✅ Yes |
| [OpenAI](https://platform.openai.com) | Embeddings + GPT-4 | Pay-per-use |
| [Stripe](https://stripe.com) | Payments | ✅ Test mode |
---
## Part 1: Supabase Setup (Database + Auth)
### 1.1 Create a Supabase project
1. Go to [supabase.com](https://supabase.com) → New project
2. Save your **Project URL** and both keys (anon + service_role)
### 1.2 Run the database schema
1. In your Supabase dashboard → **SQL Editor**
2. Open `contexta_be/supabase_schema.sql`
3. Paste the entire file → Run
This creates all tables, RLS policies, and triggers.
### 1.3 Enable Email Auth
1. In Supabase → **Authentication****Providers**
2. Ensure "Email" is enabled
3. Optionally disable "Confirm email" for faster testing
---
## Part 2: Qdrant Setup (Vector Database)
### Option A: Qdrant Cloud (recommended)
1. Go to [cloud.qdrant.io](https://cloud.qdrant.io) → Create cluster (free tier)
2. Get your **Cluster URL** and **API Key**
### Option B: Local Qdrant (for development)
```bash
docker run -p 6333:6333 qdrant/qdrant
```
Then set `QDRANT_URL=http://localhost:6333` and leave `QDRANT_API_KEY` empty.
---
## Part 3: Backend Setup (`contexta_be`)
### 3.1 Clone and configure
```bash
cd contexta_be
cp .env.example .env
```
Edit `.env` with your credentials:
```env
# App
APP_ENV=development
APP_SECRET_KEY=change-this-to-a-random-string-in-production
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000
# Supabase (from your project settings)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
# Qdrant
QDRANT_URL=https://your-cluster.qdrant.io
QDRANT_API_KEY=your-key-here
# LLM - MINIMUM REQUIRED: OpenAI (for embeddings)
OPENAI_API_KEY=sk-...
# LLM - Optional but recommended
FIREWORKS_API_KEY=fw_... # Free models for starter plan
ANTHROPIC_API_KEY=sk-ant-... # Claude models
GOOGLE_API_KEY=AIza... # Gemini models
# Stripe (use test keys for development)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_STARTER_PRICE_ID=price_...
STRIPE_PRO_PRICE_ID=price_...
```
### 3.2 Create virtual environment and install
```bash
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
```
### 3.3 Start the backend
```bash
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```
The API will be available at:
- **API**: http://localhost:8000
- **Swagger docs**: http://localhost:8000/docs
- **Health check**: http://localhost:8000/health
### 3.4 Docker alternative
```bash
# Copy and edit .env first
cp .env.example .env
# Edit .env...
# Start with Docker (includes Qdrant locally)
docker-compose up -d
```
---
## Part 4: Frontend Setup (`contexta_fe`)
### 4.1 Install dependencies
```bash
cd contexta_fe
npm install
```
### 4.2 Configure environment
```bash
cp .env.example .env
```
`.env` content:
```env
VITE_API_URL=http://localhost:8000
VITE_APP_NAME=Contexta
```
### 4.3 Start the frontend
```bash
npm run dev
```
Frontend available at: http://localhost:5173
---
## Part 5: Stripe Setup (Payments)
### 5.1 Create Stripe products
1. Go to [dashboard.stripe.com](https://dashboard.stripe.com) → Products
2. Create **Starter** product → Add price → $39/month recurring
3. Create **Pro** product → Add price → $119/month recurring
4. Copy the **Price IDs** (start with `price_`) → paste into backend `.env`
### 5.2 Set up webhook (for local testing)
Install Stripe CLI:
```bash
# Mac
brew install stripe/stripe-cli/stripe
# Others: https://stripe.com/docs/stripe-cli
```
Forward webhooks to local:
```bash
stripe listen --forward-to localhost:8000/api/v1/billing/webhook
```
Copy the webhook signing secret → paste into `STRIPE_WEBHOOK_SECRET` in `.env`
### 5.3 Test a subscription
Use Stripe test card: `4242 4242 4242 4242` with any future expiry and any CVC.
---
## Part 6: Testing the Full Flow
### 6.1 Create an account
1. Open http://localhost:5173
2. Click "Get started free" or go to http://localhost:5173/signup
3. Fill in company name, email, password
### 6.2 Create a chatbot
1. After login → **Dashboard****New Chatbot**
2. Enter a name and configure settings
3. Click **Save**
### 6.3 Upload documents
1. In the chatbot builder → **Documents** tab
2. Drag and drop a PDF, DOCX, or CSV file
3. Wait for processing (status changes to "completed" with chunk count)
> ⚠️ Document processing requires a valid OpenAI API key for embeddings and a working Qdrant instance.
### 6.4 Test in preview mode
1. In the chatbot builder → **Preview** tab
2. Type a question related to your uploaded document
3. The chatbot should answer based on the document content
### 6.5 Publish to marketplace (requires paid plan)
1. Subscribe to Starter or Pro (Stripe checkout)
2. Back in Dashboard → click **Publish** on your chatbot
3. Visit http://localhost:5173/marketplace to see it listed
### 6.6 Export code (Pro plan)
In the chatbot builder → click **Export Code** button → downloads a ZIP containing:
- `backend/` — Complete FastAPI app with your vectors
- `frontend/` — React TypeScript chat widget
- `setup.py` — Interactive setup wizard
- `QUICK_START.md` — 5-minute deployment guide
---
## API Reference
The complete API is documented via Swagger at http://localhost:8000/docs when the backend is running.
### Key endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/v1/auth/signup` | Create account |
| POST | `/api/v1/auth/login` | Login |
| GET | `/api/v1/auth/me` | Current user |
| GET | `/api/v1/chatbots` | List your chatbots |
| POST | `/api/v1/chatbots` | Create chatbot |
| PUT | `/api/v1/chatbots/{id}` | Update chatbot |
| POST | `/api/v1/chatbots/{id}/publish` | Publish to marketplace |
| POST | `/api/v1/chatbots/{id}/export` | Download code export (Pro) |
| POST | `/api/v1/chatbots/{chatbot_id}/documents` | Upload document |
| POST | `/api/v1/chat/{chatbot_id}` | Send chat message |
| GET | `/api/v1/marketplace/chatbots` | Browse marketplace |
| POST | `/api/v1/billing/checkout` | Create Stripe checkout |
---
## Deployment
### Backend → Railway
```bash
# Install Railway CLI
npm i -g @railway/cli
cd contexta_be
railway login
railway init
railway up
```
Set all environment variables in Railway dashboard → Variables tab.
### Frontend → Vercel
```bash
npm i -g vercel
cd contexta_fe
vercel
```
Set `VITE_API_URL` to your Railway backend URL in Vercel environment variables.
### Update CORS
Once deployed, update `ALLOWED_ORIGINS` in backend to include your Vercel domain:
```
ALLOWED_ORIGINS=https://your-app.vercel.app
```
---
## Minimal Setup (Testing Only, No Real AI)
If you want to test the UI without real API keys, you can:
1. Run only the frontend
2. Mock the API responses
For the quickest backend test without Qdrant/OpenAI, comment out the vector store initialization in startup and the RAG processing in document upload. The chat will still work but won't return relevant answers.
---
## Environment Variables Reference
### Backend (`contexta_be/.env`)
| Variable | Required | Description |
|----------|----------|-------------|
| `SUPABASE_URL` | ✅ | Supabase project URL |
| `SUPABASE_ANON_KEY` | ✅ | Supabase anon key |
| `SUPABASE_SERVICE_ROLE_KEY` | ✅ | Supabase service role key |
| `QDRANT_URL` | ✅ | Qdrant cluster URL |
| `QDRANT_API_KEY` | ⚠️ | Required for Qdrant Cloud |
| `OPENAI_API_KEY` | ✅ | Required for embeddings |
| `FIREWORKS_API_KEY` | ⚠️ | For free-tier Llama/Mixtral models |
| `ANTHROPIC_API_KEY` | ⚠️ | For Claude models (Pro plan) |
| `GOOGLE_API_KEY` | ⚠️ | For Gemini models (Pro plan) |
| `STRIPE_SECRET_KEY` | ⚠️ | For billing (use test key in dev) |
| `STRIPE_WEBHOOK_SECRET` | ⚠️ | For Stripe webhooks |
| `STRIPE_STARTER_PRICE_ID` | ⚠️ | Stripe price ID for Starter plan |
| `STRIPE_PRO_PRICE_ID` | ⚠️ | Stripe price ID for Pro plan |
| `ALLOWED_ORIGINS` | ✅ | Comma-separated CORS origins |
| `APP_SECRET_KEY` | ✅ | Random secret for production |
### Frontend (`contexta_fe/.env`)
| Variable | Required | Description |
|----------|----------|-------------|
| `VITE_API_URL` | ✅ | Backend API URL |
---
## Project Structure
```
contexta_be/
├── app/
│ ├── main.py # FastAPI app + router registration
│ ├── config.py # Settings + plan limits
│ ├── database.py # Supabase client
│ ├── models.py # Pydantic models
│ ├── dependencies.py # Auth middleware
│ ├── routers/
│ │ ├── auth.py # Signup, login, me
│ │ ├── chatbots.py # CRUD + publish + export
│ │ ├── documents.py # File upload + processing
│ │ ├── chat.py # RAG chat endpoint
│ │ ├── marketplace.py # Public chatbot listing
│ │ └── billing.py # Stripe checkout + webhooks
│ └── services/
│ ├── vector_store.py # Qdrant operations
│ ├── embeddings.py # OpenAI embeddings
│ ├── document_processor.py # PDF/DOCX/CSV parsing
│ ├── llm.py # Multi-provider LLM routing
│ ├── rag.py # RAG pipeline
│ └── code_export.py # ZIP code generation
├── supabase_schema.sql # Database schema (run once)
├── requirements.txt
├── Dockerfile
└── docker-compose.yml
contexta_fe/
├── src/
│ ├── main.tsx # Entry point
│ ├── App.tsx # Router + routes
│ ├── index.css # Tailwind + global styles
│ ├── types/index.ts # TypeScript interfaces
│ ├── services/api.ts # API client (axios)
│ ├── store/authStore.ts # Zustand auth state
│ ├── lib/utils.ts # Helpers + constants
│ ├── components/
│ │ ├── ui.tsx # Reusable UI (Button, Input, Card...)
│ │ ├── Layout.tsx # App shell with sidebar
│ │ └── ChatInterface.tsx # Chat UI with sources
│ └── pages/
│ ├── LandingPage.tsx
│ ├── AuthPages.tsx # Login + Signup
│ ├── DashboardPage.tsx
│ ├── ChatbotBuilderPage.tsx # Builder + docs + preview
│ ├── MarketplacePage.tsx
│ ├── PricingPage.tsx
│ └── SettingsPage.tsx
├── package.json
├── vite.config.ts
└── tailwind.config.js
```
---
## Troubleshooting
### "CORS error" in browser
→ Check `ALLOWED_ORIGINS` in backend `.env` includes your frontend URL
### "Could not connect to Qdrant"
→ Check `QDRANT_URL` is correct and the cluster is running
→ For local Docker: ensure the qdrant service is started
### "Invalid or expired token" on API calls
→ The Supabase JWT has expired. Log out and log back in.
→ Check `SUPABASE_SERVICE_ROLE_KEY` is correct
### Document processing stuck on "processing"
→ Check OpenAI API key is valid
→ Check Qdrant connection
→ Check backend logs: `docker logs contexta-api` or terminal output
### "Upgrade to publish" even after Stripe payment
→ Ensure Stripe webhook is configured and received the `checkout.session.completed` event
→ Check backend logs for webhook processing
→ For local testing, use `stripe listen --forward-to localhost:8000/api/v1/billing/webhook`
### Chat returns "I don't have information about that"
→ Document processing may have failed — check document status in builder
→ The uploaded content may not be relevant to the question
→ Try re-uploading the document
---
## Development Tips
- **Backend hot reload**: `uvicorn app.main:app --reload` watches for file changes
- **Frontend hot reload**: `npm run dev` automatically reloads
- **API testing**: Use http://localhost:8000/docs (Swagger UI)
- **Database inspection**: Supabase dashboard → Table Editor
- **Vector inspection**: Qdrant dashboard at http://localhost:6333/dashboard (local only)
---
## License
MIT — build freely, use commercially.