Conversation
- Add IdentityVerificationStatus enum and fields to Partner model - Create Veriff better-fetch client, schemas, and session helpers - Add webhook handler for Veriff decision callbacks with HMAC verification - Create server action for starting identity verification - Add IdentityVerificationCard component to partner profile page - Install @veriff/incontext-sdk for in-modal verification flow
📝 WalkthroughWalkthroughAdds partner identity verification via Veriff: DB enum/fields, Prisma index, Zod schemas, server action to create Veriff sessions, webhook route + handlers, UI component and badge, email templates, icon assets, package dependency, and a renamed rate-limit flag ( Changes
Sequence Diagram(s)sequenceDiagram
participant User as Partner (Browser)
participant UI as IdentityVerificationSection
participant Action as startIdentityVerificationAction
participant Veriff as Veriff API
participant DB as Database
participant SDK as Veriff Iframe
User->>UI: Click "Start verification"
UI->>Action: startIdentityVerificationAction(partner)
Action->>DB: Query partner & existing session
alt Session valid
Action-->>UI: Return existing sessionUrl
else Create session
Action->>Veriff: POST /v1/sessions (X-AUTH-CLIENT)
Veriff-->>Action: sessionUrl, sessionId
Action->>DB: Persist sessionId, sessionUrl, expiresAt
Action-->>UI: Return sessionUrl
end
UI->>SDK: import `@veriff/incontext-sdk`, createFrame(sessionUrl)
SDK-->>UI: Frame initialized
User->>SDK: Submit documents
SDK->>Veriff: Submit verification
Veriff-->>SDK: MESSAGES.FINISHED
UI->>UI: Show toast, call mutate()
sequenceDiagram
participant Veriff as Veriff Service
participant Webhook as /api/veriff/webhook
participant Handler as handleDecisionEvent
participant DB as Database
participant Email as Email Service
Veriff->>Webhook: POST decision event (HMAC signed)
Webhook->>Webhook: Verify HMAC-SHA256 signature & x-auth-client
alt Signature/Client invalid
Webhook-->>Veriff: 400/401
else Signature valid
Webhook->>Handler: route decision event
Handler->>DB: Find partner by veriffSessionId
alt Partner not found or already verified
Handler-->>Webhook: exit (no update)
else
Handler->>Handler: compute identity hash
Handler->>DB: check duplicate identity / country mismatch
alt Checks pass (approve)
Handler->>DB: update partner (identityVerifiedAt, hash, clear session)
Handler->>Email: send verified email (Idempotency-Key)
else Checks fail (decline)
Handler->>DB: update partner (decline reason, clear session, increment attempts)
Handler->>Email: send failed email (Idempotency-Key)
end
Handler-->>Webhook: 200
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…or handling, and refine verification logic
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/web/lib/zod/schemas/partners.ts (1)
580-581: Nitpick: Redundant field picks.
EnrolledPartnerSchemaExtendedextendsEnrolledPartnerSchema, which already picksidentityVerificationStatusandidentityVerifiedAt(lines 480-481). Picking them again here fromPartnerSchemais redundant since they're the same fields from the same source. This is harmless but could be cleaned up for clarity.♻️ Suggested fix
.extend( PartnerSchema.pick({ monthlyTraffic: true, industryInterests: true, preferredEarningStructures: true, salesChannels: true, - identityVerificationStatus: true, - identityVerifiedAt: true, }).shape, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/lib/zod/schemas/partners.ts` around lines 580 - 581, EnrolledPartnerSchemaExtended currently re-picks identityVerificationStatus and identityVerifiedAt from PartnerSchema even though they are already included via EnrolledPartnerSchema; remove the redundant picks from EnrolledPartnerSchemaExtended so those two fields are only supplied by EnrolledPartnerSchema (locate the EnrolledPartnerSchemaExtended definition and delete the identityVerificationStatus and identityVerifiedAt entries that duplicate EnrolledPartnerSchema).apps/web/.env.example (1)
193-193: Optional: Alphabetical key ordering.The linter flags that
E2E_PARTNER_PASSWORDshould come beforePLAYWRIGHT_BASE_URLalphabetically. However, the current logical grouping (base URL first, then credentials) makes semantic sense for the E2E section, so this can be safely ignored if preferred.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/.env.example` at line 193, The linter wants ENV keys alphabetized; to satisfy it, move the E2E_PARTNER_PASSWORD entry so it appears before PLAYWRIGHT_BASE_URL (i.e., place the line "E2E_PARTNER_PASSWORD=" above the "PLAYWRIGHT_BASE_URL" key) in apps/web/.env.example, or if you prefer to keep the semantic grouping, add a one-line linter-ignore directive/comment recognized by your linter next to the E2E keys and ensure the symbol E2E_PARTNER_PASSWORD remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@apps/web/.env.example`:
- Line 193: The linter wants ENV keys alphabetized; to satisfy it, move the
E2E_PARTNER_PASSWORD entry so it appears before PLAYWRIGHT_BASE_URL (i.e., place
the line "E2E_PARTNER_PASSWORD=" above the "PLAYWRIGHT_BASE_URL" key) in
apps/web/.env.example, or if you prefer to keep the semantic grouping, add a
one-line linter-ignore directive/comment recognized by your linter next to the
E2E keys and ensure the symbol E2E_PARTNER_PASSWORD remains unchanged.
In `@apps/web/lib/zod/schemas/partners.ts`:
- Around line 580-581: EnrolledPartnerSchemaExtended currently re-picks
identityVerificationStatus and identityVerifiedAt from PartnerSchema even though
they are already included via EnrolledPartnerSchema; remove the redundant picks
from EnrolledPartnerSchemaExtended so those two fields are only supplied by
EnrolledPartnerSchema (locate the EnrolledPartnerSchemaExtended definition and
delete the identityVerificationStatus and identityVerifiedAt entries that
duplicate EnrolledPartnerSchema).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f0da3d4a-1845-4465-9758-532b17f6ae51
📒 Files selected for processing (2)
apps/web/.env.exampleapps/web/lib/zod/schemas/partners.ts
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
apps/web/app/api/veriff/webhook/handle-decision-event.ts (1)
64-67:⚠️ Potential issue | 🔴 CriticalMake duplicate-identity approval authoritative at write time.
checkDuplicateIdentity()is still a read-before-write check. BecauseveriffIdentityHashis not unique inpackages/prisma/schema/partner.prisma, two concurrent"approved"webhooks can both pass the lookup and both persist the same identity. Keep the pre-check for the friendly decline path if you want, but the approval write needs a DB-backed uniqueness guarantee and a loser path when that constraint is hit.Also applies to: 123-129, 178-190
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/api/veriff/webhook/handle-decision-event.ts` around lines 64 - 67, The current checkDuplicateIdentity() is only a read-before-write and racey; make the approval write authoritative by enforcing a DB uniqueness constraint and handling constraint violations at write time: add a unique constraint for veriffIdentityHash (or the appropriate composite key) in the Prisma schema and run a migration, then wrap the approval create/upsert call (the code path that persists an "approved" Veriff identity) in a try/catch and specifically handle PrismaClientKnownRequestError P2002 (unique constraint) to treat the conflict as a duplicate (log and transition to the loser/decline path). You may keep the existing checkDuplicateIdentity() for a friendly early-decline branch, but the final decision must be based on the DB-write outcome and its error handling.
🧹 Nitpick comments (1)
packages/ui/src/icons/verified-badge.tsx (1)
3-86: Consider using unique IDs to prevent potential collisions.The hardcoded IDs
verifiedBadgeGradientandverifiedBadgeFilterwill be duplicated if multiple instances of this component render on the same page, which is invalid HTML and may cause gradient/filter references to fail in some browsers.Since you're on React 19, you can use the
useIdhook to generate unique IDs per instance.♻️ Proposed fix using useId
-import { SVGProps } from "react"; +import { SVGProps, useId } from "react"; export function VerifiedBadge(props: SVGProps<SVGSVGElement>) { + const id = useId(); + const gradientId = `verifiedBadgeGradient-${id}`; + const filterId = `verifiedBadgeFilter-${id}`; + return ( <svg width={32} height={32} viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" {...props} > - <g filter="url(`#verifiedBadgeFilter`)"> + <g filter={`url(#${filterId})`}> <path d="M26.6745 7.91113L18.7995 5.37618C18.276 5.20719 17.7225 5.20869 17.2005 5.37618L9.324 7.91113C8.232 8.26271 7.5 9.27367 7.5 10.4265V20.2645C7.5 25.5577 14.919 28.3809 17.19 29.1202C17.4555 29.2062 17.727 29.25 18 29.25C18.273 29.25 18.543 29.2078 18.807 29.1217C21.081 28.3824 28.5 25.5592 28.5 20.266V10.4265C28.5 9.27367 27.7665 8.26271 26.6745 7.91113Z" - fill="url(`#verifiedBadgeGradient`)" + fill={`url(#${gradientId})`} /> </g> <defs> <linearGradient - id="verifiedBadgeGradient" + id={gradientId} ... > ... </linearGradient> <filter - id="verifiedBadgeFilter" + id={filterId} ... > ... </filter> </defs> </svg> ); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/ui/src/icons/verified-badge.tsx` around lines 3 - 86, The SVG uses hardcoded IDs "verifiedBadgeGradient" and "verifiedBadgeFilter" which will collide when multiple VerifiedBadge components mount; update VerifiedBadge to call React's useId() (or accept an id prop) to generate a unique base ID, then replace the literal ids and their references (id="verifiedBadgeGradient" -> id={`${uid}-verifiedBadgeGradient`} and filter="url(`#verifiedBadgeFilter`)" -> filter={`url(#${uid}-verifiedBadgeFilter)`}, and similarly for all href/uri references) so each instance has unique gradient/filter IDs; keep the same element names and props (VerifiedBadge, the <linearGradient> and <filter> elements and their references) to locate the replacements.
🤖 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/app/api/veriff/webhook/handle-decision-event.ts`:
- Around line 200-208: The checkCountryMismatch function currently returns true
on match; change its logic so it returns true only when countries do not match:
compute veriffCountry as now from verification.document?.country ||
verification.person?.nationality, and if either veriffCountry or partner.country
is missing treat that as a mismatch (return true); otherwise return
partner.country.toUpperCase() !== veriffCountry. Update the return expression in
checkCountryMismatch to use !== instead of === and flip the missing-data return
value.
- Around line 131-160: The current branch sends the generic "declined" email for
every non-approved status; update the logic around effectiveStatus in the
handler so that if effectiveStatus === "review" you skip sending any email, and
for other non-approved statuses (e.g., "expired", "abandoned",
"resubmission_requested") call sendEmail with status-specific
templates/messaging instead of PartnerIdentityVerificationFailed for all cases.
Use the same identifiers (attemptId, partner, sendEmail,
PartnerIdentityVerified, PartnerIdentityVerificationFailed, effectiveStatus,
effectiveReason) to locate the code, ensure the Idempotency-Key still includes
attemptId with a status-specific suffix, and make
identityVerificationDeclineReason safe by defaulting to a sensible fallback
string only for statuses that actually have a reason to display.
- Line 121: Remove the raw dump of the verification payload
(console.log(toUpdate)); instead log only non-sensitive metadata such as
partner.id and effectiveStatus. Locate the console.log(toUpdate) call (in the
webhook handler where the toUpdate object is built) and replace it with a single
log entry that references only safe fields (e.g., partner.id and
toUpdate.effectiveStatus) using the existing logger; do not include
veriffIdentityHash, decline reasons, or other identity-derived data in logs.
---
Duplicate comments:
In `@apps/web/app/api/veriff/webhook/handle-decision-event.ts`:
- Around line 64-67: The current checkDuplicateIdentity() is only a
read-before-write and racey; make the approval write authoritative by enforcing
a DB uniqueness constraint and handling constraint violations at write time: add
a unique constraint for veriffIdentityHash (or the appropriate composite key) in
the Prisma schema and run a migration, then wrap the approval create/upsert call
(the code path that persists an "approved" Veriff identity) in a try/catch and
specifically handle PrismaClientKnownRequestError P2002 (unique constraint) to
treat the conflict as a duplicate (log and transition to the loser/decline
path). You may keep the existing checkDuplicateIdentity() for a friendly
early-decline branch, but the final decision must be based on the DB-write
outcome and its error handling.
---
Nitpick comments:
In `@packages/ui/src/icons/verified-badge.tsx`:
- Around line 3-86: The SVG uses hardcoded IDs "verifiedBadgeGradient" and
"verifiedBadgeFilter" which will collide when multiple VerifiedBadge components
mount; update VerifiedBadge to call React's useId() (or accept an id prop) to
generate a unique base ID, then replace the literal ids and their references
(id="verifiedBadgeGradient" -> id={`${uid}-verifiedBadgeGradient`} and
filter="url(`#verifiedBadgeFilter`)" ->
filter={`url(#${uid}-verifiedBadgeFilter)`}, and similarly for all href/uri
references) so each instance has unique gradient/filter IDs; keep the same
element names and props (VerifiedBadge, the <linearGradient> and <filter>
elements and their references) to locate the replacements.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5b68f317-842c-4df4-8d9e-01e286d8d08b
📒 Files selected for processing (11)
apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/identity-verification-section.tsxapps/web/app/api/veriff/webhook/handle-decision-event.tsapps/web/app/api/veriff/webhook/handle-session-event.tsapps/web/app/api/veriff/webhook/route.tsapps/web/lib/actions/partners/start-identity-verification.tsapps/web/lib/veriff/schema.tsapps/web/ui/partners/partner-info-cards.tsxpackages/email/src/templates/partner-identity-verification-failed.tsxpackages/prisma/schema/partner.prismapackages/ui/src/icons/index.tsxpackages/ui/src/icons/verified-badge.tsx
✅ Files skipped from review due to trivial changes (3)
- packages/ui/src/icons/index.tsx
- apps/web/ui/partners/partner-info-cards.tsx
- apps/web/lib/veriff/schema.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- apps/web/app/api/veriff/webhook/route.ts
- apps/web/app/api/veriff/webhook/handle-session-event.ts
- apps/web/lib/actions/partners/start-identity-verification.ts
- apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/identity-verification-section.tsx
- packages/prisma/schema/partner.prisma
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
apps/web/app/api/veriff/webhook/handle-decision-event.ts (2)
129-158:⚠️ Potential issue | 🟠 MajorUse status-specific messaging for non-approved outcomes.
The
elsebranch at Lines 144-158 also runs forreview,expired,abandoned, andresubmission_requested. That sends a "declined" email forreview, andeffectiveReason || ""can feed empty copy intoPartnerIdentityVerificationFailed, which expects an actual decline reason. Skip email forreviewand branch the remaining statuses to templates/subjects that match the stored status.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/api/veriff/webhook/handle-decision-event.ts` around lines 129 - 158, The current branch sends a "declined" email for any non-approved status; update the logic around partner.email, effectiveStatus, attemptId and sendEmail so that: 1) if effectiveStatus === "approved" send PartnerIdentityVerified as before; 2) if effectiveStatus === "review" do not send an email; 3) for explicit failure statuses (e.g., "declined", "expired", "abandoned", "resubmission_requested") send status-specific emails using distinct subjects and template components (e.g., PartnerIdentityVerificationFailed for true declines, a separate ResubmissionRequested template for "resubmission_requested", etc.); and 4) ensure PartnerIdentityVerificationFailed always receives a non-empty decline reason (use effectiveReason or a default like "unspecified" rather than an empty string). Locate and update the sendEmail calls and the use of PartnerIdentityVerificationFailed/PartnerIdentityVerified to implement this branching.
64-67:⚠️ Potential issue | 🔴 CriticalMake duplicate-identity approval atomic.
Lines 64-67 still do a read-before-write duplicate check, but
packages/prisma/schema/partner.prisma:47-56still leavesveriffIdentityHashnon-unique. Two concurrent"approved"webhooks with the same hash can both pass the pre-check and both succeed at Lines 121-127. Please make the write authoritative with a DB uniqueness guarantee and handle the loser path when that constraint trips.Also applies to: 121-127, 176-188
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/api/veriff/webhook/handle-decision-event.ts` around lines 64 - 67, The current read-before-write duplicate check (checkDuplicateIdentity) is racy because veriffIdentityHash is not unique; add a DB-level uniqueness constraint for veriffIdentityHash in the Prisma Partner model so the database is authoritative, then change the write paths in the webhook handler (the approval write at the sections around lines handling the approved webhook — the code that writes veriffIdentityHash at the 121-127 and 176-188 hotspots) to perform the write and handle a uniqueness violation instead of only relying on the pre-check: attempt the update/create inside a try/catch, catch PrismaClientKnownRequestError with code 'P2002' (unique constraint violation) and treat that as the loser path (mark as duplicate/ignore/return early and log), and remove the unsafe read-before-write reliance so the DB constraint enforces atomicity. Ensure checkDuplicateIdentity can remain for early-return optimization but the authoritative decision comes from catching the DB unique-constraint error.
🤖 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/app/api/veriff/webhook/handle-decision-event.ts`:
- Around line 37-48: The partner lookup using prisma.partner.findUnique by
veriffSessionId makes retries fail because veriffSessionId is cleared before
sendEmail() runs; change the flow so that a retryable key remains until side
effects succeed by either (a) resolving partner by an immutable identifier
(e.g., partner.id) stored earlier and use that for subsequent lookups instead of
veriffSessionId, or (b) move email delivery into an outbox/background job before
clearing veriffSessionId and only clear the veriffSessionId after the outbox job
is persisted; apply this fix to all places where prisma.partner.findUnique is
called with veriffSessionId and where sendEmail() is invoked so retries will
find the partner and not drop notifications.
- Around line 61-84: When handling an approved Veriff decision in the
effectiveStatus === "approved" branch, do not treat a missing or non-computable
identity hash as a pass; if computeIdentityHash(verification) returns
null/undefined, abort the automatic approval flow and mark the record as
declined or flagged for manual review instead of setting
toUpdate.veriffIdentityHash = null and proceeding. Update the logic around
computeIdentityHash, checkDuplicateIdentity, and checkCountryMismatch so you
only call checkDuplicateIdentity when a non-null identityHash exists, and ensure
the branches that currently set veriffIdentityHash/veriffSession* (the same
pattern repeated elsewhere around computeIdentityHash) implement the same "fail
closed" behavior by rejecting/flagging when the hash cannot be computed.
---
Duplicate comments:
In `@apps/web/app/api/veriff/webhook/handle-decision-event.ts`:
- Around line 129-158: The current branch sends a "declined" email for any
non-approved status; update the logic around partner.email, effectiveStatus,
attemptId and sendEmail so that: 1) if effectiveStatus === "approved" send
PartnerIdentityVerified as before; 2) if effectiveStatus === "review" do not
send an email; 3) for explicit failure statuses (e.g., "declined", "expired",
"abandoned", "resubmission_requested") send status-specific emails using
distinct subjects and template components (e.g.,
PartnerIdentityVerificationFailed for true declines, a separate
ResubmissionRequested template for "resubmission_requested", etc.); and 4)
ensure PartnerIdentityVerificationFailed always receives a non-empty decline
reason (use effectiveReason or a default like "unspecified" rather than an empty
string). Locate and update the sendEmail calls and the use of
PartnerIdentityVerificationFailed/PartnerIdentityVerified to implement this
branching.
- Around line 64-67: The current read-before-write duplicate check
(checkDuplicateIdentity) is racy because veriffIdentityHash is not unique; add a
DB-level uniqueness constraint for veriffIdentityHash in the Prisma Partner
model so the database is authoritative, then change the write paths in the
webhook handler (the approval write at the sections around lines handling the
approved webhook — the code that writes veriffIdentityHash at the 121-127 and
176-188 hotspots) to perform the write and handle a uniqueness violation instead
of only relying on the pre-check: attempt the update/create inside a try/catch,
catch PrismaClientKnownRequestError with code 'P2002' (unique constraint
violation) and treat that as the loser path (mark as duplicate/ignore/return
early and log), and remove the unsafe read-before-write reliance so the DB
constraint enforces atomicity. Ensure checkDuplicateIdentity can remain for
early-return optimization but the authoritative decision comes from catching the
DB unique-constraint error.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: f964ea3c-b3d1-49d0-ba2c-95083b47b888
📒 Files selected for processing (2)
apps/web/app/api/veriff/webhook/handle-decision-event.tsapps/web/app/api/veriff/webhook/route.ts
✅ Files skipped from review due to trivial changes (1)
- apps/web/app/api/veriff/webhook/route.ts
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
apps/web/lib/zod/schemas/partners.ts (1)
566-583: Redundant.pick()of identity verification fields.
EnrolledPartnerSchemaExtendedalready extendsEnrolledPartnerSchema(line 566), which picksidentityVerificationStatusandidentityVerifiedAtat lines 479-480. The second.pick()at lines 579-580 is redundant.Proposed fix
.extend( PartnerSchema.pick({ monthlyTraffic: true, industryInterests: true, preferredEarningStructures: true, salesChannels: true, - identityVerificationStatus: true, - identityVerifiedAt: true, }).shape, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/lib/zod/schemas/partners.ts` around lines 566 - 583, EnrolledPartnerSchemaExtended redundantly re-picks identityVerificationStatus and identityVerifiedAt via PartnerSchema.pick despite those being included by EnrolledPartnerSchema; update EnrolledPartnerSchemaExtended to remove the redundant identity fields from the PartnerSchema.pick call (or remove those two keys from the .pick invocation) so PartnerSchema.pick only selects monthlyTraffic, industryInterests, preferredEarningStructures, and salesChannels; reference EnrolledPartnerSchemaExtended, EnrolledPartnerSchema, PartnerSchema.pick, identityVerificationStatus, and identityVerifiedAt when making the change.
🤖 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/app/`(ee)/partners.dub.co/(dashboard)/profile/identity-verification-section.tsx:
- Around line 97-104: Update the user-facing strings for the switch cases in
identity-verification-section.tsx so they end with a period for consistency:
modify the "expired" and "abandoned" branches that set failedReason (the
variable in the switch) to include a trailing "." at the end of each sentence.
In `@apps/web/app/api/veriff/webhook/handle-decision-event.ts`:
- Around line 113-117: The current logic only increments
toUpdate.identityVerificationAttemptCount when effectiveStatus is "approved" or
"declined", but terminal states "expired" and "abandoned" should also count as
consumed attempts; update the conditional in handle-decision-event.ts (the
branch that checks effectiveStatus) to include "expired" and "abandoned" so that
toUpdate.identityVerificationAttemptCount = { increment: 1 } runs for those
statuses as well, ensuring consistency with the
MAX_PARTNER_IDENTITY_VERIFICATION_ATTEMPTS enforcement in
start-identity-verification.ts.
In `@apps/web/app/api/veriff/webhook/route.ts`:
- Around line 58-64: Wrap the JSON.parse(rawBody) call in a try/catch to return
a controlled 400 response when parsing fails, then validate the parsed object
against veriffDecisionEventSchema and veriffSessionEventSchema before calling
the handlers: if ("verification" in body) call handleDecisionEvent only after
the body passes veriffDecisionEventSchema validation (otherwise return 400),
else call handleSessionEvent only after passing veriffSessionEventSchema
(otherwise return 400); ensure error messages are generic and do not leak
internal details.
---
Nitpick comments:
In `@apps/web/lib/zod/schemas/partners.ts`:
- Around line 566-583: EnrolledPartnerSchemaExtended redundantly re-picks
identityVerificationStatus and identityVerifiedAt via PartnerSchema.pick despite
those being included by EnrolledPartnerSchema; update
EnrolledPartnerSchemaExtended to remove the redundant identity fields from the
PartnerSchema.pick call (or remove those two keys from the .pick invocation) so
PartnerSchema.pick only selects monthlyTraffic, industryInterests,
preferredEarningStructures, and salesChannels; reference
EnrolledPartnerSchemaExtended, EnrolledPartnerSchema, PartnerSchema.pick,
identityVerificationStatus, and identityVerifiedAt when making the change.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2ddcc15f-ab6d-413a-a3a5-43abb24d7083
📒 Files selected for processing (6)
apps/web/app/(ee)/partners.dub.co/(dashboard)/profile/identity-verification-section.tsxapps/web/app/api/veriff/webhook/handle-decision-event.tsapps/web/app/api/veriff/webhook/route.tsapps/web/lib/actions/partners/start-identity-verification.tsapps/web/lib/zod/schemas/partners.tspackages/prisma/schema/partner.prisma
✅ Files skipped from review due to trivial changes (1)
- apps/web/lib/actions/partners/start-identity-verification.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/prisma/schema/partner.prisma
Summary by CodeRabbit
New Features
Chores