Skip to content

Fix KYC user info upsert on reapproval - #70

Merged
aledefra merged 1 commit into
developfrom
codex/kyc-userinfo-upsert
Jun 25, 2026
Merged

Fix KYC user info upsert on reapproval#70
aledefra merged 1 commit into
developfrom
codex/kyc-userinfo-upsert

Conversation

@aledefra

Copy link
Copy Markdown
Collaborator

Summary

Fixes repeated KYC approval handling when a wallet already has a user_infos row.

Root cause: Sumsub GREEN approval processing always called CreateUserInfo, but UserInfo.BlockchainAddress is the primary key. When a user is approved, reset/moved back to pending, then approved again, the second approval can fail on duplicate blockchain_address before KYC state is updated.

Changes:

  • Add storage.CreateOrUpdateUserInfo using Postgres/GORM ON CONFLICT (blockchain_address) DO UPDATE.
  • Use the idempotent user info write for both ApplicantReviewed GREEN and ApplicantOnHold GREEN approval paths.
  • Move KYC confirmation email sending after successful persistence and make email failure warning-only, so mail delivery does not block a valid approved state.
  • Use explicit upsert columns instead of UpdateAll.

Notion task: https://app.notion.com/p/Issue-on-KYC-status-change-357d59ab66578056a359f900ab65c8fd?source=copy_link

Verification

  • gofmt -w service/sumsubService.go storage/userInfoStorer.go
  • git diff --check -- service/sumsubService.go storage/userInfoStorer.go
  • go test ./service -run 'Test_TrimWhitespacesAndToLower|Test_IncreaseCountMapOverLimit|TestSemaphore|TestNotificationEmailsForAccount_DeduplicatesConfirmedRecipients'
  • go test ./proxy/handlers -run TestNonExistent
  • go test ./service -run '^$' -count=0
  • go test -c ./storage -o <tmp>/storage.test

Blocked locally:

  • go test ./storage -run TestNonExistent requires local DB config; current config fails with lookup port=0: no such host.

Critic Review

Ran three read-only critic passes:

  • Round 1 found partial state risk on email failure and overly broad UpdateAll; fixed by persisting approval state before warning-only email and using explicit upsert columns.
  • Round 2 found the same issue still existed for ApplicantOnHold GREEN; fixed by sharing the idempotent approved-user-info flow across both GREEN approval paths.
  • Final pass reported no blocking findings. Residual gap: no DB-backed regression test currently covers duplicate GREEN approval/upsert behavior because local storage tests require external Postgres setup.

@aledefra
aledefra requested a review from Copilot June 25, 2026 14:36
@aledefra
aledefra marked this pull request as ready for review June 25, 2026 14:36
@aledefra aledefra changed the title [codex] Fix KYC user info upsert on reapproval Fix KYC user info upsert on reapproval Jun 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR makes KYC “GREEN” approval handling idempotent when a wallet already has an existing user_infos row (where blockchain_address is the PK), preventing duplicate-key failures during re-approval flows and ensuring email delivery does not block persisting an approved state.

Changes:

  • Add storage.CreateOrUpdateUserInfo using a Postgres/GORM ON CONFLICT (blockchain_address) DO UPDATE upsert.
  • Use the new idempotent user-info persistence path for both ApplicantReviewed GREEN and ApplicantOnHold GREEN flows.
  • Send the KYC confirmation email after successful persistence, and make email failures warning-only.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
storage/userInfoStorer.go Adds a CreateOrUpdateUserInfo upsert helper for user_infos keyed by blockchain_address.
service/sumsubService.go Switches GREEN approval paths to the idempotent user-info write and moves confirmed-email sending after persistence (warning-only on failure).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread storage/userInfoStorer.go
Comment on lines +68 to +75
if txUpdate.Error != nil {
txUpdate.Rollback()
return txUpdate.Error
}
if txUpdate.RowsAffected == 0 {
txUpdate.Rollback()
return gorm.ErrRecordNotFound
}
@aledefra
aledefra merged commit 5b619f2 into develop Jun 25, 2026
1 check passed
@aledefra
aledefra deleted the codex/kyc-userinfo-upsert branch June 25, 2026 14:43
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