Skip to content

Conversation

aidankmcalister
Copy link
Member

@aidankmcalister aidankmcalister commented Aug 15, 2025

Summary by CodeRabbit

  • New Features

    • Browser-based Web Interface at https://create-db.prisma.io/web for creating and claiming temporary Prisma Postgres DBs, with timers, claim flow, and success/error screens.
    • Web Connect view with copyable connection strings (Prisma & node-postgres), built-in schema editor (format/push/pull/force) and integrated Prisma Studio.
  • Documentation

    • README & Quick Start updated to include Web Interface option and browser-based getting-started steps.
  • Chores

    • Project workspace, build, and ignore/config updates; legacy worker templates and test scaffolding removed.

Copy link

coderabbitai bot commented Aug 15, 2025

Walkthrough

Moves 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

Cohort / File(s) Summary
Docs: Web Interface & Quick Start
README.md, claim-db-worker/README.md
Adds Web Interface documentation, reorders overview, expands Quick Start with browser option and web URL.
Workspace
pnpm-workspace.yaml
Adds schema-api-routes package to the workspace.
Ignore & formatter changes
claim-db-worker/.gitignore, deleted: claim-db-worker/.editorconfig, claim-db-worker/.prettierrc
Removes editor/Prettier files; replaces .gitignore with grouped patterns and example-file negations.
Next.js / OpenNext migration & build config
claim-db-worker/package.json, claim-db-worker/next.config.ts, claim-db-worker/open-next.config.ts, claim-db-worker/postcss.config.mjs, claim-db-worker/tsconfig.json, claim-db-worker/wrangler.jsonc
Overhauls package manifest and scripts for Next.js + OpenNext, adds PostCSS/Tailwind config, updates TS config, and adjusts wrangler to consume OpenNext output.
Removed legacy Worker & tests
deleted: claim-db-worker/src/index.ts, claim-db-worker/src/templates/*, claim-db-worker/test/*, claim-db-worker/vitest.config.mts
Removes old Cloudflare Worker fetch handler, HTML templates, tests, and worker test config.
App Router API routes
claim-db-worker/app/api/{auth/callback,claim,create-db,check-db-status,get-connection-string,studio,test}/route.ts
Adds API-first endpoints for OAuth callback, claim analytics, DB create, status check, connection string proxy, Studio BFF, and a rate-limit test endpoint.
App shell, global styles & layout
claim-db-worker/app/layout.tsx, claim-db-worker/app/globals.css
New global layout, metadata, DropContext provider, Toaster integration, and comprehensive theming + scrollbar utilities.
Pages, components & UI
claim-db-worker/app/page.tsx, claim-db-worker/app/{claim,success,error,db-unavailable}/page.tsx, claim-db-worker/app/test/*, claim-db-worker/components/*
Adds landing, claim, success/error, db-unavailable, test pages, and many UI components (Navbar, Footer, CodeSnippet, Modal, LoadingScreen, PrismaPostgresLogo, schema-editor UI parts, ClientRedirect, etc.).
Web Interface: DB lifecycle & pages
claim-db-worker/app/contexts/DropContext.tsx, claim-db-worker/app/web/{layout,page,connect,schema,studio}/*, claim-db-worker/app/web/DatabaseContext.tsx
Adds DropContext and DatabaseProvider, web layout with tabs/actions, connect guide, Monaco-based schema editor, Studio client, expiry/create-new flows and UI.
Prisma Schema Editor libs
claim-db-worker/lib/prismaSchemaEditor/{defaultSchema,editorOptions,monacoConfig,prismaSchemaUtils,schemaApi}.ts
New default schema, editor options, Monaco language/theme/providers, schema formatter utilities, and client helpers for format/push/pull/force APIs.
Auth, transfer, analytics, utils
claim-db-worker/lib/{auth-utils,project-transfer,analytics,response-utils,custom-toast,env,utils}.ts
Adds OAuth token exchange, project transfer helper, PostHog + dataset analytics helpers, redirect helpers, custom toasts, environment accessor, and cookie utilities.
Middleware: DB availability
claim-db-worker/middleware.ts
Middleware reads temp_db_info cookie, calls /api/check-db-status, and redirects to /db-unavailable on error.
Cloudflare/OpenNext types
claim-db-worker/worker-configuration.d.ts
Expands Cloudflare env typings, Node process.env mapping, MessagePort/messaging types, DurableObject additions, and other type-level surface changes.
Schema API service (new package)
schema-api-routes/{package.json,tsconfig.json,vercel.json,.gitignore,README.md,src/index.ts,src/routes/schema/{format,pull,push,push-force}.ts}
New Hono-based service exposing /api/schema/format, /pull, /push, /push-force using Prisma CLI with temporary files; includes CORS and Vercel build config.

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
Loading
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 }
Loading
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
Loading

Possibly related PRs

Suggested reviewers

  • mhessdev
  • ankur-arch
  • nurul3101
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claim-worker-migrate-nextjs

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

cloudflare-workers-and-pages bot commented Aug 15, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

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

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-16995245179:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-16995245179.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17046258853:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17046258853.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17058303249:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17058303249.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17072544444:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17072544444.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17128921539:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17128921539.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17131575451:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17131575451.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17158141840:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17158141840.

Copy link

github-actions bot commented Sep 2, 2025

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17409337752:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17409337752.

Copy link

github-actions bot commented Sep 3, 2025

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17432975104:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17432975104.

Copy link

github-actions bot commented Sep 3, 2025

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17433187812:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17433187812.

Copy link

github-actions bot commented Sep 3, 2025

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17434229965:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17434229965.

Copy link

github-actions bot commented Sep 3, 2025

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17438156547:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17438156547.

@aidankmcalister aidankmcalister marked this pull request as ready for review September 3, 2025 15:28
@aidankmcalister aidankmcalister changed the title migrate claim worker -> next.js DC-4974 create-db web Sep 3, 2025
Copy link

@coderabbitai coderabbitai bot left a 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 workflow

Missing 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 1b633e4 and 14acdb2.

⛔ 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 workspace

Workspace entry for “schema-api-routes” looks correct.

claim-db-worker/lib/prismaSchemaEditor/defaultSchema.ts (2)

9-12: Validate env var contract

Confirm 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 generator prisma-client is valid and requires a custom output path; switching to prisma-client-js and removing output 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 for db 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 worker

Looks 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.js dev now.

Given the Next.js migration, running the app with wrangler dev may not reflect local Next features. Prefer pnpm dev (or next dev) in claim-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 dev
claim-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-export

Re-export pattern is fine.

claim-db-worker/app/test/claim/page.tsx (1)

1-3: LGTM: simple re-export

Matches 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
Ensure INTEGRATION_TOKEN is defined as a secret or environment variable in your Cloudflare Worker (via the Dashboard or wrangler.toml) and that Node.js compatibility (nodejs_compat flag or compatibility_date) is enabled, so process.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
No variables.json found in the repo; confirm that CREATE_DB_WORKER_URL, CLAIM_DB_RATE_LIMITER, and CREATE_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 logs

Search 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.

Copy link

@coderabbitai coderabbitai bot left a 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...

Comment on lines +7 to +14
// 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")),
]);
}

Copy link

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.

Suggested change
// 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.

Comment on lines +18 to +23
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">> {}
}
Copy link

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.

Comment on lines +1119 to 1160
/**
* 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;
}
/**
Copy link

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 to any and add optional origin, lastEventId, source, ports properties to match the standard spec.
  • Apply this change in both worker-configuration.d.ts and cloudflare-env.d.ts under claim-db-worker and create-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.

Comment on lines 116 to 126
#### `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

Copy link

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.

Suggested change
#### `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/,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Comment on lines +26 to +39
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,
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

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.

Suggested change
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.

Copy link

@coderabbitai coderabbitai bot left a 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...

Comment on lines +3 to +26
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 });
}
}
Copy link

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.

Suggested change
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.

Comment on lines +15 to +35
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",
}),
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

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.

Suggested change
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.

Comment on lines +43 to +49
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 });
Copy link

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.

Suggested change
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.

Comment on lines +22 to +24
const CREATE_DB_WORKER_URL =
process.env.CREATE_DB_WORKER_URL || "https://create-db-temp.prisma.io";

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

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.

Comment on lines +31 to +39
const prismaResponse = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
region,
name,
utm_source: "drop",
}),
});
Copy link

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.

Comment on lines +30 to +35
const envPath = `${tempDir}/.env-${Date.now()}`;

try {
await writeFile(schemaPath, schema);
await writeFile(envPath, `DATABASE_URL="${connectionString}"`);

Copy link

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

Comment on lines +36 to +50
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",
}
);
Copy link

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.

Comment on lines +37 to +41
const result = execSync(
`npx prisma db push --schema=${schemaPath} --accept-data-loss`,
{
env: {
...process.env,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.

Suggested change
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.

Comment on lines +52 to +67
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;
}
}
Copy link

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?

Copy link

@coderabbitai coderabbitai bot left a 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...

Copy link

@coderabbitai coderabbitai bot left a 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...

Copy link

github-actions bot commented Sep 3, 2025

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17439093689:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17439093689.

Copy link

@coderabbitai coderabbitai bot left a 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 deletion

Your 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 14acdb2 and 7434ee2.

📒 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

Copy link

github-actions bot commented Sep 3, 2025

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr42-claim-worker-migrate-nextjs-17442977349:

npx create-db@pr42
npx create-pg@pr42
npx create-postgres@$pr42

Worker URLs
• Create-DB Worker:
• Claim-DB Worker:

These will live as long as this PR exists under tag pr42-claim-worker-migrate-nextjs-17442977349.

Copy link

@coderabbitai coderabbitai bot left a 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 7434ee2 and 6f65028.

📒 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 in Footer.tsx (logo-dark.svg, discord.svg, xtwitter.svg, youtube.svg, github.svg, gdpr.svg, hipaa.svg, iso27.svg, soc2.svg) are present in public/.

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 LGTM

Good 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 exactly

Ensure the button text is “Pull” in the UI to avoid mismatched guidance.

@mhessdev mhessdev merged commit f4d7ca6 into main Sep 3, 2025
4 checks passed
This was referenced Sep 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants