Skip to content

sending new templates#794

Merged
N2D4 merged 73 commits intodevfrom
sending-new-templates
Jul 29, 2025
Merged

sending new templates#794
N2D4 merged 73 commits intodevfrom
sending-new-templates

Conversation

@BilalG1
Copy link
Contributor

@BilalG1 BilalG1 commented Jul 23, 2025


Important

This PR enhances email template management with customizable themes, UI improvements, and refactoring across backend and frontend components.

  • New Features:
    • Added support for selecting, previewing, and editing email templates with customizable themes in page-client.tsx.
    • Introduced the ability to create new email templates via a dedicated dialog in page-client.tsx.
    • Added a new error message when attempting to edit templates without a custom email server in route.tsx.
  • Improvements:
    • Enhanced email template management UI with simplified listing and editing in page-client.tsx.
    • Expanded theme selection options to include "No theme" and "Project theme" in page-client.tsx.
    • Improved handling of theme identifiers in email-rendering.tsx.
  • Bug Fixes:
    • Updated test cases and email subject handling to reflect dynamic subject rendering in send-sign-in-code.test.ts.
  • Refactor:
    • Consolidated and streamlined email template and theme editor components in vibe-coding/index.ts.
    • Removed deprecated or redundant UI components related to email template editing and preview in vibe-coding/index.ts.
  • Chores:
    • Updated type definitions and interfaces to support broader theme ID values in admin-interface.ts.

This description was created by Ellipsis for a4eaa52. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • New Features

    • Added support for selecting, previewing, and editing email templates with customizable themes in the dashboard.
    • Introduced the ability to create new email templates via a dedicated dialog.
    • Added a new error message when attempting to edit templates without a custom email server.
  • Improvements

    • Enhanced email template management UI with simplified listing and editing.
    • Expanded theme selection options to include "No theme" and "Project theme".
    • Improved handling of theme identifiers, allowing for more flexible theme assignment.
  • Bug Fixes

    • Updated test cases and email subject handling to reflect dynamic subject rendering.
  • Refactor

    • Consolidated and streamlined email template and theme editor components.
    • Removed deprecated or redundant UI components related to email template editing and preview.
  • Chores

    • Updated type definitions and interfaces to support broader theme ID values.
    • Removed the @stackframe/stack-emails package and related dependencies and components.

@vercel
Copy link

vercel bot commented Jul 23, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
stack-backend ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 29, 2025 0:25am
stack-dashboard 🛑 Canceled (Inspect) Jul 29, 2025 0:25am
stack-demo ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 29, 2025 0:25am
stack-docs 🛑 Canceled (Inspect) Jul 29, 2025 0:25am

@recurseml
Copy link

recurseml bot commented Jul 23, 2025

✨ No issues found! Your code is sparkling clean! ✨

🗒️ View all ignored comments in this repo
  • The constraint 'TokenStoreType extends string' is too restrictive. It should likely be 'TokenStoreType extends string | object' to match the condition check in line 113 where TokenStoreType is checked against {}
  • Return type mismatch - the interface declares useUsers() returning ServerUser[] but the Team interface that this extends declares useUsers() returning TeamUser[]
  • There is a syntax error in the super constructor call due to the ellipsis operator used incorrectly. Objects aren't being merged correctly. This syntax usage can lead to runtime errors when trying to pass the merged object to 'super()'. Verify that the intended alterations to the object occur before or outside of the super() call if needed.
  • Throwing an error when no active span is found is too aggressive. The log function should gracefully fallback to console.log or another logging mechanism when there's no active span, since not all execution contexts will have an active span. This makes the code less resilient and could break functionality in non-traced environments.

📚 Relevant Docs

  • Function sets backendContext with a new configuration but doesn't pass 'defaultProjectKeys'. Since defaultProjectKeys is required in the type definition and cannot be updated (throws error if tried to set), this will cause a type error.
  • The schema is using array syntax for pick() which is incorrect for Yup schemas. The pick() method in Yup expects individual arguments, not an array. Should be changed to: emailConfigSchema.pick('type', 'host', 'port', 'username', 'sender_name', 'sender_email')

📚 Relevant Docs

  • Creating a refresh token with current timestamp as expiration means it expires immediately. Should set a future date for token expiration.
  • The 'tools' object is initialized as an empty object, even though 'tools' is presumably expected to contain tool definitions. This could cause the server capabilities to lack necessary tool configurations, thus potentially impacting functionalities that depend on certain tool setups.

📚 Relevant Docs

  • 'STACK_SECRET_SERVER_KEY' is potentially being included in every request header without checking its existence again here. Although it's checked during initialization, this could lead to security issues as it's exposed in all communications where the header is logged or captured.

📚 Relevant Docs

  • When adding 'use client' directive at the beginning, it doesn't check if file.text already contains the 'use client' directive. This could lead to duplicate 'use client' directives if the file already has one.

📚 Relevant Docs

⚠️ Only 5 files were analyzed due to processing limits.

Need help? Join our Discord for support!
https://discord.gg/qEjHQk64Z9

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Summary

This PR introduces a major migration from the legacy email template system to a new TSX-based email template architecture. The changes consolidate email template functionality by removing the experimental email-templates-new pages and integrating their features into the main email-templates system.

Key Changes:

  1. New Email Template Architecture: The system now uses TSX components for email templates instead of document-based configurations. Templates are stored as TSX source code in tenancy configuration and rendered using React components.

  2. Template Management Consolidation: The separate email-templates-new directory has been removed, and all functionality has been merged into the main email-templates system. Navigation and routing have been updated to use template IDs instead of template types.

  3. Enhanced Error Handling: A new RequiresCustomEmailServer error prevents users from editing email templates when using shared email servers, enforcing the business requirement that custom templates need dedicated SMTP configurations.

  4. Template Rendering Pipeline: The new system separates themes from templates, with getActiveEmailTheme() handling theme retrieval and renderEmailWithTemplate() providing enhanced validation for required components like subject and notification categories.

  5. Test Updates: E2E tests have been updated to handle the new email format where OTP codes are embedded in JSON structures ("otp":"[CODE]") rather than plain text, reflecting the structured data approach of the new template system.

The migration maintains backward compatibility while providing a more flexible foundation for email customization with better React integration and developer experience.

Confidence score: 4/5

• This PR appears safe to merge with extensive refactoring but may need careful monitoring due to the complexity of the email system changes
• The score reflects the comprehensive nature of the changes spanning multiple systems (templates, routing, rendering, validation) which increases risk despite thorough implementation
• The backend route handler in apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx needs attention for proper error handling validation

16 files reviewed, 2 comments

Edit Code Review Bot Settings | Greptile

@BilalG1 BilalG1 assigned N2D4 and unassigned BilalG1 Jul 23, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 27, 2025

Walkthrough

This update overhauls the email template and theme editing system, refactoring both backend and frontend logic. It introduces support for nullable and "false" theme IDs, restructures template and theme handling, and consolidates UI components. Several frontend components are deleted or replaced, and backend validation, error handling, and API contracts are updated to match the new model. Test cases and type definitions are revised accordingly.

Changes

