Skip to content

OUT-3735 | Reminder copy helper: getReminderEmailDetails#1230

Merged
arpandhakal merged 2 commits into
feature/email-remindersfrom
OUT-3735-reminder-copy-helper
May 25, 2026
Merged

OUT-3735 | Reminder copy helper: getReminderEmailDetails#1230
arpandhakal merged 2 commits into
feature/email-remindersfrom
OUT-3735-reminder-copy-helper

Conversation

@arpandhakal
Copy link
Copy Markdown
Collaborator

Summary

  • Adds getReminderEmailDetails(workspace, task, isCompanyRecipient) in notification.helpers.ts — returns subject/header/title/body/ctaParams for each of the six TaskReminderType variants.
  • Header branches on recipient kind: "to you" for individuals, "to your {groupTerm}" for companies (resolved via getWorkspaceLabels).
  • Subjects include {brandName} portal: prefix interpolated from workspace.brandName.
  • Lives alongside getEmailDetails rather than merging — NotificationTaskActions and reminder types have separate lifecycles.

Note: stacked on top of #1229 (OUT-3734). Base should switch to main once that lands.

Minor copy deviation: PRD shows DUE_DATE_OVERDUE_7D subject without the {Company} portal: prefix (the other 5 have it). I included the prefix for consistency — looks like a PRD typo. Easy to drop if intentional.

Test plan

  • Helper returns a value for every TaskReminderType variant
  • Snapshot test covers all 6 variants for individual recipient
  • Snapshot test covers all 6 variants for company recipient
  • Custom groupTerm from workspace labels flows into header
  • Missing brandName degrades gracefully (portal: prefix without leading whitespace)
  • ctaParams: { taskId } emitted on every variant
  • tsc --noEmit passes

🤖 Generated with Claude Code

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 15, 2026

OUT-3735

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tasks-app Ready Ready Preview, Comment May 25, 2026 6:52am

Request Review

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 15, 2026

Greptile Summary

Introduces getReminderEmailDetails, a pure helper that maps all six TaskReminderType variants to their reminder email fields (subject, header, title, body, ctaParams). The brandName-prefixed subject and groupTerm-based header branching are both well-implemented, and the new test file provides strong coverage including snapshots, edge-case fallbacks, and per-variant ctaParams assertions.

  • getReminderEmailDetails computes portalPrefix via trimStart() which correctly degrades to \"portal: …\" when brandName is absent, and resolves the groupTerm through the shared getWorkspaceLabels utility.
  • Six TaskReminderType variants are all covered; the return type is a strict Record<TaskReminderType, …> so TypeScript will catch any future enum additions at compile time.
  • The isCompanyRecipient flag only gates the header field — all body strings use "you"/"assigned to you" regardless of recipient type, which may be intentional (emails go to individual company members) but is worth confirming.

Confidence Score: 4/5

Safe to merge — the helper is pure, isolated, and fully tested; the only open question is whether body copy for company recipients should differ from individual copy

The new function is a straightforward data mapping helper with no side effects. The brandName fallback and groupTerm interpolation are both correct, and the return type's use of Record<TaskReminderType, …> ensures compile-time exhaustiveness. The one open question — whether body copy should adapt when isCompanyRecipient=true — has no current wrong behavior since the snapshots lock in the existing output, but the inconsistency between header and body phrasing for company emails deserves a brief clarification before the code grows.

The body strings in notification.helpers.ts always use "you" / "assigned to you" regardless of isCompanyRecipient; worth a quick cross-check against the PRD to confirm this is intentional

Important Files Changed

Filename Overview
src/app/api/notification/notification.helpers.ts Adds getReminderEmailDetails — a pure helper returning subject/header/title/body/ctaParams for all 6 TaskReminderType variants; brandName fallback and groupTerm interpolation are handled correctly, but body copy does not vary with isCompanyRecipient
src/app/api/notification/notification.helpers.test.ts New test file covering all 6 variants, snapshot parity for individual and company recipients, custom groupTerm propagation, missing brandName fallback, and ctaParams emission
src/app/api/notification/snapshots/notification.helpers.test.ts.snap Auto-generated Jest snapshot confirming stable output for all 6 reminder types in both recipient modes; snapshots look correct

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["getReminderEmailDetails(workspace, task, isCompanyRecipient)"] --> B["portalPrefix = brandName ?? '' + ' portal:' trimStart()"]
    A --> C["labels = getWorkspaceLabels(workspace)"]
    A --> D{isCompanyRecipient?}
    D -- true --> E["header = 'A task was assigned to your {groupTerm}'"]
    D -- false --> F["header = 'A task was assigned to you'"]
    E --> G["Build Record<TaskReminderType, EmailFields>"]
    F --> G
    B --> G
    G --> H["NO_DUE_DATE_3D"]
    G --> I["NO_DUE_DATE_7D"]
    G --> J["DUE_DATE_BEFORE_3D"]
    G --> K["DUE_DATE_TODAY"]
    G --> L["DUE_DATE_OVERDUE_3D"]
    G --> M["DUE_DATE_OVERDUE_7D"]
    H & I & J & K & L & M --> N["{ subject, header, title, body, ctaParams: { taskId } }"]
Loading

Reviews (1): Last reviewed commit: "feat(OUT-3735): add getReminderEmailDeta..." | Re-trigger Greptile

> => {
const portalPrefix = `${workspace.brandName ?? ''} portal:`.trimStart()
const labels = getWorkspaceLabels(workspace)
const header = isCompanyRecipient ? `A task was assigned to your ${labels.groupTerm}` : 'A task was assigned to you'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Body copy never adapts to isCompanyRecipient

The header correctly branches on isCompanyRecipient, but all six body strings are hardcoded with "you"/"assigned to you" phrasing. When isCompanyRecipient=true, a reader sees header "A task was assigned to your company" alongside body "…you have a task '...' assigned to you that's still pending completion" — the "you" in the body contradicts the company-assignment framing in the header. If the body is intentionally addressed to the individual even for company assignments (a common B2B pattern), a brief comment explaining that design decision would prevent future confusion.

Copy link
Copy Markdown
Collaborator

@SandipBajracharya SandipBajracharya left a comment

Choose a reason for hiding this comment

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

lgtm

@arpandhakal arpandhakal force-pushed the arpandhakal/out-3734-schema-add-taskremindersent-table-taskremindertype-enum branch from b4fdbe6 to d3b94ad Compare May 18, 2026 10:49
Returns subject/header/title/body/ctaParams for each of the six
TaskReminderType variants. Header branches on whether the recipient is
a company (uses workspace groupTerm) or an individual.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@arpandhakal arpandhakal force-pushed the OUT-3735-reminder-copy-helper branch from cc71a88 to ff14b29 Compare May 18, 2026 10:50
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 18, 2026

Deployment failed with the following error:

Deploying Serverless Functions to multiple regions is restricted to the Pro and Enterprise plans.

Learn More: https://vercel.link/multiple-function-regions

@arpandhakal arpandhakal changed the base branch from arpandhakal/out-3734-schema-add-taskremindersent-table-taskremindertype-enum to feature/email-reminders May 25, 2026 06:50
@arpandhakal arpandhakal merged commit 7fe64ff into feature/email-reminders May 25, 2026
2 of 3 checks passed
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