refactor: replace Apollo Client with Prisma for user data retrieval i…#8872
refactor: replace Apollo Client with Prisma for user data retrieval i…#8872mikeallisonJS wants to merge 2 commits intomainfrom
Conversation
WalkthroughThe changes replace Apollo Client GraphQL-based user lookups with Prisma database queries throughout the email service implementation and its corresponding tests. Apollo client initialization, GraphQL query definitions, and associated mocks are removed and replaced with Prisma user.findUnique and user.findMany calls. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit c39240a
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apis/api-journeys-modern/src/workers/email/service/service.spec.ts (1)
195-200: Add regression coverage for the new lookup edge cases.These specs only mock fully populated user rows. Please add cases for a
userIdlookup returningemail: nulland for the manager batch lookup returning fewer rows than requested, so the new recipient-resolution branches fail loudly instead of regressing silently.Also applies to: 273-288
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apis/api-journeys-modern/src/workers/email/service/service.spec.ts` around lines 195 - 200, Add two regression tests in service.spec.ts to exercise the recipient-resolution error branches: 1) Create a test that stubs mockPrismaUsers.user.findUnique (the userId lookup) to resolve to an object with email: null (and valid id/firstName) and assert the service throws or rejects with the expected error when resolving recipients for that userId; 2) Create a test that stubs mockPrismaUsers.user.findMany (the manager batch lookup used by the manager-resolution code path) to return fewer rows than the requested manager IDs and assert the service fails loudly (throws/rejects) rather than silently continuing. Use the same setup helpers/fixtures already present in the file and mirror existing test structure around mockPrismaUsers.user.findUnique and mockPrismaUsers.user.findMany so these new tests cover the two new edge branches referenced in recipient-resolution.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apis/api-journeys-modern/src/workers/email/service/service.ts`:
- Around line 59-66: The code is coercing null emails to an empty string when
building recipient objects (see recipientUser -> user creation), which allows
invalid recipients to proceed; update the logic to 1) define a shared
EmailRecipient type/helper and use it across the places mentioned (current block
and the similar blocks at the other ranges), 2) check recipientUser.email
explicitly and if it's null/undefined return or throw before any
rendering/sending or preference lookups, and 3) replace the current spread that
sets email: recipientUser.email ?? '' with construction that only creates an
EmailRecipient when email is present (and preserve lastName handling as
optional). Locate and update the recipient construction code paths referencing
recipientUser, ensure preference/delivery functions accept the typed
EmailRecipient only, and remove the empty-string normalization.
- Around line 221-230: The code currently builds recipients via
recipientUserIds.map(id => recipientUsersByUserId.get(id)) and only throws
inside the send loop, which can cause partial delivery; modify the logic in the
block around recipients, recipientUserIds and recipientUsersByUserId to validate
the entire batch before any sends by checking for any undefined entries (e.g.,
find missingIds = recipientUserIds.filter(id => !recipientUsersByUserId.has(id))
or check recipients.some(r => r == null)) and throw a clear error (including
missing ids) if any manager is absent so the subsequent send loop over
recipients only runs when all recipients are present.
---
Nitpick comments:
In `@apis/api-journeys-modern/src/workers/email/service/service.spec.ts`:
- Around line 195-200: Add two regression tests in service.spec.ts to exercise
the recipient-resolution error branches: 1) Create a test that stubs
mockPrismaUsers.user.findUnique (the userId lookup) to resolve to an object with
email: null (and valid id/firstName) and assert the service throws or rejects
with the expected error when resolving recipients for that userId; 2) Create a
test that stubs mockPrismaUsers.user.findMany (the manager batch lookup used by
the manager-resolution code path) to return fewer rows than the requested
manager IDs and assert the service fails loudly (throws/rejects) rather than
silently continuing. Use the same setup helpers/fixtures already present in the
file and mirror existing test structure around mockPrismaUsers.user.findUnique
and mockPrismaUsers.user.findMany so these new tests cover the two new edge
branches referenced in recipient-resolution.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 0ba6bdf0-7f1f-4cfb-9512-4e10d75f4115
📒 Files selected for processing (2)
apis/api-journeys-modern/src/workers/email/service/service.spec.tsapis/api-journeys-modern/src/workers/email/service/service.ts
| const user = | ||
| recipientUser == null | ||
| ? null | ||
| : { | ||
| ...recipientUser, | ||
| email: recipientUser.email ?? '', | ||
| lastName: recipientUser.lastName ?? undefined | ||
| } |
There was a problem hiding this comment.
Don't coerce missing email addresses into sendable recipients.
The users schema allows email to be null for these userId-based lookups, but these branches normalize it to '' and later use that value for preference lookups and delivery. Please guard email explicitly and return/throw before rendering or sending; extracting a shared EmailRecipient type/helper would also remove the repeated object-shape copies here.
As per coding guidelines **/*.{ts,tsx}: Define a type if possible.
Also applies to: 210-218, 290-297, 349-356
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apis/api-journeys-modern/src/workers/email/service/service.ts` around lines
59 - 66, The code is coercing null emails to an empty string when building
recipient objects (see recipientUser -> user creation), which allows invalid
recipients to proceed; update the logic to 1) define a shared EmailRecipient
type/helper and use it across the places mentioned (current block and the
similar blocks at the other ranges), 2) check recipientUser.email explicitly and
if it's null/undefined return or throw before any rendering/sending or
preference lookups, and 3) replace the current spread that sets email:
recipientUser.email ?? '' with construction that only creates an EmailRecipient
when email is present (and preserve lastName handling as optional). Locate and
update the recipient construction code paths referencing recipientUser, ensure
preference/delivery functions accept the typed EmailRecipient only, and remove
the empty-string normalization.
| const recipients = recipientUserIds.map((userId) => | ||
| recipientUsersByUserId.get(userId) | ||
| ) | ||
|
|
||
| if (recipients.length === 0) { | ||
| throw new Error('Team Managers not found') | ||
| } | ||
|
|
||
| for (const recipient of recipientEmails) { | ||
| if (recipient.user == null) throw new Error('User not found') | ||
| for (const recipient of recipients) { | ||
| if (recipient == null) throw new Error('User not found') |
There was a problem hiding this comment.
Validate the full manager batch before the first send.
recipientUsersByUserId.get(userId) can still be undefined when one of the manager records is missing. Because that check happens inside the send loop, earlier managers may already have been emailed before the function throws, leaving the batch partially delivered.
Suggested guard
const recipients = recipientUserIds.map((userId) =>
recipientUsersByUserId.get(userId)
)
-if (recipients.length === 0) {
+if (recipients.length === 0 || recipients.some((recipient) => recipient == null)) {
throw new Error('Team Managers not found')
}
for (const recipient of recipients) {
- if (recipient == null) throw new Error('User not found')
-
// check recipient preferences📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const recipients = recipientUserIds.map((userId) => | |
| recipientUsersByUserId.get(userId) | |
| ) | |
| if (recipients.length === 0) { | |
| throw new Error('Team Managers not found') | |
| } | |
| for (const recipient of recipientEmails) { | |
| if (recipient.user == null) throw new Error('User not found') | |
| for (const recipient of recipients) { | |
| if (recipient == null) throw new Error('User not found') | |
| const recipients = recipientUserIds.map((userId) => | |
| recipientUsersByUserId.get(userId) | |
| ) | |
| if (recipients.length === 0 || recipients.some((recipient) => recipient == null)) { | |
| throw new Error('Team Managers not found') | |
| } | |
| for (const recipient of recipients) { | |
| // check recipient preferences |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apis/api-journeys-modern/src/workers/email/service/service.ts` around lines
221 - 230, The code currently builds recipients via recipientUserIds.map(id =>
recipientUsersByUserId.get(id)) and only throws inside the send loop, which can
cause partial delivery; modify the logic in the block around recipients,
recipientUserIds and recipientUsersByUserId to validate the entire batch before
any sends by checking for any undefined entries (e.g., find missingIds =
recipientUserIds.filter(id => !recipientUsersByUserId.has(id)) or check
recipients.some(r => r == null)) and throw a clear error (including missing ids)
if any manager is absent so the subsequent send loop over recipients only runs
when all recipients are present.
…n email service
Summary by CodeRabbit