diff --git a/.env.example b/.env.example index bda1d49..bea32be 100644 --- a/.env.example +++ b/.env.example @@ -16,6 +16,10 @@ POSTGRES_USER= POSTGRES_HOST= POSTGRES_PASSWORD= POSTGRES_DATABASE= +# Used by prisma/schema.prisma. Full Prisma connection URL with pool params appended. +# Keep connection_limit small (~5) for Vercel serverless — see schema.prisma for why. +# Paste the literal URL (copy POSTGRES_PRISMA_URL's value and append the pool params); do not use $-interpolation. +POSTGRES_PRISMA_URL_WITH_POOL="postgres://USER:PASS@HOST/DB?pgbouncer=true&connect_timeout=15&connection_limit=5&pool_timeout=20" # --- Vercel hosts and credentials diff --git a/AGENTS.md b/AGENTS.md index 1a93cd4..b1ed12f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -18,6 +18,7 @@ yarn prettier:fix # Prettier auto-format ``` After changing `prisma/schema.prisma`: + ```bash npx prisma generate # Regenerate Prisma client (also runs on postinstall) npx prisma db push # Push schema changes to database @@ -44,11 +45,12 @@ No test suite is configured. ### Database (Prisma + PostgreSQL) Three models in `prisma/schema.prisma`: + - `CustomFieldAccess` — per-portal field-level VIEW/EDIT permissions - `ClientProfileUpdates` — audit log of profile changes (stores full custom fields + changed fields as JSONB) - `Setting` — per-portal JSON configuration -Uses `relationMode = "prisma"` for serverless compatibility. Connection string uses `POSTGRES_PRISMA_URL_HIGHER_CONNECTION_LIMIT`. +Uses `relationMode = "prisma"` for serverless compatibility. Connection string uses `POSTGRES_PRISMA_URL_WITH_POOL`. ### Mutable/Immutable State Pattern @@ -66,6 +68,7 @@ Settings and custom field access are stored as two copies in context: a read-onl ## Environment Setup Copy `.env.example` to `.env.local`. Required variables: + - `COPILOT_API_KEY` — from the Assembly/Copilot dashboard - `COPILOT_ENV` — `local` for test tokens, `production` for real tokens - `POSTGRES_PRISMA_URL` and related DB vars — PostgreSQL connection strings diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f0e3463..c7cf623 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -7,9 +7,13 @@ generator client { datasource db { provider = "postgresql" - // Vercel won't let us change the POSTGRES_* config so update it with a connection_limit key using a custom env var like - // POSTGRES_PRISMA_URL_HIGHER_CONNECTION_LIMIT="$POSTGRES_PRISMA_URL&connection_limit=20" - url = env("POSTGRES_PRISMA_URL_HIGHER_CONNECTION_LIMIT") + // Vercel won't let us edit the integration-managed POSTGRES_* vars directly, so we set a separate var that holds the + // full Prisma connection URL with pool params appended. Keep connection_limit small for Vercel serverless — each + // lambda gets its own client-side pool, and large values multiplied by concurrent lambdas saturate pgBouncer + // (see https://pris.ly/d/connection-pool). Example value (paste the literal URL, do not use $-interpolation): + // POSTGRES_PRISMA_URL_WITH_POOL="postgres://USER:PASS@HOST/DB?pgbouncer=true&connect_timeout=15&connection_limit=5&pool_timeout=20" + // Heads up: if the Vercel/Neon integration rotates POSTGRES_PRISMA_URL's credentials, update this var to match. + url = env("POSTGRES_PRISMA_URL_WITH_POOL") directUrl = env("POSTGRES_URL_NON_POOLING") // Emulates relationships in Prisma client itself. Better for serverless databases like neon or planetscale relationMode = "prisma"