-
Notifications
You must be signed in to change notification settings - Fork 28
feat: add Express + MongoDB boilerplate to community projects and doc⦠#115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add Express + MongoDB boilerplate to community projects and doc⦠#115
Conversation
|
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 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. π Files selected for processing (1)
WalkthroughAdds 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
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
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
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
Estimated code review effortπ― 3 (Moderate) | β±οΈ ~20 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touchesβ Failed checks (2 warnings)
β Passed checks (3 passed)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
π Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
π 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.mdxdeveloper-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.mdxdeveloper-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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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 TSimport = requireto 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:
- 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);
- 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
π 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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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) andsubscriptions.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
π 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.jsonconfiguration 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-specificapplication/jsontype, ensuring signature verification works with webhooks that use non-standard content-types (e.g.,application/webhook+jsonor 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/apiroutes (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: truefor 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.
|
β¦egration and improved webhook handling
β¦tegories with icons
β¦count Management, include express-mongodb-boilerplate in Integration Guides
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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
DodoPaymentsclient 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.envshould never be committed to version control.For a boilerplate guide, beginners might inadvertently commit secrets. Add a note in the
.envsection:`.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 -->
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
β»οΈ Duplicate comments (2)
developer-resources/express-mongodb-boilerplate.mdx (2)
299-375: Critical: Webhook route must use raw body middleware, notexpress.json().Line 308 uses
express.json()to parse the request body before signature verification. This consumes the original raw bytes, preventingDodopaymentsHandler.handle(req)from verifying the HMAC SHA256 signature. Per past review feedback, replaceexpress.json()withraw({ 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
π 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
titleanddescriptionfields as per documentation guidelines.
65-78: TypeScript interop guidance is clear and correct.The Tip section properly addresses the
esModuleInteroprequirement and provides both the recommended configuration and an alternative namespace-import approach for developers who prefer not to modifytsconfig.json. This resolves a critical compilation issue that was flagged in prior reviews.
β¦ication and library usage
π Description
Add Express + MongoDB boilerplate guide with webhook handling and Mongo persistence. Link it under Integration Guides and Community β Boilerplates.
π― Type of Change
π What documentation does this PR affect?
β Checklist
mintlify devdocs.json(if applicable)π§ͺ Testing
πΈ Screenshots (if applicable)
N/A
π Related Issues
Closes #99
π Additional Notes
Includes
dodopayments-webhooksusage, raw body verification, Mongo models, and routes.Summary by CodeRabbit