-
Notifications
You must be signed in to change notification settings - Fork 1
Introduced webhook support #31
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?
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
WalkthroughThis update introduces a comprehensive webhook system, enabling real-time email event notifications through customizable endpoints. It adds database schema changes, backend API routes, event processing logic with sandboxed code execution, and an enhanced UI for managing webhooks. Documentation and shared constants for webhook events are included, along with improved message status handling and type safety. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant WebApp
participant Backend
participant DB
User->>WebApp: Configure webhook (name, authCode, transformCode)
WebApp->>Backend: Create/Update webhook via API
Backend->>DB: Store webhook config
DB-->>Backend: Ack
Backend-->>WebApp: Success
Note over User,Backend: Later, an SMTP provider triggers a webhook event
participant SMTP
SMTP->>Backend: POST /webhook/:webhookId with payload
Backend->>DB: Lookup webhook config by webhookId
DB-->>Backend: Webhook config
Backend->>Backend: Run sandboxed authCode (if present)
alt Auth fails
Backend-->>SMTP: 401 Unauthorized
else Auth succeeds
Backend->>Backend: Run sandboxed transformCode (if present)
Backend->>Backend: Validate event schema
Backend->>DB: Find message by messageId and organizationId
alt Message found
Backend->>DB: Update message status and error message
Backend-->>SMTP: 200 OK
else Message not found
Backend-->>SMTP: 404 Not Found
end
end
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 7
🧹 Nitpick comments (6)
todo.md (1)
1-1: Consider hyphenating "To-dos".
LanguageTool flags that the plural noun “to-dos” should include a hyphen. Update the header from# Todosto# To-dosfor correct grammar.apps/web/package.json (2)
10-10: Addedcheck-typesscript
Great addition for enforcing type safety. Consider integrating this script into the CI pipeline to catch type errors automatically.
16-16: Monaco Editor dependencies
@monaco-editor/react,@types/react-syntax-highlighter, andmonaco-editorare correctly added. To optimize bundle size, consider externalizing Monaco workers or lazy-loading the editor in your Vite config.Also applies to: 24-24, 29-29
apps/backend/prisma/schema.prisma (1)
27-27: Added Webhooks relation to Organization
The one-to-many relation is correctly defined. Consider adding a unique constraint (e.g., onorganizationId+urlorname) to prevent duplicate webhooks per organization.apps/backend/src/webhook/query.ts (1)
27-34: Consider adding pagination for scalability.For organizations with many webhooks, returning all webhooks at once could impact performance. Consider implementing pagination with limit/offset or cursor-based pagination.
const webhooks = await prisma.webhook.findMany({ where: { organizationId: input.organizationId, }, orderBy: { createdAt: "desc", }, + take: input.limit || 20, + skip: input.offset || 0, })Don't forget to add
limitandoffsetto the input schema.apps/docs/src/app/webhooks/page.mdx (1)
46-57: Enhance the transform function example with timestamp handling.The example could better demonstrate timestamp handling, which is important for accurate event tracking.
function transform(payload, headers, query) { // Transform the provider-specific payload into LetterSpace format return { messageId: payload.messageId, // Required: External message ID event: payload.event, // Required: Event type - timestamp: payload.timestamp, // Optional: Event timestamp + timestamp: payload.timestamp || new Date().toISOString(), // Optional: Event timestamp (use current time if not provided) reason: payload.reason, // Optional: Failure/bounce reason } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (38)
.cursor/rules/general.mdc(1 hunks)RELEASE_NOTES.md(1 hunks)apps/backend/package.json(1 hunks)apps/backend/prisma/migrations/20250530060003_add_webhook_model/migration.sql(1 hunks)apps/backend/prisma/schema.prisma(4 hunks)apps/backend/src/app.ts(3 hunks)apps/backend/src/campaign/mutation.ts(1 hunks)apps/backend/src/cron/dailyMaintenance.ts(1 hunks)apps/backend/src/cron/sendMessages.ts(2 hunks)apps/backend/src/message/query.ts(1 hunks)apps/backend/src/stats/query.ts(1 hunks)apps/backend/src/subscriber/mutation.ts(3 hunks)apps/backend/src/utils/message-status.ts(1 hunks)apps/backend/src/webhook/handler.ts(1 hunks)apps/backend/src/webhook/mutation.ts(1 hunks)apps/backend/src/webhook/query.ts(1 hunks)apps/backend/src/webhook/router.ts(1 hunks)apps/docs/src/app/_meta.ts(1 hunks)apps/docs/src/app/api/_meta.ts(1 hunks)apps/docs/src/app/webhooks/_meta.ts(1 hunks)apps/docs/src/app/webhooks/page.mdx(1 hunks)apps/docs/src/components/index.ts(1 hunks)apps/docs/src/components/webhook-events-reference.tsx(1 hunks)apps/docs/src/mdx-components.tsx(2 hunks)apps/web/package.json(1 hunks)apps/web/src/components/alert-dialog-confirmation.tsx(3 hunks)apps/web/src/components/copy-button.tsx(1 hunks)apps/web/src/components/index.ts(1 hunks)apps/web/src/components/monaco-editor.tsx(1 hunks)apps/web/src/components/webhook-events-reference.tsx(1 hunks)apps/web/src/pages/dashboard/messages/message-status-badge.tsx(1 hunks)apps/web/src/pages/dashboard/messages/message-status-filter.tsx(1 hunks)apps/web/src/pages/dashboard/settings/page.tsx(3 hunks)apps/web/src/pages/dashboard/settings/webhook-form.tsx(1 hunks)apps/web/src/pages/dashboard/settings/webhook-settings.tsx(2 hunks)packages/shared/index.ts(1 hunks)packages/shared/webhook-events-data.ts(1 hunks)todo.md(1 hunks)
🧰 Additional context used
🪛 LanguageTool
todo.md
[grammar] ~1-~1: It appears that a hyphen is missing in the plural noun “to-dos”?
Context: # Todos - [x] I want the transform code and th...
(TO_DO_HYPHEN)
apps/docs/src/app/webhooks/page.mdx
[uncategorized] ~35-~35: Loose punctuation mark.
Context: ...``` The function receives: - headers: Request headers object - `body`: Reques...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~61-~61: Loose punctuation mark.
Context: ...``` The function receives: - payload: The raw webhook payload from your SMTP ...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~69-~69: Loose punctuation mark.
Context: ...med payload must include: - messageId: The external message ID from your SMTP ...
(UNLIKELY_OPENING_PUNCTUATION)
🔇 Additional comments (53)
.cursor/rules/general.mdc (1)
4-4: LGTM! Configuration change promotes development consistency.Enabling unconditional application of the development rules ensures consistent AI assistance behavior across the webhook implementation and future development work.
apps/backend/package.json (1)
42-42: Evaluate security implications ofvm2dependency.
Addingvm2enables sandboxed JS execution for webhook scripts, but it has had security advisories in the past. Please verify that version^3.9.19has no known vulnerabilities (e.g., vianpm auditor a vulnerability-scanning CI step) and ensure your usage restricts script capabilities to only what's necessary.apps/docs/src/app/api/_meta.ts (1)
1-8: Metadata module looks good.
The newmetaexport correctly defines the API Overview section for Nextra. No changes needed.apps/web/src/pages/dashboard/messages/message-status-badge.tsx (1)
46-50: NewCOMPLAINEDstatus mapping is consistent.
The addition ofCOMPLAINEDusing the same yellow styling asRETRYINGaligns with the backend enum changes and maintains UI consistency.apps/backend/src/stats/query.ts (1)
24-31: IncludeCOMPLAINEDin processed statuses.
Adding"COMPLAINED"toprocessedMessageStatusesensures it’s counted in overall stats, matching the updated enum and other query filters.apps/backend/src/campaign/mutation.ts (1)
201-211: Excellent improvement to data integrity!The change from a simple delete to a transactional operation ensures atomicity and prevents orphaned messages. This is a critical improvement that maintains referential integrity when campaigns are deleted.
apps/backend/src/message/query.ts (1)
16-17: Good addition of new message statuses.These new status values align well with the webhook system implementation. "COMPLAINED" supports tracking spam complaints from email providers, while "CANCELLED" enables proper status tracking for cancelled messages.
packages/shared/index.ts (1)
5-5: Clean addition to shared package exports.The new export follows the established pattern and makes webhook event data available across the monorepo. This enables proper code reuse for webhook-related functionality.
apps/web/src/components/index.ts (1)
16-17: Good additions to component exports.The new component exports follow the established pattern and support the webhook functionality. These enable consistent usage of webhook-related UI components throughout the application.
apps/docs/src/app/webhooks/_meta.ts (1)
1-7: Proper documentation metadata setup.The metadata configuration correctly follows the Nextra pattern and provides appropriate labeling for the webhook documentation section.
apps/docs/src/app/_meta.ts (1)
7-7: LGTM! Clean documentation metadata addition.The webhooks entry is properly added to the navigation metadata, following the existing pattern and maintaining alphabetical-ish ordering.
apps/docs/src/mdx-components.tsx (2)
3-3: LGTM! Proper component import.The WebhookEventsReference component is correctly imported from the local components module.
12-12: LGTM! Correct MDX component integration.The WebhookEventsReference component is properly added to the MDX components object with the right precedence order.
apps/docs/src/components/index.ts (1)
2-2: LGTM! Standard component export.The webhook-events-reference component is properly exported following the established pattern.
apps/web/src/pages/dashboard/messages/message-status-filter.tsx (1)
20-21: LGTM! Consistent status additions.The new message statuses "CANCELLED" and "COMPLAINED" are correctly added to the array, maintaining consistency with the existing pattern and extending the MessageStatus union type appropriately.
apps/backend/src/cron/dailyMaintenance.ts (1)
27-27: Verify the behavioral change in cleanup logic.This is a significant change from a whitelist to blacklist approach for message cleanup. The new logic will now include any message status not in
["QUEUED", "PENDING", "RETRYING"]for cleanup, including the newly added statuses like "CANCELLED" and "COMPLAINED".While this aligns with treating these as completed states, please verify that this change doesn't inadvertently clean up messages that should be preserved, especially if there are other message statuses not explicitly handled.
#!/bin/bash # Description: Verify all possible message statuses in the schema and codebase # Expected: Confirm all statuses are properly categorized as pending vs completed # Search for MessageStatus enum definition in Prisma schema rg -A 20 "enum MessageStatus" # Search for any other message status references to ensure completeness rg "MessageStatus|message.*status" --type ts -B 2 -A 2apps/backend/src/app.ts (3)
17-17: LGTM: Clean import integrationThe webhook imports are properly structured and follow the existing conventions in the file.
Also applies to: 23-23
34-34: LGTM: Proper tRPC router integrationThe webhookRouter is correctly integrated into the main appRouter following the established pattern.
153-153: LGTM: Strategic webhook endpoint placementThe webhook POST route is correctly positioned to handle direct HTTP requests before tRPC processing, which is appropriate for webhook endpoints.
apps/backend/src/cron/sendMessages.ts (2)
36-36: LGTM: Appropriate rate limiting inclusionIncluding "COMPLAINED" status in rate limiting is correct since these are successfully processed messages that should count against delivery limits.
103-110: LGTM: Logical campaign completion criteriaAdding "COMPLAINED" to the campaign completion status check is appropriate since it represents a final message state that should contribute to campaign completion determination.
apps/web/src/pages/dashboard/settings/page.tsx (3)
9-9: LGTM: Consistent import patternThe WebhookSettings import follows the established pattern for other settings components.
52-52: LGTM: Proper tab trigger integrationThe Webhooks tab trigger is correctly implemented following the existing TabsTrigger pattern.
78-80: LGTM: Consistent tab content structureThe webhooks TabsContent is properly structured and follows the established pattern for other settings tabs.
apps/docs/src/components/webhook-events-reference.tsx (4)
1-3: LGTM: Clean component setupThe import and component declaration follow React best practices with proper naming conventions.
5-20: LGTM: Well-structured documentation tableThe table implementation uses proper semantic HTML with comprehensive styling including dark mode support and clear column headers.
22-30: LGTM: Proper React list renderingThe row rendering follows React best practices with proper key usage and clean alternating row styling for improved readability.
31-48: LGTM: Well-formatted technical documentationThe cell content uses appropriate styling with monospace fonts for technical elements and proper code formatting for aliases, enhancing readability for developers.
apps/backend/src/webhook/router.ts (2)
1-3: LGTM: Clean import organizationThe imports follow the established pattern of separating tRPC router creation from operation implementations, promoting good code organization.
5-11: LGTM: Complete CRUD router implementationThe webhook router properly implements all standard CRUD operations (list, get, create, update, delete) following the established tRPC pattern with clear, consistent naming.
RELEASE_NOTES.md (3)
3-7: Well-documented feature additions
The new entries for Webhooks support, Complained Message Status, and Monaco Code Editor clearly summarize the enhancements.
11-11: Bug fix note is clear
The unsubscribe functionality fix is concisely noted under Bug Fixes.
15-16: Documentation link included
The link to the comprehensive webhook docs enhances discoverability.apps/backend/src/utils/message-status.ts (1)
1-13: Clear categorization of message statuses
The separation intopendingMessagesandcompletedMessagesis straightforward and aligns with the updated enum.apps/backend/prisma/schema.prisma (2)
203-203:COMPLAINEDstatus added
Integrates the new enum value for tracking spam complaints. Ensure existing data migrations handle this addition gracefully.
230-230: Index onmessageId
This index will improve lookup performance for message-related queries. Good catch.packages/shared/webhook-events-data.ts (1)
1-39: Canonical webhook events defined
TheWEBHOOK_EVENTSarray provides a clear mapping of event names, aliases, and statuses. Great alignment with backend enums.apps/backend/prisma/migrations/20250530060003_add_webhook_model/migration.sql (3)
1-2: LGTM! Clean enum extension.The addition of 'COMPLAINED' to the MessageStatus enum is well-implemented and aligns with the webhook functionality described in the PR summary.
4-17: Well-structured webhook table design.The table structure includes all necessary fields for webhook functionality:
- Standard metadata fields (id, name, url, timestamps)
- Business logic fields (isActive with sensible default, authCode, transformCode)
- Proper organization scoping with foreign key relationship
The design supports both authentication and payload transformation, which is essential for webhook integrations.
19-20: Appropriate foreign key constraint with CASCADE operations.The CASCADE operations for both DELETE and UPDATE ensure data integrity - when an organization is deleted or updated, all associated webhooks will be automatically handled. This prevents orphaned webhook records.
apps/web/src/components/alert-dialog-confirmation.tsx (2)
15-17: Good API enhancement for controlled state management.Making
triggeroptional and addingopen/onOpenChangeprops enables both controlled and uncontrolled usage patterns, increasing component flexibility.
38-39: Proper conditional rendering implementation.The conditional rendering of
AlertDialogTriggerprevents rendering issues when no trigger is provided, while the controlled props are correctly passed to the rootAlertDialogcomponent.apps/web/src/components/webhook-events-reference.tsx (2)
6-18: Well-designed component interface with sensible defaults.The props interface provides good flexibility while maintaining usability:
- Optional customization for title, description, and event list
- Sensible default values that work out of the box
- Proper TypeScript typing with imported shared types
27-47: Clean and accessible event display implementation.The event rendering logic is well-structured:
- Proper key usage for React lists
- Semantic HTML structure with appropriate spacing
- Good visual hierarchy with badges for names/aliases
- Informative status display with proper code formatting
apps/web/src/components/copy-button.tsx (2)
6-9: Good API enhancement for direct text copying.Making
onCopyoptional and adding thetextprop provides more flexibility for different use cases - direct text copying vs. custom copy logic.
14-22: Proper implementation of dual copy modes.The logic correctly prioritizes direct text copying over callback execution, providing clear behavior when both options are available. The async handling and user feedback timing are appropriate.
apps/web/src/components/monaco-editor.tsx (4)
6-15: Comprehensive and well-typed component interface.The props interface covers all essential Monaco editor features:
- Standard editor props (value, onChange, language)
- UI customization (placeholder, className, height)
- State management (disabled)
- Monaco-specific options for advanced configuration
29-31: Proper value normalization for controlled input.The
handleChangefunction correctly normalizes undefined values to empty strings, ensuring consistent behavior for controlled React components.
33-48: Excellent default editor configuration.The default options provide a great out-of-the-box experience for code editing:
- Disabled minimap saves space
- Proper font size and line numbers
- Word wrap and automatic layout for responsive behavior
- Correct read-only mode based on disabled state
- Sensible scroll behavior
54-66: Good theme integration and loading UX.The theme switching based on the application theme and the loading placeholder with customizable text provide excellent user experience.
apps/backend/src/webhook/handler.ts (1)
101-108: Good security practice with organization-scoped message lookup.The message lookup is properly scoped to the webhook's organization through the Campaign relationship, preventing cross-organization data access.
apps/backend/src/subscriber/mutation.ts (1)
369-403: Good implementation of transactional unsubscribe with message cancellation.The transaction wrapper ensures atomicity between the unsubscribe operation and message cancellation. The query correctly identifies pending messages that should be cancelled based on the campaign lists.
apps/web/src/pages/dashboard/settings/webhook-settings.tsx (1)
1-285: Excellent refactor with improved maintainability and UX.The refactor successfully:
- Extracts form logic into a reusable
WebhookFormcomponent- Implements proper state management for CRUD operations
- Adds comprehensive error handling with user feedback
- Provides intuitive empty states and loading indicators
- Uses controlled dialogs with proper key management for re-rendering
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: 4
🧹 Nitpick comments (8)
apps/backend/prisma/client/sql/index.edge.js (1)
4-4: Note: Redundant "use strict" directive in generated code.The static analysis tool correctly identifies that the "use strict" directive is redundant in ES6 modules. However, since this is generated Prisma code (as indicated by the header comment), this should be addressed in the Prisma code generator configuration rather than manual editing.
Consider updating the Prisma client generation settings to remove redundant "use strict" directives from generated files.
apps/backend/prisma/client/sql/index.js (1)
4-4: Note: Redundant "use strict" directive in generated code.Same issue as in
index.edge.js- the "use strict" directive is redundant in ES6 modules. Since this is generated Prisma code, address this in the generator configuration rather than manual editing.apps/web/src/pages/dashboard/messages/message-id-cell.tsx (1)
13-17: Consider adding error handling for clipboard operations.The clipboard API call could fail in certain browsers or security contexts. Consider adding error handling:
const copyToClipboard = () => { if (messageId) { - navigator.clipboard.writeText(messageId) - toast.success("Message ID copied to clipboard") + navigator.clipboard.writeText(messageId).then(() => { + toast.success("Message ID copied to clipboard") + }).catch(() => { + toast.error("Failed to copy message ID") + }) } }apps/backend/src/cron/cleanupWebhookLogs.ts (2)
40-43: Remove unnecessary continue statement.The
continuestatement is unnecessary since it's the last statement in the loop iteration.} catch (error) { console.error(`Error deleting webhook logs for org ${org.id}: ${error}`) - continue }
17-20: Consider validating cleanup interval bounds.While the default 90-day cleanup interval is reasonable, consider adding validation to prevent extremely short intervals that could cause excessive database operations or data loss.
- const cleanupIntervalDays = org.GeneralSettings?.cleanupInterval ?? 90 + const cleanupIntervalDays = Math.max(1, org.GeneralSettings?.cleanupInterval ?? 90)apps/docs/src/app/webhooks/page.mdx (1)
29-29: Critical security consideration appropriately documented.The security warning about plain text storage of authentication code and secrets is crucial for users to understand. Consider implementing encrypted storage for sensitive data in future versions.
apps/web/src/pages/dashboard/settings/webhook-settings.tsx (2)
28-30: Consider removing redundant date formatting library.The component imports both
date-fnsanddayjsfor date formatting. This creates unnecessary bundle bloat and potential confusion. Sincedayjsis used for relative time formatting anddate-fnsfor absolute dates, consider standardizing on one library.Replace the
date-fnsimport and usage withdayjs:-import { format } from "date-fns" -import dayjs from "dayjs" -import relativeTime from "dayjs/plugin/relativeTime" +import dayjs from "dayjs" +import relativeTime from "dayjs/plugin/relativeTime"Then update line 232:
-{format(new Date(webhook.createdAt), "MMM d, yyyy")} +{dayjs(webhook.createdAt).format("MMM D, YYYY")}
310-318: Consider extracting large components for better maintainability.This component handles multiple responsibilities (listing, creating, editing, deleting webhooks). While functional, it could benefit from being split into smaller, focused components.
Consider extracting:
WebhookListcomponent for the table renderingWebhookActionscomponent for the action buttonsWebhookDeleteDialogas a separate componentThis would improve testability and maintainability while keeping the logic centralized in the main component.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (49)
apps/backend/package.json(2 hunks)apps/backend/prisma/client/sql/$DbEnums.d.ts(1 hunks)apps/backend/prisma/client/sql/countDbSize.d.ts(1 hunks)apps/backend/prisma/client/sql/countDbSize.edge.js(1 hunks)apps/backend/prisma/client/sql/countDbSize.edge.mjs(1 hunks)apps/backend/prisma/client/sql/countDbSize.js(1 hunks)apps/backend/prisma/client/sql/countDbSize.mjs(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipients.d.ts(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipients.edge.js(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipients.edge.mjs(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipients.js(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipients.mjs(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.d.ts(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.edge.js(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.edge.mjs(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.js(1 hunks)apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.mjs(1 hunks)apps/backend/prisma/client/sql/index.d.ts(1 hunks)apps/backend/prisma/client/sql/index.edge.js(1 hunks)apps/backend/prisma/client/sql/index.edge.mjs(1 hunks)apps/backend/prisma/client/sql/index.js(1 hunks)apps/backend/prisma/client/sql/index.mjs(1 hunks)apps/backend/prisma/client/sql/subscriberGrowthQuery.d.ts(1 hunks)apps/backend/prisma/client/sql/subscriberGrowthQuery.edge.js(1 hunks)apps/backend/prisma/client/sql/subscriberGrowthQuery.edge.mjs(1 hunks)apps/backend/prisma/client/sql/subscriberGrowthQuery.js(1 hunks)apps/backend/prisma/client/sql/subscriberGrowthQuery.mjs(1 hunks)apps/backend/prisma/migrations/20250621175427_add_transformed_payload_to_webhook_logs/migration.sql(1 hunks)apps/backend/prisma/migrations/20250621191015_remove_webhook_url_field/migration.sql(1 hunks)apps/backend/prisma/schema.prisma(4 hunks)apps/backend/prisma/sql/countDbSize.sql(3 hunks)apps/backend/src/cron/cleanupWebhookLogs.ts(1 hunks)apps/backend/src/cron/cron.ts(2 hunks)apps/backend/src/lib/Mailer.ts(2 hunks)apps/backend/src/utils/message-id.test.ts(1 hunks)apps/backend/src/utils/message-id.ts(1 hunks)apps/backend/src/webhook/handler.ts(1 hunks)apps/backend/src/webhook/mutation.ts(1 hunks)apps/backend/src/webhook/processor.ts(1 hunks)apps/backend/src/webhook/types.ts(1 hunks)apps/docs/src/app/_meta.ts(1 hunks)apps/docs/src/app/webhooks/page.mdx(1 hunks)apps/web/src/pages/dashboard/messages/columns.tsx(2 hunks)apps/web/src/pages/dashboard/messages/message-id-cell.tsx(1 hunks)apps/web/src/pages/dashboard/settings/page.tsx(3 hunks)apps/web/src/pages/dashboard/settings/webhook-details.tsx(1 hunks)apps/web/src/pages/dashboard/settings/webhook-form.tsx(1 hunks)apps/web/src/pages/dashboard/settings/webhook-settings.tsx(3 hunks)package.json(2 hunks)
✅ Files skipped from review due to trivial changes (13)
- apps/backend/prisma/client/sql/index.d.ts
- apps/backend/prisma/client/sql/index.edge.mjs
- apps/backend/prisma/client/sql/countDistinctRecipients.edge.mjs
- apps/backend/prisma/migrations/20250621175427_add_transformed_payload_to_webhook_logs/migration.sql
- apps/backend/prisma/client/sql/index.mjs
- apps/docs/src/app/_meta.ts
- apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.edge.mjs
- apps/backend/prisma/client/sql/subscriberGrowthQuery.mjs
- apps/backend/prisma/client/sql/countDistinctRecipients.mjs
- apps/backend/prisma/client/sql/subscriberGrowthQuery.edge.mjs
- apps/backend/src/utils/message-id.ts
- apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.mjs
- apps/web/src/pages/dashboard/settings/webhook-details.tsx
🚧 Files skipped from review as they are similar to previous changes (9)
- apps/backend/package.json
- package.json
- apps/web/src/pages/dashboard/settings/page.tsx
- apps/backend/src/webhook/mutation.ts
- apps/backend/src/webhook/types.ts
- apps/web/src/pages/dashboard/settings/webhook-form.tsx
- apps/backend/src/webhook/processor.ts
- apps/backend/src/webhook/handler.ts
- apps/backend/prisma/schema.prisma
🧰 Additional context used
🪛 Biome (1.9.4)
apps/backend/src/cron/cleanupWebhookLogs.ts
[error] 42-42: Unnecessary continue statement
Unsafe fix: Delete the unnecessary continue statement
(lint/correctness/noUnnecessaryContinue)
apps/backend/prisma/client/sql/countDbSize.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/countDbSize.edge.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/countDistinctRecipients.edge.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/countDistinctRecipients.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.d.ts
[error] 8-8: Duplicate parameter name.
The parameter overrides a preceding parameter by using the same name.
(lint/suspicious/noDuplicateParameters)
apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.edge.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/index.edge.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/index.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/subscriberGrowthQuery.d.ts
[error] 8-8: Duplicate parameter name.
The parameter overrides a preceding parameter by using the same name.
(lint/suspicious/noDuplicateParameters)
apps/backend/prisma/client/sql/subscriberGrowthQuery.edge.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
apps/backend/prisma/client/sql/subscriberGrowthQuery.js
[error] 3-4: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
🪛 LanguageTool
apps/docs/src/app/webhooks/page.mdx
[uncategorized] ~49-~49: Loose punctuation mark.
Context: ...``` The function receives: - headers: Request headers object - `body`: Reques...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~86-~86: Loose punctuation mark.
Context: ...``` The function receives: - payload: The raw webhook payload sent by your SM...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~94-~94: Loose punctuation mark.
Context: ...rm function must include: - messageId: The external message ID provided by you...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~99-~99: Possible missing comma found.
Context: ... webhook system works with popular SMTP providers including: - SendGrid: Configure t...
(AI_HYDRA_LEO_MISSING_COMMA)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Build and Push Bun Image
- GitHub Check: Build and Push Node Image
🔇 Additional comments (42)
apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.js (1)
1-7: Auto-generated Prisma client – no manual edits neededThis file is generated by Prisma; the only changes are stylistic. The SQL, function signature, and behavior are unchanged.
apps/backend/prisma/client/sql/countDistinctRecipientsInTimeRange.edge.js (1)
1-7: Skip review: Generated Prisma client file
This is an auto-generated file by Prisma (per the header). All formatting changes originate from the code generator, so manual edits are not needed or recommended.apps/backend/prisma/client/sql/subscriberGrowthQuery.js (2)
4-4: Ignore redundant 'use strict' directive in generated file
This file is auto-generated by Prisma; manual edits here will be overwritten. Address this at the generator configuration level if needed.
5-6: Approve SQL formatting and factory call style
The refactored query string and factory invocation align with project conventions and introduce no functional changes.apps/backend/prisma/client/sql/subscriberGrowthQuery.edge.js (4)
1-1: Remove extraneous leading newline
The leading blank line has been trimmed, which is purely cosmetic.
4-4: Retainuse strictin generated code
Although modules are implicitly strict, this file is auto-generated by Prisma—avoid manual edits.
5-5: Single-line import invocation is fine
Converting therequirecall to a single line is a harmless stylistic change.
6-6: Single-line SQL string preserves logic
Switching from a multi-line to a single-line"\n"-delimited string doesn’t alter the query’s behavior.apps/backend/prisma/client/sql/$DbEnums.d.ts (1)
5-6: LGTM! Enum extensions support webhook functionality well.The additions to both
CampaignStatusandMessageStatusenums are well-aligned with webhook event processing requirements. The new message statuses (AWAITING_WEBHOOK,CANCELLED,COMPLAINED) provide necessary granularity for tracking email delivery states in webhook scenarios.apps/backend/prisma/migrations/20250621191015_remove_webhook_url_field/migration.sql (1)
7-11: LGTM! Migration follows proper sequence and aligns with architectural changes.The migration correctly drops the unique index before removing the column, which is the proper order to avoid constraint violations. The change aligns with the architectural shift to dynamically constructed webhook URLs.
Ensure that any existing webhook data migration or cleanup is handled appropriately in the application code, since this migration will result in data loss for the
urlcolumn.apps/backend/src/lib/Mailer.ts (2)
4-4: Good addition of utility import for message ID normalization.Importing
stripAngleBracketsutility supports consistent message ID formatting across the webhook system.
92-94: LGTM! Proper message ID sanitization with null safety.The conditional application of
stripAngleBracketsensures that message IDs are normalized while properly handling undefined values. This standardization is important for webhook event correlation and message tracking.apps/backend/prisma/client/sql/countDistinctRecipients.edge.js (2)
4-4: Address the redundant "use strict" directive.The static analysis tool correctly identified that the "use strict" directive is redundant in ES modules. However, since this is Prisma-generated code (as indicated by the comment on line 2), this should be addressed in the Prisma configuration or generator settings rather than manually editing this file.
5-6: LGTM - Formatting improvements in generated code.The consolidation of the multi-line factory call and string formatting changes improve readability while maintaining the same functionality.
apps/web/src/pages/dashboard/messages/columns.tsx (2)
73-77: LGTM - Well-structured column addition.The new Message ID column follows the established pattern and integrates cleanly with the existing column definitions. The use of a dedicated
MessageIdCellcomponent promotes reusability and separation of concerns.
7-7: Verify the MessageIdCell component exists.Ensure that the
MessageIdCellcomponent is properly implemented and exported from the specified path.#!/bin/bash # Description: Verify MessageIdCell component exists and is properly exported # Check if the MessageIdCell component file exists fd "message-id-cell" --type f # Verify the component is properly exported if [ -f "apps/web/src/pages/dashboard/messages/message-id-cell.tsx" ]; then echo "Found MessageIdCell file, checking exports:" rg "export.*MessageIdCell" apps/web/src/pages/dashboard/messages/message-id-cell.tsx fiapps/backend/src/cron/cron.ts (3)
35-40: LGTM - Appropriate cron job configuration.The webhook logs cleanup job is well-configured:
- Daily execution at 1 AM is appropriate for maintenance tasks
- Follows the established pattern for other cron jobs
- Enabled by default is reasonable for log cleanup
46-46: LGTM - Proper integration with existing cron system.The new job is correctly added to the cronJobs array and will be properly initialized by the existing cron management system.
5-5: Verify the cleanupWebhookLogsCron function exists.Ensure that the imported
cleanupWebhookLogsCronfunction is properly implemented and exported.#!/bin/bash # Description: Verify cleanupWebhookLogsCron function exists and is properly exported # Check if the cleanupWebhookLogs file exists fd "cleanupWebhookLogs" --type f # Verify the function is properly exported if [ -f "apps/backend/src/cron/cleanupWebhookLogs.ts" ]; then echo "Found cleanupWebhookLogs file, checking exports:" rg "export.*cleanupWebhookLogsCron" apps/backend/src/cron/cleanupWebhookLogs.ts fiapps/backend/prisma/client/sql/countDbSize.d.ts (2)
18-18: LGTM - Consistent type addition for webhook logs.The new
webhook_log_countfield follows the same pattern as other count fields (nullable bigint), which is appropriate for aggregated count data that may be null when no records exist.
9-21: LGTM - Improved formatting consistency.The removal of unnecessary parentheses and semicolons improves code consistency and readability while maintaining the same type definitions.
apps/backend/prisma/sql/countDbSize.sql (3)
82-82: LGTM - Consistent integration with existing size calculation.The webhook log count and size calculations are properly integrated:
- Count is included in the SELECT clause
- Sizes are added to the total size calculation following the same pattern
- All values are properly coalesced to handle null cases
Also applies to: 97-99
107-107: LGTM - Proper LEFT JOIN pattern.The LEFT JOIN with
webhook_log_storagefollows the same pattern as other storage CTEs, ensuring organizations without webhook logs are still included in the results.
60-72: Verify webhook table schema and relationships.The new CTE follows the established pattern, but ensure that:
- The
WebhookLogandWebhooktables exist with the referenced fields- The relationship between
WebhookLog.webhookIdandWebhook.idis properly defined- The
requestBodyfield casting to::textis appropriate for its data type#!/bin/bash # Description: Verify webhook table schema in Prisma schema # Check for Webhook and WebhookLog models in schema rg -A 10 "model Webhook" apps/backend/prisma/schema.prisma rg -A 10 "model WebhookLog" apps/backend/prisma/schema.prisma # Check for the relationship fields rg "webhookId.*Webhook" apps/backend/prisma/schema.prismaapps/backend/prisma/client/sql/countDistinctRecipients.js (1)
1-6: LGTM: Formatting improvements in generated code.The formatting changes improve code consistency by removing unnecessary whitespace and consolidating the export statement. While the static analysis tool flags the redundant
"use strict"directive, this is generated code from Prisma, so direct modifications may be overwritten during regeneration.apps/web/src/pages/dashboard/messages/message-id-cell.tsx (2)
12-18: Good component structure and error handling.The component properly handles the null messageId case and implements clipboard functionality with user feedback. The TypeScript typing is correct and the null check prevents runtime errors.
24-54: Well-structured dialog implementation.The dialog structure follows good accessibility patterns with proper header, content organization, and responsive design. The monospace font for message ID display and the copy button placement are user-friendly design choices.
apps/backend/prisma/client/sql/countDistinctRecipients.d.ts (1)
6-12: LGTM: Improved type declaration formatting.The consolidation to a single-line arrow function type makes the declaration more concise while preserving all type information. The parameter and return types remain unchanged, maintaining API compatibility.
apps/backend/src/utils/message-id.test.ts (1)
4-78: Excellent test coverage with comprehensive edge cases.The test suite thoroughly covers the
stripAngleBracketsfunction with well-named test cases that include:
- Normal cases with both brackets
- Edge cases with single brackets
- Empty strings and bracket-only strings
- Complex message ID formats with timestamps and UUIDs
- Multiple consecutive brackets
The test structure follows good practices with descriptive test names and clear assertions.
apps/backend/src/cron/cleanupWebhookLogs.ts (1)
5-54: Well-structured cron job with appropriate error handling.The webhook log cleanup logic is sound with proper organization-specific cleanup intervals and comprehensive logging. The database query correctly filters by organization and creation date.
apps/backend/prisma/client/sql/countDbSize.js (1)
6-6: Well-structured webhook log storage calculation.The SQL logic correctly adds webhook log metrics to the database size calculation. The CTE properly joins
WebhookLogandWebhooktables, handles null values withCOALESCE, and includes all relevant size calculations (request body, response body, error messages).apps/backend/prisma/client/sql/countDbSize.mjs (1)
5-5: Consistent implementation across module formats.The ESM version correctly mirrors the CommonJS implementation with identical SQL logic for webhook log storage calculation.
apps/backend/prisma/client/sql/countDbSize.edge.js (1)
6-6: Edge runtime implementation maintains consistency.The edge runtime version correctly implements the same webhook log storage calculations with appropriate runtime-specific imports.
apps/backend/prisma/client/sql/countDbSize.edge.mjs (1)
5-5: Complete coverage across runtime and module formats.All four generated client variants now consistently include webhook log storage calculations, ensuring proper database size metrics regardless of the runtime environment.
apps/docs/src/app/webhooks/page.mdx (4)
58-67: Well-documented runtime limits enhance security and stability.The sandboxed execution environment with configurable limits (timeout, memory, stack size) provides good protection against resource exhaustion and malicious code execution.
70-82: Clear transform function specification.The example provides a good template for users implementing transform functions. The required/optional field specification is helpful for proper integration.
99-107: Comprehensive SMTP provider coverage.The documentation covers major SMTP providers and explains the necessity of transform functions due to varying payload formats. This will help users understand the integration requirements.
129-137: Complete HTTP status code reference.The response codes are well-documented and cover all the expected scenarios, helping developers debug webhook integration issues.
apps/web/src/pages/dashboard/settings/webhook-settings.tsx (4)
42-49: Good implementation of conditional data fetching.The webhook list query is properly disabled when organization ID is not available, preventing unnecessary API calls and potential errors.
53-84: Excellent mutation handling with proper error management.The mutations include comprehensive success/error handling with user feedback through toast notifications and proper cache invalidation to keep the UI in sync.
171-192: Well-implemented loading and empty states.The loading indicator and empty state provide excellent user experience with clear messaging about the webhook functionality and SMTP server integration.
245-292: Smart use of React keys for dialog re-rendering.Using unique keys (
edit-${webhook.id}andform-${webhook.id}) ensures proper component re-mounting when switching between different webhooks for editing, preventing stale form state.
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
🧹 Nitpick comments (2)
apps/backend/prisma/seed.ts (2)
177-177: Remove redundant fallback operator.The
|| undefinedis redundant sincetransformedPayloadis alreadynullwhen falsy.- transformedPayload: transformedPayload || undefined, + transformedPayload,
122-131: Consider extracting hardcoded test data to constants.The hardcoded arrays for events, providers, and status codes could be extracted to constants for better maintainability and reusability.
+const TEST_WEBHOOK_EVENTS = [ + "delivered", + "bounced", + "complained", + "opened", + "clicked", + "failed", +] as const + +const TEST_PROVIDERS = ["ses", "sendgrid", "postmark", "mailgun", "resend"] as const +const TEST_STATUS_CODES = [200, 201, 400, 401, 404, 500, 502, 503] as const + - const events = [ - "delivered", - "bounced", - "complained", - "opened", - "clicked", - "failed", - ] - const providers = ["ses", "sendgrid", "postmark", "mailgun", "resend"] - const statusCodes = [200, 201, 400, 401, 404, 500, 502, 503] + const events = TEST_WEBHOOK_EVENTS + const providers = TEST_PROVIDERS + const statusCodes = TEST_STATUS_CODES
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/backend/prisma/seed.ts(2 hunks)
🔇 Additional comments (3)
apps/backend/prisma/seed.ts (3)
3-3: LGTM: Type import addition is appropriate.The addition of
type Prismaimport supports the new webhook log type annotations.
91-118: Webhook creation looks good with proper upsert pattern.The webhook creation follows good practices with upsert to prevent duplicates and includes realistic test code for authorization and transformation logic.
207-213: LGTM: Batch insertion is a good performance optimization.Using batch insertion with a reasonable batch size of 50 prevents potential memory issues and improves performance when creating large amounts of test data.
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
🧹 Nitpick comments (3)
todo.md (3)
1-1: Use consistent pluralization for to-dos heading.Consider changing “# Todos” to “# To-dos” or “# TODOs” for grammatical accuracy and alignment with common conventions.
5-5: Clarify the instruction sentence.The phrase “Anything in this list, do not touch them or do them.” is awkward. For clarity and readability, rephrase to something like:
- “Items in this list are postponed—do not modify or implement them now.”
10-11: Add placeholder for empty Bugs section.The “## Bugs” section is currently empty. If there are no known bugs yet, consider adding a placeholder like “- No bugs identified at this time” to indicate intent.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
apps/docs/src/app/getting-started/configuration/page.mdx(1 hunks)apps/docs/src/app/getting-started/page.mdx(1 hunks)apps/web/src/components/index.ts(1 hunks)apps/web/src/components/webhook-url-display.tsx(1 hunks)apps/web/src/hooks/useSession.ts(1 hunks)apps/web/src/pages/dashboard/settings/webhook-details.tsx(1 hunks)apps/web/src/pages/dashboard/settings/webhook-settings.tsx(3 hunks)docker-compose.node.yaml(1 hunks)docker-compose.yaml(1 hunks)package.json(2 hunks)todo.md(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- apps/docs/src/app/getting-started/page.mdx
- docker-compose.yaml
- apps/web/src/pages/dashboard/settings/webhook-details.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
- package.json
- apps/docs/src/app/getting-started/configuration/page.mdx
- apps/web/src/pages/dashboard/settings/webhook-settings.tsx
🧰 Additional context used
🪛 LanguageTool
todo.md
[grammar] ~1-~1: It appears that a hyphen is missing in the plural noun “to-dos”?
Context: # Todos ## For later Anything in this list, d...
(TO_DO_HYPHEN)
🔇 Additional comments (5)
docker-compose.node.yaml (1)
26-26: Explicitly setNODE_ENVto production
AddingNODE_ENV: productionaligns the container behavior with best practices for a production environment and matches other compose files.apps/web/src/hooks/useSession.ts (1)
9-12: Good performance optimization for user session data.The addition of
staleTimeand disablingrefetchOnWindowFocusare sensible optimizations for user session data that doesn't change frequently. This will reduce unnecessary network requests while maintaining data freshness.apps/web/src/components/webhook-url-display.tsx (2)
18-21: Clever debounced copy confirmation logic.The use of a counter with debounced value to show copy confirmation is an interesting approach. This works well to provide temporary visual feedback without additional timers or effects.
32-62: Well-structured variant handling.The component properly separates the two variants with clear visual distinctions and appropriate sizing. The conditional rendering is clean and the styling is consistent between variants.
Also applies to: 64-93
apps/web/src/components/index.ts (1)
16-18: Consistent export additions for webhook components.The new exports follow the established pattern and correctly expose the webhook-related components for use throughout the application.
| const handleCopyUrl = async () => { | ||
| await navigator.clipboard.writeText(url) | ||
| setCopyTriggered((prev) => prev + 1) | ||
| } |
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.
🛠️ Refactor suggestion
Add error handling for clipboard API.
The navigator.clipboard.writeText call should include error handling as the clipboard API can fail in certain contexts (e.g., non-HTTPS environments, permission denied).
const handleCopyUrl = async () => {
- await navigator.clipboard.writeText(url)
- setCopyTriggered((prev) => prev + 1)
+ try {
+ await navigator.clipboard.writeText(url)
+ setCopyTriggered((prev) => prev + 1)
+ } catch (error) {
+ console.error('Failed to copy to clipboard:', error)
+ // Could show a toast notification or fallback behavior
+ }
}📝 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.
| const handleCopyUrl = async () => { | |
| await navigator.clipboard.writeText(url) | |
| setCopyTriggered((prev) => prev + 1) | |
| } | |
| const handleCopyUrl = async () => { | |
| try { | |
| await navigator.clipboard.writeText(url) | |
| setCopyTriggered((prev) => prev + 1) | |
| } catch (error) { | |
| console.error('Failed to copy to clipboard:', error) | |
| // Could show a toast notification or fallback behavior | |
| } | |
| } |
🤖 Prompt for AI Agents
In apps/web/src/components/webhook-url-display.tsx around lines 27 to 30, the
clipboard writeText call lacks error handling, which can cause unhandled promise
rejections if the clipboard API fails. Wrap the await
navigator.clipboard.writeText(url) call in a try-catch block and handle errors
gracefully, such as logging the error or showing a user-friendly message, to
ensure the app remains stable in failure scenarios.
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 (2)
packages/shared/webhook-events-data.ts (1)
4-4: Consider using a union type for better type safety.The
statusfield could be more type-safe by using a union type instead of a generic string.+export type WebhookEventStatus = 'PENDING' | 'SENT' | 'OPENED' | 'CLICKED' | 'FAILED' | 'COMPLAINED' export interface WebhookEvent { name: string aliases: string[] - status: string + status: WebhookEventStatus description: string }apps/docs/src/app/webhooks/page.mdx (1)
99-106: Consider adding setup links for SMTP providers.While the provider list is comprehensive, adding direct links to each provider's webhook configuration documentation would enhance user experience.
- **SendGrid**: Configure the webhook URL in your SendGrid Event Webhook settings + **SendGrid**: Configure the webhook URL in your [SendGrid Event Webhook settings](https://docs.sendgrid.com/for-developers/tracking-events/getting-started-event-webhook) - **Mailgun**: Set up the webhook URL in your Mailgun webhook configuration + **Mailgun**: Set up the webhook URL in your [Mailgun webhook configuration](https://documentation.mailgun.com/en/latest/user_manual.html#webhooks)And similar for other providers.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/backend/src/webhook/types.ts(1 hunks)apps/docs/src/app/webhooks/page.mdx(1 hunks)apps/web/src/components/webhook-events-reference.tsx(1 hunks)packages/shared/webhook-events-data.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/src/components/webhook-events-reference.tsx
- apps/backend/src/webhook/types.ts
🧰 Additional context used
🪛 LanguageTool
apps/docs/src/app/webhooks/page.mdx
[uncategorized] ~49-~49: Loose punctuation mark.
Context: ...``` The function receives: - headers: Request headers object - `body`: Reques...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~86-~86: Loose punctuation mark.
Context: ...``` The function receives: - payload: The raw webhook payload sent by your SM...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~94-~94: Loose punctuation mark.
Context: ...rm function must include: - messageId: The external message ID provided by you...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~99-~99: Possible missing comma found.
Context: ... webhook system works with popular SMTP providers including: - SendGrid: Configure t...
(AI_HYDRA_LEO_MISSING_COMMA)
🔇 Additional comments (7)
packages/shared/webhook-events-data.ts (2)
1-6: Well-structured interface design.The
WebhookEventinterface is clean and covers all necessary fields for webhook event metadata.
8-45: Comprehensive webhook events coverage.The webhook events array covers all essential email lifecycle states with appropriate aliases and clear descriptions. The status mappings are logical and consistent.
apps/docs/src/app/webhooks/page.mdx (5)
3-9: Excellent beta feature disclosure.The prominent beta warning appropriately sets user expectations about potential API changes.
29-29: Critical security warning well-positioned.The security warning about plain text storage of authentication code is appropriately prominent and helps users make informed decisions about sensitive data.
62-66: Well-documented runtime limits.The runtime limits for the sandboxed environment are clearly specified with configurable environment variables, providing both security and flexibility.
119-127: Status mappings consistent with shared data.The status table correctly reflects the webhook event mappings defined in
packages/shared/webhook-events-data.ts, ensuring consistency across documentation and implementation.
134-174: Comprehensive transform function examples.The examples effectively demonstrate real-world usage patterns for different SMTP providers, making the documentation actionable for users.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores