Skip to content

Comments

added mongodb#10

Open
justinwuzijin wants to merge 1 commit intomasterfrom
mongodb-integration
Open

added mongodb#10
justinwuzijin wants to merge 1 commit intomasterfrom
mongodb-integration

Conversation

@justinwuzijin
Copy link
Collaborator

@justinwuzijin justinwuzijin commented Jan 10, 2026

Summary by CodeRabbit

  • New Features

    • Added an API endpoint to retrieve collision data with customizable result limits (1-1000 records).
  • Chores

    • Added database support for collision data storage.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 10, 2026

📝 Walkthrough

Walkthrough

The changes add MongoDB integration to a Next.js application by introducing a database utility module for client management and collection access, creating a new API route for retrieving collision data with configurable query limits, and updating project dependencies to support these additions.

Changes

Cohort / File(s) Change Summary
MongoDB Integration
lib/mongodb.ts, package.json
Added new lib/mongodb.ts module with MongoDB client singleton management (development vs. production), URI validation and normalization, and typed collection helper. Updated package.json to include mongodb@^7.0.0 dependency and modified dev script to use Doppler runner.
Collision Data API
app/api/collisions/route.ts
Created new GET endpoint that parses and clamps limit query parameter (1–1000, default 100), queries collisions_2025 collection, and returns results as JSON response.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hoppy hops into MongoDB's burrow,
Collisions surface, no need to borrow,
Limits clamped, queries narrow,
Singleton patterns tomorrow!
✨ Doppler speeds the dev's arrow

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'added mongodb' is vague and generic, using minimal descriptive language that doesn't convey the actual implementation details or purpose of the changes. Revise the title to be more specific, such as 'Add MongoDB collisions API endpoint' or 'Implement MongoDB integration with collisions route' to better reflect the actual changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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

Comment @coderabbitai help to get the list of available commands and usage tips.

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

🤖 Fix all issues with AI agents
In @app/api/collisions/route.ts:
- Around line 1-16: The GET handler's limit parsing uses `parseInt(...) || 100`
which turns a valid 0 into 100 and hides parse errors; change the logic in `GET`
to parse `limitParam` with `Number.parseInt(limitParam ?? "100", 10)`, detect
NaN via `Number.isNaN(parsed)` and only use the 100 default when parsing fails,
then clamp the parsed value with `Math.max(0, Math.min(parsed, 1000))` (use 0 as
the minimum if you want to allow zero); add a try/catch around the DB calls (the
`getCollisionsCollection`, `collection.find(...).limit(limit).toArray()`
sequence) and return a controlled NextResponse with status 500 on error; finally
add a projection on the find (e.g. `collection.find({}, { projection: { _id: 0 }
})`) or map results to remove/transform `_id` before returning.

In @lib/mongodb.ts:
- Around line 62-66: getDb currently calls client.db(dbName) even when
process.env.MONGODB_DB is undefined, which can return an unintended default DB;
update getDb to explicitly validate that process.env.MONGODB_DB is set (e.g.,
const dbName = process.env.MONGODB_DB) and throw a clear error including the env
var name when it's missing before calling client.db(dbName); reference the getDb
function and clientPromise so the change is made in that function only.
- Around line 4-42: Remove the console.log statements that print the raw/uri
values (they leak secrets), call normalizeMongoUri on process.env.MONGODB_URI
and use the returned value for all subsequent validation and connection logic
(replace uses of the raw uri variable with the normalized value), and validate
the normalized URI with the existing startsWith checks (throw the same errors
but referencing the normalized value or its prefix snippet); ensure no sensitive
values are logged anywhere in this module.

In @package.json:
- Line 6: Add a Node engine constraint and a fallback dev script in
package.json: declare "engines.node" set to ">=20.19.0" to reflect
mongodb@^7.0.0 requirements and modify the scripts section to keep "dev" as
"doppler run -- next dev" while adding a new script name "dev:local" (or
"dev:plain") that runs "next dev" so developers can run locally without Doppler;
update package.json accordingly and, if desired, mention the Doppler requirement
in README.
🧹 Nitpick comments (1)
lib/mongodb.ts (1)

