Deployment
Constellation is deployed on Vercel as a multi-zone topology:
| Zone | Host | Vercel project |
|---|---|---|
| Directory (root) | constellation.planetb2b.com | constellation-directory |
| Project Tracker | /projects/* (rewritten) | constellation-platform |
| Catalog | /catalog/* (rewritten) | constellation-catalog |
| Docs | docs.planetb2b.com | constellation-docs |
Directory is the root zone and rewrites requests for /projects/* and /catalog/* to the other Vercel projects.
NEXT_PUBLIC_BASE_PATH
Sub-zone apps read this env var at build time:
| Environment | Value | Behaviour |
|---|---|---|
| Production | /projects or /catalog | Multi-zone: served under prefix, rewrites from Directory |
| Preview | unset | Standalone: served at / for preview deploys |
| Local dev | unset | Standalone: turbo dev on app-local port |
fetch() and basePath
Next.js auto-prepends basePath to <Link> and router.push, but not to fetch(). Use the apiUrl() helper from each app's src/lib/api-url.ts:
import { apiUrl } from '@/lib/api-url';
const res = await fetch(apiUrl('/api/people')); // '/projects/api/people' in prod
Migration gate on release PRs
Every PR targeting main (release branches and hotfixes) runs the Verify Release Migrations CI job. It fails the merge if either staging (DEV_DATABASE_URL) or production (PROD_DATABASE_URL) is missing a migration that's on the branch. The job is read-only — it never applies migrations. Apply outstanding migrations to both databases via the Supabase dashboard SQL editor or the Supabase MCP (apply_migration / execute_sql) before opening the release PR.
See scripts/check-migrations.ts (invoked with --strict from the gate) for the implementation.
Environment variables per Vercel project
| Vercel project | Var | Value | Environments |
|---|---|---|---|
constellation-platform | NEXT_PUBLIC_BASE_PATH | /projects | Required on production. Standalone preview/dev unset (serves at /) |
constellation-catalog | NEXT_PUBLIC_BASE_PATH | /catalog | Required on production. Standalone preview/dev unset |
constellation-directory | PROJECTS_ZONE_URL | https://constellation-platform.vercel.app | Required on production. Optional elsewhere (falls back to localhost defaults) |
constellation-directory | CATALOG_ZONE_URL | https://constellation-catalog.vercel.app | Required on production. Optional elsewhere (falls back to localhost defaults) |
The resolveBasePath() helper in scripts/resolve-base-path.ts fails fast if NEXT_PUBLIC_BASE_PATH is missing on Vercel production — without it the sub-zone app deploys at / and breaks multi-zone routing.
Vercel project wiring
The four Vercel projects share a build root (the monorepo) but each has its own Root Directory set to apps/<name> so Vercel runs each build from inside that workspace. installCommand and buildCommand are left blank on three of them (Vercel auto-detects); the docs project overrides them to use Turborepo, see apps/docs/vercel.json. All projects use the framework default output directory (.next for the three Next apps, build for Docusaurus) — apps/docs/vercel.json declares outputDirectory: "build" explicitly, but it matches the Docusaurus default.