Skip to content

Conversation

@yashranaway
Copy link
Contributor

@yashranaway yashranaway commented Oct 8, 2025

πŸ“‹ Description

Add Express + MongoDB boilerplate guide with webhook handling and Mongo persistence. Link it under Integration Guides and Community β†’ Boilerplates.

🎯 Type of Change

  • πŸ“ Documentation update (improving existing docs)
  • ✨ New documentation (adding new guides, API docs, etc.)
  • πŸ› Bug fix (fixing errors, broken links, incorrect information)
  • 🎨 Style/formatting (improving readability, fixing formatting)
  • πŸ—οΈ Structural change (reorganizing content, navigation updates)
  • 🌐 Translation (adding or improving translations)
  • πŸ–ΌοΈ Assets (adding or updating images, diagrams)

πŸ“– What documentation does this PR affect?

  • Getting Started / Setup
  • API Reference
  • Developer Resources
  • Integration Guides
  • Features Documentation
  • External Integrations
  • Changelog
  • Other: Community β†’ Boilerplates & Starters

βœ… Checklist

  • I have read the Contributing Guidelines
  • I have tested my changes locally with mintlify dev
  • All links are working correctly
  • Images are properly displayed and optimized
  • Code examples are tested and working
  • I have updated the navigation in docs.json (if applicable)
  • My changes follow the project's style guide
  • I have performed a self-review of my changes
  • I have added appropriate frontmatter to new pages

πŸ§ͺ Testing

  • Verified locally at http://localhost:3000 (served at 3002)
  • Checked responsive design on mobile viewport
  • Tested all code examples
  • Validated all external links

πŸ“Έ Screenshots (if applicable)

N/A

πŸ”— Related Issues

Closes #99

πŸ“ Additional Notes

Includes dodopayments-webhooks usage, raw body verification, Mongo models, and routes.

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive Express + MongoDB boilerplate guide covering prerequisites, quickstart, project layout, payment and subscription integrations, webhook handling, environment configuration, and deployment notes.
    • Includes guidance on webhook signature verification, raw-body handling, input validation, idempotency, and error handling.
    • Added a new Boilerplates & Starters card and updated site navigation to include the guide under Developer Resources β†’ Integration Guides.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

Warning

Rate limit exceeded

@yashranaway has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 0 minutes and 7 seconds before requesting another review.

βŒ› How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 6364390 and 68ad90c.

πŸ“’ Files selected for processing (1)
  • developer-resources/express-mongodb-boilerplate.mdx (1 hunks)

Walkthrough

Adds an Express + MongoDB boilerplate guide and docs page, inserts it into Developer Resources navigation, and adds a corresponding Boilerplates & Starters card to the community projects listing.

Changes

Cohort / File(s) Summary of edits
Community listing update
community/projects.mdx
Added a new Card for "Express + MongoDB Boilerplate (Dodo Payments)" under the Boilerplates & Starters tab, placed before the existing DodoPayments Boilerplate entry.
New integration guide content
developer-resources/express-mongodb-boilerplate.mdx
Added a new developer guide describing an Express + MongoDB starter: prerequisites, project structure, env-driven config, DB client & models (Customer, Payment, Subscription), payments/subscriptions routes, webhook raw-body verification and handlers, quickstart/deployment notes, TypeScript interop, and code snippets.
Docs navigation update
docs.json
Inserted developer-resources/express-mongodb-boilerplate into Guides β†’ Integration Guides pages array (between developer-resources/checkout-session and developer-resources/subscription-upgrade-downgrade).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Client
  participant API as Express API
  participant Dodo as Dodo Payments
  participant DB as MongoDB

  rect rgba(200,235,255,0.18)
  note over API: Create Payment
  Dev->>API: POST /api/payments {amount,...}
  API->>Dodo: createPayment(payload)
  Dodo-->>API: payment {id,status}
  API->>DB: upsert Payment document
  API-->>Dev: 201 Created {payment}
  end
Loading
sequenceDiagram
  autonumber
  actor Dev as Client
  participant API as Express API
  participant Dodo as Dodo Payments
  participant DB as MongoDB

  rect rgba(220,255,220,0.18)
  note over API: Create Subscription
  Dev->>API: POST /api/subscriptions {plan,customer}
  API->>Dodo: createSubscription(payload)
  Dodo-->>API: subscription {id,status}
  API->>DB: upsert Subscription document
  API-->>Dev: 201 Created {subscription}
  end