68-72: Align collection typing with Mongo documents (_id) or project it out.
db.collection<CollisionRecord>() implies returned docs match types/collision.ts exactly, but Mongo will include _id unless you project it out in queries (or you model the document type as CollisionRecord & { _id: ... }).

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b533a6 and 68b7ef8.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • app/api/collisions/route.ts
  • lib/mongodb.ts
  • package.json
🧰 Additional context used
🧬 Code graph analysis (2)
app/api/collisions/route.ts (1)
lib/mongodb.ts (1)
  • getCollisionsCollection (68-72)
lib/mongodb.ts (1)
types/collision.ts (1)
  • CollisionRecord (1-14)

Comment on lines +1 to +16
export const runtime = "nodejs";
import { NextResponse } from "next/server";
import { getCollisionsCollection } from "@/lib/mongodb";

export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const limitParam = searchParams.get("limit");
const limit = Math.max(
1,
Math.min(Number.parseInt(limitParam ?? "100", 10) || 100, 1000)
);
const collection = await getCollisionsCollection("collisions_2025");
const data = await collection.find({}).limit(limit).toArray();

return NextResponse.json({ data });
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix limit parsing (0 should not default to 100) + consider projection/error handling.
parseInt(...) || 100 treats 0 as invalid and returns 100. Also, consider projecting out _id (or mapping it) and returning a controlled error response on DB failures.

Proposed fix
 export async function GET(request: Request) {
   const { searchParams } = new URL(request.url);
   const limitParam = searchParams.get("limit");
-  const limit = Math.max(
-    1,
-    Math.min(Number.parseInt(limitParam ?? "100", 10) || 100, 1000)
-  );
-  const collection = await getCollisionsCollection("collisions_2025");
-  const data = await collection.find({}).limit(limit).toArray();
-
-  return NextResponse.json({ data });
+  const parsed = limitParam ? Number.parseInt(limitParam, 10) : NaN;
+  const limit = Math.max(1, Math.min(Number.isFinite(parsed) ? parsed : 100, 1000));
+
+  try {
+    const collection = await getCollisionsCollection();
+    const data = await collection
+      .find({}, { projection: { _id: 0 } })
+      .limit(limit)
+      .toArray();
+    return NextResponse.json({ data });
+  } catch (err) {
+    console.error("Failed to fetch collisions", err);
+    return NextResponse.json({ error: "Internal Server Error" }, { status: 500 });
+  }
 }
📝 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 const runtime = "nodejs";
import { NextResponse } from "next/server";
import { getCollisionsCollection } from "@/lib/mongodb";
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const limitParam = searchParams.get("limit");
const limit = Math.max(
1,
Math.min(Number.parseInt(limitParam ?? "100", 10) || 100, 1000)
);
const collection = await getCollisionsCollection("collisions_2025");
const data = await collection.find({}).limit(limit).toArray();
return NextResponse.json({ data });
}
export const runtime = "nodejs";
import { NextResponse } from "next/server";
import { getCollisionsCollection } from "@/lib/mongodb";
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const limitParam = searchParams.get("limit");
const parsed = limitParam ? Number.parseInt(limitParam, 10) : NaN;
const limit = Math.max(1, Math.min(Number.isFinite(parsed) ? parsed : 100, 1000));
try {
const collection = await getCollisionsCollection();
const data = await collection
.find({}, { projection: { _id: 0 } })
.limit(limit)
.toArray();
return NextResponse.json({ data });
} catch (err) {
console.error("Failed to fetch collisions", err);
return NextResponse.json({ error: "Internal Server Error" }, { status: 500 });
}
}
🤖 Prompt for AI Agents
In @app/api/collisions/route.ts around lines 1 - 16, The GET handler's limit
parsing uses `parseInt(...) || 100` which turns a valid 0 into 100 and hides
parse errors; change the logic in `GET` to parse `limitParam` with
`Number.parseInt(limitParam ?? "100", 10)`, detect NaN via
`Number.isNaN(parsed)` and only use the 100 default when parsing fails, then
clamp the parsed value with `Math.max(0, Math.min(parsed, 1000))` (use 0 as the
minimum if you want to allow zero); add a try/catch around the DB calls (the
`getCollisionsCollection`, `collection.find(...).limit(limit).toArray()`
sequence) and return a controlled NextResponse with status 500 on error; finally
add a projection on the find (e.g. `collection.find({}, { projection: { _id: 0 }
})`) or map results to remove/transform `_id` before returning.

Comment on lines +4 to +42
function normalizeMongoUri(raw: string | undefined) {
console.log("raw", raw);
if (!raw) return "";
let value = raw.trim();
// Strip surrounding quotes if present
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1);
}
// Remove accidental trailing semicolon
if (value.endsWith(";")) {
value = value.slice(0, -1);
}
// If there is stray punctuation right after the scheme (e.g., "mongodb+srv://;user")
// normalize it by removing non-alphanumeric chars immediately following "://"
value = value.replace(
/^(mongodb(?:\+srv)?:\/\/)\s*[^A-Za-z0-9]+/,
(_m, scheme) => `${scheme}`
);
return value;
}

const uri = process.env.MONGODB_URI;
console.log("uri", uri);
if (!uri) {
throw new Error("❌ MONGODB_URI is not defined");
}
console.log("uri.startsWith('mongodb://')", uri.startsWith("mongodb://"));
console.log("uri.startsWith('mongodb+srv://')", uri.startsWith("mongodb+srv://"));
if (!(uri.startsWith("mongodb://") || uri.startsWith("mongodb+srv://"))) {
throw new Error(
`❌ Invalid MONGODB_URI. It must start with "mongodb://" or "mongodb+srv://". Received prefix: ${uri.slice(
0,
20
)}...`
);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the lib/mongodb.ts file
find . -name "mongodb.ts" -type f 2>/dev/null

Repository: Lemirq/cision

Length of output: 73


🏁 Script executed:

# Check the size and content of lib/mongodb.ts
if [ -f "lib/mongodb.ts" ]; then
  wc -l lib/mongodb.ts
fi

Repository: Lemirq/cision

Length of output: 74


🏁 Script executed:

# Read the content of lib/mongodb.ts to verify the code state
if [ -f "lib/mongodb.ts" ]; then
  cat -n lib/mongodb.ts
fi

Repository: Lemirq/cision

Length of output: 2720


🌐 Web query:

mongodb driver v7 ObjectId JSON serialization toJSON() Next.js Route Handlers

💡 Result:

Short answer: convert ObjectId values to plain strings before returning them from Next.js Route Handlers (Next.js disallows objects with custom toJSON methods). Use ObjectId.toString() (or String(id)) when mapping documents, or serialize with a replacer/EJSON on the server — don’t rely on the driver’s toJSON behavior across versions.

Why + references:

  • Next.js route handlers enforce JSON-serializable plain values and will error on objects with toJSON methods. [1]
  • The MongoDB ObjectId exposes a toString() method to get the hex string. Use that to convert IDs. [2]
  • Driver v7 ships with bson v7 (breaking changes possible), so behavior may differ vs older drivers — explicitly converting is safer. [3]

Minimal example for an app-route handler (Next.js):

  • Map documents before returning:
    const docs = await collection.find({}).toArray();
    const out = docs.map(d => ({ ...d, _id: d._id.toString() }));
    return new Response(JSON.stringify(out), { headers: { 'Content-Type': 'application/json' } });

Alternative approaches:

  • Return only plain fields (e.g., replace _id with id string).
  • Use a JSON replacer: JSON.stringify(doc, (k, v) => (v && v._bsontype === 'ObjectId' ? v.toString() : v));
  • Use server-side EJSON serialization if you need to preserve BSON types and then decode client-side (but this adds complexity).

If you want, tell me your Next.js / mongodb package versions and I’ll give an exact snippet for your setup.

Sources:
[1] Next.js serialization / "Objects with toJSON methods are not supported".
[2] MongoDB docs: ObjectId.toString().
[3] MongoDB Node.js driver v7 docs / release notes.


🏁 Script executed:

# Search for all uses of normalizeMongoUri throughout the repo
rg "normalizeMongoUri" --type ts --type js

Repository: Lemirq/cision

Length of output: 125


Remove secret-leaking logs and apply normalizeMongoUri() before validation/connection.

The code logs raw and uri (which expose credentials) and validates the un-normalized URI directly, so quoted/semicolon URIs will fail even though the normalization function exists and should handle them.

Proposed fix
 function normalizeMongoUri(raw: string | undefined) {
-  console.log("raw", raw);
   if (!raw) return "";
   let value = raw.trim();
   // Strip surrounding quotes if present
   if (
     (value.startsWith('"') && value.endsWith('"')) ||
     (value.startsWith("'") && value.endsWith("'"))
   ) {
     value = value.slice(1, -1);
   }
   // Remove accidental trailing semicolon
   if (value.endsWith(";")) {
     value = value.slice(0, -1);
   }
   // If there is stray punctuation right after the scheme (e.g., "mongodb+srv://;user")
   // normalize it by removing non-alphanumeric chars immediately following "://"
   value = value.replace(
     /^(mongodb(?:\+srv)?:\/\/)\s*[^A-Za-z0-9]+/,
     (_m, scheme) => `${scheme}`
   );
   return value;
 }

-const uri = process.env.MONGODB_URI;
-console.log("uri", uri);
+const uri = normalizeMongoUri(process.env.MONGODB_URI);
 if (!uri) {
-  throw new Error("❌ MONGODB_URI is not defined");
+  throw new Error("MONGODB_URI is not defined");
 }
-console.log("uri.startsWith('mongodb://')", uri.startsWith("mongodb://"));
-console.log("uri.startsWith('mongodb+srv://')", uri.startsWith("mongodb+srv://"));
 if (!(uri.startsWith("mongodb://") || uri.startsWith("mongodb+srv://"))) {
   throw new Error(
-    `❌ Invalid MONGODB_URI. It must start with "mongodb://" or "mongodb+srv://". Received prefix: ${uri.slice(
-      0,
-      20
-    )}...`
+    'Invalid MONGODB_URI. It must start with "mongodb://" or "mongodb+srv://".'
   );
 }
📝 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
function normalizeMongoUri(raw: string | undefined) {
console.log("raw", raw);
if (!raw) return "";
let value = raw.trim();
// Strip surrounding quotes if present
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1);
}
// Remove accidental trailing semicolon
if (value.endsWith(";")) {
value = value.slice(0, -1);
}
// If there is stray punctuation right after the scheme (e.g., "mongodb+srv://;user")
// normalize it by removing non-alphanumeric chars immediately following "://"
value = value.replace(
/^(mongodb(?:\+srv)?:\/\/)\s*[^A-Za-z0-9]+/,
(_m, scheme) => `${scheme}`
);
return value;
}
const uri = process.env.MONGODB_URI;
console.log("uri", uri);
if (!uri) {
throw new Error("❌ MONGODB_URI is not defined");
}
console.log("uri.startsWith('mongodb://')", uri.startsWith("mongodb://"));
console.log("uri.startsWith('mongodb+srv://')", uri.startsWith("mongodb+srv://"));
if (!(uri.startsWith("mongodb://") || uri.startsWith("mongodb+srv://"))) {
throw new Error(
`❌ Invalid MONGODB_URI. It must start with "mongodb://" or "mongodb+srv://". Received prefix: ${uri.slice(
0,
20
)}...`
);
}
function normalizeMongoUri(raw: string | undefined) {
if (!raw) return "";
let value = raw.trim();
// Strip surrounding quotes if present
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1);
}
// Remove accidental trailing semicolon
if (value.endsWith(";")) {
value = value.slice(0, -1);
}
// If there is stray punctuation right after the scheme (e.g., "mongodb+srv://;user")
// normalize it by removing non-alphanumeric chars immediately following "://"
value = value.replace(
/^(mongodb(?:\+srv)?:\/\/)\s*[^A-Za-z0-9]+/,
(_m, scheme) => `${scheme}`
);
return value;
}
const uri = normalizeMongoUri(process.env.MONGODB_URI);
if (!uri) {
throw new Error("MONGODB_URI is not defined");
}
if (!(uri.startsWith("mongodb://") || uri.startsWith("mongodb+srv://"))) {
throw new Error(
'Invalid MONGODB_URI. It must start with "mongodb://" or "mongodb+srv://".'
);
}
🤖 Prompt for AI Agents
In @lib/mongodb.ts around lines 4 - 42, Remove the console.log statements that
print the raw/uri values (they leak secrets), call normalizeMongoUri on
process.env.MONGODB_URI and use the returned value for all subsequent validation
and connection logic (replace uses of the raw uri variable with the normalized
value), and validate the normalized URI with the existing startsWith checks
(throw the same errors but referencing the normalized value or its prefix
snippet); ensure no sensitive values are logged anywhere in this module.

