Open-source cap table & equity management platform — a free Carta alternative for startups.
Manage stakeholders, share classes, SAFE notes, equity grants, 409A valuations, documents, data rooms, board management, and financial reporting. Built with Test-Driven Development (TDD) and fully aligned with the Open Cap Table Alliance (OCTA) schema.
🌐 opencapstack.com | 📖 Documentation | 💬 Community
OpenCap Stack uses a modern, cloud-native architecture:
| Component | Technology | Description |
|---|---|---|
| Primary Database | ZeroDB (AINative) | NoSQL tables, vector search, event streaming |
| Backend | Node.js + Express | REST API server |
| File Storage | MinIO / ZeroDB | S3-compatible file storage |
| API Gateway | Kong | Rate limiting, authentication |
| Containerization | Docker | Deployment and development |
ZeroDB provides:
- NoSQL table storage for all application data
- Vector search for semantic document search
- Memory management for AI agent context
- Event streaming for real-time updates
- File metadata storage
This project follows the Semantic Seed Venture Studio Coding Standards (SSCS) which emphasizes:
- Structured Backlog Management with proper story IDs (OCAE-XXX, OCDI-XXX format)
- Test-Driven Development (TDD) with Red-Green-Refactor cycle
- Consistent Branch Naming (
feature/OCAE-XXX,bug/OCAE-XXX,chore/OCAE-XXX) - Daily Commits with proper prefixes (including "WIP:" for work in progress)
- Pull Request Process that maintains traceability to backlog items
For detailed workflow guidelines, see SSCS_Workflow_Guide.md.
Follow these steps to set up the project on your local machine:
- Node.js (v14 or higher)
- Docker and Docker Compose (for containerized development)
- Git
- ZeroDB Account (sign up at https://api.ainative.studio/)
git clone https://github.com/Open-Cap-Stack/opencap.git
cd opencapnpm installCreate a .env file in the root directory based on the .env.example template:
cp .env.example .envOpenCap Stack uses ZeroDB (via AINative Studio) as its primary database for all operations including:
- NoSQL table storage for all application data
- Vector search for semantic document search
- Memory management for agent context
- Event streaming for real-time updates
- File storage for document uploads
ZeroDB is required to run OpenCap Stack.
# ZeroDB API Configuration
ZERODB_API_KEY=your_zerodb_api_key_here
ZERODB_BASE_URL=https://api.ainative.studio/api/v1
ZERODB_PROJECT_ID=your_project_id_hereSetting up ZeroDB:
-
Create an AINative Studio Account:
- Visit https://api.ainative.studio/
- Sign up for an account or log in
-
Obtain API Credentials:
- Navigate to your account settings
- Generate an API token
- Copy the token to
ZERODB_API_KEYin your.envfile
-
Create a ZeroDB Project:
- Option A: Create via API (recommended for automation):
curl -X POST https://api.ainative.studio/api/v1/projects/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "OpenCap", "description": "OpenCap Financial Management System with Lakehouse Analytics"}'
- Option B: Create via AINative Studio dashboard
- Copy the project ID from the response to
ZERODB_PROJECT_ID
- Option A: Create via API (recommended for automation):
-
Verify ZeroDB Setup:
curl -X GET https://api.ainative.studio/api/v1/projects/YOUR_PROJECT_ID/database/status \ -H "Authorization: Bearer YOUR_API_KEY"You should see
status: ACTIVEanddatabase_enabled: true
For complete migration instructions from MongoDB, see the ZeroDB Migration Guide.
For detailed API documentation, see the ZeroDB API Reference.
If you encounter any issues, check the Troubleshooting Guide.
MongoDB is completely optional and only needed if you want to use the continuous sync feature (GitHub Issue #14).
To run OpenCap Stack without MongoDB:
- Set
SYNC_ENABLED=falsein your.envfile (or omit it entirely) - Comment out or remove
MONGODB_URI - Start the application normally - it will use ZeroDB as the sole database
To enable MongoDB for continuous sync:
If you have an existing MongoDB database and want real-time synchronization to ZeroDB, you can enable the continuous sync feature:
# MongoDB connection (only needed if SYNC_ENABLED=true)
MONGODB_URI=mongodb://localhost:27017/opencap
# Enable real-time sync
SYNC_ENABLED=true
# Batch processing configuration
SYNC_BATCH_SIZE=50
SYNC_BATCH_TIMEOUT_MS=5000
# Retry configuration
SYNC_RETRY_ATTEMPTS=3
SYNC_RETRY_DELAY_MS=1000
SYNC_MAX_RETRY_DELAY_MS=30000
# Collections to sync (comma-separated, leave empty for all)
SYNC_COLLECTIONS=users,companies,stakeholders,transactions,documents
# Operation types to sync
SYNC_OPERATION_TYPES=insert,update,delete,replaceContinuous Sync Features:
- Real-time change detection using MongoDB Change Streams
- Automatic resume on connection loss with resume tokens
- Batch processing for high performance
- Exponential backoff retry with dead letter queue
- Comprehensive metrics and health monitoring
- Graceful shutdown with state persistence
For detailed documentation, see MongoDB to ZeroDB Sync Guide
PORT=3001
NODE_ENV=developmentJWT_SECRET=your_jwt_secret_change_this_in_production
JWT_EXPIRATION=24hImportant: Change the default JWT_SECRET to a strong, random value in production.
npm startThis command starts the server on http://localhost:5000.
For automatic restarts on code changes, use:
npm run devFor a containerized development environment:
# Build and start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop all services
docker-compose downdocker-compose -f docker-compose.test.yml up --buildThis will run all tests in a containerized environment, ensuring consistent test results across different development machines.
The project uses Jest for testing. To run the tests, use the following command:
npm testThis command runs all the test cases defined in the tests directory.
Tests use ZeroDB mocks provided by tests/setup.js and tests/setup/db.js. No external database connection (MongoDB, ZeroDB, etc.) is required to run the unit test suite.
We measure test coverage locally for development purposes only:
npm run test:coverageImportant Note: We do NOT integrate with Codecov or any other third-party coverage service. All coverage reporting should be performed locally and documented in pull requests when relevant.
Our continuous integration and deployment pipeline focuses on:
- Docker Hub: For container image storage and versioning
- Digital Ocean: For deployment and hosting
The following secrets are required for our CI/CD pipeline:
DOCKERHUB_USERNAMEDOCKERHUB_TOKENDIGITALOCEAN_ACCESS_TOKEN
We follow the deployment plan outlined in OpenCap_TestCoverage_DigitalOceanDeployment.md.
To maintain codebase integrity and avoid conflicts:
-
Verify Existing Docker Resources:
docker ps -a # Check existing containers docker volume ls # Check existing volumes
-
Check Existing Files and Directories:
ls -la [directory] # List directory contents find . -name "pattern" # Find files matching pattern
-
Review Configurations: Always check current configuration before making changes
-
Database Schema Changes: Analyze existing schemas before modifications
These practices prevent duplication, conflicts, and ensure proper integration with the existing codebase.
Here are the primary API endpoints for the project:
- POST /api/users: Create a new user
- GET /api/users: Get all users
- GET /api/users/:id: Get a user by ID
- PUT /api/users/:id: Update a user by ID
- DELETE /api/users/:id: Delete a user by ID
- POST /api/stakeholders: Create a new stakeholder
- GET /api/stakeholders: Get all stakeholders
- GET /api/stakeholders/:id: Get a stakeholder by ID
- PUT /api/stakeholders/:id: Update a stakeholder by ID
- DELETE /api/stakeholders/:id: Delete a stakeholder by ID
- POST /api/communications: Create a new communication
- GET /api/communications: Get all communications
- GET /api/communications/:id: Get a communication by ID
- PUT /api/communications/:id: Update a communication
- GET /api/communications/threads/:threadId: Get communications by thread ID
- POST /api/communications/threads: Create a new thread
- POST /api/spv: Create a new SPV
- GET /api/spv: Get all SPVs
- GET /api/spv/:id: Get an SPV by ID
- PUT /api/spv/:id: Update an SPV
- GET /api/spv/status/:statusId: Get SPVs by status
- POST /api/spv-assets: Create a new SPV asset
- GET /api/spv-assets: Get all SPV assets
- GET /api/spv-assets/:id: Get an SPV asset by ID
- PUT /api/spv-assets/:id: Update an SPV asset
- POST /api/spv-assets/:id/valuation: Add a valuation to an SPV asset
- POST /api/compliance-checks: Create a new compliance check
- GET /api/compliance-checks: Get all compliance checks
- GET /api/compliance-checks/:id: Get a compliance check by ID
- PUT /api/compliance-checks/:id: Update a compliance check
- POST /api/taxCalculations: Create a new tax calculation
- GET /api/taxCalculations: Get all tax calculations
- GET /api/taxCalculations/:id: Get a tax calculation by ID
- PUT /api/taxCalculations/:id: Update a tax calculation
- POST /api/share-classes: Create a new share class
- GET /api/share-classes: Get all share classes
- GET /api/share-classes/:id: Get a share class by ID
- PUT /api/share-classes/:id: Update a share class by ID
- DELETE /api/share-classes/:id: Delete a share class by ID
- POST /api/documents: Create a new document
- GET /api/documents: Get all documents
- GET /api/documents/:id: Get a document by ID
- PUT /api/documents/:id: Update a document by ID
- DELETE /api/documents/:id: Delete a document by ID
- POST /api/activities: Create a new activity
- GET /api/activities: Get all activities
- GET /api/activities/:id: Get an activity by ID
- PUT /api/activities/:id: Update an activity by ID
- DELETE /api/activities/:id: Delete an activity by ID
- POST /api/notifications: Create a new notification
- GET /api/notifications: Get all notifications
- GET /api/notifications/:id: Get a notification by ID
- PUT /api/notifications/:id: Update a notification by ID
- DELETE /api/notifications/:id: Delete a notification by ID
- POST /api/equity-simulations: Create a new equity simulation
- GET /api/equity-simulations: Get all equity simulations
- GET /api/equity-simulations/:id: Get an equity simulation by ID
- PUT /api/equity-simulations/:id: Update an equity simulation by ID
- DELETE /api/equity-simulations/:id: Delete an equity simulation by ID
- POST /api/tax-calculations: Create a new tax calculation
- GET /api/tax-calculations: Get all tax calculations
- GET /api/tax-calculations/:id: Get a tax calculation by ID
- PUT /api/tax-calculations/:id: Update a tax calculation by ID
- DELETE /api/tax-calculations/:id: Delete a tax calculation by ID
- POST /api/financial-reports: Create a new financial report
- GET /api/financial-reports: Get all financial reports
- GET /api/financial-reports/:id: Get a financial report by ID
- PUT /api/financial-reports/:id: Update a financial report by ID
- DELETE /api/financial-reports/:id: Delete a financial report by ID
The project structure is organized as follows:
opencap/
├── controllers/ # Controllers for handling API requests
├── models/ # Data models (Mongoose schemas, compatible with ZeroDB)
├── routes/ # API routes
│ └── v1/ # Versioned API routes
├── services/ # Business logic and external service integrations
│ ├── zerodbService.js # ZeroDB API client
│ ├── databaseAdapter.js # Database abstraction layer
│ └── ... # Other services
├── middleware/ # Express middleware (auth, validation, etc.)
├── tests/ # Test cases
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ ├── e2e/ # End-to-end tests
│ └── security/ # Security tests
├── docs/ # Project documentation
│ ├── api/ # API documentation
│ ├── security/ # Security documentation
│ └── reports/ # Generated reports
├── scripts/ # Utility scripts
├── deployment/ # Deployment configurations
│ ├── kubernetes/ # K8s manifests
│ └── terraform/ # Infrastructure as code
├── config/ # Configuration files
├── .env.example # Environment template
├── docker-compose.yml # Docker compose for development
├── package.json # Project metadata and dependencies
└── README.md # This fileContributions are welcome! This project follows the Semantic Seed Venture Studio Coding Standards (SSCS) with a Test-Driven Development (TDD) approach. All contributions should adhere to these standards for consistent workflow and code quality.
This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please read the CODE_OF_CONDUCT.md for details on our code of conduct.
-
Fork the repository:
git fork https://github.com/Open-Cap-Stack/opencap.git
-
Create a new branch following SSCS naming conventions:
git checkout -b feature/OCAE-XXX # For new features git checkout -b bug/OCAE-XXX # For bug fixes git checkout -b chore/OCAE-XXX # For maintenance tasks
-
Write tests first (Red Tests):
- Write tests that demonstrate the functionality is NOT already present.
- Make a WIP commit:
git add . git commit -m "WIP: OCAE-XXX: Red Tests for feature description"
-
Implement code to pass the tests (Green Tests):
- Write the minimum amount of code required to pass the tests.
- Make a WIP commit when tests pass:
git add . git commit -m "WIP: OCAE-XXX: Green Tests for feature description"
-
Refactor your code:
- Refactor to improve code quality without changing functionality.
- Re-run the tests and commit with a final message:
git add . git commit -m "OCAE-XXX: Implement feature description"
-
Push your branch and create a pull request:
git push origin feature/OCAE-XXX
- Create a PR on GitHub with the story ID in the title.
- Include story details in the description.
- Mark the story as "Finished" in Shortcut.
-
Daily Commits Required:
- Even for incomplete work, commit daily with "WIP:" prefix.
- This ensures visibility and allows for collaboration.
For more detailed guidelines, refer to our SSCS_Workflow_Guide.md.
Follow these steps to submit your code changes:
-
Create a new branch:
git checkout -b feature/{story-id} # For features git checkout -b bug/{story-id} # For bugs git checkout -b chore/{story-id} # For chores -
Make your changes:
- Ensure your code follows the coding standards (see below).
-
Write failing tests:
- Write tests that demonstrate the functionality is NOT already present.
- Make a WIP commit:
git add . git commit -m "WIP: Red Tests."
-
Implement code to pass the tests:
- Make WIP commits as you go, and commit code when your tests are green:
git add . git commit -m "WIP: Green Tests."
-
Refactor your code:
- Refactor to improve code quality. Re-run the tests and commit:
git add . git commit -m "Refactor complete."
-
Submit a pull request:
git push origin feature/{story-id} # Push your branch- Go to the repository on GitHub and create a pull request from your branch to the main branch.
-
Review process:
- Review outstanding pull requests, comment on, approve and merge open pull requests, or request changes on any PRs that need improvement.
Please follow these coding standards to maintain code quality and consistency:
-
Indentation: Use 4 spaces for indentation.
-
Naming Conventions:
- Variables and functions: camelCase
- Classes and components: PascalCase
- Constants: UPPERCASE_SNAKE_CASE
-
Comments:
- Use JSDoc style comments for functions and classes.
Provide meaningful comments for complex code segments and functions.
-
Document any public APIs and classes with clear explanations of their purpose and usage.
-
Remove or update outdated comments as code changes.
-
Code Structure:
- Organize code into modules and components.
- Keep functions small and focused on a single task.
-
Lint: Ensure your code passes ESLint checks:
npm run lint
-
Testing:
-
Write unit tests using BDD-style frameworks like Mocha or Jasmine.
-
Follow the Arrange, Act, and Assert (AAA) pattern:
it('should correctly add two positive numbers', () => { // Arrange const num1 = 5; const num2 = 7; // Act const result = add(num1, num2); // Assert expect(result).to.equal(12); });
-
Write integration tests to validate interactions between different parts of the application.
-
Write functional tests to validate the application's functionality.
-
This project is licensed under the MIT License. See the LICENSE file for details.