Loading
sequenceDiagram
  autonumber
  participant Dodo as Dodo Payments
  participant API as Express Webhook Endpoint
  participant DB as MongoDB

  rect rgba(255,245,200,0.20)
  note over API: Webhook verification (raw body)
  Dodo->>API: POST /webhooks (signature + raw body)
  API->>API: verifySignature(rawBody, header)
  alt valid
    API->>DB: upsert/update by event type (subscription.active/on_hold, payment.succeeded/failed)
    API-->>Dodo: 200 OK
  else invalid
    API-->>Dodo: 400/401
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review focus: developer-resources/express-mongodb-boilerplate.mdx (code snippets, env names, webhook raw-body handling).
  • Confirm rendering and ordering in community/projects.mdx.
  • Validate JSON structure and ordering in docs.json.

Possibly related PRs

  • Update projects.mdxΒ #90 β€” Adds a boilerplate Card to community/projects.mdx; related because both modify the Boilerplates & Starters listing.

Poem

A rabbit hops in with a starter bright,
Routes hum softly in the code-lit night,
Webhooks verified, records tucked away,
Mongo keeps secrets, payments dance and play,
Fork the seedling, build by morning light πŸ₯•

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The PR addresses most coding-related requirements from issue #99, including code examples for webhook handling with dodopayments-webhooks, MongoDB persistence, raw body verification, and Mongo models/routes. The boilerplate documentation is properly added to both Integration Guides and Community Boilerplates & Starters as specified. However, a critical requirement from the issue description and commenter feedback is not clearly addressed: the explicit request to "Create a template of boilerplate code for how to start using Dodo Payments with Express + MongoDB in your Github profile" and the required comment stating "Create a GitHub repository in the contributor's account containing the boilerplate code and add a link to it in the PR so others can fork or access files directly." The PR appears to provide code examples within documentation files rather than delivering a separate, forklable GitHub repository that developers can use as a starter template. Verify that a GitHub repository containing the complete boilerplate code exists in the contributor's account and that a direct link to the repository is included in this PR or the documentation. This repository should be readily forklable and serve as a standalone starter template for developers. If such a repository exists, ensure its link is prominently featured in the PR materials so reviewers and users can access the boilerplate directly.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
βœ… Passed checks (3 passed)
Check name Status Explanation
Title Check βœ… Passed The PR title "feat: add Express + MongoDB boilerplate to community projects and doc…" clearly and concisely describes the primary change in the changeset. It accurately reflects that a new Express + MongoDB boilerplate is being added to both community projects and documentation. The title is specific and informative without being overly verbose, making it easy for developers scanning the history to understand the core purpose of the change.
Out of Scope Changes Check βœ… Passed All code changes in this PR are directly aligned with the objectives from issue #99. The modifications include adding a new Card entry to community/projects.mdx for the boilerplate, creating a new documentation file at developer-resources/express-mongodb-boilerplate.mdx with comprehensive examples and guidance, and updating docs.json to include the new page in the Integration Guides navigation. Each change serves a clear purpose in fulfilling the feature request to document and surface the Express + MongoDB boilerplate. No unrelated or tangential changes are present.
Description Check βœ… Passed The PR description follows the provided template comprehensively and includes all required sections: a clear description of changes, properly marked type of change selections (new documentation and structural change), affected documentation areas (Developer Resources, Integration Guides, and Community Boilerplates), and a completed checklist with all items marked as done. The description also includes testing verification, related issue linkage (#99), and additional context about the boilerplate features. All core template sections are filled out appropriately and substantively.

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
Contributor

@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

πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 8ce6a50 and 2ffccc6.

πŸ“’ Files selected for processing (3)
  • community/projects.mdx (1 hunks)
  • developer-resources/express-mongodb-boilerplate.mdx (1 hunks)
  • docs.json (1 hunks)
🧰 Additional context used
πŸ““ Path-based instructions (2)
**/*.{md,mdx}

πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)

Every documentation page must begin with YAML frontmatter containing title and description

Files:

  • community/projects.mdx
  • developer-resources/express-mongodb-boilerplate.mdx
**/*.mdx

πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)