Comment on lines +62 to +66
export async function getDb() {
const client = await clientPromise;
const dbName = process.env.MONGODB_DB;
return client.db(dbName);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle missing MONGODB_DB explicitly (avoid accidentally using the wrong database).
client.db(dbName) with dbName === undefined can silently select an unintended default DB.

Proposed fix (pick one behavior)
 export async function getDb() {
   const client = await clientPromise;
-  const dbName = process.env.MONGODB_DB;
-  return client.db(dbName);
+  const dbName = process.env.MONGODB_DB?.trim();
+  // Option A (strict): require explicit DB name
+  // if (!dbName) throw new Error("MONGODB_DB is not defined");
+  // return client.db(dbName);
+
+  // Option B (flexible): fall back to default DB from URI
+  return dbName ? client.db(dbName) : client.db();
 }
📝 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 getDb() {
const client = await clientPromise;
const dbName = process.env.MONGODB_DB;
return client.db(dbName);
}
export async function getDb() {
const client = await clientPromise;
const dbName = process.env.MONGODB_DB?.trim();
// Option A (strict): require explicit DB name
// if (!dbName) throw new Error("MONGODB_DB is not defined");
// return client.db(dbName);
// Option B (flexible): fall back to default DB from URI
return dbName ? client.db(dbName) : client.db();
}
🤖 Prompt for AI Agents
In @lib/mongodb.ts around lines 62 - 66, getDb currently calls client.db(dbName)
even when process.env.MONGODB_DB is undefined, which can return an unintended
default DB; update getDb to explicitly validate that process.env.MONGODB_DB is
set (e.g., const dbName = process.env.MONGODB_DB) and throw a clear error
including the env var name when it's missing before calling client.db(dbName);
reference the getDb function and clientPromise so the change is made in that
function only.

"private": true,
"scripts": {
"dev": "next dev",
"dev": "doppler run -- next 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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check package.json for Node version, Next.js version, and MongoDB version
cat package.json

Repository: Lemirq/cision

Length of output: 1191


🏁 Script executed:

# Check for .nvmrc file
if [ -f .nvmrc ]; then cat .nvmrc; else echo "No .nvmrc file found"; fi

Repository: Lemirq/cision

Length of output: 77


🌐 Web query:

MongoDB Node.js driver v7 Node.js version requirements compatibility

💡 Result:

Short answer: MongoDB Node.js driver v7 requires Node.js >= 20.19.0 (minimum support); older Node.js versions are not supported. The v7 release also updates TypeScript target to ES2023 and bumps related peer-dependencies. [1][2]

Sources:

  • Release notes for driver v7 (minimum Node.js v20.19.0, peer-dep changes). [1]
  • MongoDB Node.js driver compatibility docs. [2]

Add Node.js engine constraint and fallback dev script.

mongodb@^7.0.0 requires Node.js ≥ 20.19.0, but the repo does not document this in engines.node—add it to prevent mismatched local/CI builds. Additionally, npm run dev hard-requires Doppler with no fallback; add a dev:plain or dev:local script pointing to next dev for local development without Doppler, or document the Doppler setup requirement clearly.

Suggested fix:
{
  "engines": {
    "node": ">=20.19.0"
  },
  "scripts": {
    "dev": "doppler run -- next dev",
    "dev:local": "next dev"
  }
}
🤖 Prompt for AI Agents
In @package.json at line 6, Add a Node engine constraint and a fallback dev
script in package.json: declare "engines.node" set to ">=20.19.0" to reflect
mongodb@^7.0.0 requirements and modify the scripts section to keep "dev" as
"doppler run -- next dev" while adding a new script name "dev:local" (or
"dev:plain") that runs "next dev" so developers can run locally without Doppler;
update package.json accordingly and, if desired, mention the Doppler requirement
in README.

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.

1 participant