Captable, Inc. is an open-source cap table management platform designed as an alternative to Carta, Pulley, and AngelList. The platform provides comprehensive equity management, fundraising tools, and stakeholder communication features.
- Framework: Next.js 14 (App Router) with TypeScript
- Database: PostgreSQL with Prisma ORM
- API: tRPC for type-safe APIs
- Authentication: NextAuth with Passkey support
- Styling: Tailwind CSS with shadcn/ui components
- Email: React Email with Nodemailer
- File Storage: AWS S3 compatible (Minio for local dev)
- Payments: Stripe integration
- PDF: PDF-lib for generation, React-PDF for viewing
- Queue: pg-boss for job processing
- Monitoring: Sentry for error tracking
- Share Classes: Common and Preferred shares with customizable terms
- Securities: Shares, Options (ISO/NSO/RSU), SAFEs, Convertible Notes
- Equity Plans: Employee stock option plans with vesting schedules
- Stakeholder Management: Individual and institutional investors, employees, advisors
- SAFE Agreements: YC standard templates (Post-money cap, discount, MFN variants)
- Investment Tracking: Record investments with share issuance
- Convertible Notes: Support for various types (CCD, OCD, NOTE)
- E-Signing: Full document signing workflow with templates and fields
- Data Rooms: Secure document sharing with access controls
- Document Storage: Secure file uploads with S3-compatible storage
- Investor Updates: Rich-text updates with public/private sharing
- Email Notifications: Automated emails for various workflows
- Audit Trail: Comprehensive activity logging
- RBAC: Role-based access control with custom roles
- Passkeys: WebAuthn support for passwordless authentication
- API Access: Token-based API access for integrations
src/
├── app/ # Next.js app router pages
│ ├── (authenticated)/ # Protected routes (dashboard, etc.)
│ ├── (unauthenticated)/ # Public routes (login, signup, etc.)
│ ├── (documents)/ # Document-related pages
│ └── api/ # API routes (auth, stripe, trpc)
├── components/ # React components organized by feature
├── server/ # Server-side utilities and services
├── trpc/ # tRPC setup and routers
│ ├── api/ # API configuration
│ └── routers/ # Feature-specific routers
├── lib/ # Utility functions and constants
├── providers/ # React context providers
├── hooks/ # Custom React hooks
├── emails/ # Email templates
├── jobs/ # Background job handlers
└── schema/ # Validation schemas
- Company: Central entity representing an organization
- User: System users with authentication
- Member: Company members with roles and permissions
- Stakeholder: Equity holders (investors, employees, etc.)
- ShareClass: Define share types and terms
- Share: Issued shares with vesting
- Option: Stock options with exercise terms
- Safe: SAFE agreements
- ConvertibleNote: Convertible debt instruments
- EquityPlan: Stock option plans
- Document: File storage references
- Template: E-sign document templates
- TemplateField: Form fields for e-signing
- DataRoom: Secure document collections
- Audit: Activity log entries
- Update: Investor updates
- BankAccount: Company bank accounts
- Billing: Stripe integration entities
auth: Login, signup, password resetpasskey: WebAuthn registration/authenticationsecurity: Password managementaccessToken: API token management
company: Company CRUD operationsmember: Team member managementrbac: Role and permission managementbankAccounts: Bank account management
shareClass: Share class configurationequityPlan: Equity plan managementsecurities: Shares and options issuancesafe: SAFE agreement managementstakeholder: Stakeholder CRUD
document: File upload/managementtemplate: E-sign template managementtemplateField: E-sign field configurationdataRoom: Data room managementupdate: Investor update creation/sharing
audit: Audit log accessbilling: Stripe subscription managementbucket: File storage operationscommon: Shared utilities
- Uses NextAuth with custom adapters
- Supports email/password and passkey authentication
- Session-based authentication with JWT tokens
- Member-based access control (users can be members of multiple companies)
- Client requests presigned URL from bucket router
- Direct upload to S3-compatible storage
- Reference stored in database
- Access controlled through application logic
- Upload PDF document
- Create template with recipients
- Add form fields (signature, text, date, etc.)
- Send to recipients
- Track signing progress
- Generate completed document
Uses pg-boss for job queuing:
- Email sending (verification, invites, notifications)
- PDF generation for completed documents
- Async processing for heavy operations
Key environment variables:
DATABASE_URL: PostgreSQL connectionNEXTAUTH_URL/SECRET: Authentication configEMAIL_*: SMTP configurationUPLOAD_*: S3-compatible storage configSTRIPE_*: Payment processingNEXT_PUBLIC_*: Client-side variables
- Row-Level Security: Enforced through Prisma queries with company/member context
- API Protection: All tRPC procedures check authentication and authorization
- File Access: Presigned URLs with expiration for secure file access
- Audit Trail: Comprehensive logging of all significant actions
- Data Isolation: Multi-tenant architecture with strict data separation
- Define database schema in
prisma/schema.prisma - Create tRPC router in
src/trpc/routers/ - Add to appRouter in
src/trpc/api/root.ts - Build UI components in
src/components/ - Create pages in
src/app/
- Always check company context
- Validate stakeholder relationships
- Maintain audit trail for compliance
- Handle vesting calculations properly
- Create email template in
src/emails/ - Create job handler in
src/jobs/ - Register job in
src/jobs/register.ts - Queue job from tRPC procedure
- Use seeded data for development (see
prisma/seeds/) - Test multi-company scenarios
- Verify permission boundaries
- Check email delivery in Mailpit (local dev)
- Database: Proper indexing on foreign keys and frequently queried fields
- File Storage: Direct uploads to S3 bypass server
- Pagination: Built into data tables and lists
- Caching: React Query for client-side caching
- Background Jobs: Heavy operations processed asynchronously
This file (LLM.md) is symlinked as:
.AGENTS.mdCLAUDE.mdQWEN.mdGEMINI.md
All files reference the same knowledge base. Updates here propagate to all AI systems.
- ALWAYS update LLM.md with significant discoveries
- NEVER commit symlinked files (.AGENTS.md, CLAUDE.md, etc.) - they're in .gitignore
- NEVER create random summary files - update THIS file