Skip to main content

PostgreSQL, Prisma & Local Auth

Local development only. The default local stack now runs a Docker-backed PostgreSQL database and a setup-seeded username/password login.


Services Used​

ServicePurpose
PostgreSQLStores workflows, projects, integrations, environments, and secrets
PrismaProvides the API schema, client, and local database bootstrap
Local authIssues JWT bearer tokens for the setup-configured username/password

Local Defaults​

./start-local.sh now starts the local Postgres container automatically from docker-compose.yml. By default it uses:

postgresql://postgres:postgres@127.0.0.1:5431/playrunner?schema=public

These values come from the repo-root .env.local file, which is created from .env.local.example on first run if it does not already exist.

If you change POSTGRES_PORT in the repo-root .env.local, both the Docker bind and the setup form's default DATABASE_URL move with it automatically.

On the normal startup path it also runs:

cd apps/api
npm run prisma:generate
npx prisma db push

How the local database config flows​

  1. The repo-root .env.local defines the local web port, setup installer port, and Docker-backed Postgres connection defaults.
  2. When setup is active, ./start-local.sh starts Postgres with those values and passes the derived DATABASE_URL into the setup app.
  3. The setup installer writes the chosen DATABASE_URL into apps/api/.env and stores the local admin username/password settings in PostgreSQL.
  4. ./start-local.sh later reuses that config, and if you are still using the standard Docker-backed Postgres settings it keeps apps/api/.env aligned with the repo-root .env.local before running Prisma bootstrap.

Stored Auth Config​

The setup wizard stores the local admin username, password hash, and JWT signing secret in PostgreSQL.

The web login page calls POST /api/auth/login, the API verifies the configured credentials, and successful logins receive a local JWT.


Prisma Models​

The local schema currently includes:

  • Project
  • Workflow
  • Connection
  • Environment
  • Secret

The schema lives in apps/api/prisma/schema.prisma, and the shared Prisma client is exported from apps/api/src/lib/prisma.ts.


Workflow descriptions​

Workflow.description is nullable text. The Project Dashboard's Edit workflow dialog saves it alongside the workflow name, and workflow store reads return it as description.

POST /api/store/workflows accepts an optional description. PUT /api/store/workflows/:id changes it only when the field is supplied; omitting it preserves the current description, including during editor graph saves. The dashboard sends null when a user clears the description, restoring the default card text.

For an existing local checkout, restart with ./start-local.sh after updating the code so Prisma generates the client and applies the schema before the API starts. The corresponding migration is apps/api/prisma/migrations/20260930000000_workflow_description/migration.sql.


Web Data Access​

All app-side persistence still flows through apps/frontend/src/lib/db.ts, but that module now talks to Prisma-backed API routes under /api/store/*.

Key routes include:

GET/POST/PUT/DELETE /api/store/projects
GET/POST/PUT/DELETE /api/store/workflows
GET/PUT/DELETE /api/store/integrations/:provider
GET/PUT/DELETE /api/store/cloud-credentials/:provider
GET/PUT/DELETE /api/store/environments/:id
PUT /api/store/secrets/:secretKey

Integration and cloud credentials share the Connection model and are distinguished by kind. Public store reads return non-secret config and a credentialStatus; package API routes and workflow execution resolve decrypted secrets on the server. OAuth refresh also runs on the server and writes updated tokens back as encrypted secrets.