**/*.mdx: Use clear, direct language appropriate for technical audiences
Write instructions in second person (you)
Use active voice over passive voice
Use present tense for current states and future tense for outcomes
Maintain consistent terminology across documentation
Keep sentences concise while preserving necessary context
Use parallel structure in lists, headings, and procedures
Lead sections with the most important information (inverted pyramid)
Use progressive disclosure: introduce basics before advanced topics
Break complex procedures into numbered steps using /
Include prerequisites and context before instructions
Provide expected outcomes for each major step
End sections with next steps or related information
Use descriptive, keyword-rich headings for navigation and SEO
Focus on user goals and outcomes rather than system features
Anticipate common questions and address them proactively
Include troubleshooting for likely failure points
Provide multiple pathways (beginner vs advanced) when appropriate, with an opinionated recommended path
Use for supplementary information that supports main content
Use for expert advice, shortcuts, or best practices
Use for critical cautions, breaking changes, or destructive actions
Use for neutral background or contextual information
Use for success confirmations or achievement indicators
Use to present the same concept in multiple languages
Provide complete, runnable code examples with language specified and filename when relevant
Include RequestExample/ResponseExample blocks for API endpoint docs
Document API parameters using (path, query, header, body) with types and required/defaults
Document API responses using with names, types, and required flags
Use for nested object properties or hierarchical information
Use / for platform-specific or alternative approaches
Use / for suppl...

Files:

  • community/projects.mdx
  • developer-resources/express-mongodb-boilerplate.mdx
πŸ”‡ Additional comments (2)
community/projects.mdx (1)

52-56: Card addition looks solid.

Clear positioning, concise pitch, and consistent tag list. Nice addition.

docs.json (1)

126-126: Navigation entry added in the right slot.

Keeps the Integration Guides grouping coherent.

Copy link
Contributor

@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 (2)
developer-resources/express-mongodb-boilerplate.mdx (2)

58-71: esModuleInterop guidance added β€” resolves prior blocker.

The Tip addresses the earlier default-import compilation issue and clearly sets required tsconfig flags. Good.


171-177: Fix no‑esModuleInterop example: default import of SDK will fail.

Without esModuleInterop, import DodoPayments from 'dodopayments' can break. Use TS import = require to instantiate safely.

Apply this diff:

-// src/routes/payments.ts (no esModuleInterop)
-import * as express from 'express';
-import DodoPayments from 'dodopayments';
+// src/routes/payments.ts (no esModuleInterop)
+import * as express from 'express';
+import DodoPayments = require('dodopayments');

 const client = new DodoPayments({ bearerToken: process.env.DODO_PAYMENTS_API_KEY });
 const router = express.Router();
🧹 Nitpick comments (8)
developer-resources/express-mongodb-boilerplate.mdx (8)

290-297: Add idempotency (dedup) for webhook events.

Retries can re-deliver the same event; current handler will reprocess. Dedup by webhook-id with a unique collection.

Apply these diffs to the snippets:

  1. models.ts: add ProcessedEvent model with unique _id
 // src/db/models.ts
 import mongoose from 'mongoose';
+const { Schema } = mongoose;
@@
 export const Payment = mongoose.model('Payment', PaymentSchema);
 export const Subscription = mongoose.model('Subscription', SubscriptionSchema);
+const ProcessedEventSchema = new Schema(
+  { _id: { type: String, required: true } },
+  { timestamps: true }
+);
+ProcessedEventSchema.index({ _id: 1 }, { unique: true });
+export const ProcessedEvent = mongoose.model('ProcessedEvent', ProcessedEventSchema);
  1. webhooks.ts: import and short-circuit on duplicates
-import { Subscription, Payment } from '../db/models';
+import { Subscription, Payment, ProcessedEvent } from '../db/models';
@@
-    await webhook.verify(rawBody, headers);
+    await webhook.verify(rawBody, headers);
+    // Idempotency: store event id; ignore if already processed
+    try {
+      await ProcessedEvent.create({ _id: headers['webhook-id'] });
+    } catch (e: any) {
+      if (e?.code === 11000) {
+        return res.json({ received: true });
+      }
+      throw e;
+    }

Also applies to: 299-315, 365-373


192-227: Return 500 for server errors; reserve 400 for bad input.

Currently all exceptions map to 400. Differentiate validation vs server errors.

Apply this diff in both routes:

   router.post('/', async (req, res) => {
-  try {
+  try {
     const {
@@
-    if (!billing || !customer || !product_cart) {
-      return res.status(400).json({ error: 'billing, customer, and product_cart are required' });
+    if (!billing || !customer || !product_cart) {
+      return res.status(400).json({ error: 'billing, customer, and product_cart are required' });
     }
@@
-    res.json(payment);
-  } catch (err: any) {
-    res.status(400).json({ error: err.message });
+    res.json(payment);
+  } catch (err: any) {
+    const status = err?.name === 'ValidationError' ? 400 : 500;
+    res.status(status).json({ error: err.message ?? 'Internal Server Error' });
   }

Repeat analogous change for subscriptions route (validation 400; others 500).

Also applies to: 242-279


98-121: Tighten Mongoose schema types and indexes.

Use Mixed/Map for metadata, and make ids unique for faster upserts and integrity.

Apply this diff:

-const CustomerSchema = new mongoose.Schema({
-  customerId: { type: String, index: true },
+const CustomerSchema = new mongoose.Schema({
+  customerId: { type: String, index: true, unique: true },
   email: String,
   name: String,
 });
 
-const PaymentSchema = new mongoose.Schema({
-  paymentId: { type: String, index: true },
+const PaymentSchema = new mongoose.Schema({
+  paymentId: { type: String, index: true, unique: true },
   status: String,
   amount: Number,
   currency: String,
   customerId: String,
-  metadata: {},
+  metadata: { type: mongoose.Schema.Types.Mixed, default: {} },
 });
 
-const SubscriptionSchema = new mongoose.Schema({
-  subscriptionId: { type: String, index: true },
+const SubscriptionSchema = new mongoose.Schema({
+  subscriptionId: { type: String, index: true, unique: true },
   status: String,
   productId: String,
   customerId: String,
   currentPeriodEnd: Date,
-  metadata: {},
+  metadata: { type: mongoose.Schema.Types.Mixed, default: {} },
 });

334-338: Consider upsert for state‑only updates.

If an on_hold/failed event arrives before initial creation, the update will no‑op. Upsert ensures record presence.

Apply this diff:

 await Subscription.updateOne(
   { subscriptionId: data.subscription_id },
-  { status: 'on_hold' }
+  { status: 'on_hold' },
+  { upsert: true }
 );
@@
 await Payment.updateOne(
   { paymentId: p.payment_id },
-  { status: 'failed' }
+  { status: 'failed' },
+  { upsert: true }
 );

Also applies to: 359-362


49-56: Use Steps and include a run/test step.

Make the Quickstart executable end‑to‑end with a start command and verification.

Apply this diff:

-## Quickstart
-
-```bash
-npm init -y
-npm install express mongoose cors dotenv dodopayments standardwebhooks
-npm install -D typescript ts-node @types/express @types/node @types/cors
-npx tsc --init
-```
+## Quickstart
+
+<Steps>
+  <Step title="Initialize project">
+    ```bash
+    npm init -y
+    npm install express mongoose cors dotenv dodopayments standardwebhooks
+    npm install -D typescript ts-node @types/express @types/node @types/cors
+    npx tsc --init
+    ```
+  </Step>
+  <Step title="Add a start script">
+    ```json filename="package.json"
+    {
+      "scripts": {
+        "dev": "ts-node src/app.ts"
+      }
+    }
+    ```
+  </Step>
+  <Step title="Run and verify">
+    ```bash
+    npm run dev
+    # Expect: "Server listening on :3000"
+    ```
+  </Step>
+</Steps>

73-80: Use realistic env examples and warn against committing secrets.

Prefer a local Mongo URI in examples and add a secrets warning.

Apply this diff:

-```bash
-DODO_PAYMENTS_API_KEY=sk_test_xxx
-DODO_WEBHOOK_SECRET=whsec_xxx
-MONGODB_URI=mongodb+srv://<user>:<pass>@<cluster>/dodo?retryWrites=true&w=majority
-PORT=3000
-```
+```bash
+DODO_PAYMENTS_API_KEY=sk_test_1234567890
+DODO_WEBHOOK_SECRET=whsec_1234567890
+# Local dev
+MONGODB_URI=mongodb://127.0.0.1:27017/dodo
+PORT=3000
+```
+
+<Warning>
+Never commit .env files or secrets to source control. Use environment variables in production.
+</Warning>

88-91: Handle connecting state and surface connection errors.

Avoid duplicate connects and add basic error handling.

Apply this diff:

 export async function connectDB(uri: string) {
-  if (mongoose.connection.readyState === 1) return;
-  await mongoose.connect(uri, { dbName: 'dodo' });
+  if (mongoose.connection.readyState === 1 || mongoose.connection.readyState === 2) return;
+  try {
+    await mongoose.connect(uri, { dbName: 'dodo' });
+  } catch (err) {
+    console.error('Mongo connection error', err);
+    throw err;
+  }
 }

379-381: Reinforce raw‑body constraint with a code hint.

Add a minimal snippet showing path‑scoped raw as an alternative to router‑level.

Apply this diff:

 <Warning>
 Ensure your Express app does not use `express.json()` on the webhook route, as it must read the raw body for signature verification.
+```ts
+// Alternative: path-scoped raw
+app.post('/webhooks/dodo', raw({ type: '*/*' }), webhooksRouter);
+```
 </Warning>
πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 2ffccc6 and 65439a4.

πŸ“’ Files selected for processing (1)
  • developer-resources/express-mongodb-boilerplate.mdx (1 hunks)
🧰 Additional context used
πŸ““ Path-based instructions (2)
**/*.{md,mdx}

πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)

Every documentation page must begin with YAML frontmatter containing title and description

Files:

  • developer-resources/express-mongodb-boilerplate.mdx
**/*.mdx

πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)

**/*.mdx: Use clear, direct language appropriate for technical audiences
Write instructions in second person (you)
Use active voice over passive voice
Use present tense for current states and future tense for outcomes
Maintain consistent terminology across documentation
Keep sentences concise while preserving necessary context
Use parallel structure in lists, headings, and procedures
Lead sections with the most important information (inverted pyramid)
Use progressive disclosure: introduce basics before advanced topics
Break complex procedures into numbered steps using /
Include prerequisites and context before instructions
Provide expected outcomes for each major step
End sections with next steps or related information
Use descriptive, keyword-rich headings for navigation and SEO
Focus on user goals and outcomes rather than system features
Anticipate common questions and address them proactively
Include troubleshooting for likely failure points
Provide multiple pathways (beginner vs advanced) when appropriate, with an opinionated recommended path
Use for supplementary information that supports main content
Use for expert advice, shortcuts, or best practices
Use for critical cautions, breaking changes, or destructive actions
Use for neutral background or contextual information
Use for success confirmations or achievement indicators
Use to present the same concept in multiple languages
Provide complete, runnable code examples with language specified and filename when relevant
Include RequestExample/ResponseExample blocks for API endpoint docs
Document API parameters using (path, query, header, body) with types and required/defaults
Document API responses using with names, types, and required flags
Use for nested object properties or hierarchical information
Use / for platform-specific or alternative approaches
Use / for suppl...

Files:

  • developer-resources/express-mongodb-boilerplate.mdx

Copy link
Contributor

@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: 0

🧹 Nitpick comments (1)
developer-resources/express-mongodb-boilerplate.mdx (1)

192-227: Consider extracting the DodoPayments client to a singleton utility.

Both payments.ts (line 189) and subscriptions.ts (line 240) instantiate a new DodoPayments client. Extracting this to a shared module (e.g., src/lib/dodo-client.ts) would eliminate duplication and avoid re-initializing the client on every request.

Example utility:

// src/lib/dodo-client.ts
import DodoPayments from 'dodopayments';

export const dodoClient = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
});

Then import and use in both routes:

import { dodoClient } from '../lib/dodo-client';

const payment = await dodoClient.payments.create({
  // ...
});

Also applies to: 242-279

πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 65439a4 and b7ca3ef.

πŸ“’ Files selected for processing (1)
  • developer-resources/express-mongodb-boilerplate.mdx (1 hunks)
🧰 Additional context used
πŸ““ Path-based instructions (2)
**/*.{md,mdx}

πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)

Every documentation page must begin with YAML frontmatter containing title and description

Files:

  • developer-resources/express-mongodb-boilerplate.mdx
**/*.mdx

πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)

**/*.mdx: Use clear, direct language appropriate for technical audiences
Write instructions in second person (you)
Use active voice over passive voice
Use present tense for current states and future tense for outcomes
Maintain consistent terminology across documentation
Keep sentences concise while preserving necessary context
Use parallel structure in lists, headings, and procedures
Lead sections with the most important information (inverted pyramid)
Use progressive disclosure: introduce basics before advanced topics
Break complex procedures into numbered steps using /
Include prerequisites and context before instructions
Provide expected outcomes for each major step
End sections with next steps or related information
Use descriptive, keyword-rich headings for navigation and SEO
Focus on user goals and outcomes rather than system features
Anticipate common questions and address them proactively
Include troubleshooting for likely failure points
Provide multiple pathways (beginner vs advanced) when appropriate, with an opinionated recommended path
Use for supplementary information that supports main content
Use for expert advice, shortcuts, or best practices
Use for critical cautions, breaking changes, or destructive actions
Use for neutral background or contextual information
Use for success confirmations or achievement indicators
Use to present the same concept in multiple languages
Provide complete, runnable code examples with language specified and filename when relevant
Include RequestExample/ResponseExample blocks for API endpoint docs
Document API parameters using (path, query, header, body) with types and required/defaults
Document API responses using with names, types, and required flags
Use for nested object properties or hierarchical information
Use / for platform-specific or alternative approaches
Use / for suppl...

Files:

  • developer-resources/express-mongodb-boilerplate.mdx
πŸ”‡ Additional comments (6)
developer-resources/express-mongodb-boilerplate.mdx (6)

58-71: βœ“ esModuleInterop requirement is now clearly explained.

The section properly addresses the previous critical issue by explicitly stating the requirement and showing the exact tsconfig.json configuration needed. Users will now understand why default imports require these flags before encountering compile errors.


299-299: βœ“ Webhook middleware now uses robust content-type handling.

The middleware now correctly uses raw({ type: '*/*' }) instead of the overly-specific application/json type, ensuring signature verification works with webhooks that use non-standard content-types (e.g., application/webhook+json or include charset parameters). This resolves the previous concern and aligns with Standard Webhooks best practices.


1-5: βœ“ Frontmatter is present with title and description.

The YAML frontmatter includes both required fields and an appropriate icon. The title and description are clear, descriptive, and SEO-friendly.


129-156: βœ“ App bootstrap logic is sound and middleware ordering is correct.

The code correctly applies express.json() only to /api routes (line 142), leaving the webhook route to use the raw body middleware separately (line 149). The comment on line 141 clearly documents this intent, and the subsequent section (lines 379–381) reinforces this critical detail.


283-377: βœ“ Webhook handler is well-structured with signature verification and idempotent updates.

The handler correctly:

  • Extracts and verifies Standard Webhooks headers
  • Calls webhook.verify() before processing
  • Uses upsert: true for safe, idempotent database updates
  • Handles multiple event types with a switch statement
  • Includes error handling that returns a 400 status on verification or database failures

The design ensures that replayed or out-of-order webhooks won't create duplicates or corrupt state.


7-15: βœ“ CardGroup links to relevant resources.

The two cards link readers to the Dodo Payments SDKs and Webhook Events Guide, providing natural pathways for deeper learning. The component placement and descriptions are clear and helpful.

@sancho1952007
Copy link
Contributor

  1. (Required) Please create the code in a Github repository on your account and add a link to it for easier access. You can keep the current content intact. This is so that people don't have to create the files and write content in them from scratch instead they can just fork your repository.

  2. (Recommendation) For webhook handling, you can use a Dodo Payments webhook handler library with good types support. If you want you can use the library I created.

Copy link
Contributor

@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: 3

🧹 Nitpick comments (3)
developer-resources/express-mongodb-boilerplate.mdx (3)

200-238: Payments route: Consider reusing a shared client instance for performance.

Creating a new DodoPayments client on every request (line 204) incurs unnecessary initialization overhead. For a production boilerplate, consider initializing the client once at module level or through a singleton pattern:

  // src/routes/payments.ts
  import { Router } from 'express';
  import DodoPayments from 'dodopayments';
  
+ const apiKey = process.env.DODO_PAYMENTS_API_KEY;
+ if (!apiKey) throw new Error('DODO_PAYMENTS_API_KEY is not set');
+ const client = new DodoPayments({ bearerToken: apiKey });
  const router = Router();
  
  router.post('/', async (req, res) => {
    try {
-     const apiKey = process.env.DODO_PAYMENTS_API_KEY;
-     if (!apiKey) return res.status(500).json({ error: 'DODO_PAYMENTS_API_KEY is not set' });
-     const client = new DodoPayments({ bearerToken: apiKey });
      const {

This pattern reduces initialization per-request and improves latency. Apply the same refactor to the subscriptions route.


252-291: Subscriptions route: Apply client reuse pattern.

Like the payments route, creating a new client per request (line 256) is inefficient. Use the same shared client instance approach:

  // src/routes/subscriptions.ts
  import { Router } from 'express';
  import DodoPayments from 'dodopayments';
  
+ const apiKey = process.env.DODO_PAYMENTS_API_KEY;
+ if (!apiKey) throw new Error('DODO_PAYMENTS_API_KEY is not set');
+ const client = new DodoPayments({ bearerToken: apiKey });
  const router = Router();
  
  router.post('/', async (req, res) => {
    try {
-     const apiKey = process.env.DODO_PAYMENTS_API_KEY;
-     if (!apiKey) return res.status(500).json({ error: 'DODO_PAYMENTS_API_KEY is not set' });
-     const client = new DodoPayments({ bearerToken: apiKey });
      const {

56-87: Add clarification that .env should never be committed to version control.

For a boilerplate guide, beginners might inadvertently commit secrets. Add a note in the .env section:

  `.env`:
  
+ <Warning>Never commit the `.env` file to version control. Add `.env` to your `.gitignore` immediately.</Warning>
+
  ```bash
  DODO_PAYMENTS_API_KEY=sk_test_xxx
  DODO_WEBHOOK_SECRET=whsec_xxx
  MONGODB_URI=mongodb+srv://<user>:<pass>@<cluster>/dodo?retryWrites=true&w=majority
  PORT=3000

