Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@devkiran
Copy link
Collaborator

@devkiran devkiran commented Nov 26, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Fraud detection now runs only when relevant webhook partner data is present, avoiding unnecessary processing.
  • Changes

    • Fraud events API now returns grouped events without customer details; related types adjusted.
    • Test flow updated to poll for fraud events instead of using fixed delays for more reliable verification.
  • Chores

    • Adjusted logging around fraud detection to improve error visibility.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Contributor

vercel bot commented Nov 26, 2025

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

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Nov 26, 2025 11:19am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 26, 2025

Walkthrough

Removed customer data from grouped fraud event schema and its query/mapping; gated fraud detection calls on webhookPartner truthiness; added a retry helper and replaced static waits in tests; adjusted identity-hash environment gating and added an error log in fraud recording.

Changes

Cohort / File(s) Summary
Schema & Query Changes
apps/web/lib/zod/schemas/fraud.ts, apps/web/lib/api/fraud/get-grouped-fraud-events.ts, apps/web/lib/types.ts
Renamed exported schema to groupedFraudEventSchema, removed the customer field from the schema, updated imports/types to use groupedFraudEventSchema, and removed customer join/fields from the grouped fraud events SQL query and in-memory mapping.
Fraud Detection Callsite Guards
apps/web/app/(ee)/api/stripe/integration/webhook/utils/create-new-customer.ts, apps/web/lib/api/conversions/track-lead.ts, apps/web/lib/api/conversions/track-sale.ts
detectAndRecordFraudEvent is now only invoked when webhookPartner is truthy; removed previous unconditional invocation in these flows.
Fraud Recording Logging
apps/web/lib/api/fraud/detect-record-fraud-event.ts
Added an error log path when context validation fails and removed a prior console.log of detected events.
Identity-hash Env Gate Change
apps/web/lib/middleware/utils/get-identity-hash.ts
Changed environment gating: test identity path enabled for NODE_ENV === "development" or VERCEL_ENV === "preview" (previously NODE_ENV was `"test"
Test Utilities & Tests
apps/web/tests/utils/helpers.ts, apps/web/tests/fraud/index.test.ts
Added a generic retry helper for polling async actions; replaced static 8s wait with polling logic in verifyFraudEvent, narrowed verifyFraudEvent customer parameter to only require externalId.
Formatting/Minor Change
apps/web/app/(ee)/api/stripe/integration/webhook/utils/create-new-customer.ts
Minor formatting change (blank line) and removal of a commission existence check so fraud detection runs when webhookPartner is truthy regardless of commission presence.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Event Source
    participant Guard as webhookPartner check
    participant Fraud as detectAndRecordFraudEvent
    participant DB as grouped fraud query

    rect rgb(240,240,240)
    note right of Caller: New flow (high level)
    Caller->>Guard: provides webhookPartner
    alt webhookPartner truthy
        Guard->>Fraud: invoke detectAndRecordFraudEvent(...)
        Fraud->>DB: record / query grouped events (customer fields removed)
        DB-->>Fraud: grouped event(s)
        Fraud-->>Caller: success
    else webhookPartner falsy
        Guard-->>Caller: skip fraud detection
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to review closely:
    • Schema migration: confirm all consumers of grouped fraud events accept the removed customer field.
    • SQL/query changes in get-grouped-fraud-events.ts to ensure no leftover references to customer columns.
    • Callsite gating: ensure legitimate cases still trigger fraud detection when required.
    • Test retry helper semantics and timeouts to avoid flaky tests.

Possibly related PRs

Suggested reviewers

  • steven-tey

Poem

🐰 I nibble schemas, trim a field away,
I hop where retries chase the day,
Partners now call when they’re true,
Logs whisper errors, tests retry too,
A little rabbit refactor — hip hooray! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Fraud improvements' is vague and generic, using non-descriptive language that doesn't convey specific information about the changes made. Consider a more specific title like 'Refactor fraud event schema to remove customer data' or 'Update fraud detection with conditional webhookPartner checks' to better reflect the actual changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fraud-improvements

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 426381c and 53e0517.

📒 Files selected for processing (2)
  • apps/web/lib/api/fraud/detect-record-fraud-event.ts (1 hunks)
  • apps/web/lib/middleware/utils/get-identity-hash.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web/lib/api/fraud/detect-record-fraud-event.ts
  • apps/web/lib/middleware/utils/get-identity-hash.ts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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 0185f25 and 084eb68.

📒 Files selected for processing (5)
  • apps/web/lib/api/fraud/get-grouped-fraud-events.ts (3 hunks)
  • apps/web/lib/types.ts (2 hunks)
  • apps/web/lib/zod/schemas/fraud.ts (1 hunks)
  • apps/web/tests/fraud/index.test.ts (5 hunks)
  • apps/web/tests/utils/helpers.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: devkiran
Repo: dubinc/dub PR: 3089
File: apps/web/lib/api/fraud/fraud-rules-registry.ts:17-25
Timestamp: 2025-11-24T09:10:12.494Z
Learning: In apps/web/lib/api/fraud/fraud-rules-registry.ts, the fraud rules `partnerCrossProgramBan` and `partnerDuplicatePayoutMethod` intentionally have stub implementations that return `{ triggered: false }` because they are partner-scoped rules handled separately during partner application/onboarding flows (e.g., in detect-record-fraud-application.ts), rather than being evaluated per conversion event like other rules in the registry. The stubs exist only to satisfy the `Record<FraudRuleType, ...>` type constraint.
📚 Learning: 2025-11-24T09:10:12.494Z
Learnt from: devkiran
Repo: dubinc/dub PR: 3089
File: apps/web/lib/api/fraud/fraud-rules-registry.ts:17-25
Timestamp: 2025-11-24T09:10:12.494Z
Learning: In apps/web/lib/api/fraud/fraud-rules-registry.ts, the fraud rules `partnerCrossProgramBan` and `partnerDuplicatePayoutMethod` intentionally have stub implementations that return `{ triggered: false }` because they are partner-scoped rules handled separately during partner application/onboarding flows (e.g., in detect-record-fraud-application.ts), rather than being evaluated per conversion event like other rules in the registry. The stubs exist only to satisfy the `Record<FraudRuleType, ...>` type constraint.

Applied to files:

  • apps/web/lib/types.ts
  • apps/web/tests/fraud/index.test.ts
  • apps/web/lib/zod/schemas/fraud.ts
🧬 Code graph analysis (3)
apps/web/lib/api/fraud/get-grouped-fraud-events.ts (1)
apps/web/lib/zod/schemas/fraud.ts (1)
  • groupedFraudEventSchema (12-32)
apps/web/lib/types.ts (1)
apps/web/lib/zod/schemas/fraud.ts (1)
  • groupedFraudEventSchema (12-32)
apps/web/tests/fraud/index.test.ts (3)
apps/web/lib/types.ts (2)
  • Customer (424-424)
  • fraudEventGroupProps (676-676)
apps/web/tests/utils/resource.ts (1)
  • E2E_FRAUD_PARTNER (220-227)
apps/web/tests/utils/helpers.ts (1)
  • retry (37-58)
🪛 GitHub Actions: Public API Tests
apps/web/tests/fraud/index.test.ts

[error] 252-252: Fraud event not ready.


[error] 252-252: Fraud event not ready.

⏰ 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: build
🔇 Additional comments (6)
apps/web/lib/api/fraud/get-grouped-fraud-events.ts (1)

2-2: LGTM! Schema rename is consistent.

The import and usage of groupedFraudEventSchema aligns with the schema changes across the codebase.

Also applies to: 131-131

apps/web/tests/utils/helpers.ts (1)

37-58: LGTM! Clean retry utility implementation.

The retry utility is well-implemented with sensible defaults and proper error handling. This provides a reusable pattern for polling operations in tests.

apps/web/lib/types.ts (1)

62-62: LGTM! Type definition updated consistently.

The import and type inference changes align with the schema rename in apps/web/lib/zod/schemas/fraud.ts.

Also applies to: 676-676

apps/web/lib/zod/schemas/fraud.ts (1)

12-32: LGTM! Schema refactored to remove customer data.

The schema rename and customer field removal align with the PR objectives for fraud improvements. The schema shape is consistent with the query results in get-grouped-fraud-events.ts.

apps/web/tests/fraud/index.test.ts (2)

190-227: LGTM! Simplified verification signature.

The updated verifyFraudEvent function now only requires externalId, which aligns with the removal of customer data from the grouped fraud event schema.


14-14: Concurrent test execution requires database-level transaction isolation.

The fraud tests share the same E2E_FRAUD_PARTNER across all concurrent tests. While customer isolation via randomCustomer() prevents direct conflicts, the fraud event creation logic in detectAndRecordFraudEvent() (apps/web/lib/api/fraud/detect-record-fraud-event.ts, lines 63–92) contains a Time-of-Check-Time-of-Use (TOCTOU) race condition: events are read (line 63) and checked for duplicates, but new events are created later (line 92) without atomic transactional protection. Concurrent test execution could cause:

  • Duplicate fraud events for the same partner/customer/type combination
  • Test flakiness if fraud event queries return unexpected duplicates
  • Unpredictable results when multiple tests trigger fraud rules simultaneously

Either wrap fraud event creation in a database transaction to ensure atomicity, or convert this suite to sequential execution (remove .concurrent).

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: 1

🧹 Nitpick comments (1)
apps/web/lib/middleware/utils/get-identity-hash.ts (1)

9-16: Gate identity-hash debug logging to non‑production

Logging "getIdentityHash", process.env.NODE_ENV on every request will be noisy in production and adds avoidable overhead on a hot path, with limited diagnostic value once issues are resolved.

Recommend either removing this or gating it to non‑production and downgrading to console.debug, e.g.:

-export async function getIdentityHash(req: Request) {
-  console.log("getIdentityHash", process.env.NODE_ENV)
+export async function getIdentityHash(req: Request) {
+  if (process.env.NODE_ENV !== "production") {
+    console.debug("getIdentityHash", process.env.NODE_ENV);
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40aae46 and 426381c.

📒 Files selected for processing (2)
  • apps/web/lib/api/fraud/detect-record-fraud-event.ts (1 hunks)
  • apps/web/lib/middleware/utils/get-identity-hash.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: devkiran
Repo: dubinc/dub PR: 3089
File: apps/web/lib/api/fraud/fraud-rules-registry.ts:17-25
Timestamp: 2025-11-24T09:10:12.494Z
Learning: In apps/web/lib/api/fraud/fraud-rules-registry.ts, the fraud rules `partnerCrossProgramBan` and `partnerDuplicatePayoutMethod` intentionally have stub implementations that return `{ triggered: false }` because they are partner-scoped rules handled separately during partner application/onboarding flows (e.g., in detect-record-fraud-application.ts), rather than being evaluated per conversion event like other rules in the registry. The stubs exist only to satisfy the `Record<FraudRuleType, ...>` type constraint.
📚 Learning: 2025-11-24T09:10:12.494Z
Learnt from: devkiran
Repo: dubinc/dub PR: 3089
File: apps/web/lib/api/fraud/fraud-rules-registry.ts:17-25
Timestamp: 2025-11-24T09:10:12.494Z
Learning: In apps/web/lib/api/fraud/fraud-rules-registry.ts, the fraud rules `partnerCrossProgramBan` and `partnerDuplicatePayoutMethod` intentionally have stub implementations that return `{ triggered: false }` because they are partner-scoped rules handled separately during partner application/onboarding flows (e.g., in detect-record-fraud-application.ts), rather than being evaluated per conversion event like other rules in the registry. The stubs exist only to satisfy the `Record<FraudRuleType, ...>` type constraint.

Applied to files:

  • apps/web/lib/api/fraud/detect-record-fraud-event.ts
⏰ 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: build

@devkiran devkiran marked this pull request as draft November 26, 2025 10:32
@devkiran devkiran marked this pull request as ready for review November 26, 2025 16:27
@steven-tey steven-tey merged commit a8abcda into main Nov 26, 2025
8 of 9 checks passed
@steven-tey steven-tey deleted the fraud-improvements branch November 26, 2025 17:03
This was referenced Nov 27, 2025
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.

3 participants