Cohort / File(s) Change Summary
Backend: Email Rendering & API
apps/backend/src/app/api/latest/emails/render-email/route.tsx
apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx
apps/backend/src/lib/email-rendering.tsx
apps/backend/src/lib/emails.tsx
apps/backend/src/app/api/latest/internal/send-sign-in-invitation/route.tsx
Refactored email rendering and template logic to support nullable/false theme IDs, centralized theme retrieval, improved validation, and error handling. Added new utility functions for theme selection and updated rendering pipeline. Added extra variable for team display name in invitation emails.
Backend: Type & Error Definitions
packages/stack-shared/src/interface/admin-interface.ts
packages/stack-shared/src/known-errors.tsx
packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts
packages/template/src/lib/stack-app/apps/interfaces/admin-app.ts
Expanded themeId parameter types to accept string, null, or false. Added new known error (RequiresCustomEmailServer). Updated interface and implementation signatures for email preview and template update methods.
Frontend: Email Templates UI Refactor
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page-client.tsx
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[templateId]/page-client.tsx
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page.tsx
apps/dashboard/src/components/email-preview.tsx
Refactored email templates UI: new editing/previewing component with theme selection supporting nullable/false theme IDs, simplified template listing, new template creation dialog, and updated navigation. Removed dev feature flag from "Themes" nav. Updated prop types for themeId to accept string, null, or false.
Frontend: Component Deletions/Removals
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/page-client.tsx
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/[templateId]/page-client.tsx
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[type]/page-client.tsx
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[type]/page.tsx
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/page.tsx
apps/dashboard/src/components/vibe-coding/index.ts
apps/dashboard/src/components/vibe-coding/preview-panel.tsx
apps/dashboard/src/components/vibe-coding/template-preview.tsx
apps/dashboard/src/components/vibe-coding/vibe-assistant-chat.tsx
apps/dashboard/src/components/vibe-coding/vibe-code-editor-layout.tsx
apps/dashboard/src/components/vibe-coding/vibe-code-editor.tsx
apps/dashboard/src/components/vibe-coding/vibe-preview-panel.tsx
Deleted legacy or now-obsolete email template editing, preview, code editor, and assistant chat UI components/pages. Removed export of PreviewPanel and simplified theme preview rendering by removing its wrapper.
Frontend: Theme Preview Panel Update
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-themes/[themeId]/page-client.tsx
Simplified theme preview rendering by removing PreviewPanel wrapper, rendering EmailPreview directly.
Testing: E2E/Backend Test Updates
apps/e2e/tests/backend/endpoints/api/v1/auth/otp/send-sign-in-code.test.ts
apps/e2e/tests/backend/endpoints/api/v1/auth/otp/sign-in.test.ts
apps/e2e/tests/backend/endpoints/api/v1/auth/password/reset.test.ts
apps/e2e/tests/backend/endpoints/api/v1/auth/password/send-reset-code.test.ts
apps/e2e/tests/backend/endpoints/api/v1/auth/password/sign-up.test.ts
apps/e2e/tests/backend/endpoints/api/v1/contact-channels/legacy-send-verification-code.test.ts
apps/e2e/tests/backend/endpoints/api/v1/contact-channels/send-verification-code.test.ts
apps/e2e/tests/backend/endpoints/api/v1/contact-channels/verify.test.ts
apps/e2e/tests/backend/endpoints/api/v1/internal/email.test.ts
apps/e2e/tests/backend/endpoints/api/v1/internal/projects.test.ts
apps/e2e/tests/backend/endpoints/api/v1/render-email.test.ts
Updated test assertions, regex patterns, and expected subject line formats to match new JSX-like templated subjects and theme/template logic. Adjusted for new error and type handling.
Backend: Removed Legacy Email Template CRUD and Conversion
apps/backend/src/app/api/latest/email-templates/crud.tsx
apps/backend/src/app/api/latest/email-templates/[type]/route.tsx
apps/backend/src/app/api/latest/email-templates/route.tsx
apps/backend/src/app/api/latest/internal/email-templates/temp/[projectId]/route.tsx
apps/backend/src/app/api/latest/internal/email-templates/temp/convert.tsx
Removed legacy CRUD handlers, API routes, and template conversion utilities for email templates.
Frontend: Removed Legacy Email Template Migration and Management Pages
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/migrations/templates-migration/page-client.tsx
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/migrations/templates-migration/page.tsx
Removed email template migration UI components and pages.
Frontend: Removed Legacy Email Editor and Related Components
packages/stack-emails/src/editor.tsx
packages/stack-emails/src/editor/documents/editor/core.tsx
packages/stack-emails/src/editor/documents/editor/editor-block.tsx
packages/stack-emails/src/editor/documents/editor/editor-context.tsx
packages/stack-emails/src/editor/email-builder/index.ts
packages/stack-emails/src/editor/email-builder/reader/core.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/index.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/button-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/columns-container-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/container-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/divider-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/heading-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/base-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/color-input/base-color-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/color-input/index.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/column-widths-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-family.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-size-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-weight-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/padding-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/raw/raw-slider-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/single-toggle-group.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/slider-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-align-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-dimension-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-input.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/style-inputs/multi-style-property-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/style-inputs/single-style-property-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/image-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/spacer-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/text-sidebar-panel.tsx
packages/stack-emails/src/editor/sidebar/index.tsx
packages/stack-emails/src/editor/sidebar/settings-panel.tsx
packages/stack-emails/src/editor/sidebar/toggle-inspector-panel-button.tsx
packages/stack-emails/src/editor/sidebar/variables-panel.tsx
packages/stack-emails/src/editor/template-panel/download-json/index.tsx
packages/stack-emails/src/editor/template-panel/import-json/import-json-dialog.tsx
packages/stack-emails/src/editor/template-panel/import-json/index.tsx
packages/stack-emails/src/editor/template-panel/import-json/validateJsonStringValue.ts
packages/stack-emails/src/editor/template-panel/index.tsx
Removed legacy email editor, sidebar, input panels, helpers, and template panel components. Removed import/export JSON UI and validation. Removed editor context and state management.
Frontend: Removed Legacy Editor Blocks and Helpers
packages/stack-emails/src/editor/documents/blocks/columns-container/columns-container-editor.tsx
packages/stack-emails/src/editor/documents/blocks/columns-container/columns-container-props-schema.ts
packages/stack-emails/src/editor/documents/blocks/columns-container/columns-container-reader.tsx
packages/stack-emails/src/editor/documents/blocks/container/container-editor.tsx
packages/stack-emails/src/editor/documents/blocks/container/container-props-schema.tsx
packages/stack-emails/src/editor/documents/blocks/container/container-reader.tsx
packages/stack-emails/src/editor/documents/blocks/email-layout/email-layout-editor.tsx
packages/stack-emails/src/editor/documents/blocks/email-layout/email-layout-props-schema.tsx
packages/stack-emails/src/editor/documents/blocks/email-layout/email-layout-reader.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/editor-block-wrapper.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/reader-block-wrapper.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/tune-menu.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/block-button.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/blocks-menu.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/buttons.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/index.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/index.tsx
packages/stack-emails/src/editor/documents/blocks/helpers/font-family.ts
packages/stack-emails/src/editor/documents/blocks/helpers/t-style.ts
packages/stack-emails/src/editor/documents/blocks/helpers/zod.ts
packages/stack-emails/src/editor/documents/editor/core.tsx
packages/stack-emails/src/editor/documents/editor/editor-block.tsx
packages/stack-emails/src/editor/documents/editor/editor-context.tsx
Removed legacy editor blocks, schemas, readers, wrappers, helpers, and editor core components.
Frontend: Removed Legacy Email Template Blocks
packages/stack-emails/src/editor/blocks/block-button.tsx
packages/stack-emails/src/editor/blocks/block-columns-container.tsx
packages/stack-emails/src/editor/blocks/block-container.tsx
packages/stack-emails/src/editor/blocks/block-divider.tsx
packages/stack-emails/src/editor/blocks/block-heading.tsx
packages/stack-emails/src/editor/blocks/block-image.tsx
packages/stack-emails/src/editor/blocks/block-spacer.tsx
packages/stack-emails/src/editor/blocks/block-text.tsx
packages/stack-emails/src/editor/documents/editor/core.tsx
Removed legacy email template block components and their validation schemas.
Frontend: Removed Legacy Email Templates and Empty Templates
packages/stack-emails/src/templates/email-verification.tsx
packages/stack-emails/src/templates/empty.tsx
packages/stack-emails/src/templates/magic-link-old.tsx
packages/stack-emails/src/templates/magic-link.tsx
packages/stack-emails/src/templates/password-reset.tsx
Removed legacy email template configurations for verification, magic link, and password reset emails.
Package & Config Cleanup
apps/backend/package.json
apps/dashboard/package.json
apps/dashboard/tailwind.config.ts
packages/stack-emails/.eslintrc.cjs
packages/stack-emails/CHANGELOG.md
packages/stack-emails/LICENSE
packages/stack-emails/package.json
packages/stack-emails/src/globals.d.ts
Removed @stackframe/stack-emails package files and dependencies from backend and dashboard apps. Removed ESLint config, changelog, license, and type declarations related to stack-emails. Cleaned Tailwind config to exclude stack-emails sources.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DashboardUI
    participant AdminAPI
    participant EmailRendering
    participant TenancyConfig

    User->>DashboardUI: Edit email template
    DashboardUI->>AdminAPI: PATCH /email-templates/:id (tsxSource, themeId)
    AdminAPI->>TenancyConfig: Validate themeId (nullable/false allowed)
    AdminAPI->>EmailRendering: getEmailThemeForTemplate(tenancy, themeId)
    EmailRendering->>TenancyConfig: Retrieve theme or fallback
    EmailRendering-->>AdminAPI: Return theme TSX source
    AdminAPI->>EmailRendering: Render email with template + theme
    EmailRendering-->>AdminAPI: Rendered HTML/subject/text
    AdminAPI-->>DashboardUI: Save result or error
    DashboardUI-->>User: Show preview, success, or error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

