API Development
Prerequisites
- Node.js ≤22.4.x (see
.nvmrcfor version) - Yarn 1.22.x (Classic)
- Docker & Docker Compose – for Postgres, Redis, and optional full-stack run
Quick Start
1. Install Dependencies
cd cred-api-commercial
nvm use
yarn install
2. Environment Setup
Recommended: Automated setup via Cursor AI
If you use Cursor IDE, ask the AI agent to set up your .env:
"Set up my .env for local development"
This runs the env-setup skill, which fetches all env vars from the Cloud Run dev service via gcloud and applies local overrides from .env.local-overrides (DB, Redis, NODE_ENV pointing to localhost). Requires gcloud auth login with your @credinvestments.com account.
Manual setup
Alternatively, create a .env file manually. Copy from .env.example and add the variables below. For secrets, see the 1Password Commercial API env item.
# Database (used when app connects to Docker Postgres)
DATABASE_URL=postgres://cred@db:5432/cred_commercial
PG_DATABASE_PORT=5432
# Redis (commercial_cache is the Docker Compose service name)
REDISCLOUD_URL=redis://commercial_cache:6379
API_REDIS_PORT=6379
# Application
NODE_ENV=local
PORT=8000
WEB_PORT=8000
WEB_DEBUG_PORT=9222
# GraphQL Router (if using with_federation profile)
GRAPHQL_ROUTER_PORT=4000
# Model API (points to dev – already set correctly in .env.example / 1Password)
CRED_MODEL_API_URL=https://model-api-dev.credplatform.com/graphql
# Auth (optional for local dev)
JWT_SECRET=your-local-dev-secret
OKTA_AUTH_CALLBACK_ENDPOINT=http://localhost:8000/okta/auth/callback
CRED_COMMERCIAL_WEB_LOGIN_PAGE=http://localhost:8002/signin
3. Start the API (Docker – recommended)
Start Postgres, Redis, and the Commercial API in containers:
docker compose up
Equivalent to yarn dev. The web container runs nodemon inside Docker, so the app restarts automatically when you edit src/ files.
With a clean rebuild:
docker compose up --build
# or
yarn dev:rebuild
The API runs at http://localhost:8000/graphql.
Verify it's running:
curl -s http://localhost:8000/graphql -H 'Content-Type: application/json' \
-d '{"query":"{ __typename }"}' | head -c 100
You should see {"data":{"__typename":"Query"}}.
.env changes require container recreation
If you change .env after containers are already running, use docker compose up -d (not docker compose restart) to pick up the new values.
4. Database Setup
To get the database working (fresh setup or reset), run:
When using full Docker – inside the web container:
docker compose run --rm web yarn reset
When running the app on the host – set DATABASE_URL=postgres://cred@localhost:5432/cred_commercial and run:
yarn reset
yarn reset does: build → drop cache → drop DB → migrate → seed.
For incremental migrations only (no wipe), use yarn prep-db instead.
5. Database Seeding
Seeds populate the local database with test data so the app is usable out of the box. They run automatically as part of yarn reset and yarn prep-db, or you can run them separately.
Running seeds:
# Full Docker (recommended)
docker compose run --rm web yarn seed
# App on host (DB + Redis in Docker)
DATABASE_URL=postgres://cred@localhost:5432/cred_commercial \
REDISCLOUD_URL=redis://localhost:6379 \
NODE_ENV=local \
yarn seed
NODE_ENV must be local
Several seeds only run when NODE_ENV is local or test. If you see "Skipping 004-user" in the output, your NODE_ENV is wrong. Set NODE_ENV=local in your .env or pass it inline.
What the seeds create:
| Seed | What it creates |
|---|---|
| 001-currencies | All currency codes (USD, EUR, etc.) |
| 002-languages | 35 languages |
| 003-feature | Feature definitions (credits, enrichment, waterfall, etc.) |
| 004-user | 3 test users, 2 companies, and initial credits |
| 005 / 006 | Waterfall enrichment configurations |
| 007-account | 10 test accounts (Acme Corp, Globex, etc.) |
| 008-contact | 12 test contacts linked to accounts |
| 009-opportunity | 8 test opportunities across pipeline stages |
| 010-collection | 10 custom lists (account, contact, opportunity) with items |
Test login credentials:
| Password | Role | Company | |
|---|---|---|---|
admin@credinvestments.com |
P@ssword01 |
Admin | CRED Investments |
test@credinvestments.com |
P@ssword01 |
User | Test Company |
test2@credinvestments.com |
P@ssword01 |
User | Test Company |
Running a single seed (on host):
DATABASE_URL=postgres://cred@localhost:5432/cred_commercial \
REDISCLOUD_URL=redis://localhost:6379 \
NODE_ENV=local \
node -e "require('./dist/data/seeds/007-account').seed().then(() => process.exit(0))"
Note
When running individual seeds on the host, you must yarn build first — seeds run from the compiled dist/ directory.
All seeds are idempotent — safe to run multiple times without duplicating data.
Run Modes
Full Docker (docker compose up)
- Postgres, Redis, and the web app run in Docker.
- The web container runs nodemon internally – edits to
src/trigger automatic restarts. - App listens on
http://localhost:8000. - Debug port:
9222(e.g.localhost:9222).
App on Host, DB + Redis in Docker
Useful for debugging or development without running the app in Docker:
-
Start only Postgres and Redis:
docker compose up -d db redis -
Update your
.envto point at localhost instead of Docker service names:DATABASE_URL=postgres://cred@localhost:5432/cred_commercial REDISCLOUD_URL=redis://localhost:6379 -
Build and run:
yarn build yarn migrate yarn seed yarn nodemon
The API will be at http://localhost:8000/graphql.
GraphQL Router (Federation)
Federation runs the full CRED platform locally: a local commercial-api behind an Apollo Router that composes a supergraph from 4 subgraphs.
Frontend (localhost:8002)
│
▼
Apollo Router (localhost:4000)
├── commercial-api (localhost:8000) ← LOCAL (Docker)
├── model-api-dev.credplatform.com ← REMOTE
├── filter-api-dev.credplatform.com ← REMOTE
└── agent-ai-dev.credplatform.com ← REMOTE
Automated setup
If you use Cursor IDE, ask: "Set up local federation" — this runs the local-federation-setup skill which handles everything below automatically.
1. Prepare .env
Use the dev target of env-setup (not local), then comment out DATABASE_URL so Docker Compose uses its internal db hostname. Verify these are present:
# DATABASE_URL=... ← must be commented out
CRED_MODEL_API_URL=https://model-api-dev.credplatform.com/graphql
CRED_FILTER_API_URL=https://filter-api-dev.credplatform.com/graphql
CRED_AGENT_AI_URL=https://agent-ai-dev.credplatform.com/graphql
2. Start the backend
docker compose --profile with_federation up
First run takes several minutes (Docker build + TypeScript compilation). Wait for these log lines:
- Web container:
Server ready ... graphqlUrl: http://localhost:8000/graphql - Router:
GraphQL endpoint exposed at http://0.0.0.0:4000/graphql
3. Run migrations and seed (first run only)
docker compose exec web yarn migrate
docker compose exec web yarn seed
4. Start the frontend
In the cred-web-commercial repo:
bun install
bun run dev:local
This uses .env.local.local which points the frontend at the local gateway (localhost:4000). Frontend starts on http://localhost:8002.
5. Switching between local and remote dev
# Switch to remote dev
rm -rf apps/web-commercial/.next
bun run dev
# Switch back to local
rm -rf apps/web-commercial/.next
bun run dev:local
The cache clear is required — Next.js caches env vars in .next/.
6. Regenerating GraphQL types after schema changes
When you add or change fields in the backend:
cd cred-web-commercial
bash scripts/gql-local.sh --restart # after backend schema change (~40s)
bash scripts/gql-local.sh # just regenerate types, no restart (~10s)
Use --restart when you've changed the backend GraphQL schema. Skip it when you only changed frontend .gql query files.
| Service | URL |
|---|---|
| Frontend | http://localhost:8002 |
| Federation Gateway | http://localhost:4000/graphql |
| Commercial API | http://localhost:8000/graphql |
Trino (BigQuery / analytics)
To include Trino:
docker compose --profile with_trino up
Model API
The Commercial API uses the CRED Model API for AI features. When running Commercial locally, it connects to the dev Model API. The .env file (from .env.example or 1Password) already includes the correct CRED_MODEL_API_URL. No extra setup is required.
Cursor AI Skills
If you use Cursor IDE, the repo includes AI-powered skills that automate common workflows. Mention the skill name in chat and the agent will follow the instructions automatically.
| Skill | What to ask | What it does |
|---|---|---|
| env-setup | "Set up my .env for local" | Fetches env vars from Cloud Run dev, applies local overrides, writes .env |
| local-federation-setup | "Set up local federation" | Starts backend (Docker) + frontend (host) + Apollo Router with full federation |
| pg-database-access | "Connect to the dev database" | Opens a read-only connection to Local/Dev/Staging/Prod via Cloud SQL Proxy |
| db-migration | "Create a migration to add column X" | Generates a Knex migration file following repo conventions |
| testing | "Write tests for my use case" | Scaffolds unit/integration tests for use cases, repos, resolvers |
Skills live in .cursor/skills/ in the repo. Run ls .cursor/skills/ to see all available skills.
Useful Commands
| Command | Description |
|---|---|
docker compose up |
Start full stack (Postgres, Redis, API with hot reload) |
yarn dev |
Same as docker compose up |
yarn dev:rebuild |
Rebuild containers and start |
yarn nodemon |
Run app with hot reload (when app runs on host, not in Docker) |
yarn reset |
Reset DB: build, drop cache, drop db, migrate, seed |
yarn prep-db |
Build, migrate, seed (no drop – incremental) |
yarn migrate |
Run migrations |
yarn seed |
Run seeds |
yarn start:worker |
Background workers (Merge/Polytomic webhooks, etc.) |
yarn start:nylas-worker |
Nylas webhook workers |
Endpoints
| Service | URL |
|---|---|
| GraphQL API | http://localhost:8000/graphql |
| GraphQL Playground | http://localhost:8000/graphql |
| GraphQL Router | http://localhost:4000 (with with_federation) |
| Debug port | localhost:9222 |
| Prometheus metrics | http://localhost:8001/prometheus/metrics |
Troubleshooting
Database connection refused
- Ensure Postgres and Redis are running:
docker compose ps - With app on host:
DATABASE_URL=postgres://cred@localhost:5432/cred_commercial,REDISCLOUD_URL=redis://localhost:6379
Model API errors
- Ensure
CRED_MODEL_API_URLin.envpoints tohttps://model-api-dev.credplatform.com/graphql
Port conflicts
- Override ports in
.env:WEB_PORT,PG_DATABASE_PORT,API_REDIS_PORT
tsc -w crashes with exit code 134
- The TypeScript watcher inside the Docker
webcontainer can run out of memory and exit with code 134. This is harmless — the app server (nodemon) runs independently and will still start. You can safely ignore this.
Clean reset
yarn clean
docker compose down -v
docker compose up --build
# Then: docker compose run --rm web yarn reset