Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughTightens partner postback emission to require both partnerId and programId, includes programId in partner postback payloads, threads program-level customerDataSharingEnabledAt into postback enrichment, adds customer masking/random-name logic, and exposes email in postback customer schemas and sample events. Changes
Sequence Diagram(s)sequenceDiagram
participant Trigger as Conversion Trigger
participant SendPB as sendPartnerPostback
participant DB as ProgramEnrollment DB
participant Enricher as PostbackEventEnricher
participant Transformer as transformCustomer
participant Partner as Partner Endpoint
Trigger->>SendPB: call(event, data, partnerId, programId)
SendPB->>DB: query ProgramEnrollment(partnerId, programId)
alt enrollment found
DB-->>SendPB: { customerDataSharingEnabledAt }
SendPB->>Enricher: enrich(event, data, { customerDataSharingEnabledAt })
Enricher->>Transformer: transformCustomer(customer, customerDataSharingEnabledAt)
alt sharing enabled
Transformer-->>Enricher: original customer/email
else sharing disabled
Transformer-->>Enricher: masked email or random name
end
Enricher-->>SendPB: enriched payload
SendPB->>Partner: POST enriched payload (includes programId)
else enrollment missing
DB-->>SendPB: not found (log & abort)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 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)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
apps/web/lib/integrations/shopify/create-lead.ts (1)
121-154: Inconsistent condition key order between the two guard blocks.Line 121 checks
link.partnerId && link.programIdwhile line 137 checkslink.programId && link.partnerId. These are semantically equivalent, but aligning them avoids confusion during future diffs.♻️ Proposed fix
- ...(link.programId && link.partnerId + ...(link.partnerId && link.programId ? [ syncPartnerLinksStats({🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/lib/integrations/shopify/create-lead.ts` around lines 121 - 154, Two adjacent guard blocks use the same boolean check but in different operand orders; make them consistent to avoid noisy diffs by using the same key order in both places (e.g., change the second guard to use link.partnerId && link.programId). Update the conditional that guards the syncPartnerLinksStats and prisma.customer.update calls so it matches the first guard that wraps sendPartnerPostback (both should check link.partnerId && link.programId), leaving sendPartnerPostback, syncPartnerLinksStats, and prisma.customer.update unchanged.apps/web/app/(ee)/api/stripe/integration/webhook/invoice-paid.ts (1)
299-313: LGTM. Minor: unnecessary optional chaining onlinkUpdated.
linkUpdatedis the direct result ofprisma.link.update(), so it's always non-null;linkUpdated?.programIdcan safely drop the?.. Non-blocking.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/`(ee)/api/stripe/integration/webhook/invoice-paid.ts around lines 299 - 313, The conditional uses unnecessary optional chaining on linkUpdated (result of prisma.link.update) — change `linkUpdated?.programId` to `linkUpdated.programId` in the ternary that builds the array for sendPartnerPostback so the condition reads `...(link?.partnerId && linkUpdated.programId ? [ sendPartnerPostback({ ... }) ] : []),` referencing the existing variables `link`, `linkUpdated`, and the call to `sendPartnerPostback`.apps/web/lib/partners/create-partner-commission.ts (1)
364-372: Redundantcustomeroverride after spreadingcommission.
commissionalready includes thecustomerrelation (frominclude: { customer: true }at line 294), so explicitly restating it is a no-op.♻️ Proposed fix
sendPartnerPostback({ partnerId, programId, event: "commission.created", data: { - ...commission, - customer: commission.customer, + ...commission, }, }),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/lib/partners/create-partner-commission.ts` around lines 364 - 372, The data object passed to sendPartnerPostback redundantly sets customer: commission.customer after spreading commission; remove the explicit "customer: commission.customer" property so the spread of commission already provides the customer relation and avoid the no-op override in sendPartnerPostback({ partnerId, programId, event: "commission.created", data: { ...commission } }).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/lib/postback/api/postback-event-enrichers.ts`:
- Around line 58-78: The transformCustomer function is incorrectly populating
the email field with customer.name or a generated name when customer.email is
missing; change it so email remains null/undefined when no valid customer.email
exists and move the fallback logic to the name field instead. Specifically, in
transformCustomer ensure you only set email from customer.email (masked when
customerDataSharingEnabledAt is falsy) or leave it unset/null if absent, and set
name to customer.name || generateRandomName() so consumers get a valid name
fallback without polluting the email field; update the returned object (from
transformCustomer) to spread ...customer and explicitly override name and email
accordingly.
---
Nitpick comments:
In `@apps/web/app/`(ee)/api/stripe/integration/webhook/invoice-paid.ts:
- Around line 299-313: The conditional uses unnecessary optional chaining on
linkUpdated (result of prisma.link.update) — change `linkUpdated?.programId` to
`linkUpdated.programId` in the ternary that builds the array for
sendPartnerPostback so the condition reads `...(link?.partnerId &&
linkUpdated.programId ? [ sendPartnerPostback({ ... }) ] : []),` referencing the
existing variables `link`, `linkUpdated`, and the call to `sendPartnerPostback`.
In `@apps/web/lib/integrations/shopify/create-lead.ts`:
- Around line 121-154: Two adjacent guard blocks use the same boolean check but
in different operand orders; make them consistent to avoid noisy diffs by using
the same key order in both places (e.g., change the second guard to use
link.partnerId && link.programId). Update the conditional that guards the
syncPartnerLinksStats and prisma.customer.update calls so it matches the first
guard that wraps sendPartnerPostback (both should check link.partnerId &&
link.programId), leaving sendPartnerPostback, syncPartnerLinksStats, and
prisma.customer.update unchanged.
In `@apps/web/lib/partners/create-partner-commission.ts`:
- Around line 364-372: The data object passed to sendPartnerPostback redundantly
sets customer: commission.customer after spreading commission; remove the
explicit "customer: commission.customer" property so the spread of commission
already provides the customer relation and avoid the no-op override in
sendPartnerPostback({ partnerId, programId, event: "commission.created", data: {
...commission } }).
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.tsapps/web/app/(ee)/api/stripe/integration/webhook/invoice-paid.tsapps/web/app/(ee)/api/stripe/integration/webhook/utils/create-new-customer.tsapps/web/lib/api/conversions/track-lead.tsapps/web/lib/api/conversions/track-sale.tsapps/web/lib/integrations/shopify/create-lead.tsapps/web/lib/integrations/shopify/create-sale.tsapps/web/lib/partners/create-partner-commission.tsapps/web/lib/postback/api/postback-event-enrichers.tsapps/web/lib/postback/api/send-partner-postback.tsapps/web/lib/postback/sample-events/commission-created.jsonapps/web/lib/postback/sample-events/lead-created.jsonapps/web/lib/postback/sample-events/sale-created.jsonapps/web/lib/postback/schemas.ts
|
@coderabbitai full review please |
|
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
apps/web/lib/postback/api/postback-event-enrichers.ts (1)
58-79:customer.emailis absent.When
customer.emailis falsy, line 73 assignscustomer?.name || generateRandomName()to🐛 Proposed fix
function transformCustomer({ customer, customerDataSharingEnabledAt, }: { customer: Record<string, any>; customerDataSharingEnabledAt: PostbackEnricherContext["customerDataSharingEnabledAt"]; }) { if (!customer) { return null; } - const email = customer?.email - ? customerDataSharingEnabledAt - ? customer.email - : customer.email.replace(/(?<=^.).+(?=.@)/, "****") - : customer?.name || generateRandomName(); + const email = customer?.email + ? customerDataSharingEnabledAt + ? customer.email + : customer.email.replace(/(?<=^.).+(?=.@)/, "****") + : null; return { ...customer, email, }; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/lib/postback/api/postback-event-enrichers.ts` around lines 58 - 79, In transformCustomer, the email variable is being set to customer?.name or generateRandomName() when customer.email is falsy; change this so the email field is either the actual (or obfuscated) customer.email or null/undefined instead of a non-email string. Update the email assignment in transformCustomer to: if customer.email is truthy use customerDataSharingEnabledAt ? customer.email : obfuscated email, otherwise set email to null (or undefined) so the returned object from transformCustomer does not place names/random strings into the email property.
🧹 Nitpick comments (4)
apps/web/app/(ee)/api/stripe/integration/webhook/utils/create-new-customer.ts (1)
154-158: Use one source object for IDs to avoid stale/mixed reads.Line 154 and Line 157 mix
linkandlinkUpdated. Prefer usinglinkUpdatedconsistently for both guard and payload IDs.♻️ Suggested refactor
- ...(link.partnerId && linkUpdated.programId + ...(linkUpdated.partnerId && linkUpdated.programId ? [ sendPartnerPostback({ - partnerId: link.partnerId, + partnerId: linkUpdated.partnerId, programId: linkUpdated.programId, event: "lead.created", data: {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/`(ee)/api/stripe/integration/webhook/utils/create-new-customer.ts around lines 154 - 158, The guard and payload are mixing two sources (link vs linkUpdated) which can cause stale/mixed reads; update the conditional and payload to use linkUpdated consistently so both the truthy check and the sendPartnerPostback call reference the same object (use linkUpdated.partnerId and linkUpdated.programId) — locate the conditional that opens with ...(link.partnerId && linkUpdated.programId ? and the sendPartnerPostback invocation and replace the guard to check linkUpdated.partnerId and pass partnerId/programId from linkUpdated to sendPartnerPostback.apps/web/lib/integrations/shopify/create-lead.ts (1)
121-121: Nit: Inconsistent operand ordering between the two guard conditions.Line 121 uses
link.partnerId && link.programIdwhile Line 137 useslink.programId && link.partnerId. Consider picking one order for consistency.Also applies to: 137-137
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/lib/integrations/shopify/create-lead.ts` at line 121, Unify the boolean guard ordering in create-lead.ts by choosing one consistent operand order for the link checks; replace either occurrences of "link.partnerId && link.programId" or "link.programId && link.partnerId" so both use the same order (e.g., always "link.partnerId && link.programId") in the relevant conditional expressions within the createLead handler/function to keep the codebase consistent and readable.apps/web/lib/integrations/shopify/create-sale.ts (1)
216-230: LGTM — postback gated andprogramIdpropagated correctly.The condition properly requires both IDs, and
programIdis passed tosendPartnerPostback.Minor nit:
link?.partnerId && link?.programIduses optional chaining here whilecreate-lead.ts(Line 121) useslink.partnerId && link.programIdwithout it. Sincelinkis always defined at this point (result ofprisma.link.updatefrom thePromise.allabove), the optional chaining is unnecessary. Consider aligning the style across both Shopify integration files.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/lib/integrations/shopify/create-sale.ts` around lines 216 - 230, The guard currently uses optional chaining in the expression link?.partnerId && link?.programId even though link is guaranteed to be defined here (result of prisma.link.update); change the condition to use direct property access (link.partnerId && link.programId) to match the style used in create-lead.ts and remove the unnecessary optional chaining; update the conditional around sendPartnerPostback in create-sale.ts to reference link.partnerId and link.programId without the "?" to align both Shopify integration files.apps/web/lib/postback/api/send-partner-postback.ts (1)
46-72: Early return when enrollment is missing silently drops the postback.When
programIdis provided but the enrollment lookup fails (Line 64-68), the function returns without sending any postback. This is a reasonable guard, but note that any transient DB issue or data inconsistency (e.g., race condition during enrollment creation) will silently suppress the postback with only aconsole.warn. Consider whether this warrants a more visible alert (e.g., logging to your error tracking) for production observability.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/lib/postback/api/send-partner-postback.ts` around lines 46 - 72, The current early return when prisma.programEnrollment.findUnique returns no result silently drops the postback; in sendPartnerPostback replace the console.warn + return with a visible error/alert: log an error via the app's error logger (e.g., processLogger.error) and send the event to error tracking (e.g., Sentry.captureException or your notifyError helper) including partnerId, programId and context, or alternatively throw a retryable error so the postback can be retried, ensuring programEnrollment lookup failures are observable and not silently ignored.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@apps/web/lib/postback/api/postback-event-enrichers.ts`:
- Around line 58-79: In transformCustomer, the email variable is being set to
customer?.name or generateRandomName() when customer.email is falsy; change this
so the email field is either the actual (or obfuscated) customer.email or
null/undefined instead of a non-email string. Update the email assignment in
transformCustomer to: if customer.email is truthy use
customerDataSharingEnabledAt ? customer.email : obfuscated email, otherwise set
email to null (or undefined) so the returned object from transformCustomer does
not place names/random strings into the email property.
---
Nitpick comments:
In
`@apps/web/app/`(ee)/api/stripe/integration/webhook/utils/create-new-customer.ts:
- Around line 154-158: The guard and payload are mixing two sources (link vs
linkUpdated) which can cause stale/mixed reads; update the conditional and
payload to use linkUpdated consistently so both the truthy check and the
sendPartnerPostback call reference the same object (use linkUpdated.partnerId
and linkUpdated.programId) — locate the conditional that opens with
...(link.partnerId && linkUpdated.programId ? and the sendPartnerPostback
invocation and replace the guard to check linkUpdated.partnerId and pass
partnerId/programId from linkUpdated to sendPartnerPostback.
In `@apps/web/lib/integrations/shopify/create-lead.ts`:
- Line 121: Unify the boolean guard ordering in create-lead.ts by choosing one
consistent operand order for the link checks; replace either occurrences of
"link.partnerId && link.programId" or "link.programId && link.partnerId" so both
use the same order (e.g., always "link.partnerId && link.programId") in the
relevant conditional expressions within the createLead handler/function to keep
the codebase consistent and readable.
In `@apps/web/lib/integrations/shopify/create-sale.ts`:
- Around line 216-230: The guard currently uses optional chaining in the
expression link?.partnerId && link?.programId even though link is guaranteed to
be defined here (result of prisma.link.update); change the condition to use
direct property access (link.partnerId && link.programId) to match the style
used in create-lead.ts and remove the unnecessary optional chaining; update the
conditional around sendPartnerPostback in create-sale.ts to reference
link.partnerId and link.programId without the "?" to align both Shopify
integration files.
In `@apps/web/lib/postback/api/send-partner-postback.ts`:
- Around line 46-72: The current early return when
prisma.programEnrollment.findUnique returns no result silently drops the
postback; in sendPartnerPostback replace the console.warn + return with a
visible error/alert: log an error via the app's error logger (e.g.,
processLogger.error) and send the event to error tracking (e.g.,
Sentry.captureException or your notifyError helper) including partnerId,
programId and context, or alternatively throw a retryable error so the postback
can be retried, ensuring programEnrollment lookup failures are observable and
not silently ignored.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
apps/web/app/(ee)/api/stripe/integration/webhook/checkout-session-completed.tsapps/web/app/(ee)/api/stripe/integration/webhook/invoice-paid.tsapps/web/app/(ee)/api/stripe/integration/webhook/utils/create-new-customer.tsapps/web/lib/api/conversions/track-lead.tsapps/web/lib/api/conversions/track-sale.tsapps/web/lib/integrations/shopify/create-lead.tsapps/web/lib/integrations/shopify/create-sale.tsapps/web/lib/partners/create-partner-commission.tsapps/web/lib/postback/api/postback-event-enrichers.tsapps/web/lib/postback/api/send-partner-postback.tsapps/web/lib/postback/sample-events/commission-created.jsonapps/web/lib/postback/sample-events/lead-created.jsonapps/web/lib/postback/sample-events/sale-created.jsonapps/web/lib/postback/schemas.ts
Summary by CodeRabbit
New Features
Bug Fixes