Savvi Studio

Codegen Usage Guide

Purpose: How to run codegen and integrate it into your workflow
Last Updated: 2024-11-28

Quick Start

Running Codegen

pnpm db:codegen

Output

Generated files appear in src/__generated__/:

src/__generated__/
├── index.ts
├── audit/
├── auth/
├── graph/
└── studio/

Development Workflow

Step 1: Add SQL Function

Create or modify SQL file in db/ directory

Step 2: Load Schema Changes

# Restart database to load new SQL
docker compose restart postgres

# Or if using reset script
pnpm db:reset

Step 3: Run Codegen

pnpm db:codegen

Step 4: Verify Generated Code

Check that the wrapper was generated in src/__generated__/

Step 5: Use in Application

Import and use the generated function:

import { withClient } from '@/lib/db';
import { calculateTotal } from '@db/my_schema';

const total = await withClient(async (client) => {
  return await calculateTotal(client, {
    p_user_id: userId,
    p_start_date: startDate,
    p_end_date: endDate
  });
});

Step 6: Test

Write tests using the generated functions

When to Run Codegen

Required

Run codegen when you:

  • ✅ Add new SQL functions
  • ✅ Modify function signatures (parameters or return types)
  • ✅ Create new types (enums, composites, domains)
  • ✅ Change type definitions
  • ✅ Initial project setup

Not Required

Don't need to run when you:

  • ❌ Modify function implementation (body only)
  • ❌ Add/modify comments
  • ❌ Change non-type schema elements
  • ❌ Modify indexes or constraints

Integration with CI/CD

Verify Generated Code is Up-to-Date

# In CI pipeline
pnpm db:codegen --check

# Fails if generated code doesn't match schema

Pre-commit Hook

Check if SQL files changed and regenerate if needed

GitHub Actions Example

name: Codegen Check
on: [pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
      - run: pnpm install
      - run: docker compose up -d postgres
      - run: pnpm db:reset
      - run: pnpm db:codegen --check

Configuration

Database Connection

Codegen uses environment variables:

# .env
DATABASE_URL=postgresql://savvi:password@localhost:54320/savvi_studio

tsconfig.json Path Alias

{
  "compilerOptions": {
    "paths": {
      "@db": ["./src/__generated__/index.ts"],
      "@db/*": ["./src/__generated__/*"]
    }
  }
}

Schema Selection

Command line:

pnpm db:codegen --schema graph --schema auth

Config file (if supported):

// codegen.config.ts
export default {
  schemas: ['graph', 'auth', 'studio'],
  output: 'src/__generated__'
};

Best Practices

1. Run Codegen Early

Run codegen as soon as you change SQL:

# Good - run codegen first
pnpm db:codegen
pnpm dev  # ✅ Works!

# Bad - wait until compile errors
pnpm dev  # ❌ Errors!

2. Commit Generated Code

Generated code should be in version control:

git add src/__generated__/
git commit -m "feat: add calculateTotal function"

Benefits:

  • Reviewable in PRs
  • No need to run codegen to build
  • Visible type changes

3. Function Naming Conventions

In SQL (snake_case):

CREATE FUNCTION my_schema.create_user_account(...)

Generated TypeScript (camelCase):

export async function createUserAccount(...)

Naming tips:

  • Use descriptive names: create_user_account not create_user
  • Prefix parameters: p_user_id not user_id
  • Avoid reserved words: p_type not type

4. Parameter Naming

Good:

CREATE FUNCTION process_order(
    p_order_id bigint,
    p_user_id bigint,
    p_options jsonb DEFAULT '{}'
)

Avoid:

CREATE FUNCTION process_order(
    id bigint,           -- Too generic
    usr bigint,          -- Unclear abbreviation
    opt jsonb            -- Missing default
)

5. Type Annotations

Add SQL comments for documentation:

CREATE FUNCTION calculate_total(
    p_user_id bigint,
    p_start_date timestamp
) RETURNS numeric AS $$
    -- Calculates total for user within date range
    -- Returns 0 if no transactions found
$$;

Generated TypeScript includes comments as JSDoc.

Performance Tips

Incremental Generation

Generate only changed schemas:

pnpm db:codegen --schema graph

Parallel Generation

Multiple schemas can generate in parallel:

pnpm db:codegen --parallel

Cache Introspection

Cache pg_catalog queries between runs:

pnpm db:codegen --cache

Detailed Examples

For detailed workflow examples and code, see:


Key Takeaway: Run codegen early and often. Commit generated code. Let TypeScript catch breaking changes.