Skip to main content

Set up Neon and PostGIS

Wits World uses PostgreSQL with PostGIS for event locations, proximity checks, and campus boundaries. Neon hosts the deployed database; local development can use Neon or a PostgreSQL server with PostGIS installed.

Complete the repository setup in Getting started before running the commands below from the repository root.

Required databases​

Use separate development and test databases, or separate Neon branches. The test target must not contain production or development data. A different password or a pooled connection to the same database does not provide isolation.

For Neon, copy the connection strings for each target and retain sslmode=require. The role applying migrations must be able to create the application schemas and enable PostGIS.

Configure the API​

If the API environment file does not exist, create it:

cp apps/api/.env.example apps/api/.env

Set these values in the ignored apps/api/.env file:

VariableTarget
DATABASE_URLDevelopment database. A pooled Neon endpoint is supported for ordinary queries.
LISTENER_DATABASE_URLDirect, non-pooled connection to the same development database, used for PostgreSQL notifications.
MIGRATION_DATABASE_URLOptional direct maintenance connection to the same endpoint/database as DATABASE_URL; ignored by test commands.
TEST_DATABASE_URLSeparate database used by test commands.

The CLI loads the API environment file automatically. Values already exported in the terminal take precedence. Test commands require both DATABASE_URL and TEST_DATABASE_URL so they can check that the configured targets differ.

Keep connection strings out of browser configuration and committed files. See Getting started for the remaining API and Web settings.

Initialise development data​

npm run prepare:api
npm run db:migrate --workspace @wits-world/api
npm run db:check --workspace @wits-world/api
npm run db:seed --workspace @wits-world/api

Migrations enable PostGIS and create the application schema. Run them before db:check on a new database: the readiness check expects PostGIS to be available. Applied migrations are tracked and skipped on later runs. The runner checks all applied filenames and checksums before applying pending SQL; missing or changed applied files stop the run.

Migration and release commands automatically derive a direct Neon endpoint from a -pooler runtime URL. They leave the API runtime connection unchanged. Migration lock waits stop after 30 seconds and statements after five minutes. See bounded migration connections and release waits for maintenance credentials, serialization, seed locking, and recovery.

Normal seeding loads reusable reference data and checks that the card catalogue is ready.

Prepare the test target​

npm run db:migrate:test --workspace @wits-world/api
npm run db:check:test --workspace @wits-world/api
npm run db:seed:test --workspace @wits-world/api

The :test commands use TEST_DATABASE_URL. Database integration tests also need a role that can create and drop temporary databases:

npm run test:database --workspace @wits-world/api

The suite creates isolated databases, applies migrations, and removes its temporary databases afterward. Pull-request CI supplies an ephemeral PostGIS service rather than using Neon. The bounded maintenance regression tests refuse remote databases; use disposable local PostGIS for the automated suite.

Coordinated production scheduling requires both PRODUCTION_GAMEPLAY_SCHEDULER_BACKEND=upstash and PRODUCTION_GAMEPLAY_WRITERS_COORDINATED=true, after all unaware writers have been retired. CI retains polling unless both settings allow activation and verifies the Azure setting after database release succeeds. Follow Gameplay workers for the rollout and deployed-mode checks.

Production changes follow the separate database release procedure.

AI declaration: Prepared and updated with assistance from Codex-CLI[GPT-5], Codex[GPT-5], Codex[GPT-5.6 Sol], Codex[gpt-5.6-sol], Codex-CLI[GPT-6], Codex-CLI[gpt-6-luna], and Codex[GPT-6].