</blockquote></details>

</blockquote></details>

<details>
<summary>πŸ“œ Review details</summary>

**Configuration used**: CodeRabbit UI

**Review profile**: CHILL

**Plan**: Pro

<details>
<summary>πŸ“₯ Commits</summary>

Reviewing files that changed from the base of the PR and between b7ca3efadec9858491b5de89224a058a65dc49ac and e7fece53cebde03c7b7375d2faacd7def28707ea.

</details>

<details>
<summary>πŸ“’ Files selected for processing (3)</summary>

* `community/projects.mdx` (1 hunks)
* `developer-resources/express-mongodb-boilerplate.mdx` (1 hunks)
* `docs.json` (1 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (2)</summary>

* community/projects.mdx
* docs.json

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>πŸ““ Path-based instructions (2)</summary>

<details>
<summary>**/*.{md,mdx}</summary>


**πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)**

> Every documentation page must begin with YAML frontmatter containing title and description

Files:
- `developer-resources/express-mongodb-boilerplate.mdx`

</details>
<details>
<summary>**/*.mdx</summary>


**πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)**

> `**/*.mdx`: Use clear, direct language appropriate for technical audiences
> Write instructions in second person (you)
> Use active voice over passive voice
> Use present tense for current states and future tense for outcomes
> Maintain consistent terminology across documentation
> Keep sentences concise while preserving necessary context
> Use parallel structure in lists, headings, and procedures
> Lead sections with the most important information (inverted pyramid)
> Use progressive disclosure: introduce basics before advanced topics
> Break complex procedures into numbered steps using <Steps>/<Step>
> Include prerequisites and context before instructions
> Provide expected outcomes for each major step
> End sections with next steps or related information
> Use descriptive, keyword-rich headings for navigation and SEO
> Focus on user goals and outcomes rather than system features
> Anticipate common questions and address them proactively
> Include troubleshooting for likely failure points
> Provide multiple pathways (beginner vs advanced) when appropriate, with an opinionated recommended path
> Use <Note> for supplementary information that supports main content
> Use <Tip> for expert advice, shortcuts, or best practices
> Use <Warning> for critical cautions, breaking changes, or destructive actions
> Use <Info> for neutral background or contextual information
> Use <Check> for success confirmations or achievement indicators
> Use <CodeGroup> to present the same concept in multiple languages
> Provide complete, runnable code examples with language specified and filename when relevant
> Include RequestExample/ResponseExample blocks for API endpoint docs
> Document API parameters using <ParamField> (path, query, header, body) with types and required/defaults
> Document API responses using <ResponseField> with names, types, and required flags
> Use <Expandable> for nested object properties or hierarchical information
> Use <Tabs>/<Tab> for platform-specific or alternative approaches
> Use <AccordionGroup>/<Accordion> for suppl...

