-
Notifications
You must be signed in to change notification settings - Fork 1
DC-4974 create-db web #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughMoves claim-db-worker from a Cloudflare Worker to a Next.js App Router (OpenNext) app, adds a browser Web Interface for temporary DB provisioning and claiming, introduces a Hono-based schema-api-routes service, and adds UI, API routes, schema-editor tooling, middleware, and workspace/config updates. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Web as Next.js UI
participant API as App Router API
participant Prisma as Prisma Auth/API
participant PostHog as Analytics
User->>Web: Visit homepage (/)
Web->>API: GET /api/claim?projectID&utm_*
API-->>PostHog: sendPosthogEvent("create_db:claim_page_viewed")
API-->>Web: { success: true }
User->>Web: Click "Claim database" (opens auth)
Web->>Prisma: Redirect to /authorize (client_id, redirect_uri, state)
Prisma-->>User: Redirect back to /api/auth/callback?code&state&projectID
User->>API: GET /api/auth/callback?code&state&projectID
API->>Prisma: POST /token (exchange code)
API->>Prisma: GET /v1/projects/{projectID} (validate)
API->>Prisma: POST /v1/projects/{projectID}/transfer
alt success
API-->>PostHog: trackClaimSuccess
API-->>Web: redirect /success?projectID
else failure
API-->>PostHog: trackClaimFailure
API-->>Web: redirect /error?title&message&details
end
sequenceDiagram
autonumber
actor User
participant Web as Next.js Web UI (/web)
participant API as App Router API
participant SchemaSvc as schema-api-routes
participant PrismaCLI as Prisma CLI
User->>Web: Visit /web
Web->>API: POST /api/create-db
API->>Prisma (worker): request create
API-->>Web: { connectionString, projectId, databaseId }
Web->>Cookie: save temp_db_info
User->>Web: Open /web/schema
Web->>SchemaSvc: POST /api/schema/pull (X-Connection-String)
SchemaSvc->>PrismaCLI: run `prisma db pull` (temp files)
SchemaSvc-->>Web: { schema | isEmpty }
User->>Web: Click Format/Push
Web->>SchemaSvc: POST /api/schema/format or /push
SchemaSvc->>PrismaCLI: run prisma format / db push (/push-force)
SchemaSvc-->>Web: { formattedSchema | success | requiresForceReset }
sequenceDiagram
autonumber
participant MW as Next.js Middleware
participant API as App Router API
participant Web as Next.js Pages
MW->>Cookie: read temp_db_info
alt projectId present
MW->>API: POST /api/check-db-status { projectId }
API->>Prisma: GET /v1/projects/{projectId}
alt error
MW-->>Web: redirect /db-unavailable
else ok
MW-->>Web: continue
end
else no projectId
MW-->>Web: continue
end
Possibly related PRs
Suggested reviewers
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
Deploying with
|
Status | Name | Latest Commit | Preview URL | Updated (UTC) |
---|---|---|---|---|
✅ Deployment successful! View logs |
claim-db-worker | 6f65028 | Commit Preview URL Branch Preview URL |
Sep 03 2025, 06:46 PM |
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 188
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
schema-api-routes/README.md (1)
1-29
: Add a proper title, code fence languages, and align with pnpm/monorepo workflowMissing H1 and untyped fences trigger markdownlint; commands use npm while the repo is pnpm-first; “open …” is macOS-specific.
Apply this diff:
+# schema-api-routes + Prerequisites: -- [Vercel CLI](https://vercel.com/docs/cli) installed globally +- [Vercel CLI](https://vercel.com/docs/cli) installed globally (`vc`/`vercel`) To develop locally: -``` -npm install -vc dev -``` +```bash +pnpm install +vc dev +``` -``` -open http://localhost:3000 -``` +Open http://localhost:3000 in your browser. To build locally: -``` -npm install -vc build -``` +```bash +pnpm install +vc build +``` To deploy: -``` -npm install -vc deploy -``` +```bash +pnpm install +vc deploy +```Optional additions:
- Add “vc login” and “vc link” steps for first-time setup.
- Document required env vars (e.g., DATABASE_URL) if any.
The current README is missing a top-level heading and language hints; fix to pass MD041/MD040.
README.md (3)
306-311
: Config text still references “static HTML assets”.Replace with OpenNext output terminology.
Apply this diff:
-**Claim DB Worker** (`claim-db-worker/wrangler.jsonc`): +**Claim DB Web App** (`claim-db-worker/wrangler.jsonc`): @@ -- Assets: Static files for HTML templates +- Assets: OpenNext bundle (functions, assets, and middleware)
373-395
: Project structure is outdated (templates, src/).Update to reflect the Next.js App Router (
app/web/*
, components/, lib/, config files, OpenNext artifacts).Would you like me to propose an updated tree based on the new files (app/web, components, lib, open-next.config.ts, next.config.ts, wrangler.jsonc)?
411-415
: Fix orphaned fenced code block and missing language.There’s a stray code fence that triggers MD040.
Apply this diff:
-``` - -``` +```md +<!-- end of document --> +```claim-db-worker/worker-configuration.d.ts (1)
6352-6352
: Biome: noEmptyInterface on Disposable (generated code)Biome flags the empty interface. Since this file is generated, don’t hand-edit. Suppress at the tool level:
- Exclude this file in biome config, or
- Add a file header ignore:
/* biome-ignore lint/suspicious/noEmptyInterface: generated types keep this for TS<5.2 compat */
Want a PR to update biome.json to ignore generated d.ts files?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (3)
claim-db-worker/app/favicon.ico
is excluded by!**/*.ico
claim-db-worker/package-lock.json
is excluded by!**/package-lock.json
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (84)
README.md
(8 hunks)claim-db-worker/.editorconfig
(0 hunks)claim-db-worker/.gitignore
(1 hunks)claim-db-worker/.prettierrc
(0 hunks)claim-db-worker/README.md
(1 hunks)claim-db-worker/app/api/auth/callback/route.ts
(1 hunks)claim-db-worker/app/api/check-db-status/route.ts
(1 hunks)claim-db-worker/app/api/claim/route.ts
(1 hunks)claim-db-worker/app/api/create-db/route.ts
(1 hunks)claim-db-worker/app/api/get-connection-string/route.ts
(1 hunks)claim-db-worker/app/api/studio/route.ts
(1 hunks)claim-db-worker/app/api/test/route.ts
(1 hunks)claim-db-worker/app/claim/page.tsx
(1 hunks)claim-db-worker/app/contexts/DropContext.tsx
(1 hunks)claim-db-worker/app/db-unavailable/page.tsx
(1 hunks)claim-db-worker/app/error/page.tsx
(1 hunks)claim-db-worker/app/globals.css
(1 hunks)claim-db-worker/app/layout.tsx
(1 hunks)claim-db-worker/app/page.tsx
(1 hunks)claim-db-worker/app/success/page.tsx
(1 hunks)claim-db-worker/app/test/claim/page.tsx
(1 hunks)claim-db-worker/app/test/error/page.tsx
(1 hunks)claim-db-worker/app/test/success/page.tsx
(1 hunks)claim-db-worker/app/web/DatabaseContext.tsx
(1 hunks)claim-db-worker/app/web/connect/page.tsx
(1 hunks)claim-db-worker/app/web/layout.tsx
(1 hunks)claim-db-worker/app/web/page.tsx
(1 hunks)claim-db-worker/app/web/schema/page.tsx
(1 hunks)claim-db-worker/app/web/studio/StudioClient.tsx
(1 hunks)claim-db-worker/app/web/studio/page.tsx
(1 hunks)claim-db-worker/components/ClientRedirect.tsx
(1 hunks)claim-db-worker/components/CodeSnippet.tsx
(1 hunks)claim-db-worker/components/Footer.tsx
(1 hunks)claim-db-worker/components/LoadingScreen.tsx
(1 hunks)claim-db-worker/components/Modal.tsx
(1 hunks)claim-db-worker/components/Navbar.tsx
(1 hunks)claim-db-worker/components/PrismaPostgresLogo.tsx
(1 hunks)claim-db-worker/components/prismaSchemaEditor/BusyPanel.tsx
(1 hunks)claim-db-worker/components/prismaSchemaEditor/InfoNote.tsx
(1 hunks)claim-db-worker/components/prismaSchemaEditor/InitOverlay.tsx
(1 hunks)claim-db-worker/components/prismaSchemaEditor/SidebarActions.tsx
(1 hunks)claim-db-worker/lib/analytics.ts
(1 hunks)claim-db-worker/lib/auth-utils.ts
(1 hunks)claim-db-worker/lib/custom-toast.ts
(1 hunks)claim-db-worker/lib/env.ts
(1 hunks)claim-db-worker/lib/prismaSchemaEditor/defaultSchema.ts
(1 hunks)claim-db-worker/lib/prismaSchemaEditor/editorOptions.ts
(1 hunks)claim-db-worker/lib/prismaSchemaEditor/monacoConfig.ts
(1 hunks)claim-db-worker/lib/prismaSchemaEditor/prismaSchemaUtils.ts
(1 hunks)claim-db-worker/lib/prismaSchemaEditor/schemaApi.ts
(1 hunks)claim-db-worker/lib/project-transfer.ts
(1 hunks)claim-db-worker/lib/response-utils.ts
(1 hunks)claim-db-worker/lib/utils.ts
(1 hunks)claim-db-worker/middleware.ts
(1 hunks)claim-db-worker/next.config.ts
(1 hunks)claim-db-worker/open-next.config.ts
(1 hunks)claim-db-worker/package.json
(1 hunks)claim-db-worker/postcss.config.mjs
(1 hunks)claim-db-worker/src/index.ts
(0 hunks)claim-db-worker/src/templates/claim-success-template.ts
(0 hunks)claim-db-worker/src/templates/claim-template.ts
(0 hunks)claim-db-worker/src/templates/error-template.ts
(0 hunks)claim-db-worker/src/templates/footer-template.ts
(0 hunks)claim-db-worker/src/templates/homepage-template.ts
(0 hunks)claim-db-worker/src/templates/navbar-template.ts
(0 hunks)claim-db-worker/src/templates/terminal-animation-template.ts
(0 hunks)claim-db-worker/test/env.d.ts
(0 hunks)claim-db-worker/test/index.spec.ts
(0 hunks)claim-db-worker/test/tsconfig.json
(0 hunks)claim-db-worker/tsconfig.json
(1 hunks)claim-db-worker/vitest.config.mts
(0 hunks)claim-db-worker/worker-configuration.d.ts
(27 hunks)claim-db-worker/wrangler.jsonc
(1 hunks)pnpm-workspace.yaml
(1 hunks)schema-api-routes/.gitignore
(1 hunks)schema-api-routes/README.md
(1 hunks)schema-api-routes/package.json
(1 hunks)schema-api-routes/src/index.ts
(1 hunks)schema-api-routes/src/routes/schema/format.ts
(1 hunks)schema-api-routes/src/routes/schema/pull.ts
(1 hunks)schema-api-routes/src/routes/schema/push-force.ts
(1 hunks)schema-api-routes/src/routes/schema/push.ts
(1 hunks)schema-api-routes/tsconfig.json
(1 hunks)schema-api-routes/vercel.json
(1 hunks)
💤 Files with no reviewable changes (14)
- claim-db-worker/src/templates/footer-template.ts
- claim-db-worker/test/env.d.ts
- claim-db-worker/.editorconfig
- claim-db-worker/src/templates/claim-template.ts
- claim-db-worker/test/tsconfig.json
- claim-db-worker/.prettierrc
- claim-db-worker/src/templates/claim-success-template.ts
- claim-db-worker/src/templates/terminal-animation-template.ts
- claim-db-worker/test/index.spec.ts
- claim-db-worker/src/templates/homepage-template.ts
- claim-db-worker/src/templates/navbar-template.ts
- claim-db-worker/src/templates/error-template.ts
- claim-db-worker/src/index.ts
- claim-db-worker/vitest.config.mts
🧰 Additional context used
🧬 Code graph analysis (32)
claim-db-worker/lib/auth-utils.ts (2)
claim-db-worker/lib/env.ts (1)
getEnv
(11-39)create-db-worker/src/index.ts (1)
fetch
(15-160)
claim-db-worker/app/test/error/page.tsx (1)
claim-db-worker/app/error/page.tsx (1)
ErrorPage
(68-74)
claim-db-worker/app/success/page.tsx (1)
claim-db-worker/components/PrismaPostgresLogo.tsx (1)
PrismaPostgresLogo
(3-15)
claim-db-worker/app/web/connect/page.tsx (2)
claim-db-worker/app/web/DatabaseContext.tsx (1)
useDatabase
(30-36)claim-db-worker/lib/custom-toast.ts (1)
customToast
(40-71)
claim-db-worker/app/web/page.tsx (1)
claim-db-worker/app/web/DatabaseContext.tsx (1)
useDatabase
(30-36)
claim-db-worker/app/api/test/route.ts (2)
claim-db-worker/app/api/auth/callback/route.ts (1)
GET
(12-116)claim-db-worker/app/api/claim/route.ts (1)
GET
(4-50)
claim-db-worker/lib/analytics.ts (2)
claim-db-worker/lib/env.ts (1)
getEnv
(11-39)create-db-worker/src/index.ts (1)
fetch
(15-160)
claim-db-worker/app/api/get-connection-string/route.ts (2)
claim-db-worker/app/api/create-db/route.ts (1)
POST
(25-66)create-db-worker/src/index.ts (1)
fetch
(15-160)
claim-db-worker/app/api/create-db/route.ts (2)
create-db/index.js (2)
CREATE_DB_WORKER_URL
(15-16)name
(655-655)create-db-worker/src/index.ts (1)
fetch
(15-160)
claim-db-worker/app/test/claim/page.tsx (1)
claim-db-worker/app/claim/page.tsx (1)
ClaimPage
(92-98)
schema-api-routes/src/routes/schema/push.ts (1)
create-db/index.js (2)
c
(95-95)envPath
(153-153)
claim-db-worker/lib/project-transfer.ts (2)
claim-db-worker/lib/env.ts (1)
getEnv
(11-39)create-db-worker/src/index.ts (1)
fetch
(15-160)
claim-db-worker/app/test/success/page.tsx (1)
claim-db-worker/app/success/page.tsx (1)
SuccessPage
(77-83)
claim-db-worker/app/api/claim/route.ts (3)
claim-db-worker/app/api/auth/callback/route.ts (1)
GET
(12-116)claim-db-worker/lib/env.ts (1)
getEnv
(11-39)claim-db-worker/lib/analytics.ts (1)
sendPosthogEvent
(3-33)
claim-db-worker/app/web/schema/page.tsx (10)
claim-db-worker/app/web/DatabaseContext.tsx (1)
useDatabase
(30-36)claim-db-worker/lib/prismaSchemaEditor/defaultSchema.ts (1)
DEFAULT_PRISMA_SCHEMA
(1-12)claim-db-worker/lib/prismaSchemaEditor/monacoConfig.ts (6)
createPrismaLanguageConfig
(3-53)createPrismaTheme
(55-98)createCompletionProvider
(100-491)createHoverProvider
(493-545)createFormattingProvider
(547-564)createEditorActions
(566-581)claim-db-worker/lib/prismaSchemaEditor/schemaApi.ts (4)
formatSchema
(1-24)pushSchema
(26-58)pullSchema
(60-92)forcePushSchema
(94-116)claim-db-worker/lib/custom-toast.ts (1)
customToast
(40-71)claim-db-worker/components/prismaSchemaEditor/SidebarActions.tsx (1)
SidebarActions
(16-93)claim-db-worker/components/prismaSchemaEditor/BusyPanel.tsx (1)
BusyPanel
(5-20)claim-db-worker/lib/prismaSchemaEditor/editorOptions.ts (1)
PRISMA_EDITOR_OPTIONS
(1-77)claim-db-worker/components/prismaSchemaEditor/InitOverlay.tsx (1)
InitOverlay
(5-30)claim-db-worker/components/prismaSchemaEditor/InfoNote.tsx (1)
InfoNote
(6-15)
claim-db-worker/app/web/DatabaseContext.tsx (2)
claim-db-worker/app/contexts/DropContext.tsx (1)
useDropContext
(47-53)claim-db-worker/lib/utils.ts (1)
cookieUtils
(1-24)
claim-db-worker/components/CodeSnippet.tsx (1)
claim-db-worker/lib/custom-toast.ts (1)
customToast
(40-71)
claim-db-worker/app/api/auth/callback/route.ts (5)
claim-db-worker/lib/env.ts (1)
getEnv
(11-39)claim-db-worker/lib/response-utils.ts (3)
redirectToError
(8-25)getBaseUrl
(3-6)redirectToSuccess
(27-38)claim-db-worker/lib/auth-utils.ts (2)
exchangeCodeForToken
(7-33)validateProject
(35-57)claim-db-worker/lib/analytics.ts (2)
trackClaimFailure
(52-62)trackClaimSuccess
(35-50)claim-db-worker/lib/project-transfer.ts (1)
transferProject
(4-36)
claim-db-worker/app/api/studio/route.ts (1)
claim-db-worker/app/api/create-db/route.ts (1)
POST
(25-66)
claim-db-worker/app/web/studio/page.tsx (1)
claim-db-worker/app/web/studio/StudioClient.tsx (1)
StudioClient
(58-77)
claim-db-worker/app/api/check-db-status/route.ts (2)
create-db/index.js (2)
response
(42-47)projectId
(495-495)create-db-worker/src/index.ts (1)
fetch
(15-160)
schema-api-routes/src/routes/schema/push-force.ts (1)
create-db/index.js (2)
c
(95-95)envPath
(153-153)
claim-db-worker/app/contexts/DropContext.tsx (1)
create-db/index.js (2)
projectId
(495-495)claimUrl
(517-517)
claim-db-worker/app/db-unavailable/page.tsx (1)
claim-db-worker/lib/utils.ts (1)
cookieUtils
(1-24)
claim-db-worker/components/Navbar.tsx (1)
claim-db-worker/app/contexts/DropContext.tsx (1)
useDropContext
(47-53)
claim-db-worker/lib/prismaSchemaEditor/monacoConfig.ts (1)
claim-db-worker/lib/prismaSchemaEditor/prismaSchemaUtils.ts (2)
isInsideBlock
(1-26)formatPrismaSchema
(28-96)
schema-api-routes/src/routes/schema/pull.ts (1)
create-db/index.js (2)
c
(95-95)envPath
(153-153)
claim-db-worker/app/layout.tsx (3)
claim-db-worker/app/contexts/DropContext.tsx (1)
DropProvider
(19-45)claim-db-worker/components/Navbar.tsx (1)
Navbar
(9-126)claim-db-worker/components/Footer.tsx (1)
Footer
(3-68)
claim-db-worker/app/claim/page.tsx (1)
claim-db-worker/components/PrismaPostgresLogo.tsx (1)
PrismaPostgresLogo
(3-15)
claim-db-worker/app/page.tsx (3)
claim-db-worker/components/ClientRedirect.tsx (1)
ClientRedirect
(10-24)claim-db-worker/components/PrismaPostgresLogo.tsx (1)
PrismaPostgresLogo
(3-15)claim-db-worker/components/CodeSnippet.tsx (1)
CodeSnippet
(6-32)
claim-db-worker/app/web/layout.tsx (4)
claim-db-worker/app/web/DatabaseContext.tsx (2)
useDatabase
(30-36)DatabaseProvider
(42-151)claim-db-worker/app/contexts/DropContext.tsx (1)
useDropContext
(47-53)claim-db-worker/lib/custom-toast.ts (1)
customToast
(40-71)claim-db-worker/components/LoadingScreen.tsx (1)
LoadingScreen
(1-25)
claim-db-worker/worker-configuration.d.ts (1)
claim-db-worker/lib/env.ts (1)
Env
(1-9)
🪛 LanguageTool
schema-api-routes/README.md
[grammar] ~1-~1: Use correct spacing
Context: Prerequisites: - Vercel CLI...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: Use correct spacing
Context: .../vercel.com/docs/cli) installed globally To develop locally: ``` npm install vc ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~5-~5: Use correct spacing
Context: ... installed globally To develop locally: npm install vc dev
open http://localhost:3000
To build locally: ``` npm install vc bu...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~16-~16: Use correct spacing
Context: ...://localhost:3000 To build locally:
npm install vc build To deploy:
npm install vc deploy ``...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~23-~23: Use correct spacing
Context: ...npm install vc build
To deploy: npm install vc deploy
(QB_NEW_EN_OTHER_ERROR_IDS_5)
claim-db-worker/README.md
[grammar] ~3-~3: Use correct spacing
Context: ...atabase projects to authenticated users. ## Features - ✅ OAuth authentication with ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~5-~5: Use correct spacing
Context: ...cts to authenticated users. ## Features - ✅ OAuth authentication with Prisma - ✅ D...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~7-~7: There might be a mistake here.
Context: ...es - ✅ OAuth authentication with Prisma - ✅ Database project claiming - ✅ Rate lim...
(QB_NEW_EN)
[grammar] ~8-~8: There might be a mistake here.
Context: ...ith Prisma - ✅ Database project claiming - ✅ Rate limiting (100 requests per minute...
(QB_NEW_EN)
[grammar] ~9-~9: There might be a mistake here.
Context: ... Rate limiting (100 requests per minute) - ✅ PostHog analytics tracking - ✅ Cloudfl...
(QB_NEW_EN)
[grammar] ~10-~10: There might be a mistake here.
Context: ...r minute) - ✅ PostHog analytics tracking - ✅ Cloudflare Analytics Engine integratio...
(QB_NEW_EN)
[grammar] ~11-~11: There might be a mistake here.
Context: ... Cloudflare Analytics Engine integration - ✅ Error handling and user feedback - ✅ R...
(QB_NEW_EN)
[grammar] ~12-~12: There might be a mistake here.
Context: ...ion - ✅ Error handling and user feedback - ✅ Responsive UI with Tailwind CSS ## Qu...
(QB_NEW_EN)
[grammar] ~13-~13: Use correct spacing
Context: ...back - ✅ Responsive UI with Tailwind CSS ## Quick Start ### Development 1. **Insta...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~15-~15: Use correct spacing
Context: ...ive UI with Tailwind CSS ## Quick Start ### Development 1. **Install dependencies:*...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~17-~17: Use correct spacing
Context: ...ind CSS ## Quick Start ### Development 1. Install dependencies: ```bash np...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~19-~19: Use correct spacing
Context: ... Development 1. Install dependencies: bash npm install
2. Set up environment variables: Creat...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~24-~24: Use correct spacing
Context: ...`` 2. Set up environment variables: Create a .env.local
file: ```env ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~25-~25: Use correct spacing
Context: ...iables:** Create a .env.local
file: env CLIENT_ID=your_prisma_client_id CLIENT_SECRET=your_prisma_client_secret INTEGRATION_TOKEN=your_prisma_integration_token POSTHOG_API_KEY=your_posthog_api_key POSTHOG_API_HOST=https://app.posthog.com
3. Start development server: ```bash ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~34-~34: Use correct spacing
Context: ...m 3. **Start development server:**
bash npm run dev ``` 4. Test the flow: Visit `http://localh...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~39-~39: Use correct spacing
Context: ...pm run dev ``` 4. Test the flow: Visit `http://localhost:3000/?projectID=...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~40-~40: Use correct spacing
Context: ... ``` 4. Test the flow: Visit http://localhost:3000/?projectID=test123
### Production Deployment 1. **Set up Cloud...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~42-~42: Use correct spacing
Context: ...ctID=test123` ### Production Deployment 1. Set up Cloudflare secrets: ```bash ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~44-~44: Use correct spacing
Context: ...loyment 1. Set up Cloudflare secrets: bash wrangler secret put CLIENT_ID wrangler secret put CLIENT_SECRET wrangler secret put INTEGRATION_TOKEN wrangler secret put POSTHOG_API_KEY wrangler secret put POSTHOG_API_HOST
2. Build and deploy: ```bash npm ru...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~53-~53: Use correct spacing
Context: ..._API_HOST 2. **Build and deploy:**
bash npm run deploy ``` ## API Endpoints - /api/claim
- Gene...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~58-~58: Use correct spacing
Context: ... npm run deploy ``` ## API Endpoints - /api/claim
- Generates OAuth URLs and tracks page ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~60-~60: Use correct spacing
Context: ...nerates OAuth URLs and tracks page views - /api/auth/callback
- Handles OAuth callback and project tra...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~61-~61: Use correct spacing
Context: ...dles OAuth callback and project transfer - /api/test
- Rate limit testing endpoint - **`/api/...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~62-~62: Use correct spacing
Context: ...pi/test** - Rate limit testing endpoint - **
/api/success-test`** - Test endpoint for success page ## Pag...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~63-~63: Use correct spacing
Context: ...test** - Test endpoint for success page ## Pages - **
/`** - Homepage (redirects t...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~65-~65: Use correct spacing
Context: ...Test endpoint for success page ## Pages - /
- Homepage (redirects to claim flow if ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~67-~67: Use correct spacing
Context: ...cts to claim flow if projectID provided) - /claim
- Claim page with OAuth button - **`/suc...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~68-~68: Use correct spacing
Context: .../claim** - Claim page with OAuth button - **
/success** - Success page after claiming - **
/erro...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~69-~69: Use correct spacing
Context: ...success** - Success page after claiming - **
/error`** - Error page for various error states #...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~70-~70: Use correct spacing
Context: ...** - Error page for various error states ## Flow 1. User visits /?projectID=123
2...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~72-~72: Use correct spacing
Context: ...r page for various error states ## Flow 1. User visits /?projectID=123
2. Homepag...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~74-~74: There might be a mistake here.
Context: ...s error states ## Flow 1. User visits /?projectID=123
2. Homepage redirects to `/api/claim?projec...
(QB_NEW_EN)
[grammar] ~75-~75: There might be a mistake here.
Context: ...projectID=1232. Homepage redirects to
/api/claim?projectID=123` 3. API generates OAuth URL and redirects to...
(QB_NEW_EN)
[grammar] ~76-~76: There might be a mistake here.
Context: ...PI generates OAuth URL and redirects to /claim?projectID=123&authUrl=...
4. User clicks OAuth, redirects to `/api/au...
(QB_NEW_EN)
[grammar] ~77-~77: There might be a mistake here.
Context: ......4. User clicks OAuth, redirects to
/api/auth/callback` 5. API exchanges code for token and transfe...
(QB_NEW_EN)
[grammar] ~78-~78: There might be a mistake here.
Context: ...ges code for token and transfers project 6. API redirects to `/success?projectID=123...
(QB_NEW_EN)
[grammar] ~79-~79: Use correct spacing
Context: ...d transfers project 6. API redirects to /success?projectID=123
## Configuration The project uses Cloudfla...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~81-~81: Use correct spacing
Context: ...success?projectID=123` ## Configuration The project uses Cloudflare Worker bindi...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~83-~83: There might be a mistake here.
Context: ...project uses Cloudflare Worker bindings: - Rate limiting via `CLAIM_DB_RATE_LIMITER...
(QB_NEW_EN)
[grammar] ~84-~84: There might be a mistake here.
Context: ...ting via CLAIM_DB_RATE_LIMITER
binding - Analytics via CREATE_DB_DATASET
bindin...
(QB_NEW_EN)
[grammar] ~85-~85: There might be a mistake here.
Context: ...nalytics via CREATE_DB_DATASET
binding - Environment variables as secrets See `w...
(QB_NEW_EN)
[grammar] ~86-~86: Use correct spacing
Context: ...nding - Environment variables as secrets See wrangler.jsonc
for the complete co...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~88-~88: Use correct spacing
Context: ...r.jsonc` for the complete configuration. ## Development vs Production - **Developme...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~90-~90: Use periods with abbreviations
Context: ...complete configuration. ## Development vs Production - Development: Uses `pr...
(QB_NEW_EN_OTHER_ERROR_IDS_34)
[grammar] ~90-~90: Use correct spacing
Context: ...iguration. ## Development vs Production - Development: Uses process.env
with g...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~92-~92: There might be a mistake here.
Context: ...allbacks for rate limiting and analytics - Production: Uses Cloudflare Worker bin...
(QB_NEW_EN_OTHER)
[grammar] ~93-~93: Use correct spacing
Context: ...**: Uses Cloudflare Worker bindings via globalThis
The lib/env.ts
utility handles this au...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~95-~95: Use correct spacing
Context: ....tsutility handles this automatically. ## Testing - **Local testing**:
npm run d...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~97-~97: Use correct spacing
Context: ... handles this automatically. ## Testing - Local testing: npm run dev
then visi...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~99-~99: There might be a mistake here.
Context: ... npm run dev
then visit with projectID - Rate limit testing: Visit /api/test
...
(QB_NEW_EN_OTHER)
[grammar] ~100-~100: There might be a mistake here.
Context: ...ojectID - Rate limit testing: Visit /api/test
- Success page testing: Visit `/api/succ...
(QB_NEW_EN)
[grammar] ~101-~101: Use correct spacing
Context: ...test- **Success page testing**: Visit
/api/success-test`
(QB_NEW_EN_OTHER_ERROR_IDS_5)
README.md
[grammar] ~10-~10: There might be a mistake here.
Context: ...r database creation 2. Web Interface - Browser-based database creation at cre...
(QB_NEW_EN_OTHER)
[grammar] ~10-~10: There might be a mistake here.
Context: ...atabase creation 2. Web Interface - Browser-based database creation at create-db.pri...
(QB_NEW_EN_OTHER)
[grammar] ~10-~10: There might be a mistake here.
Context: ...database creation at create-db.prisma.io 3. Cloudflare Workers - Backend services ...
(QB_NEW_EN)
[typographical] ~11-~11: To join two clauses or set off examples, consider using an em dash.
Context: ...ate-db.prisma.io 3. Cloudflare Workers - Backend services for database management and OA...
(QB_NEW_EN_DASH_RULE_EM)
[grammar] ~11-~11: There might be a mistake here.
Context: ...base management and OAuth authentication 4. Monorepo Infrastructure - Shared tooli...
(QB_NEW_EN)
[typographical] ~12-~12: To join two clauses or set off examples, consider using an em dash.
Context: ...hentication 4. Monorepo Infrastructure - Shared tooling and versioning ## CLI Referenc...
(QB_NEW_EN_DASH_RULE_EM)
[grammar] ~12-~12: Use correct spacing
Context: ...ucture** - Shared tooling and versioning ## CLI Reference ### Available Flags | Fl...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~75-~75: Use correct spacing
Context: ...te-postgres` commands ### Web Interface ### Option 1: Using the web interface (recom...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~77-~77: Use correct spacing
Context: ...1: Using the web interface (recommended) The create-db web application provides a...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~79-~79: Use correct spacing
Context: ...or creating and managing your databases. Key features: - No installation requi...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~81-~81: Use correct spacing
Context: ...anaging your databases. Key features: - No installation required - works directl...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[typographical] ~83-~83: To join two clauses or set off examples, consider using an em dash.
Context: .... Key features: - No installation required - works directly in your web browser - Visual i...
(QB_NEW_EN_DASH_RULE_EM)
[grammar] ~83-~83: There might be a mistake here.
Context: ...red - works directly in your web browser - Visual interface for database management...
(QB_NEW_EN_OTHER)
[grammar] ~84-~84: There might be a mistake here.
Context: ...Visual interface for database management - Easy connection string display and copyi...
(QB_NEW_EN_OTHER)
[grammar] ~85-~85: There might be a mistake here.
Context: ...sy connection string display and copying - Built-in schema viewer and editor - Dire...
(QB_NEW_EN_OTHER)
[grammar] ~86-~86: There might be a mistake here.
Context: ...ying - Built-in schema viewer and editor - Direct integration with Prisma Studio - ...
(QB_NEW_EN_OTHER)
[grammar] ~87-~87: There might be a mistake here.
Context: ... - Direct integration with Prisma Studio - Simple database claiming workflow **Get...
(QB_NEW_EN_OTHER)
[grammar] ~88-~88: There might be a mistake here.
Context: ...udio - Simple database claiming workflow Getting started: 1. Visit [create-db....
(QB_NEW_EN_OTHER)
[grammar] ~90-~90: Use correct spacing
Context: ...se claiming workflow Getting started: 1. Visit [create-db.prisma.io](https://crea...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~92-~92: There might be a mistake here.
Context: ...create-db.prisma.io) in your web browser 2. Click "Create with the web interface" 3....
(QB_NEW_EN_OTHER)
[grammar] ~93-~93: There might be a mistake here.
Context: ...b browser 2. Click "Create with the web interface" 3. Modify your schema and interact with the...
(QB_NEW_EN_OTHER)
[grammar] ~94-~94: There might be a mistake here.
Context: ...your schema and interact with the Studio 4. Copy the provided connection strings for...
(QB_NEW_EN_OTHER)
[grammar] ~95-~95: There might be a mistake here.
Context: ...ided connection strings for your project 5. Claim your database to make it permanent...
(QB_NEW_EN_OTHER)
[grammar] ~96-~96: There might be a mistake here.
Context: ...Claim your database to make it permanent ### Backend Services #### `create-db-worker...
(QB_NEW_EN_OTHER)
[grammar] ~118-~118: There might be a mistake here.
Context: ...ip transfer and serves the web interface - Features: - Prisma OAuth authenticat...
(QB_NEW_EN_OTHER)
[grammar] ~119-~119: There might be a mistake here.
Context: ...serves the web interface - Features: - Prisma OAuth authentication - Rate lim...
(QB_NEW_EN)
[grammar] ~120-~120: There might be a mistake here.
Context: ...tures**: - Prisma OAuth authentication - Rate limiting (100 requests/minute) - ...
(QB_NEW_EN)
[grammar] ~121-~121: There might be a mistake here.
Context: ... - Rate limiting (100 requests/minute) - Secure project transfer - User-friendl...
(QB_NEW_EN)
[grammar] ~122-~122: There might be a mistake here.
Context: ...ests/minute) - Secure project transfer - User-friendly HTML interfaces - Analyt...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ...ansfer - User-friendly HTML interfaces - Analytics tracking - Web application h...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ...y HTML interfaces - Analytics tracking - Web application hosting **API Endpoints...
(QB_NEW_EN)
[grammar] ~125-~125: Use correct spacing
Context: ...ics tracking - Web application hosting API Endpoints: - `GET /claim?projectI...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~134-~134: Use correct spacing
Context: ...Quick Start ### Option 1: Using the CLI bash # Create a database with default settings npx create-db # Create a database in a specific region npx create-db --region us-east-1 # Interactive mode to select region npx create-db --interactive # Alternative command names npx create-pg --region eu-west-1 npx create-postgres --interactive
### Option 2: Using the Web Interface Visit...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~151-~151: Use correct spacing
Context: ...` ### Option 2: Using the Web Interface Visit [create-db.prisma.io/web](https://...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[typographical] ~153-~153: To join two clauses or set off examples, consider using an em dash.
Context: ...rectly in your browser. No installation required - just click "Create Database Online" to get s...
(QB_NEW_EN_DASH_RULE_EM)
[grammar] ~153-~153: Use correct spacing
Context: ..."Create Database Online" to get started. ### Environment Setup For local development...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🪛 markdownlint-cli2 (0.17.2)
schema-api-routes/README.md
1-1: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
7-7: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
12-12: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
18-18: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
25-25: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
README.md
412-412: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 Biome (2.1.2)
claim-db-worker/app/web/connect/page.tsx
[error] 167-176: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 197-204: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 210-220: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
claim-db-worker/components/prismaSchemaEditor/InitOverlay.tsx
[error] 9-16: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
claim-db-worker/components/Footer.tsx
[error] 7-7: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
[error] 18-18: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
[error] 28-28: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
[error] 38-38: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
[error] 50-50: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
claim-db-worker/app/web/schema/page.tsx
[error] 281-284: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 309-315: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 318-322: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
claim-db-worker/components/CodeSnippet.tsx
[error] 23-27: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
claim-db-worker/components/LoadingScreen.tsx
[error] 5-11: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
claim-db-worker/components/prismaSchemaEditor/SidebarActions.tsx
[error] 36-36: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 40-40: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 57-57: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 61-61: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 80-80: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 84-84: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 29-34: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 50-55: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 71-78: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
claim-db-worker/components/prismaSchemaEditor/BusyPanel.tsx
[error] 10-10: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
claim-db-worker/components/Navbar.tsx
[error] 19-19: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
[error] 53-56: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.
Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.
(lint/a11y/useKeyWithClickEvents)
[error] 53-56: Static Elements should not be interactive.
To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.
(lint/a11y/noStaticElementInteractions)
[error] 57-64: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 86-86: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
[error] 97-97: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
[error] 108-108: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
[error] 116-116: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
claim-db-worker/app/claim/page.tsx
[error] 61-65: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
claim-db-worker/app/web/layout.tsx
[error] 75-81: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 112-115: Static Elements should not be interactive.
To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.
(lint/a11y/noStaticElementInteractions)
[error] 112-115: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.
Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.
(lint/a11y/useKeyWithClickEvents)
[error] 116-123: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 314-320: Alternative text title element cannot be empty
For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.
(lint/a11y/noSvgWithoutTitle)
[error] 94-97: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 135-138: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 143-150: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 186-189: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 193-200: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 234-237: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 240-243: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
[error] 285-292: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form
element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
claim-db-worker/worker-configuration.d.ts
[error] 6826-6826: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Workers Builds: claim-db-worker
- GitHub Check: Workers Builds: create-db-worker
🔇 Additional comments (28)
claim-db-worker/tsconfig.json (2)
16-20
: Next.js TypeScript plugin configured correctly.The "next" plugin entry is correct for App Router projects.
14-14
: JSX preset is appropriate for Next."jsx": "preserve" matches Next/SWC expectations.
pnpm-workspace.yaml (1)
2-7
: LGTM: package added to workspaceWorkspace entry for “schema-api-routes” looks correct.
claim-db-worker/lib/prismaSchemaEditor/defaultSchema.ts (2)
9-12
: Validate env var contractConfirm
DATABASE_URL
is always present in environments where the editor pulls/pushes the schema; otherwise, surface a clearer error or a placeholder value during local dev.
4-7
: Do not change Prisma generator provider or output The preview generatorprisma-client
is valid and requires a customoutput
path; switching toprisma-client-js
and removingoutput
is incorrect. (prisma.io)Likely an incorrect or invalid review comment.
schema-api-routes/src/routes/schema/push-force.ts (1)
37-38
: Confirmed Prisma CLI supports both --accept-data-loss and --force-reset fordb push
The Prisma CLI v6.15.0 help output lists both flags, so this usage is valid.
claim-db-worker/wrangler.jsonc (3)
4-4
: Sanity check: main points to the built workerLooks correct for OpenNext. Ensure CI builds before publish.
7-7
: Compatibility flag valid
The “global_fetch_strictly_public” flag is officially supported in the current Wrangler version (as of September 3, 2025).
18-20
: Add staticAssets config for “ASSETS” in open-next.config.ts
wrangler.jsonc (claim-db-worker/wrangler.jsonc lines 17–20) declares"assets": { "binding": "ASSETS", "directory": ".open-next/assets" }
but open-next.config.ts has no matching staticAssets section and no
.open-next/assets
directory exists pre-build. Confirm your build emits.open-next/assets
and update open-next.config.ts with:export default defineCloudflareConfig({ staticAssets: { binding: "ASSETS", directory: ".open-next/assets", }, // … })claim-db-worker/.gitignore (1)
45-50
: Env patterns are correct and protect secrets while keeping examples tracked.Good use of negations for
.dev.vars.example
and.env.example
.README.md (2)
10-12
: Unify the Web Interface URL (/web
vs root).Docs mix create-db.prisma.io and create-db.prisma.io/web. Choose one canonical path and use it consistently.
Apply this diff if
/web
is the intended entry:-2. **Web Interface** - Browser-based database creation at create-db.prisma.io +2. **Web Interface** - Browser-based database creation at create-db.prisma.io/web-Visit [create-db.prisma.io/web](https://create-db.prisma.io/web) to create databases directly in your browser. No installation required - just click "Create Database Online" to get started. +Visit [create-db.prisma.io/web](https://create-db.prisma.io/web) to create databases directly in your browser. No installation required—click "Create Database Online" to get started.Also applies to: 151-154
214-223
: Dev command likely needs Next.jsdev
now.Given the Next.js migration, running the app with
wrangler dev
may not reflect local Next features. Preferpnpm dev
(ornext dev
) inclaim-db-worker/
, with OpenNext used for builds/deploys.Apply this diff if accurate:
-# Start Claim DB Worker (in another terminal) -cd claim-db-worker -npx wrangler dev --port 9999 +# Start Claim DB Web App (in another terminal) +cd claim-db-worker +pnpm devclaim-db-worker/worker-configuration.d.ts (1)
430-436
: No action needed—no idFromName/getByName call sites detected
No invocations of idFromName or getByName were found in implementation files, so introducing getByName has no downstream impact.claim-db-worker/app/test/error/page.tsx (1)
1-3
: LGTM: simple re-exportRe-export pattern is fine.
claim-db-worker/app/test/claim/page.tsx (1)
1-3
: LGTM: simple re-exportMatches the pattern used elsewhere.
claim-db-worker/open-next.config.ts (1)
1-9
: Enable R2 incremental cache and verify R2 binding
- In claim-db-worker/open-next.config.ts, add
+import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache"; export default defineCloudflareConfig({ - // incrementalCache: r2IncrementalCache, + incrementalCache: r2IncrementalCache, });- Ensure your Cloudflare Worker configuration (e.g. wrangler.toml or dashboard settings) defines the R2 bucket binding required by OpenNext; no wrangler.toml was found in the repo—please verify manually.
claim-db-worker/app/web/studio/page.tsx (1)
6-6
: Remove unnecessary await on cookies().cookies() is synchronous in App Router server components. The await can cause type friction.
- const cookieStore = await cookies(); + const cookieStore = cookies();claim-db-worker/components/prismaSchemaEditor/InitOverlay.tsx (1)
7-7
: Confirm intention of pointer-events-none on the overlay.As written, clicks pass through to underlying UI while “Loading…”. This can trigger actions before initialization.
Would you prefer the overlay to block interaction? If yes, drop pointer-events-none (or add an inert wrapper).
claim-db-worker/next.config.ts (1)
3-15
: serverExternalPackages key and TS config are compatible
serverExternalPackages is the stable option since v15.0.0 (renamed from experimental.serverComponentsExternalPackages) (nextjs.org) and using next.config.ts is natively supported in v15.4.6 (nextjs.org).schema-api-routes/src/index.ts (1)
42-51
: Routes wiring looks good.Mount points and default handler are clear and consistent.
claim-db-worker/app/api/get-connection-string/route.ts (1)
1-19
: Verify Cloudflare Worker env binding and Node.js compatibility
EnsureINTEGRATION_TOKEN
is defined as a secret or environment variable in your Cloudflare Worker (via the Dashboard orwrangler.toml
) and that Node.js compatibility (nodejs_compat
flag orcompatibility_date
) is enabled, soprocess.env.INTEGRATION_TOKEN
is populated at runtime.claim-db-worker/app/success/page.tsx (1)
12-74
: LGTM: polished success UI and safe external link.Looks good; clean UX and correct noopener usage.
claim-db-worker/lib/prismaSchemaEditor/editorOptions.ts (1)
72-75
: Remove unsupported inlineSuggest.showToolbar (not in Monaco API).Inline suggestions don’t expose showToolbar in Monaco. Keep enabled flag only.
inlineSuggest: { - enabled: false, - showToolbar: "never", + enabled: false, },Likely an incorrect or invalid review comment.
claim-db-worker/app/api/create-db/route.ts (1)
25-39
: Add basic rate limiting and CSRF origin check to protect the create endpoint.This endpoint can be abused from third-party sites via a user’s browser. Mirror the pattern used in /api/claim and validate same-origin.
[Suggest_essential_refactor]export async function POST(request: NextRequest) { try { + const env = getEnv(); + // Rate limiting + const rate = await env.CLAIM_DB_RATE_LIMITER.limit({ key: request.url }); + if (!rate.success) { + return NextResponse.json({ error: "Rate limit exceeded" }, { status: 429 }); + } + + // CSRF guard (same-origin) + const origin = request.headers.get("origin"); + const host = request.nextUrl.origin; + if (!origin || origin !== host) { + return NextResponse.json({ error: "Invalid origin" }, { status: 403 }); + }claim-db-worker/lib/env.ts (1)
1-9
: Verify environment bindings for new variables
Novariables.json
found in the repo; confirm thatCREATE_DB_WORKER_URL
,CLAIM_DB_RATE_LIMITER
, andCREATE_DB_DATASET
are provisioned in your deployment config (wrangler, OpenNext variables.json or equivalent).claim-db-worker/app/web/connect/page.tsx (1)
3-3
: Validate icon import name.Confirm that lucide-react exports EyeClosed; if not, use EyeOff.
claim-db-worker/lib/auth-utils.ts (1)
13-23
: No exposed credential logsSearch confirms there are no logging statements or middleware emitting
client_secret
or the request body; credentials remain unlogged.claim-db-worker/lib/prismaSchemaEditor/monacoConfig.ts (1)
3-53
: Nice language + theme setup.Registration and Monarch tokenizer look solid; theme is coherent and readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
// 1. Check if request has content | ||
const contentType = request.headers.get("content-type"); | ||
if (!contentType || !contentType.includes("application/json")) { | ||
return NextResponse.json([ | ||
serializeError(new Error("Content-Type must be application/json")), | ||
]); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Add a simple same-origin guard to reduce CSRF risk
Since this endpoint mutates server state by making privileged server-to-server calls, block cross-site POSTs.
try {
// 1. Check if request has content
const contentType = request.headers.get("content-type");
if (!contentType || !contentType.includes("application/json")) {
- return NextResponse.json([
- serializeError(new Error("Content-Type must be application/json")),
- ]);
+ return NextResponse.json(
+ [serializeError(new Error("Content-Type must be application/json"))],
+ { status: 415 }
+ );
}
+
+ // 1a. Same-origin check (best-effort)
+ const origin = request.headers.get("origin");
+ const selfOrigin = new URL(request.url).origin;
+ if (origin && origin !== selfOrigin) {
+ return NextResponse.json([serializeError(new Error("Cross-site POSTs are not allowed"))], { status: 403 });
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// 1. Check if request has content | |
const contentType = request.headers.get("content-type"); | |
if (!contentType || !contentType.includes("application/json")) { | |
return NextResponse.json([ | |
serializeError(new Error("Content-Type must be application/json")), | |
]); | |
} | |
// 1. Check if request has content | |
const contentType = request.headers.get("content-type"); | |
if (!contentType || !contentType.includes("application/json")) { | |
return NextResponse.json( | |
[serializeError(new Error("Content-Type must be application/json"))], | |
{ status: 415 } | |
); | |
} | |
// 1a. Same-origin check (best-effort) | |
const origin = request.headers.get("origin"); | |
const selfOrigin = new URL(request.url).origin; | |
if (origin && origin !== selfOrigin) { | |
return NextResponse.json( | |
[serializeError(new Error("Cross-site POSTs are not allowed"))], | |
{ status: 403 } | |
); | |
} |
🤖 Prompt for AI Agents
In claim-db-worker/app/api/studio/route.ts around lines 7 to 14, add a
same-origin guard to block cross-site POSTs: read the request's "origin"
(fallback to "referer" if needed), compare it to the server's expected origin
(derive from request.headers.get("host") plus "https://" or use a configured
APP_HOST/VERCEL_URL env var), and if it does not match return a 403
NextResponse.json with a serialized Error; keep this check before any
privileged/mutating work so only same-origin requests are allowed.
type StringifyValues<EnvType extends Record<string, unknown>> = { | ||
[Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string; | ||
}; | ||
declare namespace NodeJS { | ||
interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, "INTEGRATION_TOKEN" | "CLIENT_SECRET" | "NEXT_PUBLIC_CLIENT_ID" | "CLIENT_ID" | "POSTHOG_PROXY_HOST" | "POSTHOG_API_KEY">> {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
ProcessEnv typing is too strict and may be clobbered on regen
- Current mapping forces values to string (not string | undefined) and makes keys required. That’s unsafe for Node (envs can be absent).
- These edits live in a generated file; the next wrangler types run will likely wipe them.
Action:
- Make mapped keys optional and allow undefined.
- Move the ProcessEnv augmentation into a non-generated d.ts (e.g., claim-db-worker/types/node-process-env.d.ts) and delete it from this file.
Minimal safer typing if you keep it here:
-type StringifyValues<EnvType extends Record<string, unknown>> = {
- [Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string;
-};
+type NodeEnvFromBindings<EnvType extends Record<string, unknown>> = {
+ [Binding in keyof EnvType]?: string | undefined;
+};
declare namespace NodeJS {
- interface ProcessEnv extends StringifyValues<Pick<Cloudflare.Env, "INTEGRATION_TOKEN" | "CLIENT_SECRET" | "NEXT_PUBLIC_CLIENT_ID" | "CLIENT_ID" | "POSTHOG_PROXY_HOST" | "POSTHOG_API_KEY">> {}
+ interface ProcessEnv extends NodeEnvFromBindings<Pick<Cloudflare.Env, "INTEGRATION_TOKEN" | "CLIENT_SECRET" | "NEXT_PUBLIC_CLIENT_ID" | "CLIENT_ID" | "POSTHOG_PROXY_HOST" | "POSTHOG_API_KEY">> {}
}
And preferred: new file claim-db-worker/types/node-process-env.d.ts:
declare namespace NodeJS {
interface ProcessEnv {
INTEGRATION_TOKEN?: string;
CLIENT_SECRET?: string;
CLIENT_ID?: string;
NEXT_PUBLIC_CLIENT_ID?: string;
POSTHOG_PROXY_HOST?: string;
POSTHOG_API_KEY?: string;
}
}
🤖 Prompt for AI Agents
In claim-db-worker/worker-configuration.d.ts around lines 18 to 23, the
ProcessEnv augmentation currently forces all mapped env keys to string and
required, which is unsafe and will be overwritten by generated types; update by
removing the augmentation from this generated file and instead create a new
dedicated file claim-db-worker/types/node-process-env.d.ts that declares
NodeJS.ProcessEnv with the listed keys as optional string|undefined (i.e., KEY?:
string), or if keeping in this file change the mapped type to make properties
optional and allow undefined (e.g., add ? and | undefined), then delete the
augmentation from the generated file so wrangler regen won’t clobber it.
/** | ||
* A message received by a target object. | ||
* | ||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent) | ||
*/ | ||
declare class MessageEvent extends Event { | ||
constructor(type: string, initializer: MessageEventInit); | ||
/** | ||
* Returns the data of the message. | ||
* | ||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/data) | ||
*/ | ||
readonly data: any; | ||
/** | ||
* Returns the origin of the message, for server-sent events and cross-document messaging. | ||
* | ||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/origin) | ||
*/ | ||
readonly origin: string | null; | ||
/** | ||
* Returns the last event ID string, for server-sent events. | ||
* | ||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/lastEventId) | ||
*/ | ||
readonly lastEventId: string; | ||
/** | ||
* Returns the WindowProxy of the source window, for cross-document messaging, and the MessagePort being attached, in the connect event fired at SharedWorkerGlobalScope objects. | ||
* | ||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/source) | ||
*/ | ||
readonly source: MessagePort | null; | ||
/** | ||
* Returns the MessagePort array sent with the message, for cross-document messaging and channel messaging. | ||
* | ||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/ports) | ||
*/ | ||
readonly ports: MessagePort[]; | ||
} | ||
interface MessageEventInit { | ||
data: ArrayBuffer | string; | ||
} | ||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
MessageEventInit.data is too narrow; align with web API to avoid type errors
Project code may post objects over MessagePort; typing data: ArrayBuffer | string will reject valid cases.
Widen and make fields optional:
-interface MessageEventInit {
- data: ArrayBuffer | string;
-}
+interface MessageEventInit {
+ data?: any;
+ origin?: string;
+ lastEventId?: string;
+ source?: MessagePort | null;
+ ports?: MessagePort[];
+}
Please confirm no code relies on the narrower type; otherwise TS errors will surface when posting non-string/ArrayBuffer payloads.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the worker-configuration.d.ts file
echo "Declaration file location:"
fd --full-path 'worker-configuration.d.ts' -t f
# Search for any type annotations or interfaces using MessageEventInit
echo "Usages of MessageEventInit in the codebase:"
rg -n 'MessageEventInit' -g '!(node_modules|dist)/**' || true
# Search for direct instantiations of MessageEvent
echo "Instantiations of MessageEvent:"
rg -n 'new MessageEvent' -g '!(node_modules|dist)/**' || true
# Search for postMessage calls (to see payload types being sent)
echo "postMessage calls and their arguments:"
rg -n 'postMessage' -g '!(node_modules|dist)/**' || true
Length of output: 1713
Align MessageEventInit with Web API spec across all declaration files
- Widen
data
toany
and add optionalorigin
,lastEventId
,source
,ports
properties to match the standard spec. - Apply this change in both
worker-configuration.d.ts
andcloudflare-env.d.ts
underclaim-db-worker
andcreate-db-worker
. - No
new MessageEvent(...)
usages found—this refactor is safe.
🤖 Prompt for AI Agents
In claim-db-worker/worker-configuration.d.ts around lines 1119 to 1160 the
MessageEventInit type is too narrow (data: ArrayBuffer | string) and missing
optional origin, lastEventId, source, and ports fields; update
MessageEventInit.data to type any and add optional properties origin?: string |
null, lastEventId?: string, source?: MessagePort | null, and ports?:
MessagePort[] to match the Web API spec, and mirror the same change in
cloudflare-env.d.ts under both claim-db-worker and create-db-worker to keep
declarations consistent across the project.
#### `claim-db-worker` (Cloudflare Worker) | ||
|
||
- **Purpose**: Handles OAuth-based database ownership transfer | ||
- **Purpose**: Handles OAuth-based database ownership transfer and serves the web interface | ||
- **Features**: | ||
- Prisma OAuth authentication | ||
- Rate limiting (100 requests/minute) | ||
- Secure project transfer | ||
- User-friendly HTML interfaces | ||
- Analytics tracking | ||
- Web application hosting | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Reflect Next.js/OpenNext migration in service naming.
This still frames claim-db-worker
as a plain Worker. Update to “Next.js app via OpenNext on Cloudflare Workers” and adjust feature wording.
Apply this diff:
-#### `claim-db-worker` (Cloudflare Worker)
+#### `claim-db-worker` (Next.js app via OpenNext on Cloudflare Workers)
@@
-- **Purpose**: Handles OAuth-based database ownership transfer and serves the web interface
+- **Purpose**: Handles OAuth-based database ownership transfer and serves the Next.js web interface
@@
- - User-friendly HTML interfaces
+ - Next.js web UI (App Router)
- Analytics tracking
- - Web application hosting
+ - Web application hosting via OpenNext
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
#### `claim-db-worker` (Cloudflare Worker) | |
- **Purpose**: Handles OAuth-based database ownership transfer | |
- **Purpose**: Handles OAuth-based database ownership transfer and serves the web interface | |
- **Features**: | |
- Prisma OAuth authentication | |
- Rate limiting (100 requests/minute) | |
- Secure project transfer | |
- User-friendly HTML interfaces | |
- Analytics tracking | |
- Web application hosting | |
#### `claim-db-worker` (Next.js app via OpenNext on Cloudflare Workers) | |
- **Purpose**: Handles OAuth-based database ownership transfer and serves the Next.js web interface | |
- **Features**: | |
- Prisma OAuth authentication | |
- Rate limiting (100 requests/minute) | |
- Secure project transfer | |
- Next.js web UI (App Router) | |
- Analytics tracking | |
- Web application hosting via OpenNext |
🧰 Tools
🪛 LanguageTool
[grammar] ~116-~116: Use correct spacing
Context: ...## claim-db-worker
(Cloudflare Worker) - Purpose: Handles OAuth-based database ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~118-~118: There might be a mistake here.
Context: ...ip transfer and serves the web interface - Features: - Prisma OAuth authenticat...
(QB_NEW_EN_OTHER)
[grammar] ~119-~119: There might be a mistake here.
Context: ...serves the web interface - Features: - Prisma OAuth authentication - Rate lim...
(QB_NEW_EN)
[grammar] ~120-~120: There might be a mistake here.
Context: ...tures**: - Prisma OAuth authentication - Rate limiting (100 requests/minute) - ...
(QB_NEW_EN)
[grammar] ~121-~121: There might be a mistake here.
Context: ... - Rate limiting (100 requests/minute) - Secure project transfer - User-friendl...
(QB_NEW_EN)
[grammar] ~122-~122: There might be a mistake here.
Context: ...ests/minute) - Secure project transfer - User-friendly HTML interfaces - Analyt...
(QB_NEW_EN)
[grammar] ~123-~123: There might be a mistake here.
Context: ...ansfer - User-friendly HTML interfaces - Analytics tracking - Web application h...
(QB_NEW_EN)
[grammar] ~124-~124: There might be a mistake here.
Context: ...y HTML interfaces - Analytics tracking - Web application hosting **API Endpoints...
(QB_NEW_EN)
[grammar] ~125-~125: Use correct spacing
Context: ...ics tracking - Web application hosting API Endpoints: - `GET /claim?projectI...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🤖 Prompt for AI Agents
In README.md around lines 116 to 126, the service description still calls the
component "claim-db-worker (Cloudflare Worker)"; update it to reflect the
Next.js/OpenNext migration by renaming to "claim-db — Next.js app via OpenNext
on Cloudflare Workers" and reword the features list to mention Next.js/OpenNext
hosting, server-side rendering (via OpenNext), Prisma OAuth authentication, rate
limiting (100 requests/minute), secure project transfer, user-friendly HTML
interfaces, analytics tracking, and web application hosting; ensure phrasing
emphasizes OpenNext handling Next.js runtime on Cloudflare Workers rather than a
plain Worker.
"https://claim-db-worker-staging.raycast-0ef.workers.dev", | ||
/^https:\/\/claim-db-worker.*\.vercel\.app$/, | ||
/^https:\/\/create-db-schema-api-routes(-\w+)?\.vercel\.app$/, | ||
/^https:\/\/.*-claim-db-worker\.datacdn\.workers\.dev/, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anchor the datacdn CORS regex to prevent prefix-match bypass.
Without a trailing $, any origin starting with the allowed host (e.g., https://foo-claim-db-worker.datacdn.workers.dev.evil.com) will match. Anchor it.
- /^https:\/\/.*-claim-db-worker\.datacdn\.workers\.dev/,
+ /^https:\/\/.*-claim-db-worker\.datacdn\.workers\.dev$/,
🤖 Prompt for AI Agents
In schema-api-routes/src/index.ts around line 19 the CORS regex
/^https:\/\/.*-claim-db-worker\.datacdn\.workers\.dev/ is not anchored at the
end, allowing origins like
https://foo-claim-db-worker.datacdn.workers.dev.evil.com to match; fix it by
adding an end anchor so the pattern becomes anchored at both ends (e.g., append
$) to ensure only the exact host form is accepted.
origin: (origin) => { | ||
if (!origin) return "*"; | ||
const isAllowed = allowedOrigins.some((allowedOrigin) => { | ||
if (typeof allowedOrigin === "string") { | ||
return origin === allowedOrigin; | ||
} | ||
return allowedOrigin.test(origin); | ||
}); | ||
return isAllowed ? origin : null; | ||
}, | ||
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], | ||
allowHeaders: ["Content-Type", "X-Connection-String"], | ||
credentials: true, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Harden CORS: avoid "*", normalize/validate origin, add Authorization header, and cache preflights.
Returning "*" with credentials=true is invalid; normalize via URL, block invalid origins, and allow Authorization for typical API calls. Add maxAge for preflight performance.
- origin: (origin) => {
- if (!origin) return "*";
- const isAllowed = allowedOrigins.some((allowedOrigin) => {
- if (typeof allowedOrigin === "string") {
- return origin === allowedOrigin;
- }
- return allowedOrigin.test(origin);
- });
- return isAllowed ? origin : null;
- },
- allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
- allowHeaders: ["Content-Type", "X-Connection-String"],
- credentials: true,
+ origin: (origin) => {
+ if (!origin) return null;
+ try {
+ const normalized = new URL(origin).origin;
+ const isAllowed = allowedOrigins.some((allowed) =>
+ typeof allowed === "string" ? normalized === allowed : allowed.test(normalized)
+ );
+ return isAllowed ? normalized : null;
+ } catch {
+ return null;
+ }
+ },
+ allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
+ allowHeaders: ["Content-Type", "X-Connection-String", "Authorization"],
+ credentials: true,
+ maxAge: 86400,
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
origin: (origin) => { | |
if (!origin) return "*"; | |
const isAllowed = allowedOrigins.some((allowedOrigin) => { | |
if (typeof allowedOrigin === "string") { | |
return origin === allowedOrigin; | |
} | |
return allowedOrigin.test(origin); | |
}); | |
return isAllowed ? origin : null; | |
}, | |
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], | |
allowHeaders: ["Content-Type", "X-Connection-String"], | |
credentials: true, | |
}) | |
origin: (origin) => { | |
if (!origin) return null; | |
try { | |
const normalized = new URL(origin).origin; | |
const isAllowed = allowedOrigins.some((allowed) => | |
typeof allowed === "string" ? normalized === allowed : allowed.test(normalized) | |
); | |
return isAllowed ? normalized : null; | |
} catch { | |
return null; | |
} | |
}, | |
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], | |
allowHeaders: ["Content-Type", "X-Connection-String", "Authorization"], | |
credentials: true, | |
maxAge: 86400, |
🤖 Prompt for AI Agents
In schema-api-routes/src/index.ts around lines 26 to 39, the CORS config
currently returns "*" when origin is falsy (which is invalid with
credentials=true), does not normalize/validate origins, omits Authorization in
allowed headers, and lacks preflight caching; update the origin handler to never
return "*" — parse and normalize the origin using the URL constructor inside a
try/catch, reject invalid or malformed origins (return null), compare the
normalized origin against allowedOrigins (support both strings and regex) and
only return the actual origin when matched (ensuring credentials can be used
safely), add "Authorization" to allowHeaders, and set a sensible maxAge (e.g.,
600 seconds) on preflight responses to cache OPTIONS responses for better
performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
export async function POST(request: NextRequest) { | ||
try { | ||
const { projectId } = (await request.json()) as { projectId: string }; | ||
const response = await fetch( | ||
`https://api.prisma.io/v1/projects/${projectId}`, | ||
{ | ||
method: "GET", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: `Bearer ${process.env.INTEGRATION_TOKEN}`, | ||
}, | ||
} | ||
); | ||
|
||
if (!response.ok) { | ||
return NextResponse.json({ error: true }); | ||
} | ||
|
||
return NextResponse.json({ error: false }); | ||
} catch (error) { | ||
console.error("Error checking database status:", error); | ||
return NextResponse.json({ error: true }); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Validate input, use getEnv, encode path, add timeout; drop Content-Type on GET.
Prevents malformed projectId, avoids path issues, and adds resiliency on slow upstreams.
-import { NextRequest, NextResponse } from "next/server";
+import { NextRequest, NextResponse } from "next/server";
+import { getEnv } from "@/lib/env";
export async function POST(request: NextRequest) {
try {
- const { projectId } = (await request.json()) as { projectId: string };
- const response = await fetch(
- `https://api.prisma.io/v1/projects/${projectId}`,
- {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Authorization: `Bearer ${process.env.INTEGRATION_TOKEN}`,
- },
- }
- );
+ const body = (await request.json()) as unknown;
+ const projectId =
+ typeof (body as any)?.projectId === "string" ? (body as any).projectId.trim() : "";
+ if (!projectId) {
+ return NextResponse.json({ error: true, reason: "INVALID_INPUT" });
+ }
+ const { INTEGRATION_TOKEN } = getEnv();
+ if (!INTEGRATION_TOKEN) {
+ return NextResponse.json({ error: true, reason: "MISSING_TOKEN" });
+ }
+ const controller = new AbortController();
+ const timeout = setTimeout(() => controller.abort(), 10_000);
+ const response = await fetch(
+ `https://api.prisma.io/v1/projects/${encodeURIComponent(projectId)}`,
+ {
+ method: "GET",
+ headers: {
+ Accept: "application/json",
+ Authorization: `Bearer ${INTEGRATION_TOKEN}`,
+ },
+ signal: controller.signal,
+ }
+ ).finally(() => clearTimeout(timeout));
if (!response.ok) {
- return NextResponse.json({ error: true });
+ return NextResponse.json({ error: true, upstreamStatus: response.status });
}
return NextResponse.json({ error: false });
} catch (error) {
console.error("Error checking database status:", error);
- return NextResponse.json({ error: true });
+ return NextResponse.json({ error: true, reason: "NETWORK_ERROR" });
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export async function POST(request: NextRequest) { | |
try { | |
const { projectId } = (await request.json()) as { projectId: string }; | |
const response = await fetch( | |
`https://api.prisma.io/v1/projects/${projectId}`, | |
{ | |
method: "GET", | |
headers: { | |
"Content-Type": "application/json", | |
Authorization: `Bearer ${process.env.INTEGRATION_TOKEN}`, | |
}, | |
} | |
); | |
if (!response.ok) { | |
return NextResponse.json({ error: true }); | |
} | |
return NextResponse.json({ error: false }); | |
} catch (error) { | |
console.error("Error checking database status:", error); | |
return NextResponse.json({ error: true }); | |
} | |
} | |
import { NextRequest, NextResponse } from "next/server"; | |
import { getEnv } from "@/lib/env"; | |
export async function POST(request: NextRequest) { | |
try { | |
const body = (await request.json()) as unknown; | |
const projectId = | |
typeof (body as any)?.projectId === "string" | |
? (body as any).projectId.trim() | |
: ""; | |
if (!projectId) { | |
return NextResponse.json({ error: true, reason: "INVALID_INPUT" }); | |
} | |
const { INTEGRATION_TOKEN } = getEnv(); | |
if (!INTEGRATION_TOKEN) { | |
return NextResponse.json({ error: true, reason: "MISSING_TOKEN" }); | |
} | |
const controller = new AbortController(); | |
const timeout = setTimeout(() => controller.abort(), 10_000); | |
const response = await fetch( | |
`https://api.prisma.io/v1/projects/${encodeURIComponent(projectId)}`, | |
{ | |
method: "GET", | |
headers: { | |
Accept: "application/json", | |
Authorization: `Bearer ${INTEGRATION_TOKEN}`, | |
}, | |
signal: controller.signal, | |
} | |
).finally(() => clearTimeout(timeout)); | |
if (!response.ok) { | |
return NextResponse.json({ error: true, upstreamStatus: response.status }); | |
} | |
return NextResponse.json({ error: false }); | |
} catch (error) { | |
console.error("Error checking database status:", error); | |
return NextResponse.json({ error: true, reason: "NETWORK_ERROR" }); | |
} | |
} |
🤖 Prompt for AI Agents
In claim-db-worker/app/api/check-db-status/route.ts around lines 3 to 26,
validate the incoming projectId (ensure it's a non-empty string and matches
expected pattern), read the integration token via your getEnv helper (not
process.env), encode the projectId in the URL with encodeURIComponent to avoid
path injection, remove the unnecessary Content-Type header for a GET, and add a
fetch timeout using AbortController (abort after a sensible interval and handle
the abort error path); return NextResponse.json({ error: true }) on validation
failure or timeout and include proper try/catch around the fetch.
async function sendPosthogEvent( | ||
event: string, | ||
properties: Record<string, any> | ||
) { | ||
const POSTHOG_API_KEY = env.POSTHOG_API_KEY; | ||
const POSTHOG_PROXY_HOST = env.POSTHOG_API_HOST; | ||
|
||
await fetch(`${POSTHOG_PROXY_HOST}/e`, { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
Authorization: `Bearer ${POSTHOG_API_KEY}`, | ||
}, | ||
body: JSON.stringify({ | ||
api_key: POSTHOG_API_KEY, | ||
event, | ||
properties, | ||
distinct_id: "web-claim", | ||
}), | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Deduplicate analytics logic: reuse lib/analytics.sendPosthogEvent and guard missing config.
Local helper lacks config checks and will throw if POSTHOG vars are unset. Use the shared function which no-ops when not configured.
-import { getEnv } from "@/lib/env";
+import { getEnv } from "@/lib/env";
+import { sendPosthogEvent } from "@/lib/analytics";
...
- async function sendPosthogEvent(
- event: string,
- properties: Record<string, any>
- ) {
- const POSTHOG_API_KEY = env.POSTHOG_API_KEY;
- const POSTHOG_PROXY_HOST = env.POSTHOG_API_HOST;
-
- await fetch(`${POSTHOG_PROXY_HOST}/e`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Authorization: `Bearer ${POSTHOG_API_KEY}`,
- },
- body: JSON.stringify({
- api_key: POSTHOG_API_KEY,
- event,
- properties,
- distinct_id: "web-claim",
- }),
- });
- }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
async function sendPosthogEvent( | |
event: string, | |
properties: Record<string, any> | |
) { | |
const POSTHOG_API_KEY = env.POSTHOG_API_KEY; | |
const POSTHOG_PROXY_HOST = env.POSTHOG_API_HOST; | |
await fetch(`${POSTHOG_PROXY_HOST}/e`, { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
Authorization: `Bearer ${POSTHOG_API_KEY}`, | |
}, | |
body: JSON.stringify({ | |
api_key: POSTHOG_API_KEY, | |
event, | |
properties, | |
distinct_id: "web-claim", | |
}), | |
}); | |
} | |
// at the top of claim-db-worker/app/api/claim/route.ts | |
import { getEnv } from "@/lib/env"; | |
import { sendPosthogEvent } from "@/lib/analytics"; | |
// …rest of your code… | |
// (Remove the local sendPosthogEvent function entirely; calls below will now use | |
// the shared sendPosthogEvent, which no-ops when configuration is missing.) |
🤖 Prompt for AI Agents
In claim-db-worker/app/api/claim/route.ts around lines 15 to 35, a local
sendPosthogEvent helper duplicates analytics logic and doesn't guard against
missing POSTHOG config which will throw; replace this local helper with the
shared lib/analytics.sendPosthogEvent, import that function at the top of the
file, remove the local helper code, and call the shared function where used; the
shared implementation already no-ops when env vars are unset so this avoids
runtime errors and centralizes analytics behavior.
await sendPosthogEvent("create_db:claim_page_viewed", { | ||
"project-id": projectID, | ||
"utm-source": searchParams.get("utm_source") || "unknown", | ||
"utm-medium": searchParams.get("utm_medium") || "unknown", | ||
}); | ||
|
||
return NextResponse.json({ success: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Don’t fail the request if analytics sends error; wrap and ignore.
Analytics should be best-effort.
- await sendPosthogEvent("create_db:claim_page_viewed", {
+ try {
+ await sendPosthogEvent("create_db:claim_page_viewed", {
"project-id": projectID,
"utm-source": searchParams.get("utm_source") || "unknown",
"utm-medium": searchParams.get("utm_medium") || "unknown",
- });
+ });
+ } catch {
+ // ignore
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
await sendPosthogEvent("create_db:claim_page_viewed", { | |
"project-id": projectID, | |
"utm-source": searchParams.get("utm_source") || "unknown", | |
"utm-medium": searchParams.get("utm_medium") || "unknown", | |
}); | |
return NextResponse.json({ success: true }); | |
try { | |
await sendPosthogEvent("create_db:claim_page_viewed", { | |
"project-id": projectID, | |
"utm-source": searchParams.get("utm_source") || "unknown", | |
"utm-medium": searchParams.get("utm_medium") || "unknown", | |
}); | |
} catch { | |
// ignore | |
} | |
return NextResponse.json({ success: true }); |
🤖 Prompt for AI Agents
In claim-db-worker/app/api/claim/route.ts around lines 43 to 49, the call to
sendPosthogEvent is currently allowed to propagate errors and can cause the
whole request to fail; make analytics best-effort by wrapping the
sendPosthogEvent invocation in a try/catch, log or capture the error (without
throwing) inside the catch, and always proceed to return NextResponse.json({
success: true }) so a PostHog failure does not fail the request.
const CREATE_DB_WORKER_URL = | ||
process.env.CREATE_DB_WORKER_URL || "https://create-db-temp.prisma.io"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Do not use process.env directly on Cloudflare; wire through getEnv (and add CREATE_DB_WORKER_URL to Env).
process.env is undefined on Workers. This will break at runtime under OpenNext on Cloudflare.
-import { NextRequest, NextResponse } from "next/server";
+import { NextRequest, NextResponse } from "next/server";
+import { getEnv } from "@/lib/env";
...
-const CREATE_DB_WORKER_URL =
- process.env.CREATE_DB_WORKER_URL || "https://create-db-temp.prisma.io";
+const { CREATE_DB_WORKER_URL } = getEnv();
Note: Add CREATE_DB_WORKER_URL to lib/env.ts (see comment in that file).
🤖 Prompt for AI Agents
In claim-db-worker/app/api/create-db/route.ts around lines 22 to 24, the code
reads process.env.CREATE_DB_WORKER_URL which fails on Cloudflare Workers;
replace direct process.env access with the project's environment accessor by
importing and using getEnv (or Env) to retrieve CREATE_DB_WORKER_URL, and add
CREATE_DB_WORKER_URL to lib/env.ts (and the Env type) so it is wired correctly
for OpenNext on Cloudflare; ensure a sensible default or required-check remains
in place after switching to getEnv.
const prismaResponse = await fetch(`${CREATE_DB_WORKER_URL}/create`, { | ||
method: "POST", | ||
headers: { "Content-Type": "application/json" }, | ||
body: JSON.stringify({ | ||
region, | ||
name, | ||
utm_source: "drop", | ||
}), | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Harden upstream call: timeout, no-store, and pass-through analytics.
Avoid hanging requests and explicitly disable caching. Also accept region/name from client when provided.
- const prismaResponse = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
+ const controller = new AbortController();
+ const timeout = setTimeout(() => controller.abort(), 10000);
+
+ // Allow overrides from client body (optional)
+ const body = await request.json().catch(() => ({}));
+ const reqRegion = body?.region ?? region;
+ const reqName = body?.name ?? name;
+
+ const prismaResponse = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
method: "POST",
- headers: { "Content-Type": "application/json" },
+ headers: { "Content-Type": "application/json" },
+ cache: "no-store",
+ signal: controller.signal,
body: JSON.stringify({
- region,
- name,
+ region: reqRegion,
+ name: reqName,
utm_source: "drop",
}),
});
+ clearTimeout(timeout);
Committable suggestion skipped: line range outside the PR's diff.
const envPath = `${tempDir}/.env-${Date.now()}`; | ||
|
||
try { | ||
await writeFile(schemaPath, schema); | ||
await writeFile(envPath, `DATABASE_URL="${connectionString}"`); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Drop the .env temp file; it’s never read.
You set DATABASE_URL via env, and cwd isn’t /tmp, so Prisma won’t load this file. Writing + unlinking it is unnecessary I/O.
- const envPath = `${tempDir}/.env-${Date.now()}`;
@@
- await writeFile(envPath, `DATABASE_URL="${connectionString}"`);
@@
- await unlink(envPath);
+ // no .env file created
Also applies to: 75-77
try { | ||
const result = execSync( | ||
`npx prisma db push --schema=${schemaPath} --accept-data-loss`, | ||
{ | ||
env: { | ||
...process.env, | ||
DATABASE_URL: connectionString, | ||
npm_config_cache: "/tmp/.npm", | ||
npm_config_prefix: "/tmp/.npm", | ||
}, | ||
cwd: process.cwd(), | ||
encoding: "utf8", | ||
stdio: "pipe", | ||
} | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid shell, add timeouts, and cap buffers when invoking CLI.
execSync with a shell blocks the event loop and is brittle for error parsing. Prefer execFileSync (no shell) or async execFile with timeout and maxBuffer.
Proposed minimal safer sync call:
- const result = execSync(
- `npx prisma db push --schema=${schemaPath}`,
- {
- env: {
- ...process.env,
- DATABASE_URL: connectionString,
- npm_config_cache: "/tmp/.npm",
- npm_config_prefix: "/tmp/.npm",
- },
- cwd: process.cwd(),
- encoding: "utf8",
- stdio: "pipe",
- }
- );
+ const { execFileSync } = await import("child_process");
+ const result = execFileSync(
+ "npx",
+ ["prisma", "db", "push", `--schema=${schemaPath}`],
+ {
+ env: {
+ ...process.env,
+ DATABASE_URL: connectionString,
+ npm_config_cache: "/tmp/.npm",
+ npm_config_prefix: "/tmp/.npm",
+ },
+ cwd: process.cwd(),
+ encoding: "utf8",
+ stdio: "pipe",
+ timeout: 120_000,
+ maxBuffer: 10 * 1024 * 1024,
+ }
+ );
Committable suggestion skipped: line range outside the PR's diff.
const result = execSync( | ||
`npx prisma db push --schema=${schemaPath} --accept-data-loss`, | ||
{ | ||
env: { | ||
...process.env, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not pass --accept-data-loss on the non-force push path.
This bypasses the very safety gate you’re implementing (requiresForceReset). It’ll silently apply destructive changes instead of surfacing the warning.
Apply this diff:
- const result = execSync(
- `npx prisma db push --schema=${schemaPath} --accept-data-loss`,
+ const result = execSync(
+ `npx prisma db push --schema=${schemaPath}`,
{
env: {
...process.env,
DATABASE_URL: connectionString,
npm_config_cache: "/tmp/.npm",
npm_config_prefix: "/tmp/.npm",
},
cwd: process.cwd(),
encoding: "utf8",
stdio: "pipe",
}
);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const result = execSync( | |
`npx prisma db push --schema=${schemaPath} --accept-data-loss`, | |
{ | |
env: { | |
...process.env, | |
const result = execSync( | |
`npx prisma db push --schema=${schemaPath}`, | |
{ | |
env: { | |
...process.env, | |
DATABASE_URL: connectionString, | |
npm_config_cache: "/tmp/.npm", | |
npm_config_prefix: "/tmp/.npm", | |
}, | |
cwd: process.cwd(), | |
encoding: "utf8", | |
stdio: "pipe", | |
} | |
); |
🤖 Prompt for AI Agents
In schema-api-routes/src/routes/schema/push.ts around lines 37 to 41, the
current execSync call always includes the --accept-data-loss flag which bypasses
the requiresForceReset safety gate; change the command construction so
--accept-data-loss is only appended when the force path is taken (i.e., when
requiresForceReset/force flag is true), and for the non-force path call npx
prisma db push --schema=${schemaPath} without --accept-data-loss, keeping the
same env/options for execSync; ensure the conditional logic uses a single
execSync call with the constructed command string or two explicit execSync calls
for each branch so destructive changes are not applied silently.
if ( | ||
error instanceof Error && | ||
(error.message.includes("data loss") || | ||
error.message.includes("force-reset") || | ||
error.message.includes("reset") || | ||
error.message.includes("neither a built-in type")) | ||
) { | ||
return c.json({ | ||
requiresForceReset: true, | ||
message: | ||
"This operation will reset your database and lose all data. Please confirm to continue.", | ||
}); | ||
} else { | ||
throw error; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
🛠️ Refactor suggestion
Brittle error detection based on error.message substrings.
message may not reliably include Prisma’s stdout/stderr; matches can miss or misclassify cases. Inspect stderr/stdout (from the thrown error) and/or exit code instead.
I can provide a small parser that checks error.stdout/error.stderr for known Prisma signals and maps them to requiresForceReset vs general failure. Want me to include it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (1)
claim-db-worker/app/db-unavailable/page.tsx (1)
9-11
: Ensure cookie removal uses matching attributes to guarantee deletionYour remover currently omits SameSite (and any Domain you might add later). This can leave the cookie undeleted in some browsers/edges and create redirect loops back to /db-unavailable if /web/connect is gated by that cookie. Please align remove() with set().
Apply in claim-db-worker/lib/utils.ts:
- remove: (name: string) => { - document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/;`; - }, + remove: (name: string) => { + // Match attributes used in `set` to ensure deletion across browsers + document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/;SameSite=Lax`; + },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
claim-db-worker/app/db-unavailable/page.tsx
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
claim-db-worker/app/db-unavailable/page.tsx (1)
claim-db-worker/lib/utils.ts (1)
cookieUtils
(1-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Workers Builds: create-db-worker
- GitHub Check: Workers Builds: claim-db-worker
✅ Preview CLIs & Workers are live! Test the CLIs locally under tag npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42 Worker URLs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 16
♻️ Duplicate comments (3)
claim-db-worker/lib/custom-toast.ts (1)
62-69
: Fix icon: SVG string will render as text; pass a React element.react-hot-toast expects a ReactNode for icon, not a string.
Apply:
- return toast(message, { - style, - icon: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12 2L2 22h20L12 2Z" stroke="#A0AEC0" stroke-width="2" stroke-linejoin="round"/> -<path d="M12 9V15" stroke="#A0AEC0" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> -<path d="M9 12H15" stroke="#A0AEC0" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> -</svg>`, - }); + { + const icon = createElement( + "svg", + { width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, + createElement("path", { d: "M12 2L2 22h20L12 2Z", stroke: "#A0AEC0", strokeWidth: 2, strokeLinejoin: "round" }), + createElement("path", { d: "M12 9V15", stroke: "#A0AEC0", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }), + createElement("path", { d: "M9 12H15", stroke: "#A0AEC0", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }), + ); + return toast(message, { style, icon }); + }claim-db-worker/components/Footer.tsx (1)
7-7
: Fix rel attribute on external link (security).Use rel="noopener noreferrer" with target="_blank". Current value "opener noferrer" is unsafe and misspelled.
Apply:
- <a target="_blank" rel="opener noferrer" href="https://prisma.io"> + <a target="_blank" rel="noopener noreferrer" href="https://prisma.io">claim-db-worker/components/Modal.tsx (1)
1-1
: Add initial focus + focus restore, lock body scroll, and use a unique title id.Builds on prior feedback; improves keyboard UX and avoids duplicate ids when multiple modals exist.
Apply this diff:
-import React from "react"; +import React, { useEffect, useRef, useId } from "react"; @@ const Modal = ({ isOpen, onClose, title, children, maxWidth = "max-w-md", }: ModalProps) => { + const titleId = useId(); + const closeBtnRef = useRef<HTMLButtonElement>(null); + + // Focus management: focus Close on open, restore previously focused element on close. + useEffect(() => { + if (!isOpen) return; + const prev = document.activeElement as HTMLElement | null; + closeBtnRef.current?.focus(); + return () => prev?.focus?.(); + }, [isOpen]); + + // Body scroll lock while modal is open. + useEffect(() => { + if (!isOpen) return; + const { style } = document.body; + const prevOverflow = style.overflow; + style.overflow = "hidden"; + return () => { + style.overflow = prevOverflow; + }; + }, [isOpen]); if (!isOpen) return null; @@ - aria-labelledby="modal-title" + aria-labelledby={titleId} @@ - <h2 id="modal-title" className="text-lg font-bold text-white"> + <h2 id={titleId} className="text-lg font-bold text-white"> {title} </h2> <button type="button" aria-label="Close modal" className="text-white/80 hover:text-white" - onClick={onClose} + onClick={onClose} + ref={closeBtnRef} > × </button>Also applies to: 11-17, 18-19, 25-25, 37-39, 41-47
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
claim-db-worker/components/Footer.tsx
(1 hunks)claim-db-worker/components/Modal.tsx
(1 hunks)claim-db-worker/components/prismaSchemaEditor/InfoNote.tsx
(1 hunks)claim-db-worker/lib/custom-toast.ts
(1 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
claim-db-worker/components/Footer.tsx
[error] 7-7: Avoid using target="_blank" without rel="noopener" or rel="noreferrer".
Opening external links in new tabs without rel="noopener" is a security risk. See the explanation for more details.
Safe fix: Add the "noopener" to the existing attribute.
(lint/security/noBlankTarget)
claim-db-worker/components/Modal.tsx
[error] 32-35: Static Elements should not be interactive.
To add interactivity such as a mouse or key event listener to a static element, give the element an appropriate role value.
(lint/a11y/noStaticElementInteractions)
[error] 32-35: Enforce to have the onClick mouse event with the onKeyUp, the onKeyDown, or the onKeyPress keyboard event.
Actions triggered using mouse events should have corresponding keyboard events to account for keyboard-only navigation.
(lint/a11y/useKeyWithClickEvents)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Workers Builds: claim-db-worker
- GitHub Check: Workers Builds: create-db-worker
🔇 Additional comments (8)
claim-db-worker/lib/custom-toast.ts (1)
5-12
: Nice, consistent theming.Clear base style + per-type borders/iconTheme reads well and keeps call sites lean.
Also applies to: 14-38
claim-db-worker/components/Footer.tsx (4)
16-20
: External link hygiene + numeric Image dimensions: LGTM.Good use of rel="noopener noreferrer" and numeric width/height for next/image across these anchors.
Also applies to: 28-35, 36-40, 48-54
5-5
: Confirm md:mt-auto intent.mt-auto only at md suggests footer-push behavior in a flex column parent; confirm layout. If unintentional, remove.
Apply:
- <footer className="w-full box-border overflow-hidden mt-32 md:mt-auto mb-8"> + <footer className="w-full box-border overflow-hidden mt-32 mb-8">
58-58
: Year may freeze under SSG.If the page/layout is statically rendered without revalidate, the year won’t update until next deploy. Verify route’s dynamic/revalidation settings.
9-64
: All referenced assets found
All image files referenced inFooter.tsx
(logo-dark.svg, discord.svg, xtwitter.svg, youtube.svg, github.svg, gdpr.svg, hipaa.svg, iso27.svg, soc2.svg) are present inpublic/
.claim-db-worker/components/Modal.tsx (1)
55-55
: LGTM: export.No issues with the default export.
claim-db-worker/components/prismaSchemaEditor/InfoNote.tsx (2)
8-12
: Icon marked decorative — accessibility LGTMGood use of aria-hidden and focusable to keep the SVG out of the a11y tree and tab order.
13-14
: Confirm UI copy matches control label exactlyEnsure the button text is “Pull” in the UI to avoid mismatched guidance.
Summary by CodeRabbit
New Features
Documentation
Chores