01Context
What this was
Cravab is an open-source operations PWA for service businesses that need voice-led intake and CRM in one codebase they can self-host, audit, and extend (AGPL-3.0).
02Problem
What was broken
Before
Small teams are priced out of enterprise CRM plus telephony bundles.
What had to change
Multi-tenant data must stay isolated in the database, not only in UI guards.
- 01Inbound calls need structured capture without manual re-entry
- 02Appointment and follow-up state must stay consistent across channels
- 03Community contributors need clear module boundaries
03Solution
What I built
Next.js, TypeScript, and PWA delivery with Supabase (Auth, PostgreSQL, RLS, Realtime).
Vapi AI for inbound call handling, transcription, and structured lead capture.
Reporting dashboards, appointment lifecycle tracking, and installable mobile surfaces for owners in the field.
04Decisions
Key implementation decisions
- 01
RLS-first multi-tenancy
Tenant boundaries enforced in Postgres for defense in depth.
- 02
Voice-to-CRM pipeline
Idempotent writes from call events into customer and appointment records.
- 03
AGPL for transparent extension
Fork-friendly licensing for agencies and internal platform teams.
05Impact
Operational impact
- Teams can deploy voice + CRM without proprietary lock-in.
- Operators see calls, appointments, and follow-ups in one PWA.
- Patterns align with production Venlyn-style service workflows.
06Results
Results
- Open-source alternative to closed CRM + voice bundles.
- Documented stack: Next.js, Supabase, Vapi AI, PWA.
- Reusable across plumbing, detailing, and similar field services.
07Stack
Technology stack
- Frontend
- Next.js, TypeScript, PWA
- Backend
- Supabase, PostgreSQL, RLS
- Voice
- Vapi AI
- License
- AGPL-3.0 · github.com/stoimera/Cravab
