Skip to content

chore: dedupe public API conflict alerts (CM-1349) - #4414

Merged
skwowet merged 3 commits into
mainfrom
CM-1349-dedupe-public-api-conflict-alerts
Jul 30, 2026
Merged

chore: dedupe public API conflict alerts (CM-1349)#4414
skwowet merged 3 commits into
mainfrom
CM-1349-dedupe-public-api-conflict-alerts

Conversation

@skwowet

@skwowet skwowet commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Self-serve identity and member-resolve conflicts were spamming #cdp-lfx-self-serve-alerts on every retry. We now send those alerts once per hour (Redis dedupe), with a consistent format.

The shared error handler no longer Slack-alerts on every 409. Only identity and resolve conflicts opt in. Things like work-experience date conflicts stay quiet.

Changes

  • Add shared notifyOnce helper (Redis, 1h window, fail-open)
  • Deduped Slack alerts for identity create/verify conflicts (and single-identity member create)
  • Deduped Slack alerts for ambiguous resolveMember matches
  • Remove blanket ConflictError Slack from errorHandler

Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
@skwowet skwowet self-assigned this Jul 30, 2026
Copilot AI review requested due to automatic review settings July 30, 2026 12:48

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

Adds opt-in, Redis-deduplicated Slack alerts for actionable public API conflicts.

Changes:

  • Adds one-hour, fail-open alert deduplication.
  • Alerts on member identity and resolution conflicts.
  • Removes blanket conflict alerts from the shared error handler.

Reviewed changes

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

Show a summary per file
File Description
backend/.eslintrc.js Enables void usage; currently has an unclosed override object.
backend/src/api/public/alerts/notifyOnce.ts Adds Redis-backed alert deduplication.
backend/src/api/public/alerts/identityConflict.ts Maps and alerts identity conflicts.
backend/src/api/public/alerts/memberResolveConflict.ts Alerts ambiguous member resolution.
backend/src/api/public/middlewares/errorHandler.ts Removes blanket 409 alerting.
backend/src/api/public/v1/members/createMember.ts Alerts single-identity creation conflicts.
backend/src/api/public/v1/members/resolveMember.ts Uses targeted resolution-conflict alerts.
backend/src/api/public/v1/members/identities/createMemberIdentity.ts Uses targeted identity-conflict alerts.
backend/src/api/public/v1/members/identities/verifyMemberIdentity.ts Alerts verification conflicts.

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

Comment thread backend/.eslintrc.js
Copilot AI review requested due to automatic review settings July 30, 2026 12:52

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

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

backend/src/api/public/v1/members/identities/createMemberIdentity.ts:108

  • When data.verified is true, the transaction also verifies every same-value identity in the loop above. If one of those identities conflicts on a different platform, this reports and deduplicates the alert using data.platform, so the Slack alert points to the wrong identity. Track the identity associated with the failing insert/update and pass that subject here.
          rethrowIdentityConflict(req, error, {
            memberId,
            platform: data.platform,
            value: data.value,
            type: data.type,

backend/src/api/public/alerts/identityConflict.ts:20

  • The dedupe key uses the caller's raw casing, but the active uniqueness constraint is on lower(value) (V1785255019__member_identities_case_insensitive_unique_indexes.sql:9-12). Requests for Foo and foo therefore hit the same conflict but generate different Redis keys and duplicate Slack alerts within the hour. Canonicalize the value for the key.
    identity.value,

Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 30, 2026 13:02

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

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

backend/.eslintrc.js:50

  • This disables no-void for every backend TypeScript file to support two local fire-and-forget calls, weakening lint coverage outside this change. Keep the project-wide rule and scope the suppression or rejection handling to those call sites instead; the protected-files hook also identifies ESLint configuration as project-wide infrastructure.
        'no-void': 'off',

backend/src/api/public/alerts/identityConflict.ts:20

  • The dedupe key keeps the request's original casing, but the identity uniqueness constraint compares lower(value) (backend/src/database/migrations/V1785255019__member_identities_case_insensitive_unique_indexes.sql:9-12). Equivalent conflicts such as Foo@example.com and foo@example.com therefore reserve different Redis keys and can emit duplicate alerts. Normalize the value according to the constraint when constructing the key.
    identity.value,

@skwowet
skwowet merged commit 95faa6e into main Jul 30, 2026
17 checks passed
@skwowet
skwowet deleted the CM-1349-dedupe-public-api-conflict-alerts branch July 30, 2026 13:40
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