A minimalist, extensible open-source CRM built with Next.js, Supabase, and Tailwind CSS. Designed to be extended with Claude Code.
- 5 Core Entities: Organizations, Contacts, Projects, Offers, Services
- Offer Builder: Create proposals with service line items, discounts, and terms
- Public Offer View: Shareable offer pages with email-gated acceptance
- Dashboard: KPI cards and offer history chart
- Unified Form System: Consistent create/edit forms powered by React Hook Form + Zod
- Data Table: Sorting, filtering, search, and pagination
- Command Palette: Quick navigation with Cmd+K
- Settings: Corporate entities, payment terms, delivery conditions, offer link presets
- Dark/Light Theme: System-aware with manual override
- Framework: Next.js 16 (App Router)
- Database: Supabase (PostgreSQL + Auth)
- Styling: Tailwind CSS + Shadcn UI (Radix primitives)
- Forms: React Hook Form + Zod validation
- Data Fetching: SWR (client), unstable_cache (server)
- Language: TypeScript
git clone <repo-url> core-oss
cd core-oss
pnpm install- Create a new project at supabase.com
- Go to SQL Editor and run
migrations/001_initial_schema.sql - Run
migrations/002_seed_data.sqlfor default settings and sample services - Go to Authentication > Settings and enable email/password sign-ups
- Create your first user in Authentication > Users
cp .env.example .env.localFill in your Supabase credentials from Project Settings > API:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
NEXT_PUBLIC_BASE_URL=http://localhost:3000
pnpm devOpen http://localhost:3000 and log in.
Use the built-in dashboard probe to compare cold vs warm cached read timings:
- Open
/dashboard/performance - Click Run Performance Probe
- Compare pass 1 vs pass 2 timings
The probe uses the authenticated API endpoint:
GET /api/perf/dashboard?passes=2
It measures cached reads for dashboard home data, entity index datasets, and shared filter options.
The app ships with placeholder branding ("Envisioning"). To use your own brand, search and replace across the codebase:
- Product name:
Envisioning→ your company or product name (UI copy, meta description, dashboard subtitle). - Domain:
envisioning.comandwww.envisioning.com→ your public domain (offer redirects and "copy link" URLs insrc/app/offers/view/[id]/page.tsxandsrc/components/features/entities/entity-index-client.tsx). - Contact email:
contact@envisioning.com→ your support or contact address (public offer footer insrc/components/entities/offers/public-offer-layout.tsx). - Internal email filter: If you use a different domain for team emails, update the
@envisioning.com/@envisioning.iofilters insrc/app/dashboard/offers/page.tsxandsrc/components/features/entities/entity-index-page.tsxso internal visits are excluded from offer analytics. - Logo: Replace
public/envisioning.svgwith your own logo and update anyaltor references if you rename the file.
src/
├── app/
│ ├── api/ # REST endpoints
│ ├── auth/ # Login, reset password
│ ├── dashboard/ # Protected CRM pages
│ │ ├── organizations/ # CRUD pages
│ │ ├── contacts/
│ │ ├── projects/
│ │ ├── offers/
│ │ ├── services/
│ │ └── settings/ # System & offer settings
│ └── offers/view/[id]/ # Public offer page
├── components/
│ ├── ui/ # Shadcn primitives + composites
│ ├── forms/unified/ # Unified form system
│ ├── features/ # Entity pages, settings, analytics
│ ├── entities/ # Entity-specific components
│ ├── layouts/ # Sidebar, page headers
│ └── providers/ # Theme, SWR, command palette
├── hooks/ # SWR hooks for entities
└── lib/
├── actions/ # Server actions
├── api/ # API service classes
├── forms/ # Form configs
├── validation/ # Zod schemas
└── utils/ # Utilities
| Table | Purpose |
|---|---|
organizations |
Client companies |
contacts |
People at organizations |
projects |
Active engagements |
services |
Service catalog |
offers |
Proposals |
offer_services |
Line items linking offers to services |
offer_selected_links |
Per-offer resource links |
corporate_entities |
Your invoicing entities |
settings_payment_terms |
Payment term presets |
settings_delivery_conditions |
Delivery condition presets |
settings_offer_links |
Offer link presets |
See CLAUDE.md for a detailed guide on adding new entities, form fields, settings pages, and more.