Files:
- `developer-resources/express-mongodb-boilerplate.mdx`

</details>

</details><details>
<summary>🧠 Learnings (2)</summary>

<details>
<summary>πŸ“š Learning: 2025-09-15T12:32:29.480Z</summary>

Learnt from: CR
PR: dodopayments/dodo-docs#0
File: .cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-09-15T12:32:29.480Z
Learning: Applies to **/*.mdx : Use for critical cautions, breaking changes, or destructive actions


**Applied to files:**
- `developer-resources/express-mongodb-boilerplate.mdx`

</details>
<details>
<summary>πŸ“š Learning: 2025-09-15T12:32:29.480Z</summary>

Learnt from: CR
PR: dodopayments/dodo-docs#0
File: .cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-09-15T12:32:29.480Z
Learning: Applies to **/*.mdx : Add explanatory comments for complex logic in code examples


**Applied to files:**
- `developer-resources/express-mongodb-boilerplate.mdx`

</details>

</details>

</details>

<details>
<summary>πŸ”‡ Additional comments (1)</summary><blockquote>

<details>
<summary>developer-resources/express-mongodb-boilerplate.mdx (1)</summary><blockquote>

`1-5`: **Frontmatter is complete and compliant.**

</blockquote></details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
Contributor

@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: 2

