fix(devtools): expose POST /admin/db-migrate/resolve route (fixes #626)#627
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 63910130c9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // and there is no admin-API path to resolve it. | ||
| { | ||
| httpApi: { | ||
| path: '/admin/db-migrate/resolve', |
There was a problem hiding this comment.
Run resolve on a Lambda with Prisma available
When an operator calls this newly exposed route in the default usePrismaLambdaLayer deployment, the router Lambda cannot execute it: db-migration.js handles /admin/db-migrate/resolve by calling runPrismaMigrateResolve() (packages/core/handlers/routers/db-migration.js:267-269), but this function is configured with no Prisma layer and its router package excludes node_modules/prisma/** and all WASM files (lines 343-398). The request will reach API Gateway but fail inside the Lambda instead of resolving the P3009 state; attach/package the Prisma runtime for this route or dispatch the resolve work to the migration worker.
Useful? React with 👍 / 👎.
The core migration router registers POST /admin/db-migrate/resolve
(db-migration.js) to recover from a Prisma P3009 (failed migration), but
migration-builder only emitted API Gateway routes for status, POST migrate,
and GET {processId}. So the resolve endpoint 404'd on every deployed app —
a single failed migration blocked all subsequent migrations for that stage
with no admin-API path to resolve it (recovery required direct DB writes).
Adds the missing httpApi event so the generated routes match the router.
Fixes #626.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6391013 to
9cf8622
Compare
Exposing the resolve route (previous commit) wasn't enough: the route handler ran runPrismaMigrateResolve() synchronously in the ROUTER Lambda, which is packaged without Prisma (no layer, node_modules/prisma + WASM excluded). So a real call would 500 at runtime instead of resolving. Delegate to the worker Lambda (which has the Prisma CLI), mirroring the existing checkStatus direct-invoke pattern (GetDatabaseStateViaWorkerUseCase): - New ResolveMigrationViaWorkerUseCase invokes the worker with a resolve payload. - Worker gains a `resolve` action that runs runPrismaMigrateResolve + returns its result (validates migrationName + applied|rolled-back). - Router resolve route delegates via the use case; stays Prisma-free and synchronous (200 body from the worker, 500 on failure). Addresses the P1 review on #627. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- prisma-runner: capture resolve stderr/stdout and return it in the error (was stdio:'inherit' → Prisma's real failure, e.g. P3011 for a mistyped migration, went only to CloudWatch; the HTTP client got "exited with code 1"). The point of #626 is HTTP recovery without console access. - Validate migrationName shape (^\d{14}_[a-z0-9_]+$) in router + worker so a value like "--schema" can't be handed to the Prisma CLI as a flag. - Router maps a worker-side 400 (LambdaInvocationError.statusCode===400) to a client 400 instead of a generic 500. - Worker guards dbType !== 'postgresql' → 400 (resolve is postgres-only) instead of dying on a schema-not-found error. - Tests: worker resolve branch (malformed name, non-postgres dbType, error passthrough) + router resolve route registration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The rationale lives in the commit history / PR; the code is self-explanatory. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
🚀 PR was released in |



Summary
Fixes #626. Adds the missing
POST /admin/db-migrate/resolveAPI Gateway route inmigration-builder, so it matches the routes core's migration router actually serves.Problem
packages/core/handlers/routers/db-migration.jsregistersPOST /admin/db-migrate/resolveto recover from a Prisma P3009 (a failed migration blocks all subsequent migrations). Butmigration-builder.jsonly emitted threehttpApievents (GET .../status,POST /admin/db-migrate,GET .../{processId}) — the resolve route was never exposed. On any deployed app it returns 404, so P3009 recovery via the admin API is impossible; operators are forced into direct DB writes (prisma migrate resolve/ manual_prisma_migrationsSQL) requiring DB creds + VPC access.Hit in production: a stale duplicate
create_process_tablemigration failed months earlier; every deploy since silently no-op'd on migrations, with no API path to resolve it.Change
migration-builder.js: add{ httpApi: { path: '/admin/db-migrate/resolve', method: 'POST' } }to thedbMigrationRouterevents (no new handler needed — core's router already serves it; the route just wasn't mapped to API Gateway).migration-builder.test.js: assert the 4th route (length 3 → 4).Test plan
npx jest infrastructure/domains/database/migration-builder.test.js→ 23 passed.🤖 Generated with Claude Code
📦 Published PR as canary version:
2.0.0--canary.627.ce32cdc.0✨ Test out this PR locally via:
npm install @friggframework/admin-scripts@2.0.0--canary.627.ce32cdc.0 npm install @friggframework/core@2.0.0--canary.627.ce32cdc.0 npm install @friggframework/devtools@2.0.0--canary.627.ce32cdc.0 npm install @friggframework/eslint-config@2.0.0--canary.627.ce32cdc.0 npm install @friggframework/prettier-config@2.0.0--canary.627.ce32cdc.0 npm install @friggframework/schemas@2.0.0--canary.627.ce32cdc.0 npm install @friggframework/serverless-plugin@2.0.0--canary.627.ce32cdc.0 npm install @friggframework/test@2.0.0--canary.627.ce32cdc.0 npm install @friggframework/ui@2.0.0--canary.627.ce32cdc.0 # or yarn add @friggframework/admin-scripts@2.0.0--canary.627.ce32cdc.0 yarn add @friggframework/core@2.0.0--canary.627.ce32cdc.0 yarn add @friggframework/devtools@2.0.0--canary.627.ce32cdc.0 yarn add @friggframework/eslint-config@2.0.0--canary.627.ce32cdc.0 yarn add @friggframework/prettier-config@2.0.0--canary.627.ce32cdc.0 yarn add @friggframework/schemas@2.0.0--canary.627.ce32cdc.0 yarn add @friggframework/serverless-plugin@2.0.0--canary.627.ce32cdc.0 yarn add @friggframework/test@2.0.0--canary.627.ce32cdc.0 yarn add @friggframework/ui@2.0.0--canary.627.ce32cdc.0