seed every supabase preview branch.
Supabase preview branches ship with an empty database. Run satus once after the branch is created and every PR review gets a fully seeded environment. The 10,000-row safety guard is harmless here: preview branches start at zero.
# pull the postgres url from the supabase CLI$ export DATABASE_URL=$(supabase --experimental branches get $BRANCH --output json | jq -r .POSTGRES_URL)$ export OPENAI_API_KEY=$OPENAI_API_KEY# seed it. one transaction. all-or-nothing.$ satus generate --profile e-commerce --seed 42✓ 4,812 rows · $0.07 · 11.4s
Pin --seed so a re-run on the same branch produces identical data. Reviewers can deep-link to a specific row by ID and trust it stays put.
one job. one step. one secret per env.
The most common shape. Plan in PR jobs (no writes, free), generate on merge to main or against ephemeral DBs.
# .github/workflows/seed.yml$ name: seed$ on: { pull_request: {}, push: { branches: [main] } }$ jobs:$ seed:$ runs-on: ubuntu-latest$ steps:$ - uses: actions/checkout@v4$ - uses: actions/setup-node@v4$ with: { node-version: 20 }$ - run: npm i -g @passkeybridge/satus$ - run: satus plan --profile saas-subscriptions --json$ if: github.event_name == 'pull_request'$ - run: satus generate --profile saas-subscriptions$ if: github.ref == 'refs/heads/main'$ env:$ DATABASE_URL: ${{ secrets.DATABASE_URL }}$ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
satus plan --json is read-only and needs no DB credentials when given --schema ./schema.sql. Use it as a PR check to catch schema-breaking changes before merge.
fresh data between every test suite.
Cypress, Playwright, and Vitest E2E suites need a known-good database state. The pattern: truncate user tables, then satus generate --seed with a fixed seed. The fixed seed gives every test the same starting rows.
# scripts/reset-test-db.sh$ #!/usr/bin/env bash$ set -euo pipefail# 1 · truncate everything user-owned in a single tx$ psql "$DATABASE_URL" -c "TRUNCATE \$ orders, order_items, products, customers \$ RESTART IDENTITY CASCADE;"# 2 · re-seed with a fixed seed for deterministic IDs$ satus generate --profile e-commerce --seed 1 --force
--force is required here because the truncate may leave residual rows in tables satus doesn't own. Wire this into Cypress's before(...) hook or Playwright's globalSetup.
seed a fresh neon branch in one shell.
Neon's copy-on-write branches make per-developer or per-PR databases cheap. Combine that with satus and every engineer gets their own seeded database for the cost of the branch metadata.
# create a branch and capture its connection string$ BRANCH=$(neon branches create --name pr-$PR --project-id $NEON_PROJECT_ID --output json)$ export DATABASE_URL=$(echo "$BRANCH" | jq -r .connection_uris[0].connection_uri)# seed$ satus generate --profile saas-subscriptions
Tear the branch down on PR close. Neon charges per active branch—a stale fleet of seeded branches will surprise the bill.
Have a recipe you want documented? Email support@satus.sh. We add the most-requested integrations first.