Health Audit
SuperAssistant MVP — deep infrastructure scan — 2026-03-08
52
DB Tables
190+
Indexes
117
RLS Warnings
29
Backups
2d
Backup Gap
Security Advisors 1 Finding
Leaked Password Protection Disabled AUTH
- Supabase Auth can check passwords against HaveIBeenPwned.org to block compromised credentials
- This feature is currently disabled
- Fix: Enable in Supabase Dashboard → Auth → Providers → Email → Leaked password protection Documentation
Railway Deployment Healthy
Latest Build
- Build completed in 21.16 seconds
- Builder: Nixpacks with Python venv
- No error logs in recent deployment (filtered for "error" — zero results)
- Both schedulers started successfully on deploy
Backup Integrity Gap Detected
Daily Backups
- 29 backups in storage, daily cadence confirmed (Feb 6 – Mar 6)
- Naming convention consistent:
backup_YYYYMMDD_020000.json - Latest backup: March 6 — missing March 7 and March 8 Today's backup should run at 02:00 UTC. The scheduler restarted at 16:14 UTC today, so March 7 backup was missed during a deployment window.
- Consider: trigger a manual backup to close the gap
Recent Backup History
| Backup | Created |
|---|---|
backup_20260306_020000.json | Mar 6, 02:00 UTC |
backup_20260305_020000.json | Mar 5, 02:00 UTC |
backup_20260304_020000.json | Mar 4, 02:00 UTC |
backup_20260303_020000.json | Mar 3, 02:00 UTC |
backup_20260302_020000.json | Mar 2, 02:00 UTC |
RLS Policy Audit 117 Warnings
Multiple Permissive Policies
- 117 instances of multiple permissive RLS policies on the same table/role/action
- Performance impact: every permissive policy must be evaluated for each query (OR logic)
- Consider consolidating overlapping policies into fewer, more targeted ones
| Table | Policy Count | Severity |
|---|---|---|
conversations | 14 | High |
documents | 11 | High |
messages | 11 | High |
users | 10 | High |
document_chunks | 8 | Medium |
notion_tokens | 8 | Medium |
clients | 5 | Medium |
cave_runs | 4 | Low |
unified_evaluations | 4 | Low |
theme_settings | 4 | Low |
Database Indexes Well Indexed
Index Coverage
- 190+ indexes across 52 tables — comprehensive coverage
- Vector index on
document_chunks.embeddingfor pgvector similarity search - Composite indexes on hot paths:
conversations(user_id, updated_at),messages(conversation_id, timestamp) - GIN indexes for text search:
conversations.title,messages.content - Foreign key indexes present on all join columns
Table Row Counts Low Volume
| Table | Rows | Notes |
|---|---|---|
help_chunks | 238 | Help documentation embeddings |
evaluation_steps | 65 | AESOP evaluation pipeline |
help_documents | 43 | Indexed help docs |
interview_segments | 38 | ElevenLabs segments |
evaluations | 13 | |
users | 12 | |
conversations | 11 | |
messages | 12 | |
interview_sessions | 9 | |
agents | 6 |
Observation
- Data volume is very low — this is a pre-production/MVP environment
- Many tables have 0 rows (stakeholders, roi_opportunities, contract_analysis, etc.)
- No performance concerns at this scale — the 190+ indexes are ready for growth
Vercel Env Vars Duplicates
71 Environment Variables
- Duplicate keys detected — several vars appear twice (once for production, once for preview): SUPABASE_SERVICE_ROLE_KEY, ANTHROPIC_API_KEY, VOYAGE_API_KEY, ELEVENLABS_API_KEY, ELEVENLABS_AGENT_ID, OAUTH_ENCRYPTION_KEY, ELEVENLABS_VOICE_ID, SKIP_WEBHOOK_VERIFICATION, SUPABASE_JWT_SECRET, ELEVENLABS_WEBHOOK_SECRET, GOOGLE_GENERATIVE_AI_API_KEY, HELP_REINDEX_API_KEY, ENABLE_SEGMENTED_INTERVIEWS, RESEND_API_KEY, RESEND_FROM_EMAIL, ANTHROPIC_MODEL, DATABASE_URL, DOTENV_PRIVATE_KEY, and all ELEVENLABS_WEBHOOK_SECRET_SEGMENT_* and ELEVENLABS_AGENT_SEGMENT_* vars
- This is likely intentional — Vercel allows different values per target (production vs preview)
- Verify that production and preview values are intentionally different where duplicated
Recommended Actions
Priority 1: Security
- Enable leaked password protection in Supabase Auth settings Dashboard → Authentication → Providers → Email → Enable "Leaked password protection"
Priority 2: Operations
- Investigate missing backups (Mar 7-8) — likely caused by Railway redeployment Tonight's 02:00 UTC run should auto-resume. Trigger manual backup if data changed since Mar 6.
- Audit RLS policies on high-count tables (conversations: 14, documents: 11, messages: 11, users: 10) Consolidate overlapping permissive policies to reduce per-query evaluation overhead
Priority 3: Cleanup (Optional)
- Clean orphaned storage — 45 files in
documentsbucket with no matching DB records (legacy uploads from Nov-Dec 2025) - Verify Vercel env var duplicates are intentional (production vs preview targeting)
- Remove empty tables if features are deprecated (stakeholders, roi_opportunities, contract_analysis have 0 rows)