Skip to content

Conversation

aidankmcalister
Copy link
Member

@aidankmcalister aidankmcalister commented Aug 20, 2025

Summary by CodeRabbit

  • New Features

    • create-db CLI: added --json / -j to output machine-friendly JSON (connection strings, claim link, region/name, projectId, deletion expiry).
    • Create endpoint: now returns immediately while post-creation tasks run in background for faster responses.
  • Chores

    • .open-next/ added to .gitignore.
    • Added TypeScript ambient definitions for Next.js to improve tooling support.

Copy link

coderabbitai bot commented Aug 20, 2025

Walkthrough

Added .open-next/ to .gitignore and a Next.js ambient types file for claim-db-worker. In create-db-worker the /create JSON payload was inlined and post-create workflow/analytics were moved into a concurrent background task via ctx.waitUntil. The create-db CLI gained a --json/-j machine output mode and JSON-aware region helpers.

Changes

Cohort / File(s) Summary of Changes
Git ignore update
./.gitignore
Added ignore rule for .open-next/.
Next.js ambient types
claim-db-worker/next-env.d.ts
Added new TypeScript ambient declaration referencing next and next/image-types/global with a do-not-edit comment.
Worker request & background tasks
create-db-worker/src/index.ts
Inlined JSON payload for /create. Added backgroundTasks() executed via ctx.waitUntil(...) that parses prisma text and concurrently triggers delete-workflow and analytics (Promise.all); moved error logging into the background task; main handler returns Prisma response immediately.
CLI JSON mode and helpers
create-db/index.js
Added --json/-j machine output mode returning structured JSON. Extended getRegions(returnJson = false), validateRegion(region, returnJson = false), and createDatabase(..., returnJson = false) to support JSON output and structured error objects (rate-limit / API errors). Integrated JSON path into main flow; computed directConnectionString and claim expiry; preserved interactive UI behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant CLI as create-db CLI
  participant R as Regions API
  participant C as Create DB API

  U->>CLI: run create-db [--name, --region, --json]
  alt JSON mode (--json)
    CLI->>R: fetch regions (validate/prompt if needed)
    R-->>CLI: regions list / error
    CLI->>C: POST /create {name, region}
    C-->>CLI: creation result
    alt success
      CLI-->>U: print single JSON {connectionString, directConnectionString, claimUrl, deletionDate, region, name, projectId}
    else rate-limit / api error
      CLI-->>U: print JSON {error, message, status/details}
    end
  else interactive / UI mode
    CLI->>R: fetch regions (optional)
    R-->>CLI: regions list / fallback
    CLI->>C: POST /create {name, region}
    C-->>CLI: creation result
    CLI-->>U: console output, spinners, claim link
  end
Loading
sequenceDiagram
  autonumber
  participant Client as Caller
  participant Worker as create-db-worker
  participant Workflow as DELETE_DB_WORKFLOW
  participant Analytics as Analytics API / Env

  Client->>Worker: POST /create {name, region}
  Worker->>Worker: inline JSON body -> call DB API (prisma)
  Worker-->>Client: return Prisma response immediately
  Worker->>Worker: ctx.waitUntil(backgroundTasks())
  Note over Worker: backgroundTasks parses prismaText (projectId) and runs concurrent ops
  par concurrent ops
    Worker->>Workflow: trigger DELETE_DB_WORKFLOW.create(...)
    Worker->>Analytics: env.CREATE_DB_DATASET.writeDataPoint(...)
    Workflow-->>Worker: result / error
    Analytics-->>Worker: result / error
  end
  alt error in backgroundTasks
    Worker-->>Worker: log "Error in background tasks:" + error
  end
Loading

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch DC-4828-json-flag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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 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 20, 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 e18cd95 Commit Preview URL

Branch Preview URL
Aug 20 2025, 05:55 PM

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr43-DC-4828-json-flag-17103676514:

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

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

These will live as long as this PR exists under tag pr43-DC-4828-json-flag-17103676514.

@aidankmcalister aidankmcalister changed the title --json flag DC-4828 --json flag Aug 20, 2025
Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr43-DC-4828-json-flag-17105267979:

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

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

These will live as long as this PR exists under tag pr43-DC-4828-json-flag-17105267979.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
create-db-worker/src/index.ts (3)

68-71: Preserve optional utm_source from request body

The CLI now sends utm_source in the JSON body. You parse only { region, name }, so the upstream API never receives utm_source. Capture it here so you can forward it.

Apply this diff:

-      const { region, name } = body;
+      const { region, name, utm_source } = body;
       if (!region || !name) {
         return new Response('Missing region or name in request body', { status: 400 });
       }

15-19: Rate limiter key should consider client identity, not URL

Using request.url as the rate-limit key allows bypasses by varying path/query and doesn’t group abusive clients. Prefer a stable client key (e.g., CF-Connecting-IP), possibly combined with the route.

Example:

const ip = request.headers.get('CF-Connecting-IP') ?? 'unknown';
const route = new URL(request.url).pathname;
const { success } = await env.CREATE_DB_RATE_LIMITER.limit({ key: `${ip}:${route}` });

106-108: Consider 404 for unknown routes or include Allow header for 405

Returning 405 for all fallbacks is semantically off for unknown paths. Either return 404 for unknown routes, or include an Allow header listing permitted methods for known routes that received the wrong method.

create-db/index.js (1)

204-222: validateRegion isn’t used in JSON flow → inconsistent JSON error semantics

You introduced returnJson and throw behavior here but don’t call validateRegion(..., true) in the --json path. If a user passes an invalid region with --json, main catches the thrown error and prints a plain text message, breaking JSON-only contracts.

Apply this diff within the JSON branch to validate and return structured JSON errors:

   if (flags.json) {
     if (chooseRegionPrompt) {
       region = await promptForRegion(region);
     }
 
-    const result = await createDatabase(name, region, true);
+    // Validate region with JSON-friendly error handling
+    try {
+      await validateRegion(region, true);
+    } catch (e) {
+      console.log(
+        JSON.stringify(
+          { error: "invalid_region", message: e.message },
+          null,
+          2
+        )
+      );
+      process.exit(1);
+    }
+
+    const result = await createDatabase(name, region, true);
     console.log(JSON.stringify(result, null, 2));
     process.exit(0);
   }
📜 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 4d9bb9d and 7106187.

📒 Files selected for processing (4)
  • .gitignore (1 hunks)
  • claim-db-worker/next-env.d.ts (1 hunks)
  • create-db-worker/src/index.ts (2 hunks)
  • create-db/index.js (8 hunks)
⏰ 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 (5)
.gitignore (1)

9-9: LGTM: .open-next/ added to ignore list

This is an appropriate addition for OpenNext build artifacts. No concerns.

claim-db-worker/next-env.d.ts (1)

1-6: LGTM: Standard Next.js ambient declarations

Generated file looks correct and should remain unedited. No issues.

create-db/index.js (3)

177-202: getRegions(returnJson): Good; throwing in JSON mode is correct

The dual-mode error handling is sensible. Keep in mind callers must catch thrown errors in JSON mode to preserve JSON-only output semantics.

If there are external callers of getRegions(true), ensure they convert thrown errors to JSON responses rather than printing plain text errors.


329-339: JSON success payload: Looks good and complete

The returned fields cover connection strings, claim URL, deletion date, region, name, and projectId. This should satisfy most machine consumers.


341-364: JSON error payloads: Consistent with rate-limit error; good

The api_error shape mirrors your 429 shape. Keep this stable for integrators.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr43-DC-4828-json-flag-17106021047:

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

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

These will live as long as this PR exists under tag pr43-DC-4828-json-flag-17106021047.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr43-DC-4828-json-flag-17106152047:

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

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

These will live as long as this PR exists under tag pr43-DC-4828-json-flag-17106152047.

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: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
create-db-worker/src/index.ts (1)

15-19: Rate limit key: consider using path + client IP to avoid easy key evasion

Using the full request URL allows query string variance to bypass rate limits. Prefer a stable key like path + client IP.

Example:

const { pathname } = new URL(request.url);
const ip = request.headers.get('CF-Connecting-IP') ?? 'unknown';
const key = `${ip}:${pathname}`;
const { success } = await env.CREATE_DB_RATE_LIMITER.limit({ key });
create-db/index.js (1)

180-205: Ensure getRegions surfaces network failures in JSON mode (and doesn’t hard-exit)

A network error during fetch will currently throw and be caught only by the top-level catch, which prints a human message. Wrap fetch in try/catch and honor returnJson to throw a meaningful error (non-JSON paths can still call handleError).

 export async function getRegions(returnJson = false) {
   const url = `${CREATE_DB_WORKER_URL}/regions`;
-  const res = await fetch(url);
+  let res;
+  try {
+    res = await fetch(url);
+  } catch (e) {
+    if (returnJson) {
+      throw new Error(
+        `Network error while fetching regions: ${e?.message || e}`
+      );
+    }
+    handleError("Failed to fetch regions.", e?.message || String(e));
+  }
 
   if (!res.ok) {
     if (returnJson) {
       throw new Error(
         `Failed to fetch regions. Status: ${res.status} ${res.statusText}`
       );
     }
     handleError(
       `Failed to fetch regions. Status: ${res.status} ${res.statusText}`
     );
   }
 
   try {
     const data = await res.json();
     const regions = Array.isArray(data) ? data : data.data;
     return regions.filter((region) => region.status === "available");
   } catch (e) {
     if (returnJson) {
       throw new Error("Failed to parse JSON from /regions endpoint.");
     }
     handleError("Failed to parse JSON from /regions endpoint.", e);
   }
 }