♻️ Duplicate comments (2)
developer-resources/express-mongodb-boilerplate.mdx (2)

299-375: Critical: Webhook route must use raw body middleware, not express.json().

Line 308 uses express.json() to parse the request body before signature verification. This consumes the original raw bytes, preventing DodopaymentsHandler.handle(req) from verifying the HMAC SHA256 signature. Per past review feedback, replace express.json() with raw({ type: '*/*' }) to preserve the untransformed payload for all content-types:

  import { Router } from 'express';
  import express from 'express';
+ import { raw } from 'body-parser';
  import { Subscription, Payment } from '../db/models';
  import { DodopaymentsHandler } from 'dodopayments-webhooks';
  
  const router = Router();
  
- router.post('/', express.json(), async (req, res) => {
+ router.post('/', raw({ type: '*/*' }), async (req, res) => {
    try {
      const secret = process.env.DODO_WEBHOOK_SECRET;
      if (!secret) return res.status(500).json({ error: 'DODO_WEBHOOK_SECRET is not set' });
      const handler = new DodopaymentsHandler({ signing_key: secret });
      const event = await handler.handle(req);

Without this change, signature verification will fail on all webhook events.


381-386: Add <Warning> blocks to emphasize critical security deployment considerations.

The "Deploy Notes" section lists important items but lacks emphasis on critical security gotchas. Per coding guidelines and past review feedback, wrap the most security-sensitive items in <Warning> blocks so they visually stand out:

  ## Deploy Notes
  
- - Use environment variables for secrets
- - Prefer HTTPS for webhook endpoint
- - Configure retry-safe handlers (idempotent writes)
- - Add indexes on `paymentId`, `subscriptionId`, and `customerId`
+ <Warning>
+ **Never hardcode API keys or webhook secrets.** Always use environment variables, secret managers (e.g., AWS Secrets Manager, HashiCorp Vault), and rotate keys regularly with minimal time-to-live (TTL).
+ </Warning>
+ 
+ <Warning>
+ **Webhook endpoints must use HTTPS in production** to prevent man-in-the-middle attacks. Enforce TLS 1.2+, use HSTS headers, and verify certificate validity.
+ </Warning>
+ 
+ <Warning>
+ **Implement idempotent webhook handlers** using the `webhook-id` header to safely handle retries without duplicate processing. Check for existing webhook-ids before processing and persist the webhook-id in a deduplication log.
+ </Warning>
+ 
+ - Add database indexes on `paymentId`, `subscriptionId`, and `customerId` for query performance.
πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between e7fece5 and 6364390.

πŸ“’ Files selected for processing (1)
  • developer-resources/express-mongodb-boilerplate.mdx (1 hunks)
🧰 Additional context used
πŸ““ Path-based instructions (2)
**/*.{md,mdx}

πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)

Every documentation page must begin with YAML frontmatter containing title and description

Files:

  • developer-resources/express-mongodb-boilerplate.mdx
**/*.mdx

πŸ“„ CodeRabbit inference engine (.cursor/rules/mintlify.mdc)

**/*.mdx: Use clear, direct language appropriate for technical audiences
Write instructions in second person (you)
Use active voice over passive voice
Use present tense for current states and future tense for outcomes
Maintain consistent terminology across documentation
Keep sentences concise while preserving necessary context
Use parallel structure in lists, headings, and procedures
Lead sections with the most important information (inverted pyramid)
Use progressive disclosure: introduce basics before advanced topics
Break complex procedures into numbered steps using /
Include prerequisites and context before instructions
Provide expected outcomes for each major step
End sections with next steps or related information
Use descriptive, keyword-rich headings for navigation and SEO
Focus on user goals and outcomes rather than system features
Anticipate common questions and address them proactively
Include troubleshooting for likely failure points
Provide multiple pathways (beginner vs advanced) when appropriate, with an opinionated recommended path
Use for supplementary information that supports main content
Use for expert advice, shortcuts, or best practices
Use for critical cautions, breaking changes, or destructive actions
Use for neutral background or contextual information
Use for success confirmations or achievement indicators
Use to present the same concept in multiple languages
Provide complete, runnable code examples with language specified and filename when relevant
Include RequestExample/ResponseExample blocks for API endpoint docs
Document API parameters using (path, query, header, body) with types and required/defaults
Document API responses using with names, types, and required flags
Use for nested object properties or hierarchical information
Use / for platform-specific or alternative approaches
Use / for suppl...

Files:

  • developer-resources/express-mongodb-boilerplate.mdx
🧠 Learnings (4)
πŸ“š Learning: 2025-09-15T12:32:29.480Z
Learnt from: CR
PR: dodopayments/dodo-docs#0
File: .cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-09-15T12:32:29.480Z
Learning: Applies to **/*.mdx : Use <Update> to document versioned changes with clear labels and descriptions

Applied to files:

  • developer-resources/express-mongodb-boilerplate.mdx
πŸ“š Learning: 2025-09-15T12:32:29.480Z
Learnt from: CR
PR: dodopayments/dodo-docs#0
File: .cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-09-15T12:32:29.480Z
Learning: Applies to **/*.mdx : Use <Warning> for critical cautions, breaking changes, or destructive actions

Applied to files:

  • developer-resources/express-mongodb-boilerplate.mdx
πŸ“š Learning: 2025-09-15T12:32:29.480Z
Learnt from: CR
PR: dodopayments/dodo-docs#0
File: .cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-09-15T12:32:29.480Z
Learning: Applies to **/*.mdx : Add explanatory comments for complex logic in code examples

Applied to files:

  • developer-resources/express-mongodb-boilerplate.mdx
πŸ“š Learning: 2025-09-15T12:32:29.480Z
Learnt from: CR
PR: dodopayments/dodo-docs#0
File: .cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-09-15T12:32:29.480Z
Learning: Applies to **/*.mdx : Add warnings for destructive or security-sensitive actions using <Warning>

Applied to files:

  • developer-resources/express-mongodb-boilerplate.mdx
πŸ”‡ Additional comments (2)
developer-resources/express-mongodb-boilerplate.mdx (2)

1-5: Frontmatter is present and properly formatted.

The YAML frontmatter includes required title and description fields as per documentation guidelines.


65-78: TypeScript interop guidance is clear and correct.

The Tip section properly addresses the esModuleInterop requirement and provides both the recommended configuration and an alternative namespace-import approach for developers who prefer not to modify tsconfig.json. This resolves a critical compilation issue that was flagged in prior reviews.

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.

[Feature]: Create & add an Express + MongoDB boilerplate template

2 participants