fix: accept postgres:// in PrismaClientConfigSchema + Neon-aware health probe#1406
fix: accept postgres:// in PrismaClientConfigSchema + Neon-aware health probe#1406jaypatrick merged 2 commits intomainfrom
Conversation
… health database probe Co-authored-by: jaypatrick <1800595+jaypatrick@users.noreply.github.com> Agent-Logs-Url: https://github.com/jaypatrick/adblock-compiler/sessions/8cd0547b-71ff-4569-92ce-90e2a3b0fed3
There was a problem hiding this comment.
Pull request overview
This PR fixes Hyperdrive/Prisma configuration validation by allowing postgres:// connection strings (which Hyperdrive emits), and enhances the health check to validate the connected PostgreSQL database name for Neon/Hyperdrive misconfiguration detection.
Changes:
- Update
PrismaClientConfigSchemato accept bothpostgresql://andpostgres://schemes. - Enhance
/healthdatabase probing to querycurrent_database()and mark status asdegradedwhen connected to an unexpected DB. - Update and expand unit tests to cover
postgres://DSNs and the new health probe response shape.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| worker/lib/prisma-config.ts | Accepts postgres:// in connection string validation with a clearer refinement message. |
| worker/lib/prisma-config.test.ts | Fixes the previously incorrect rejection test and adds multiple postgres:// happy-path cases. |
| worker/lib/prisma.test.ts | Adds a postgres:// happy-path validation test. |
| worker/handlers/health.ts | Switches DB probe to current_database(), adds wrong-DB degradation logic, and includes extra DB metadata in the response. |
| worker/handlers/health.test.ts | Updates mocks and adds tests for degraded/healthy/down database scenarios and new response fields. |
| // Extended database probe: verify connectivity AND confirm we're on the correct | ||
| // production database. Returns db_name and hyperdrive_host for observability. | ||
| const databaseProbe = async (): Promise<DatabaseResult> => { |
There was a problem hiding this comment.
The inline comment describes this as a “production database” probe and says the endpoint exposes “no sensitive data”, but the handler now returns DB metadata and the file header still mentions a D1 SELECT 1 probe. Please update the documentation comments to match the current Hyperdrive/Prisma probe behavior and the data actually returned.
| const dbName = rows[0]?.db_name ?? 'unknown'; | ||
| const latency_ms = Date.now() - t0; | ||
| // Fail-fast guard: warn if connected to wrong database | ||
| if (dbName !== 'adblock-compiler') { | ||
| return { | ||
| status: 'degraded', | ||
| latency_ms, | ||
| db_name: dbName, | ||
| hyperdrive_host: env.HYPERDRIVE.host, | ||
| }; | ||
| } | ||
| return { | ||
| status: 'healthy', | ||
| latency_ms, | ||
| db_name: dbName, | ||
| hyperdrive_host: env.HYPERDRIVE.host, | ||
| }; | ||
| } catch { | ||
| return { | ||
| status: 'down', | ||
| latency_ms: Date.now() - t0, | ||
| hyperdrive_host: env.HYPERDRIVE?.host, | ||
| }; |
There was a problem hiding this comment.
/health is a publicly accessible endpoint (Anonymous tier + public CORS) but the response now includes db_name and hyperdrive_host, which leaks internal infrastructure details cross-origin and contradicts the “no sensitive data” claim. Consider removing these fields from the public response or gating them behind an authenticated/admin-only endpoint (or a debug flag that’s only honored for trusted callers).
PrismaClientConfigSchemarejectedpostgres://— the exact scheme Cloudflare Hyperdrive's.connectionStringemits — causing an instantZodErrorbefore any connection attempt. This is whydatabase.latency_ms: 0appeared in health responses and Hyperdrive showed zero activity.Changes
worker/lib/prisma-config.ts.startsWith('postgresql://')with.refine(s => s.startsWith('postgresql://') || s.startsWith('postgres://'))— both are valid PG DSNs accepted by@prisma/adapter-pgworker/handlers/health.tsSELECT 1probe withSELECT current_database() AS db_namedegraded(nothealthy) if connected to a database other thanadblock-compiler— catches misconfigured Hyperdrive endpoints silently pointing atneondbdb_nameandhyperdrive_hostin theservices.databaseresponse object for observabilityworker/lib/prisma-config.test.tspostgres://was wrongly expected to fail) to a happy-path assertionpostgres://happy-path tests: with SSL query param, without port, and localhostworker/lib/prisma.test.tspostgres://happy-path testworker/handlers/health.test.ts{ '?column?': 1 }→{ db_name: 'adblock-compiler' }hostfield toHyperdriveBindingstubsdegraded,db_namefield present on healthy,hyperdrive_hostfield present,$queryRawthrows returnsdownTesting
Zero Trust Architecture Checklist
Worker / Backend
*) on write/authenticated endpoints — N/A, read-only probe[vars]) — N/A, no secrets touchedPrismaClientConfigSchemavalidation is the subject of this fix.prepare().bind()(no string interpolation) — N/A, no D1 queriesFrontend / Angular
CanActivateFnauth guards — N/AlocalStorage) — N/AOriginal prompt
Problem
There are two issues to fix and one enhancement to add.
Bug:
PrismaClientConfigSchemarejectspostgres://— the scheme Cloudflare Hyperdrive actually returnsRoot cause:
worker/lib/prisma-config.tsvalidates the connection string with.startsWith('postgresql://'). However, the Cloudflare Hyperdrive binding's.connectionStringuses thepostgres://short alias (confirmed viawrangler hyperdrive get—"scheme": "postgres"). This meansPrismaClientConfigSchema.parse(...)throws aZodErrorbefore any connection is ever opened, causinghandleHealthto catch the error and return{ status: 'down', latency_ms: 0 }for the database service. This is why Hyperdrive shows zero activity — the connection is never established.Evidence from health endpoint:
{ "services": { "database": { "status": "down", "latency_ms": 0 } } }latency_ms: 0confirms the probe throws instantly (Zod validation) before any network round-trip.There is also an existing test that explicitly asserts this wrong behaviour:
Fix 1 (Option A): Update
PrismaClientConfigSchemato accept both schemesFile:
worker/lib/prisma-config.tsReplace:
With:
Fix 2: Update
worker/lib/prisma-config.test.tsChange the existing test
'PrismaClientConfigSchema rejects postgres:// shorthand protocol'— it should now pass (assertresult.success === true). Update the test name and comment accordingly.Add new happy-path tests for
postgres://:'PrismaClientConfigSchema validates postgres:// shorthand (Hyperdrive scheme)'— basicpostgres://user:pass@host:5432/db'PrismaClientConfigSchema validates postgres:// with SSL query param (Hyperdrive + Neon)'—postgres://user:pass@ep-xxx-pooler.eastus2.azure.neon.tech:5432/adblock-compiler?sslmode=require'PrismaClientConfigSchema validates postgres:// without port'—postgres://user:pass@host/db'PrismaClientConfigSchema validates postgres:// localhost URL'—postgres://localhost:5432/mydbKeep all other rejection tests unchanged (mysql://, http://, mongodb://, empty, null, etc. should still fail).
Also update
worker/lib/prisma.test.ts— it has a duplicate'PrismaClientConfigSchema rejects non-postgresql URL'test usingmysql://which is fine. But add a new test there too:'PrismaClientConfigSchema validates postgres:// shorthand (Hyperdrive)'Enhancement: Update
worker/handlers/health.ts— Neon-aware database smoke testReplace the simple
SELECT 1database probe with an extended probe that:SELECT current_database() AS db_namevia$queryRaw'adblock-compiler'(the production database name) — if the wrong database is connected, returns'degraded'instead of'healthy'db_nameandhyperdrive_hostin the response JSON for thedatabaseservice entryServiceResulttype for database should be extended to include optionaldb_name?: stringandhyperdrive_host?: stringfieldsUpdated
handleHealthdatabase probe section (replace lines 40–50 in the current file):