Skip to content

API Development

Prerequisites

  • Node.js ≤22.4.x (see .nvmrc for 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

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:

Email 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:

  1. Start only Postgres and Redis:

    docker compose up -d db redis
    
  2. Update your .env to point at localhost instead of Docker service names:

    DATABASE_URL=postgres://cred@localhost:5432/cred_commercial
    REDISCLOUD_URL=redis://localhost:6379
    
  3. 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_URL in .env points to https://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 web container 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