Important
Retired on August 12, 2026. This repository is preserved as a read-only
engineering archive. It has no supported public deployment, scheduled
evaluation lane, GitLab mirror, or production service. Do not rely on the
historical Vercel URLs or operational instructions below. See
docs/RETIREMENT-2026-08-12.md for the
verified closeout boundary and recovery notes.
Sections below the banner are preserved historical project documentation.
Historical privacy-first RAG workbench source — Supabase + pgvector, OpenAI, and Sentry
CSBrainAI is a privacy-first RAG workbench for technical teams that need internal knowledge assistants. User queries are never stored in raw form — only HMAC-SHA256 hashes and lengths are logged, ensuring complete privacy while maintaining full observability. Answers come with citations and similarity scores, backed by an automated eval harness and operational guardrails.
- 🔒 Privacy-First: HMAC-SHA256 hashed queries (no raw PII in logs)
- 🚀 RAG Pipeline: Supabase + pgvector for semantic search
- 🤖 OpenAI Integration: text-embedding-3-small + gpt-4o-mini
- 🛡️ Security: CSP, rate limiting (10 req/min), HSTS
- 📊 Observability: Sentry L5 tool with PII scrubbing
- 🧪 Historical eval harness: Retained in source; scheduled execution is retired
- 📦 Archived source: Preserved for inspection and possible local study; not an active service
┌─────────────┐
│ User │
└──────┬──────┘
│ query
▼
┌─────────────────────────┐
│ Next.js App Router │
│ - Rate Limiting │
│ - Security Headers │
│ - PII Scrubbing │
└──────┬──────────────────┘
│
▼
┌─────────────────────────┐
│ /api/answer │
│ 1. Hash query (HMAC) │
│ 2. Embed query (OpenAI)│
│ 3. Vector search │
│ 4. LLM generation │
└──────┬──────────────────┘
│
▼
┌─────────────────────────┐
│ Supabase + pgvector │
│ - IVFFlat index │
│ - Cosine similarity │
│ - RLS policies │
└─────────────────────────┘
| Component | Technology | Purpose |
|---|---|---|
| Framework | Next.js 16 (App Router) | Full-stack React framework |
| Language | TypeScript 5 | Type safety |
| Database | Supabase (PostgreSQL) | Vector storage with pgvector |
| Embeddings | OpenAI text-embedding-3-small | 1536-dim vectors |
| LLM | OpenAI gpt-4o-mini | Answer generation |
| Observability | Sentry | Error tracking (L5 tool) |
| Rate Limiting | Upstash Redis / Token Bucket | API protection |
| Security | Next.js Proxy | CSP, HSTS, headers |
| CI/CD | GitHub Actions | Nightly evaluations |
Prerequisites:
- Node.js 20+
- Supabase account (for vector storage)
- OpenAI API key
- Sentry account (optional but recommended)
Run the demo:
# 1. Install dependencies
npm install
# 2. Set up environment variables
cp .env.example .env
# Edit .env with your SUPABASE_URL, SUPABASE_ANON_KEY, OPENAI_API_KEY
# 3. Run database migration (in Supabase SQL Editor)
# Copy contents of supabase/migrations/001_rag_schema.sql and execute
# 4. Ingest sample knowledge
npm run ingest
# 5. Start development server
npm run dev
# 6. Test the API (in another terminal)
curl -X POST http://localhost:3000/api/answer \
-H "Content-Type: application/json" \
-d '{"query":"What is RAG?"}'Expected Output:
{
"answer": "RAG (Retrieval Augmented Generation) is an AI architecture...",
"citations": [
{
"source_url": "file://sample-1.md#chunk-0",
"content": "RAG (Retrieval Augmented Generation) is...",
"similarity": 0.87
}
],
"q_hash": "a3f2b9c1d4e5f6a7b8c9d0e1f2a3b4c5...",
"q_len": 12,
"tokensUsed": 456
}What this proves:
- Privacy-first RAG system (queries are hashed, never stored raw)
- Vector search with Supabase + pgvector
- Structured citations with similarity scores
- Operational guardrails (rate limiting, PII scrubbing, hashed-query telemetry) fit for internal knowledge assistants
Alternative demo (no setup needed):
# Run unit tests to see functionality
npm testNext Steps:
- See
docs/ANSWER-FLOW.mdfor API architecture - See
TEST_NOTES.mdfor manual test scenarios
- Node.js 20+
- Supabase account
- OpenAI API key
- Sentry account (optional but recommended)
git clone https://github.com/RazonIn4K/csbrainai.git
cd csbrainai
npm installcp .env.example .envEdit .env with your credentials:
# OpenAI
OPENAI_API_KEY=sk-...
# Supabase
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE=eyJ... # For ingestion only
# Security
HASH_SALT=$(openssl rand -hex 32)
# Sentry
SENTRY_DSN=https://xxx@xxx.ingest.sentry.io/xxx
NEXT_PUBLIC_SENTRY_DSN=https://xxx@xxx.ingest.sentry.io/xxx
# Optional: Upstash Redis (for distributed rate limiting)
UPSTASH_REDIS_REST_URL=https://xxx.upstash.io
UPSTASH_REDIS_REST_TOKEN=xxxRun the migration in Supabase SQL Editor or via CLI:
# Copy contents of supabase/migrations/001_rag_schema.sql
# and execute in Supabase SQL EditorOr using Supabase CLI:
supabase link --project-ref <your-project-ref>
supabase db pushAdd your knowledge files to data/knowledge/:
# Example structure:
data/knowledge/
├── faq.md
├── product-docs.md
└── technical-guide.mdRun ingestion:
npm run ingestExpected output:
🚀 Starting RAG ingestion...
📚 Found 3 knowledge file(s)
...
✅ Ingestion complete!
📊 Summary:
├─ Total chunks: 42
├─ Processed: 42
├─ Skipped (duplicates): 0
└─ Errors: 0
npm run devOpen http://localhost:3000 and try asking a question!
npm run evalsComprehensive docs in the docs/ directory:
- SCHEMA.md - Database schema and indexes
- INGEST.md - Ingestion process and chunking
- ANSWER-FLOW.md - Answer API architecture
- PRIVACY.md - Privacy guarantees and PII protection
- GO-LIVE-GATE.md - Production readiness checklist
✅ What we store:
- Query hash (HMAC-SHA256)
- Query length
- Metadata (timestamps, token usage)
❌ What we NEVER store:
- Raw query text
- User identifiers (beyond IP for rate limiting)
- PII of any kind
- Rate Limiting: 10 requests/min/IP
- Security Headers: CSP, HSTS, X-Frame-Options
- PII Scrubbing: Automatic Sentry
beforeSendhooks - Input Validation: Max query length, type checking
- HTTPS Only: Enforced via HSTS
See PRIVACY.md for full details.
Automated quality testing runs nightly at 2 AM UTC:
# .github/workflows/nightly-evals.yml
- Skips scheduled runs when required evaluation secrets are not configured
- Fails manual dispatches when required evaluation secrets are missing
- Loads 20 test questions from data/evals/test-questions.jsonl
- Calls /api/answer for each question
- Validates response quality, citations, latency
- Uploads results as GitHub Actions artifact
- Fails only on severe regressions (< 50% quality)Run manually:
npm run evalscurl -X POST http://localhost:3000/api/answer \
-H "Content-Type: application/json" \
-d '{"query": "What is RAG?"}'Generate an answer using RAG.
Request:
{
"query": "What is RAG and how does it work?"
}Response (200):
{
"answer": "RAG (Retrieval Augmented Generation) is an AI architecture...",
"citations": [
{
"source_url": "file://sample-1.md#chunk-0",
"content": "RAG (Retrieval Augmented Generation) is...",
"similarity": 0.87
}
],
"q_hash": "a3f2b9c1d4e5f6a7b8c9d0e1f2a3b4c5...",
"q_len": 35,
"tokensUsed": 456
}Error (429):
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Please try again later."
}See ANSWER-FLOW.md for complete API docs.
npm run dev # Start dev server
npm run build # Production build
npm run start # Start production server
npm run lint # Run ESLint
npm run type-check # TypeScript type checking
npm run ingest # Run ingestion script
npm run evals # Run evaluation suitecsbrainai/
├── app/
│ ├── api/answer/route.ts # Answer endpoint
│ ├── layout.tsx # Root layout
│ └── page.tsx # Home page
├── components/
│ └── AnswerDemo.tsx # Demo UI
├── data/
│ ├── evals/ # Evaluation questions
│ └── knowledge/ # Knowledge base files
├── docs/ # Documentation
├── lib/
│ ├── crypto-utils.ts # HMAC hashing
│ ├── openai.ts # OpenAI client
│ ├── rate-limiter.ts # Rate limiting
│ ├── sentry-utils.ts # PII scrubbing
│ └── supabase.ts # Database client
├── scripts/
│ ├── evals-runner.ts # Evaluation script
│ └── ingest.ts # Ingestion script
├── supabase/migrations/ # Database migrations
├── middleware.ts # Security & rate limiting
├── sentry.client.config.ts # Sentry client
└── sentry.server.config.ts # Sentry server
# Install Vercel CLI
npm i -g vercel
# Deploy
vercel --prodSet all variables from .env.example in Vercel dashboard:
- Project Settings → Environment Variables
- Run database migration in Supabase
- Run ingestion:
npm run ingest(local or CI) - Verify Sentry integration
- Test API endpoint
- Check nightly evals workflow
See GO-LIVE-GATE.md for production checklist.
Monitor in production:
- Error rate (target: < 1%)
- Performance (p95 < 3s)
- Rate limit violations
- PII scrubbing effectiveness
- Latency: Median, p95, p99 response times
- Quality: Nightly eval scores
- Cost: OpenAI token usage
- Errors: 4xx/5xx rates
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE for details.
- Supabase for pgvector support
- OpenAI for embeddings and LLM APIs
- Sentry for observability
- Next.js for the framework
- Upstash for serverless Redis
- Documentation: docs/
- Issues: GitHub Issues
- Security: Report vulnerabilities through GitHub Security Advisories for this repository.
Built by David Ortiz.