2026-04-06 21:54:13 +00:00
2026-02-22 21:59:37 +00:00
2026-02-22 21:59:37 +00:00
2026-02-22 21:59:37 +00:00
2026-02-22 21:59:37 +00:00
2026-04-06 21:54:13 +00:00
2026-02-22 21:59:37 +00:00
2026-02-22 21:59:37 +00:00

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 Database + Auth Yes
Qdrant Cloud Vector search Yes (1GB)
Fireworks AI LLM (free models) Yes
OpenAI Embeddings + GPT-4 Pay-per-use
Stripe Payments Test mode

Part 1: Supabase Setup (Database + Auth)

1.1 Create a Supabase project

  1. Go to 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 → AuthenticationProviders
  2. Ensure "Email" is enabled
  3. Optionally disable "Confirm email" for faster testing

Part 2: Qdrant Setup (Vector Database)

  1. Go to cloud.qdrant.io → Create cluster (free tier)
  2. Get your Cluster URL and API Key

Option B: Local Qdrant (for development)

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

cd contexta_be
cp .env.example .env

Edit .env with your credentials:

# 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

python -m venv venv
source venv/bin/activate       # On Windows: venv\Scripts\activate
pip install -r requirements.txt

3.3 Start the backend

uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

The API will be available at:

3.4 Docker alternative

# 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

cd contexta_fe
npm install

4.2 Configure environment

cp .env.example .env

.env content:

VITE_API_URL=http://localhost:8000
VITE_APP_NAME=Contexta

4.3 Start the frontend

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 → 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:

# Mac
brew install stripe/stripe-cli/stripe

# Others: https://stripe.com/docs/stripe-cli

Forward webhooks to local:

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 → DashboardNew 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

# 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

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.

Description
No description provided
Readme 310 KiB
Languages
Python 97.8%
PLpgSQL 2.1%
Dockerfile 0.1%