You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/adr/0015-how-cdp-stores-member-identities.md
+7-8Lines changed: 7 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,6 @@
3
3
**Date**: 2026-07-28
4
4
**Status**: accepted
5
5
**Deciders**: Yeganathan S
6
-
**Related**: CM-1349
7
6
8
7
## Context
9
8
@@ -20,18 +19,18 @@ Historically, `memberIdentities` uniqueness was defined on raw `value` (case-sen
20
19
21
20
Lookups used `lower(value)`, but inserts often did not. Data-sink `mergeData` matched with exact `value ===`, so a self-serve lowercase `willsonhg` plus a later GitHub ingest of `WillsonHG` produced two rows for the same identity — often both verified on the same member. Prod had tens of thousands of GitHub case-variant groups.
22
21
23
-
Ticket CM-1349 proposed soft-deleting / auto-verifying case variants at verification time. That treats a write-path bug as a product special case.
22
+
Soft-deleting or auto-verifying case variants only at verification time would treat a write-path bug as a product special case.
24
23
25
24
## Decision
26
25
27
26
**Mental model**
28
27
29
-
| Kind | Store | Compare / unique on |
30
-
| --- | --- | --- |
31
-
| username | preferred casing from the source/integration|`lower(value)`|
32
-
| email | always lowercase |`lower(value)` (same as stored) |
| username | preferred casing from the source |`lower(value)`|
31
+
| email | always lowercase|`lower(value)` (same as stored) |
33
32
34
-
Identity equality in CDP is `(platform, type, lower(value))`. The `value` column keeps what the source sent for usernames; we do not rewrite GitHub `login`casing on ingest.
33
+
Identity equality in CDP is `(platform, type, lower(value))`. Email vs username for storage casing is inferred from the value with `isValidEmail`, not from `type` (git often stores emails as `type=username`). Non-email usernames keep preferred casing from the source.
35
34
36
35
**Enforcement**
37
36
@@ -42,7 +41,7 @@ Identity equality in CDP is `(platform, type, lower(value))`. The `value` column
42
41
43
42
## Alternatives Considered
44
43
45
-
### Alternative 1: Soft-delete / auto-verify case variants at identity verification time (CM-1349 as written)
44
+
### Alternative 1: Soft-delete / auto-verify case variants at identity verification time
46
45
47
46
-**Pros**: Fixes the user-visible self-serve pain quickly; no schema change.
48
47
-**Cons**: Case variants keep being inserted by ingest/enrichment; verify path becomes a mop; duplicates still break uniqueness and analytics.
0 commit comments