♻️ Duplicate comments (2)
create-db-worker/src/index.ts (1)

61-82: Forward utm_source from CLI to Prisma API (and type it)

The CLI now includes utm_source in the /create request body. Forward it to the Prisma API for attribution and analytics, and extend the local body type accordingly.

-      let body: { region?: string; name?: string } = {};
+      let body: { region?: string; name?: string; utm_source?: string } = {};
@@
-        body: JSON.stringify({
-          region,
-          name,
-        }),
+        body: JSON.stringify({
+          region,
+          name,
+          ...(body.utm_source ? { utm_source: body.utm_source } : {}),
+        }),
create-db/index.js (1)

433-447: Telemetry: JSON flag tracking added — looks good

has-json-flag is captured alongside other flags; full-command and arch formatting are clean.

📜 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 7106187 and cb8968a.

📒 Files selected for processing (2)
  • create-db-worker/src/index.ts (1 hunks)
  • create-db/index.js (8 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
create-db-worker/src/index.ts (2)
create-db-worker/worker-configuration.d.ts (1)
  • env (6794-6794)
claim-db-worker/worker-configuration.d.ts (1)
  • env (6799-6799)
create-db/index.js (3)
create-db-worker/src/index.ts (1)
  • fetch (13-115)
claim-db-worker/src/index.ts (1)
  • fetch (31-201)
create-db/analytics.js (1)
  • analytics (48-48)
⏰ 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 (3)
create-db-worker/src/index.ts (1)

87-106: Good restoration of background semantics with ctx.waitUntil and concurrent tasks

Using ctx.waitUntil plus Promise.all keeps the response path fast while still ensuring workflow creation and analytics run reliably in the background.

create-db/index.js (2)

75-88: Help text: flags and examples look good

Help now advertises --json/-j and --list-regions and adds a JSON example. This resolves the discoverability gap.


96-108: Argument parsing: JSON flag wiring is correct

allowedFlags and shorthandMap include json/j. Parsing behavior aligns with other flags.

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: 1

♻️ Duplicate comments (7)
create-db/index.js (7)

78-80: Help text: --json and --list-regions are now documented (good catch).

The help output includes both flags and a JSON example. This resolves the earlier discoverability gap.

Also applies to: 87-87


431-447: Analytics: has-json-flag and additional fields are wired correctly.

Nice addition for observability of JSON-mode usage.


284-289: Handle network-layer failures and preserve JSON-only output in JSON mode.

A failed fetch() will throw and currently bubbles to the top-level catch, printing a human string. Wrap the call in try/catch and return a structured JSON error in JSON mode; keep spinner + exit flow otherwise.

Apply this diff:

-  const resp = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
-    method: "POST",
-    headers: { "Content-Type": "application/json" },
-    body: JSON.stringify({ region, name, utm_source: CLI_NAME }),
-  });
+  let resp;
+  try {
+    resp = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
+      method: "POST",
+      headers: { "Content-Type": "application/json" },
+      body: JSON.stringify({ region, name, utm_source: CLI_NAME }),
+    });
+  } catch (e) {
+    if (returnJson) {
+      return {
+        ok: false,
+        error: "network_error",
+        message: `Failed to reach create service: ${e?.message || String(e)}`,
+      };
+    }
+    if (s) {
+      s.stop("Network error while creating the database. Please try again.");
+    }
+    try {
+      await analytics.capture("create_db:database_creation_failed", {
+        command: CLI_NAME,
+        region,
+        "error-type": "network_error",
+      });
+    } catch {}
+    process.exit(1);
+  }

318-318: Guard against non-JSON responses from the service to avoid crashes.

resp.json() throws on HTML/text or malformed JSON. Parse from text and return a structured error in JSON mode to keep output machine-readable.

Apply this diff:

-  const result = await resp.json();
+  let result;
+  let raw;
+  try {
+    raw = await resp.text();
+    result = JSON.parse(raw);
+  } catch (e) {
+    if (returnJson) {
+      return {
+        ok: false,
+        error: "invalid_json",
+        message: "Unexpected response from create service.",
+        raw,
+        status: resp.status,
+      };
+    }
+    if (s) {
+      s.stop("Unexpected response from create service.");
+    }
+    try {
+      await analytics.capture("create_db:database_creation_failed", {
+        command: CLI_NAME,
+        region,
+        "error-type": "invalid_json",
+        "status-code": resp.status,
+      });
+    } catch {}
+    process.exit(1);
+  }

324-337: Direct connection string: include optional port/database and avoid empty credentials.

Port and database are omitted, and empty user/pass produce ://:@host/.... Include :port and db name (fallback to postgres) and only add user:pass@ when both exist.

Apply this diff:

   const directUser = directConnDetails?.user
     ? encodeURIComponent(directConnDetails.user)
     : "";
   const directPass = directConnDetails?.pass
     ? encodeURIComponent(directConnDetails.pass)
     : "";
   const directHost = directConnDetails?.host;
-  const directConn =
-    directConnDetails && directHost
-      ? `postgresql://${directUser}:${directPass}@${directHost}/postgres`
-      : null;
+  const directPort = directConnDetails?.port ? `:${directConnDetails.port}` : "";
+  const directDbName = directConnDetails?.database || "postgres";
+  const credentialsPart =
+    directConnDetails?.user && directConnDetails?.pass
+      ? `${directUser}:${directPass}@`
+      : "";
+  const directConn =
+    directConnDetails && directHost
+      ? `postgresql://${credentialsPart}${directHost}${directPort}/${directDbName}`
+      : null;

451-453: Skip offline preflight in JSON mode to preserve JSON-only output.

isOffline() prints human messages and exits. Running it in JSON mode breaks the JSON contract.

Apply this diff:

-    if (!flags.help) {
+    if (!flags.help && !flags.json) {
       await isOffline();
     }

484-505: Ensure JSON mode always emits JSON, even on unexpected errors.

Wrap the JSON-mode flow in a try/catch so any validation, network, or parsing errors print a structured JSON object and a non-zero exit.

Apply this diff:

-    if (flags.json) {
-      if (chooseRegionPrompt) {
-        region = await promptForRegion(region);
-      }
-    
-        try {
-          await validateRegion(region, true);
-        } catch (e) {
-          console.log(
-            JSON.stringify(
-              { error: "invalid_region", message: e.message },
-              null,
-              2
-            )
-          );
-          process.exit(1);
-        }
-
-        const result = await createDatabase(name, region, true);
-        console.log(JSON.stringify(result, null, 2));
-        process.exit(0);
-    }
+    if (flags.json) {
+      try {
+        if (chooseRegionPrompt) {
+          region = await promptForRegion(region);
+        } else {
+          await validateRegion(region, true);
+        }
+        const result = await createDatabase(name, region, true);
+        console.log(JSON.stringify(result, null, 2));
+        process.exit(0);
+      } catch (e) {
+        console.log(
+          JSON.stringify(
+            { error: "cli_error", message: e?.message || String(e) },
+            null,
+            2
+          )
+        );
+        process.exit(1);
+      }
+    }
📜 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 cb8968a and ce2fe2f.

📒 Files selected for processing (1)
  • create-db/index.js (8 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
create-db/index.js (3)
create-db-worker/src/index.ts (1)
  • fetch (13-115)
claim-db-worker/src/index.ts (1)
  • fetch (31-201)
create-db/analytics.js (1)
  • analytics (48-48)
⏰ 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 (3)
create-db/index.js (3)

96-102: CLI flag plumbing for --json/-j and --list-regions is correct.

allowedFlags and shorthandMap cover all new flags as expected.

Also applies to: 107-107


185-189: JSON-mode error propagation from getRegions/validateRegion looks good.

Throwing in returnJson mode lets the caller format a machine-readable error. This aligns with the JSON-only contract.

Also applies to: 200-203


270-273: Event enrichment: selection-method "interactive" looks good.

This clarifies how the region was chosen.

Copy link

Preview CLIs & Workers are live!

Test the CLIs locally under tag pr43-DC-4828-json-flag-17106316584:

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

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

These will live as long as this PR exists under tag pr43-DC-4828-json-flag-17106316584.

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: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
create-db/index.js (1)

24-26: handleError “extra” parameter is mislabeled in output; pass error details or rename label

The current handler prints extra under “Available regions:” which is misleading when the “extra” is an error message or object. Either pass e?.message or change the handleError formatter to label it “Details:”.

Apply these diffs to pass messages:

-    handleError("Failed to fetch regions.", e);
+    handleError("Failed to fetch regions.", e?.message || String(e));
-    handleError("Failed to parse JSON from /regions endpoint.", e);
+    handleError("Failed to parse JSON from /regions endpoint.", e?.message || String(e));
-    handleError("Failed to fetch regions.", e);
+    handleError("Failed to fetch regions.", e?.message || String(e));

And consider updating handleError (outside the selected ranges):

function handleError(message, details = "") {
  console.error(
    "\n" +
      chalk.red.bold("✖ An error occurred!") +
      "\n\n" +
      chalk.white("Message: ") +
      chalk.yellow(message) +
      (details ? "\n" + chalk.white("Details: ") + chalk.gray(details) : "") +
      "\n"
  );
  process.exit(1);
}

Also applies to: 200-203, 246-248

♻️ Duplicate comments (8)
create-db/index.js (8)

78-80: Help text: flags and examples updated correctly

The help now advertises --json/-j and --list-regions, plus a JSON example. This resolves prior discoverability concerns.

Also applies to: 87-87


96-102: Args parsing: allowed flags and shorthand map are consistent with help

--json is included in allowedFlags and mapped to -j. LGTM.

Also applies to: 107-107


459-477: Analytics: has-json-flag captured; payload is clean

Nice addition and tidy formatting.


481-483: Skip offline preflight in JSON mode

This preserves JSON-only output. Good.


290-298: Standardize JSON errors with ok: false

Return objects in JSON mode should include ok: false for easy client branching.

Apply this diff:

     if (returnJson) {
       return {
+        ok: false,
         error: "rate_limit_exceeded",
         message:
           "We're experiencing a high volume of requests. Please try again later.",
         status: 429,
       };
     }

Also applies to: 300-316


372-382: Success JSON: add ok: true for symmetry with errors

Makes client logic simpler.

Apply this diff:

   if (returnJson && !result.error) {
     return {
+      ok: true,
       connectionString: prismaConn,
       directConnectionString: directConn,
       claimUrl: claimUrl,
       deletionDate: expiryDate.toISOString(),
       region: database?.region?.id || region,
       name: database?.name,
       projectId: projectId,
     };
   }

385-391: API error JSON: add ok: false

Consistent with success response.

Apply this diff:

   if (result.error) {
     if (returnJson) {
       return {
+        ok: false,
         error: "api_error",
         message: result.error.message || "Unknown error",
         details: result.error,
       };
     }

284-289: createDatabase: catch network errors around fetch for structured JSON and clean UI

A network failure will currently bubble (caught at the top-level). In JSON mode that becomes { error: "cli_error" }, but we lose error-type specificity and spinner won’t stop in human mode. Catch here to preserve behavior in both modes and tag analytics.

Apply this diff:

-  const resp = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
-    method: "POST",
-    headers: { "Content-Type": "application/json" },
-    body: JSON.stringify({ region, name, utm_source: CLI_NAME }),
-  });
+  let resp;
+  try {
+    resp = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
+      method: "POST",
+      headers: { "Content-Type": "application/json" },
+      body: JSON.stringify({ region, name, utm_source: CLI_NAME }),
+    });
+  } catch (e) {
+    if (returnJson) {
+      return {
+        ok: false,
+        error: "network_error",
+        message: `Failed to reach create service: ${e?.message || String(e)}`,
+      };
+    }
+    if (s) {
+      s.stop("Network error while creating the database. Please try again.");
+    }
+    try {
+      await analytics.capture("create_db:database_creation_failed", {
+        command: CLI_NAME,
+        region,
+        "error-type": "network_error",
+      });
+    } catch {}
+    process.exit(1);
+  }
📜 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 ce2fe2f and e18cd95.

📒 Files selected for processing (1)
  • create-db/index.js (8 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
create-db/index.js (3)
create-db-worker/src/index.ts (1)
  • fetch (13-115)
claim-db-worker/src/index.ts (1)
  • fetch (31-201)
create-db/analytics.js (1)
  • analytics (48-48)
⏰ 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
🔇 Additional comments (3)
create-db/index.js (3)

207-216: validateRegion: JSON-mode behavior is correct

Throws in JSON mode with a clear message; non-JSON still uses handleError. Good separation.


267-272: Analytics: selection-method tagging looks good

Consistent "interactive" tag for prompt-based selection. LGTM.


277-283: Spinner gating on returnJson

Nice separation: spinner only in interactive/human mode.

@aidankmcalister aidankmcalister merged commit 0364097 into main Aug 20, 2025
4 checks passed
@aidankmcalister aidankmcalister deleted the DC-4828-json-flag branch August 20, 2025 18:09
This was referenced Aug 26, 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