In the warren where emails hop and play,
Themes and templates now leap a new way.
Old panels and editors burrowed away,
While nullable themes join the fray.
With tests and types all made anew—
This bunny’s code garden just grew and grew!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sending-new-templates

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (3)
apps/backend/src/app/api/latest/emails/render-email/route.tsx (1)

43-43: Use the has function for safe object property checking.

The current in operator is vulnerable to prototype pollution. For consistency with the codebase and to address the prototype pollution concern from the past review, use the has function from the utils.

-    if (body.theme_id && !(body.theme_id in tenancy.completeConfig.emails.themes)) {
+    if (body.theme_id && !has(tenancy.completeConfig.emails.themes, body.theme_id)) {

You'll need to import the has function:

+import { has } from '@stackframe/stack-shared/dist/utils/objects';
apps/backend/src/lib/emails.tsx (1)

19-31: Well-implemented template retrieval with proper error handling.

The getNewEmailTemplate function correctly:

  • Uses Maps for efficient lookups
  • Provides clear error messages for missing templates
  • Implements the suggested default case handling from previous reviews
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[templateId]/page-client.tsx (1)

105-134: Fix the broken theme selection logic.

The helper functions don't correctly handle the string | undefined | false type mapping to select values. The current implementation will break theme selection because:

  1. themeIdToSelectString(false) returns "false" but the SelectItem uses "false-sentinel"
  2. themeIdToSelectString(undefined) returns "null" but the SelectItem uses "undefined-sentinel"

Apply this fix to properly handle the type transformations:

-function themeIdToSelectString(themeId: string | undefined | false): string {
-  return JSON.stringify(themeId ?? null);
-}
-function selectStringToThemeId(value: string): string | undefined | false {
-  return JSON.parse(value) ?? undefined;
-}
+function themeIdToSelectString(themeId: string | undefined | false): string {
+  if (themeId === false) return "false-sentinel";
+  if (themeId === undefined) return "undefined-sentinel";
+  return themeId;
+}
+function selectStringToThemeId(value: string): string | undefined | false {
+  if (value === "false-sentinel") return false;
+  if (value === "undefined-sentinel") return undefined;
+  return value;
+}

Alternatively, follow the previous suggestion to use named constants:

+const NO_THEME_SENTINEL = "no-theme";
+const PROJECT_THEME_SENTINEL = "project-theme";
+
 function themeIdToSelectString(themeId: string | undefined | false): string {
-  return JSON.stringify(themeId ?? null);
+  if (themeId === false) return NO_THEME_SENTINEL;
+  if (themeId === undefined) return PROJECT_THEME_SENTINEL;
+  return themeId;
 }
 function selectStringToThemeId(value: string): string | undefined | false {
-  return JSON.parse(value) ?? undefined;
+  if (value === NO_THEME_SENTINEL) return false;
+  if (value === PROJECT_THEME_SENTINEL) return undefined;
+  return value;
 }

And update the SelectItems:

-        <SelectItem value={"false-sentinel"}>No theme</SelectItem>
-        <SelectItem value={"undefined-sentinel"}>Project theme</SelectItem>
+        <SelectItem value={NO_THEME_SENTINEL}>No theme</SelectItem>
+        <SelectItem value={PROJECT_THEME_SENTINEL}>Project theme</SelectItem>
🧹 Nitpick comments (2)
apps/backend/src/lib/emails.tsx (1)

353-377: Consider validating email subject before sending.

The new TSX-based rendering approach with theme support is well-implemented. However, defaulting the subject to an empty string (line 374) when missing could mask template configuration errors.

Consider adding validation to ensure subject is not empty:

+    if (!result.data.subject) {
+      throw new StackAssertionError("Email template rendered without subject", {
+        templateType: options.templateType,
+        templateId: template.id,
+      });
+    }
     await sendEmail({
       tenancyId: options.tenancy.id,
       emailConfig: await getEmailConfig(options.tenancy),
       to: options.email,
-      subject: result.data.subject ?? "",
+      subject: result.data.subject,
       html: result.data.html,
       text: result.data.text,
     });
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[templateId]/page-client.tsx (1)

36-38: Consider renaming for clarity.

The function name handleThemeUpdate is misleading since it updates the code content, not the theme. Consider renaming to handleCodeUpdate or handleToolCallUpdate.

-  const handleThemeUpdate = (toolCall: ToolCallContent) => {
+  const handleCodeUpdate = (toolCall: ToolCallContent) => {
     setCurrentCode(toolCall.args.content);
   };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 43340f0 and 89b769a.

📒 Files selected for processing (38)
  • apps/backend/src/app/api/latest/emails/render-email/route.tsx (3 hunks)
  • apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx (4 hunks)
  • apps/backend/src/lib/email-rendering.tsx (2 hunks)
  • apps/backend/src/lib/emails.tsx (3 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/[templateId]/page-client.tsx (0 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/page-client.tsx (0 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/page.tsx (0 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[templateId]/page-client.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[type]/page-client.tsx (0 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[type]/page.tsx (0 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page-client.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-themes/[themeId]/page-client.tsx (2 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx (1 hunks)
  • apps/dashboard/src/components/email-preview.tsx (2 hunks)
  • apps/dashboard/src/components/vibe-coding/index.ts (0 hunks)
  • apps/dashboard/src/components/vibe-coding/preview-panel.tsx (0 hunks)
  • apps/dashboard/src/components/vibe-coding/template-preview.tsx (0 hunks)
  • apps/dashboard/src/components/vibe-coding/vibe-assistant-chat.tsx (0 hunks)
  • apps/dashboard/src/components/vibe-coding/vibe-code-editor-layout.tsx (0 hunks)
  • apps/dashboard/src/components/vibe-coding/vibe-code-editor.tsx (0 hunks)
  • apps/dashboard/src/components/vibe-coding/vibe-preview-panel.tsx (0 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/auth/otp/send-sign-in-code.test.ts (2 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/auth/otp/sign-in.test.ts (3 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/auth/password/reset.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/auth/password/send-reset-code.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/auth/password/sign-up.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/contact-channels/legacy-send-verification-code.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/contact-channels/send-verification-code.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/contact-channels/verify.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/internal/email.test.ts (3 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/internal/projects.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/render-email.test.ts (1 hunks)
  • packages/stack-shared/src/helpers/emails.ts (1 hunks)
  • packages/stack-shared/src/interface/admin-interface.ts (2 hunks)
  • packages/stack-shared/src/known-errors.tsx (2 hunks)
  • packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts (3 hunks)
  • packages/template/src/lib/stack-app/apps/interfaces/admin-app.ts (2 hunks)
💤 Files with no reviewable changes (12)
  • apps/dashboard/src/components/vibe-coding/index.ts
  • apps/dashboard/src/components/vibe-coding/vibe-preview-panel.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/page.tsx
  • apps/dashboard/src/components/vibe-coding/vibe-code-editor-layout.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[type]/page-client.tsx
  • apps/dashboard/src/components/vibe-coding/template-preview.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[type]/page.tsx
  • apps/dashboard/src/components/vibe-coding/preview-panel.tsx
  • apps/dashboard/src/components/vibe-coding/vibe-assistant-chat.tsx
  • apps/dashboard/src/components/vibe-coding/vibe-code-editor.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/page-client.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates-new/[templateId]/page-client.tsx
🧰 Additional context used
🧬 Code Graph Analysis (5)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-themes/[themeId]/page-client.tsx (2)
apps/dashboard/src/components/email-preview.tsx (1)
  • EmailPreview (91-122)
packages/stack-shared/src/helpers/emails.ts (1)
  • previewTemplateSource (1-14)
apps/e2e/tests/backend/endpoints/api/v1/auth/password/reset.test.ts (1)
packages/stack-shared/src/utils/errors.tsx (1)
  • throwErr (10-19)
apps/backend/src/app/api/latest/emails/render-email/route.tsx (3)
packages/stack-shared/src/schema-fields.ts (1)
  • templateThemeIdSchema (375-375)
packages/stack-shared/src/utils/errors.tsx (1)
  • StatusError (141-250)
apps/backend/src/lib/email-rendering.tsx (1)
  • getEmailThemeForTemplate (23-32)
packages/template/src/lib/stack-app/apps/interfaces/admin-app.ts (1)
packages/template/src/lib/stack-app/common.ts (1)
  • AsyncStoreProperty (8-10)
apps/backend/src/lib/emails.tsx (6)
apps/backend/src/lib/tenancies.tsx (1)
  • Tenancy (50-50)
packages/stack-emails/src/utils.tsx (1)
  • EMAIL_TEMPLATES_METADATA (38-97)
packages/stack-shared/src/helpers/emails.ts (1)
  • DEFAULT_TEMPLATE_IDS (107-113)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (67-83)
apps/backend/src/lib/email-rendering.tsx (2)
  • getEmailThemeForTemplate (23-32)
  • renderEmailWithTemplate (49-113)
packages/stack-shared/src/utils/objects.tsx (1)
  • filterUndefined (368-370)
🪛 Gitleaks (8.27.2)
packages/stack-shared/src/helpers/emails.ts

79-79: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Security Check
🔇 Additional comments (46)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page.tsx (1)

3-5: LGTM! Title update aligns with feature consolidation.

The metadata title change from "Email Settings" to "Email Templates" accurately reflects the page's specific functionality and aligns with the broader email templates system refactoring.

apps/e2e/tests/backend/endpoints/api/v1/render-email.test.ts (1)

167-167: LGTM! Test updated for new dynamic subject extraction.

The subject expectation change from static "mock subject" to "Mock subject, undefined" correctly reflects the new email rendering logic that dynamically extracts subjects from template components. The "undefined" value is appropriate since the test template lacks a <Subject> component.

apps/e2e/tests/backend/endpoints/api/v1/auth/password/sign-up.test.ts (1)

25-25: LGTM! Test updated for new JSX-based email subject format.

The subject expectation change correctly reflects the new TSX-based email rendering system that captures raw JSX template expressions for subjects instead of static strings.

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-themes/[themeId]/page-client.tsx (2)

5-5: LGTM! Import updated for component simplification.

The removal of PreviewPanel from the imports aligns with the UI consolidation efforts in the email templates and themes system.


50-54: LGTM! Direct EmailPreview rendering simplifies the component hierarchy.

The removal of the PreviewPanel wrapper and direct use of EmailPreview with themeTsxSource and templateTsxSource props streamlines the preview functionality and aligns with the UI consolidation mentioned in the PR objectives.

apps/e2e/tests/backend/endpoints/api/v1/contact-channels/verify.test.ts (1)

21-21: LGTM! Test filter updated for new email subject format.

The subject filtering logic correctly updated to match the new JSX-based email subject format, maintaining test functionality while adapting to the email rendering system changes.

apps/e2e/tests/backend/endpoints/api/v1/internal/projects.test.ts (1)

507-507: LGTM! Improved test determinism.

Replacing the dynamically generated UUID with a fixed invalid string makes the test more deterministic while still effectively validating the invalid email theme error handling.

apps/e2e/tests/backend/endpoints/api/v1/auth/password/send-reset-code.test.ts (1)

27-27: LGTM! Test snapshots updated for new dynamic email subjects.

The updated test expectations correctly reflect the new email rendering system that uses JSX templates with dynamic projectDisplayName substitution instead of static subject strings.

Also applies to: 33-33

apps/e2e/tests/backend/endpoints/api/v1/contact-channels/legacy-send-verification-code.test.ts (1)

55-55: LGTM! Consistent test snapshot updates.

The email subject expectations have been correctly updated to match the new JSX template format with dynamic projectDisplayName substitution.

Also applies to: 61-61

apps/e2e/tests/backend/endpoints/api/v1/contact-channels/send-verification-code.test.ts (1)

42-42: LGTM! Test expectations aligned with new email rendering.

The snapshot updates correctly reflect the new dynamic email subject format using JSX templates.

Also applies to: 48-48

apps/e2e/tests/backend/endpoints/api/v1/auth/password/reset.test.ts (1)

28-28: Tests aligned with template implementation

  • Verified in packages/stack-shared/src/helpers/emails.ts that the Password Reset template (alongside Magic Link, Team Invitation, Sign-In Invitation) uses string concatenation for <Subject value="…">, while Email Verification is the only one using a template literal.
  • The updated snapshot and message-filtering in apps/e2e/tests/backend/endpoints/api/v1/auth/password/reset.test.ts correctly match the Password Reset template’s concatenation syntax.
  • No changes needed.
apps/e2e/tests/backend/endpoints/api/v1/internal/email.test.ts (3)

58-58: LGTM: Consistent test update.

The subject format update is consistent with the first test case and properly reflects the new dynamic subject rendering behavior.


105-105: LGTM: Complete test consistency.

All three test cases now use the consistent mock subject format, ensuring comprehensive test coverage of the new email rendering behavior.


43-43: Mock subject format verified

I confirmed that the test’s mock subject string:

"Mock subject, <Subject value={\"Sign in to \" + projectDisplayName + \": Your code is \" + otp} />"

exactly matches the tsxSource in the OTP email template defined in packages/stack-shared/src/helpers/emails.ts. No further changes required.

apps/dashboard/src/components/email-preview.tsx (2)

47-47: LGTM: Enhanced type flexibility for theme handling.

The expanded type string | null | false provides better semantic representation of theme states:

  • string: specific theme ID
  • null: explicitly unset theme
  • false: theme disabled

This aligns with the broader theme management improvements across the system.


72-72: LGTM: Consistent type expansion.

The type update maintains consistency with the function parameter and ensures proper theme ID handling throughout the component.

apps/e2e/tests/backend/endpoints/api/v1/auth/otp/send-sign-in-code.test.ts (2)

10-10: LGTM: Consistent email subject format update.

The subject format change is consistent with other email test updates and properly reflects the new JSX-based email template rendering.


102-104: Regex extraction matches email body format
The render-email.test.ts snapshot confirms that the plain-text body ends with a JSON payload containing "otp":"3SLSWZ". Therefore the /\"otp\":\"([A-Z0-9]{6})\"/ pattern in send-sign-in-code.test.ts will reliably capture the 6-character code.

• Verified in apps/e2e/tests/backend/endpoints/api/v1/render-email.test.ts: variables include "otp":"<CODE>"
• No changes required to the current extraction regex

packages/stack-shared/src/known-errors.tsx (2)

1394-1402: LGTM: Well-structured new known error.

The RequiresCustomEmailServer error follows the established pattern with:

  • Clear, descriptive error code
  • Appropriate 400 status code
  • Informative message guiding users to configure custom SMTP
  • Proper constructor structure

This supports the email template customization workflow effectively.


1517-1517: LGTM: Proper error export.

The new error is correctly added to the KnownErrors export, making it available throughout the system.

apps/backend/src/app/api/latest/internal/email-templates/[templateId]/route.tsx (5)

4-4: LGTM: Consistent schema import.

Adding templateThemeIdSchema import ensures consistent validation across email-related endpoints.


24-24: LGTM: Enhanced theme ID validation.

Using templateThemeIdSchema.nullable() provides proper validation for the expanded theme ID types (string | null | false).


35-37: LGTM: Appropriate security restriction.

The custom email server check prevents users with shared SMTP configurations from editing templates, which is a sensible security restriction. The new RequiresCustomEmailServer error provides clear guidance.


42-42: LGTM: Improved theme retrieval.

Using getActiveEmailTheme(tenancy) provides better error handling and centralized theme logic compared to direct property access.


62-66: LGTM: Cleaner configuration structure.

The nested object structure under emails.templates.${templateId} is more organized than separate keys and groups related template properties logically.

apps/e2e/tests/backend/endpoints/api/v1/auth/otp/sign-in.test.ts (2)

200-206: Updated OTP extraction aligns with new email format.

The regex pattern change correctly adapts to the new JSON-like structure in email bodies, moving from a generic pattern to a specific "otp":"XXXXXX" format. The use of optional chaining for safe access to the captured group is appropriate.


273-289: Consistent OTP extraction pattern applied.

The regex pattern change is consistently applied throughout the test file, maintaining the same JSON-like structure matching and safe access pattern as the earlier occurrence.

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx (1)

253-268: Navigation path consolidation looks good.

The changes consistently update email template paths from /emails/templates/ to /email-templates/ and introduce a React component for dynamic breadcrumb labels. The regex patterns, href paths, and breadcrumb configuration are all properly aligned.

apps/backend/src/app/api/latest/emails/render-email/route.tsx (4)

1-4: Imports support the theme handling refactoring.

The new imports for getEmailThemeForTemplate, renderEmailWithTemplate, and templateThemeIdSchema are necessary for the updated theme handling and validation logic.


20-20: Schema update improves theme ID validation.

The change from yupString() to templateThemeIdSchema.nullable() provides better validation for theme IDs, allowing for null values and ensuring UUID format when a string is provided.


37-37: Explicit undefined check improves validation precision.

The change from a truthy check to an explicit === undefined comparison is more precise and correctly handles the new nullable theme ID schema where null and false are valid values.


46-49: Theme source retrieval refactoring improves architecture.

The use of getEmailThemeForTemplate centralizes theme retrieval logic and handles the various theme ID types (string, null, false, undefined) appropriately. The Map usage for templateList is also appropriate.

packages/template/src/lib/stack-app/apps/interfaces/admin-app.ts (2)

37-37: Type expansion improves theme ID flexibility.

The updated type for themeId to include null and false values provides better support for different theme states - explicitly disabled themes (false) and unset themes (null) in addition to string IDs.


85-85: Method signature consistent with type updates.

The updateNewEmailTemplate method signature update maintains consistency with the emailPreview type changes, ensuring the API properly handles all theme ID states.

apps/backend/src/lib/email-rendering.tsx (4)

1-10: Imports support safe theme handling functionality.

The new imports provide the necessary utilities for theme retrieval with proper error handling (StackAssertionError) and safe object access (has, get) that addresses prototype pollution concerns.


11-21: Robust active theme retrieval with safe object access.

The getActiveEmailTheme function properly uses the has and get utility functions to avoid prototype pollution, includes comprehensive error handling with context for debugging, and provides a centralized mechanism for active theme retrieval.


23-32: Flexible theme retrieval handles multiple scenarios.

The getEmailThemeForTemplate function elegantly handles different theme ID types:

  • String IDs for specific themes with safe object access
  • false for explicitly disabling themes
  • null/undefined for falling back to active themes

The implementation uses safe utility functions and provides appropriate fallback behavior.


60-60: Improved subject extraction from template components.

The regex-based subject extraction templateComponent.match(/<Subject\s+[^>]*\/>/g)?.[0] is more robust than static strings, properly extracting Subject component tags from the template source for better mock rendering.

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page-client.tsx (1)

14-40: LGTM! Clean refactoring to use template IDs.

The changes from EmailTemplateType to string for template identification and navigation are consistent throughout the component. The simplified UI focusing on display names and edit buttons aligns well with the new template management architecture.

packages/stack-shared/src/helpers/emails.ts (1)

78-113: Excellent refactoring for template ID standardization.

The introduction of constants for template IDs and the DEFAULT_TEMPLATE_IDS mapping improves code maintainability and ensures consistent references across the codebase. This change supports the enhanced email template handling mentioned in the PR objectives.

Note: The static analysis warning about a "Generic API Key" on line 79 is a false positive - these are UUID identifiers for email templates, not API keys.

packages/stack-shared/src/interface/admin-interface.ts (1)

402-402: Good type expansion for explicit theme handling.

The expanded themeId types (string | null | false) provide clearer semantics:

  • string: Use specific theme
  • null: Use default/active theme
  • false: Use empty/no theme

This aligns well with the enhanced theme handling logic introduced in the email rendering system.

Also applies to: 460-460

packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts (1)

59-59: Consistent implementation of expanded theme ID types.

The cache keys and method signatures have been properly updated to handle the expanded themeId types (string | null | false | undefined). This maintains type safety throughout the admin app implementation.

Also applies to: 482-487, 503-504

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[templateId]/page-client.tsx (4)

1-19: LGTM! Clean import structure.

The imports are well-organized and include all necessary dependencies for the email template editing functionality.


20-34: LGTM! Proper state management and change tracking.

The component correctly initializes state from the template data and properly tracks unsaved changes with appropriate cleanup.


40-51: LGTM! Excellent error handling.

The save handler properly handles specific known errors and provides appropriate user feedback while re-throwing unexpected errors.


54-97: LGTM! Well-structured component layout.

The render logic properly handles the missing template case and provides a clean three-pane editing interface with appropriate state management.

Note: If you accept the suggestion to rename handleThemeUpdate to handleCodeUpdate, remember to update line 90 as well.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/backend/src/lib/emails.tsx (1)

19-31: Excellent implementation addresses previous review concerns.

The new getNewEmailTemplate function properly handles the default case issue raised in previous reviews by throwing an explicit error for unknown template types. The use of Map for O(1) lookups is also a good performance choice.

However, there's a potential issue with the error handling logic:

Consider simplifying the logic by removing the nested conditional:

export function getNewEmailTemplate(tenancy: Tenancy, type: keyof typeof EMAIL_TEMPLATES_METADATA) {
  const templateList = new Map(Object.entries(tenancy.completeConfig.emails.templates));
-  const defaultTemplateIdsMap = new Map(Object.entries(DEFAULT_TEMPLATE_IDS));
-  const defaultTemplateId = defaultTemplateIdsMap.get(type);
-  if (defaultTemplateId) {
-    const template = templateList.get(defaultTemplateId);
-    if (!template) {
-      throw new StackAssertionError(`Default email template not found: ${type}`);
-    }
-    return template;
-  }
-  throw new StackAssertionError(`Unknown email template type: ${type}`);
+  const defaultTemplateId = DEFAULT_TEMPLATE_IDS[type];
+  if (!defaultTemplateId) {
+    throw new StackAssertionError(`Unknown email template type: ${type}`);
+  }
+  
+  const template = templateList.get(defaultTemplateId);
+  if (!template) {
+    throw new StackAssertionError(`Default email template not found: ${type}`);
+  }
+  return template;
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b3e7fb and c2abbac.

📒 Files selected for processing (1)
  • apps/backend/src/lib/emails.tsx (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: docker
  • GitHub Check: setup-tests
  • GitHub Check: all-good
  • GitHub Check: docker
  • GitHub Check: build (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: Security Check
🔇 Additional comments (5)
apps/backend/src/lib/emails.tsx (5)

5-5: Import addition looks good.

The addition of EMAIL_TEMPLATES_METADATA import aligns with the new template handling approach.


15-16: New imports support the refactored email rendering system.

The imports of getEmailThemeForTemplate, renderEmailWithTemplate, and DEFAULT_TEMPLATE_IDS are consistent with the new TSX-based rendering pipeline mentioned in the AI summary.


353-376: Rendering logic is robust with proper error handling.

The new rendering approach using renderEmailWithTemplate with structured variables (user, project, variables) is well-designed. The error handling properly throws a StackAssertionError with context for debugging.

The variable structure is clean and follows good practices by separating concerns between user data, project data, and extra variables.


382-384: Email sending properly handles nullable subject.

The fallback to empty string for missing subject is appropriate, ensuring the email can still be sent even if subject rendering fails.


353-353: getEmailThemeForTemplate handles null and false theme IDs correctly

The implementation in apps/backend/src/lib/email-rendering.tsx already covers all cases:

  • For a valid string ID that exists in themeList, it returns the corresponding theme.
  • If templateThemeId === false, it returns emptyEmailTheme.
  • For null or undefined, it falls back to getActiveEmailTheme.

No changes required here.

@BilalG1 BilalG1 force-pushed the sending-new-templates branch from a68c1b1 to 16c74fb Compare July 28, 2025 22:00
BilalG1 added 5 commits July 28, 2025 15:24
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->

<!-- ELLIPSIS_HIDDEN -->


----

> [!IMPORTANT]
> Remove `stack-emails` package and legacy templates, updating email
template handling across backend, frontend, and tests.
> 
>   - **Removal**:
> - Remove `stack-emails` package and associated legacy email template
handling.
> - Delete legacy email template files and related code in
`packages/stack-emails`.
>   - **Backend Changes**:
> - Update `sendEmailFromTemplate()` in `emails.tsx` to use new template
system.
> - Modify `admin-interface.ts` to update email template handling
methods.
>   - **Frontend Changes**:
> - Update email template management in `page-client.tsx` and
`sidebar-layout.tsx`.
> - Modify `useEmailTemplates()` and related functions in
`admin-app-impl.ts`.
>   - **Testing**:
> - Update tests in `email-templates.test.ts` to reflect new email
template handling.
>   - **Configuration**:
> - Remove `@stackframe/stack-emails` from `package.json` dependencies.
>     - Update `docker.compose.yaml` to use specific Inbucket version.
> 
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for dedaa9c. You can
[customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this
summary. It will automatically update as commits are pushed.</sup>


<!-- ELLIPSIS_HIDDEN -->
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4eaa52 and cc27de4.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (107)
  • apps/backend/package.json (0 hunks)
  • apps/backend/src/app/api/latest/email-templates/[type]/route.tsx (0 hunks)
  • apps/backend/src/app/api/latest/email-templates/crud.tsx (0 hunks)
  • apps/backend/src/app/api/latest/email-templates/route.tsx (0 hunks)
  • apps/backend/src/app/api/latest/internal/email-templates/temp/[projectId]/route.tsx (0 hunks)
  • apps/backend/src/app/api/latest/internal/email-templates/temp/convert.tsx (0 hunks)
  • apps/backend/src/lib/email-rendering.tsx (2 hunks)
  • apps/backend/src/lib/emails.tsx (2 hunks)
  • apps/dashboard/package.json (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[templateId]/page-client.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page-client.tsx (3 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/migrations/templates-migration/page-client.tsx (0 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/migrations/templates-migration/page.tsx (0 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx (2 hunks)
  • apps/dashboard/src/components/vibe-coding/code-editor.tsx (2 hunks)
  • apps/dashboard/src/components/vibe-coding/dts/index.ts (1 hunks)
  • apps/dashboard/src/components/vibe-coding/dts/util-dts.ts (1 hunks)
  • apps/dashboard/tailwind.config.ts (0 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/auth/otp/send-sign-in-code.test.ts (2 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/auth/password/reset.test.ts (1 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/internal/email-templates.test.ts (2 hunks)
  • docker/dependencies/docker.compose.yaml (1 hunks)
  • packages/stack-emails/.eslintrc.cjs (0 hunks)
  • packages/stack-emails/CHANGELOG.md (0 hunks)
  • packages/stack-emails/LICENSE (0 hunks)
  • packages/stack-emails/package.json (0 hunks)
  • packages/stack-emails/src/editor/blocks/block-button.tsx (0 hunks)
  • packages/stack-emails/src/editor/blocks/block-columns-container.tsx (0 hunks)
  • packages/stack-emails/src/editor/blocks/block-container.tsx (0 hunks)
  • packages/stack-emails/src/editor/blocks/block-divider.tsx (0 hunks)
  • packages/stack-emails/src/editor/blocks/block-heading.tsx (0 hunks)
  • packages/stack-emails/src/editor/blocks/block-image.tsx (0 hunks)
  • packages/stack-emails/src/editor/blocks/block-spacer.tsx (0 hunks)
  • packages/stack-emails/src/editor/blocks/block-text.tsx (0 hunks)
  • packages/stack-emails/src/editor/document-core/builders/buildBlockComponent.tsx (0 hunks)
  • packages/stack-emails/src/editor/document-core/builders/buildBlockConfigurationDictionary.ts (0 hunks)
  • packages/stack-emails/src/editor/document-core/builders/buildBlockConfigurationSchema.ts (0 hunks)
  • packages/stack-emails/src/editor/document-core/index.ts (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/columns-container/columns-container-editor.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/columns-container/columns-container-props-schema.ts (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/container/container-editor.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/container/container-props-schema.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/email-layout/email-layout-editor.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/email-layout/email-layout-props-schema.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/editor-block-wrapper.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/reader-block-wrapper.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/tune-menu.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/block-button.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/blocks-menu.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/buttons.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/index.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/index.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/font-family.ts (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/t-style.ts (0 hunks)
  • packages/stack-emails/src/editor/documents/blocks/helpers/zod.ts (0 hunks)
  • packages/stack-emails/src/editor/documents/editor/core.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/editor/editor-block.tsx (0 hunks)
  • packages/stack-emails/src/editor/documents/editor/editor-context.tsx (0 hunks)
  • packages/stack-emails/src/editor/editor.tsx (0 hunks)
  • packages/stack-emails/src/editor/email-builder/blocks/columns-container/columns-container-props-schema.ts (0 hunks)
  • packages/stack-emails/src/editor/email-builder/blocks/columns-container/columns-container-reader.tsx (0 hunks)
  • packages/stack-emails/src/editor/email-builder/blocks/container/container-props-schema.tsx (0 hunks)
  • packages/stack-emails/src/editor/email-builder/blocks/container/container-reader.tsx (0 hunks)
  • packages/stack-emails/src/editor/email-builder/blocks/email-layout/email-layout-props-schema.tsx (0 hunks)
  • packages/stack-emails/src/editor/email-builder/blocks/email-layout/email-layout-reader.tsx (0 hunks)
  • packages/stack-emails/src/editor/email-builder/index.ts (0 hunks)
  • packages/stack-emails/src/editor/email-builder/reader/core.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/index.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/button-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/columns-container-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/container-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/divider-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/heading-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/base-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/color-input/base-color-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/color-input/index.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/column-widths-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-family.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-size-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-weight-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/padding-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/raw/raw-slider-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/single-toggle-group.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/slider-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-align-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-dimension-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-input.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/style-inputs/multi-style-property-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/style-inputs/single-style-property-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/image-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/spacer-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/text-sidebar-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/index.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/settings-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/toggle-inspector-panel-button.tsx (0 hunks)
  • packages/stack-emails/src/editor/sidebar/variables-panel.tsx (0 hunks)
  • packages/stack-emails/src/editor/template-panel/download-json/index.tsx (0 hunks)
  • packages/stack-emails/src/editor/template-panel/import-json/import-json-dialog.tsx (0 hunks)
  • packages/stack-emails/src/editor/template-panel/import-json/index.tsx (0 hunks)
  • packages/stack-emails/src/editor/template-panel/import-json/validateJsonStringValue.ts (0 hunks)
  • packages/stack-emails/src/editor/template-panel/index.tsx (0 hunks)
  • packages/stack-emails/src/globals.d.ts (0 hunks)
  • packages/stack-emails/src/templates/email-verification.tsx (0 hunks)
  • packages/stack-emails/src/templates/empty.tsx (0 hunks)
  • packages/stack-emails/src/templates/magic-link-old.tsx (0 hunks)
  • packages/stack-emails/src/templates/magic-link.tsx (0 hunks)
  • packages/stack-emails/src/templates/password-reset.tsx (0 hunks)
⛔ Files not processed due to max files limit (8)
  • packages/stack-emails/src/templates/sign-in-invitation.tsx
  • packages/stack-emails/src/templates/team-invitation.tsx
  • packages/stack-emails/src/utils.tsx
  • packages/stack-emails/tsconfig.json
  • packages/stack-emails/vitest.config.ts
  • packages/stack-shared/src/interface/admin-interface.ts
  • packages/template/src/lib/stack-app/apps/implementations/admin-app-impl.ts
  • packages/template/src/lib/stack-app/apps/interfaces/admin-app.ts
💤 Files with no reviewable changes (94)
  • packages/stack-emails/.eslintrc.cjs
  • apps/backend/src/app/api/latest/email-templates/route.tsx
  • packages/stack-emails/src/globals.d.ts
  • packages/stack-emails/LICENSE
  • packages/stack-emails/src/editor/document-core/builders/buildBlockConfigurationDictionary.ts
  • packages/stack-emails/src/editor/blocks/block-container.tsx
  • packages/stack-emails/src/editor/template-panel/download-json/index.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-align-input.tsx
  • packages/stack-emails/src/templates/empty.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/raw/raw-slider-input.tsx
  • apps/backend/package.json
  • packages/stack-emails/src/editor/documents/blocks/container/container-props-schema.tsx
  • packages/stack-emails/src/editor/email-builder/blocks/container/container-reader.tsx
  • packages/stack-emails/CHANGELOG.md
  • packages/stack-emails/src/editor/sidebar/toggle-inspector-panel-button.tsx
  • packages/stack-emails/src/editor/template-panel/import-json/index.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/t-style.ts
  • packages/stack-emails/src/editor/sidebar/variables-panel.tsx
  • apps/dashboard/tailwind.config.ts
  • packages/stack-emails/src/editor/document-core/builders/buildBlockConfigurationSchema.ts
  • packages/stack-emails/src/editor/document-core/builders/buildBlockComponent.tsx
  • apps/backend/src/app/api/latest/email-templates/[type]/route.tsx
  • packages/stack-emails/src/editor/email-builder/blocks/columns-container/columns-container-reader.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/divider-sidebar-panel.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/migrations/templates-migration/page.tsx
  • packages/stack-emails/src/editor/email-builder/blocks/container/container-props-schema.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/font-family.ts
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/block-button.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/base-sidebar-panel.tsx
  • packages/stack-emails/src/editor/documents/blocks/columns-container/columns-container-props-schema.ts
  • packages/stack-emails/src/editor/email-builder/blocks/email-layout/email-layout-props-schema.tsx
  • packages/stack-emails/src/editor/documents/editor/editor-context.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/style-inputs/multi-style-property-panel.tsx
  • packages/stack-emails/src/editor/email-builder/index.ts
  • packages/stack-emails/src/editor/documents/blocks/container/container-editor.tsx
  • packages/stack-emails/src/editor/template-panel/import-json/import-json-dialog.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/zod.ts
  • packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/editor-block-wrapper.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/single-toggle-group.tsx
  • packages/stack-emails/src/templates/email-verification.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/container-sidebar-panel.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/slider-input.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/index.tsx
  • packages/stack-emails/src/editor/documents/editor/editor-block.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/spacer-sidebar-panel.tsx
  • packages/stack-emails/src/editor/sidebar/index.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/tune-menu.tsx
  • packages/stack-emails/src/editor/blocks/block-divider.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/migrations/templates-migration/page-client.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-weight-input.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/block-wrappers/reader-block-wrapper.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/image-sidebar-panel.tsx
  • packages/stack-emails/src/editor/template-panel/import-json/validateJsonStringValue.ts
  • packages/stack-emails/src/editor/template-panel/index.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/heading-sidebar-panel.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/text-sidebar-panel.tsx
  • packages/stack-emails/src/templates/password-reset.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/color-input/index.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/color-input/base-color-input.tsx
  • packages/stack-emails/src/editor/documents/blocks/columns-container/columns-container-editor.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-input.tsx
  • packages/stack-emails/src/editor/sidebar/settings-panel.tsx
  • apps/backend/src/app/api/latest/email-templates/crud.tsx
  • packages/stack-emails/src/editor/documents/blocks/email-layout/email-layout-props-schema.tsx
  • packages/stack-emails/src/editor/blocks/block-text.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/buttons.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/text-dimension-input.tsx
  • packages/stack-emails/src/editor/blocks/block-image.tsx
  • packages/stack-emails/package.json
  • apps/backend/src/app/api/latest/internal/email-templates/temp/[projectId]/route.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/columns-container-sidebar-panel.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/style-inputs/single-style-property-panel.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-size-input.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/index.tsx
  • packages/stack-emails/src/editor/editor.tsx
  • packages/stack-emails/src/editor/documents/blocks/helpers/editor-children-ids/add-block-menu/blocks-menu.tsx
  • packages/stack-emails/src/editor/email-builder/blocks/email-layout/email-layout-reader.tsx
  • packages/stack-emails/src/templates/magic-link-old.tsx
  • packages/stack-emails/src/editor/blocks/block-heading.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/index.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/column-widths-input.tsx
  • packages/stack-emails/src/editor/documents/blocks/email-layout/email-layout-editor.tsx
  • packages/stack-emails/src/editor/document-core/index.ts
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/font-family.tsx
  • packages/stack-emails/src/editor/blocks/block-spacer.tsx
  • packages/stack-emails/src/templates/magic-link.tsx
  • packages/stack-emails/src/editor/blocks/block-button.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/button-sidebar-panel.tsx
  • packages/stack-emails/src/editor/email-builder/blocks/columns-container/columns-container-props-schema.ts
  • apps/backend/src/app/api/latest/internal/email-templates/temp/convert.tsx
  • packages/stack-emails/src/editor/sidebar/configuration-panel/input-panels/helpers/inputs/padding-input.tsx
  • packages/stack-emails/src/editor/blocks/block-columns-container.tsx
  • packages/stack-emails/src/editor/documents/editor/core.tsx
  • packages/stack-emails/src/editor/email-builder/reader/core.tsx
✅ Files skipped from review due to trivial changes (4)
  • apps/dashboard/package.json
  • docker/dependencies/docker.compose.yaml
  • apps/dashboard/src/components/vibe-coding/dts/index.ts
  • apps/dashboard/src/components/vibe-coding/dts/util-dts.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/e2e/tests/backend/endpoints/api/v1/auth/password/reset.test.ts
  • apps/e2e/tests/backend/endpoints/api/v1/auth/otp/send-sign-in-code.test.ts
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/page-client.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/email-templates/[templateId]/page-client.tsx
  • apps/backend/src/lib/email-rendering.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.{ts,tsx}: TypeScript with strict types, prefer type over interface
Avoid casting to any; Prefer making changes to the API so that any casts are unnecessary to access a property or method

Files:

  • apps/dashboard/src/components/vibe-coding/code-editor.tsx
  • apps/e2e/tests/backend/endpoints/api/v1/internal/email-templates.test.ts
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx
  • apps/backend/src/lib/emails.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.{js,jsx,ts,tsx}: 2-space indentation, spaces in braces, semicolons required
Return promises with return await, no floating promises
Proper error handling for async code with try/catch
Use helper functions: yupXyz() for validation, getPublicEnvVar() for env
Switch cases must use blocks

Files:

  • apps/dashboard/src/components/vibe-coding/code-editor.tsx
  • apps/e2e/tests/backend/endpoints/api/v1/internal/email-templates.test.ts
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx
  • apps/backend/src/lib/emails.tsx
**/*.{jsx,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.{jsx,tsx}: React Server Components preferred where applicable
No direct 'use' imports from React (use React.use instead)

Files:

  • apps/dashboard/src/components/vibe-coding/code-editor.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx
  • apps/backend/src/lib/emails.tsx
apps/e2e/**/*.test.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Import test utilities from /apps/e2e/test/helpers.ts

Files:

  • apps/e2e/tests/backend/endpoints/api/v1/internal/email-templates.test.ts
**/*.test.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Prefer inline snapshot testing with expect(response).toMatchInlineSnapshot(...)

Files:

  • apps/e2e/tests/backend/endpoints/api/v1/internal/email-templates.test.ts
🧠 Learnings (3)
apps/dashboard/src/components/vibe-coding/code-editor.tsx (4)

Learnt from: CR
PR: stack-auth/stack-auth#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-28T23:25:51.691Z
Learning: Applies to **/*.{ts,tsx} : Avoid casting to any; Prefer making changes to the API so that any casts are unnecessary to access a property or method

Learnt from: CR
PR: stack-auth/stack-auth#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-28T23:25:51.691Z
Learning: Applies to **/*.{ts,tsx} : TypeScript with strict types, prefer type over interface

Learnt from: CR
PR: stack-auth/stack-auth#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-28T23:25:51.691Z
Learning: Applies to **/*.{jsx,tsx} : No direct 'use' imports from React (use React.use instead)

Learnt from: CR
PR: stack-auth/stack-auth#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-28T23:25:51.691Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : 2-space indentation, spaces in braces, semicolons required

apps/e2e/tests/backend/endpoints/api/v1/internal/email-templates.test.ts (3)

Learnt from: CR
PR: stack-auth/stack-auth#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-28T23:25:51.691Z
Learning: Applies to apps/e2e/**/*.test.{ts,tsx} : Import test utilities from /apps/e2e/test/helpers.ts

Learnt from: CR
PR: stack-auth/stack-auth#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-28T23:25:51.691Z
Learning: Applies to **/*.test.{js,jsx,ts,tsx} : Prefer inline snapshot testing with expect(response).toMatchInlineSnapshot(...)

Learnt from: CR
PR: stack-auth/stack-auth#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-28T23:25:51.691Z
Learning: Applies to **/*.{ts,tsx} : Avoid casting to any; Prefer making changes to the API so that any casts are unnecessary to access a property or method

apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx (1)

Learnt from: CR
PR: stack-auth/stack-auth#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-28T23:25:51.691Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use helper functions: yupXyz() for validation, getPublicEnvVar() for env

🧬 Code Graph Analysis (3)
apps/dashboard/src/components/vibe-coding/code-editor.tsx (1)
apps/dashboard/src/components/vibe-coding/dts/index.ts (1)
  • dtsBundles (5-9)
apps/e2e/tests/backend/endpoints/api/v1/internal/email-templates.test.ts (1)
apps/e2e/tests/backend/backend-helpers.ts (1)
  • niceBackendFetch (107-165)
apps/backend/src/lib/emails.tsx (5)
apps/backend/src/lib/tenancies.tsx (1)
  • Tenancy (50-50)
packages/stack-shared/src/helpers/emails.ts (1)
  • DEFAULT_TEMPLATE_IDS (108-114)
packages/stack-shared/src/utils/errors.tsx (1)
  • StackAssertionError (67-83)
apps/backend/src/lib/email-rendering.tsx (2)
  • getEmailThemeForTemplate (23-32)
  • renderEmailWithTemplate (49-136)
packages/stack-shared/src/utils/objects.tsx (1)
  • filterUndefined (368-370)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: docker
  • GitHub Check: restart-dev-and-test
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: docker
  • GitHub Check: all-good
  • GitHub Check: build (22.x)
  • GitHub Check: Security Check
🔇 Additional comments (5)
apps/dashboard/src/components/vibe-coding/code-editor.tsx (2)

6-6: LGTM! Improved type safety with proper imports.

The import of dtsBundles replaces previous inline declarations and aligns with the coding guidelines to avoid any casts by providing proper TypeScript declaration bundles.


96-98: Excellent improvement to type definitions!

These changes replace generic type declarations with comprehensive TypeScript declaration bundles for arktype functionality. The implementation maintains consistency with existing addExtraLib calls and enhances the Monaco editor's type checking capabilities.

apps/backend/src/lib/emails.tsx (1)

307-349: LGTM! Well-structured refactoring to the new template rendering system.

The changes properly implement the new TSX-based template rendering approach with:

  • Type-safe template type parameter using keyof typeof DEFAULT_TEMPLATE_IDS
  • Clear separation of template and theme retrieval
  • Comprehensive error handling with debugging context
  • Proper handling of optional user display name
apps/e2e/tests/backend/endpoints/api/v1/internal/email-templates.test.ts (1)

5-95: LGTM! Tests properly validate the new email template API behavior.

The test updates correctly verify:

  • Rejection of template updates when using shared email configuration with the new REQUIRES_CUSTOM_EMAIL_SERVER error
  • Successful template updates with custom email configuration
  • The new TSX-based template format using tsx_source
  • Mock rendering response structure
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx (1)

250-322: LGTM! Navigation updates properly reflect the new email templates structure.

The changes correctly update:

  • Navigation paths from /email-templates-new/ to /email-templates/
  • Breadcrumb generation for the simplified route structure
  • Hook usage from useNewEmailTemplates() to useEmailTemplates()

All changes are consistent with the removal of the legacy email template system.

@N2D4 N2D4 enabled auto-merge (squash) July 29, 2025 00:24
@N2D4 N2D4 merged commit b2cc6f2 into dev Jul 29, 2025
18 of 23 checks passed
@N2D4 N2D4 deleted the sending-new-templates branch July 29, 2025 00:26
madster456 pushed a commit that referenced this pull request Aug 4, 2025
@coderabbitai coderabbitai bot mentioned this pull request Aug 18, 2025
@coderabbitai coderabbitai bot mentioned this pull request Nov 6, 2025
This was referenced Nov 14, 2025
@coderabbitai coderabbitai bot mentioned this pull request Nov 26, 2025
@coderabbitai coderabbitai bot mentioned this pull request Dec 3, 2025
@coderabbitai coderabbitai bot mentioned this pull request Dec 16, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jan 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants