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: .claude/skills/scaffold-snowflake-connector/SKILL.md
+28-13Lines changed: 28 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,7 +93,7 @@ Ask the user:
93
93
If the user provides a path: verify it by checking `{path}/services/apps/snowflake_connectors/src/integrations/index.ts` exists. If confirmed, set `CROWD_DEV_ROOT = {path}`. Proceed to Phase 1.
@@ -307,12 +307,20 @@ Example format for an ambiguity:
307
307
308
308
### 3a. Identity Mapping
309
309
310
-
**Rule:** Every member record must produce at least one identity with `type: MemberIdentityType.USERNAME`. The fallback chain is (try in order):
311
-
1. Platform-native username column from schema
312
-
2. LFID column value (used as username on `PlatformType.LFID`)
313
-
3. Email value used as the platform USERNAME (last resort)
310
+
**Rule:** Every member record must produce at least one identity with `type: MemberIdentityType.USERNAME`. The standard approach is to use the unified `buildMemberIdentities()` method on `TransformerBase` (added in the identity deduplication refactor). Only fall back to inline identity construction if the user explicitly requests it and can justify why the unified method cannot be used (e.g., fundamentally different identity shape not covered by the method's logic).
314
311
315
-
If Pre-Analysis resolved email, username, and LFID columns with HIGH confidence and the user confirmed them, skip to the summary step below.
312
+
The unified method covers the standard fallback chain automatically. Full behavior by case:
313
+
314
+
| `platformUsername` | `lfUsername` | Identities produced |
| set | set | EMAIL(platform) + USERNAME(platform, platformUsername) + USERNAME(LFID, lfUsername) |
320
+
321
+
**Critical:** Never pass `lfUsername` as `platformUsername`. When a source only has an LFID column (no platform-native username), pass `platformUsername: null` — the lfUsername-only path (row 3 above) already produces the correct USERNAME identity for the platform using the lfUsername value.
322
+
323
+
If Pre-Analysis resolved email, platformUsername, and LFID columns with HIGH confidence and the user confirmed them, skip to the summary step below.
316
324
317
325
For any unresolved identity field, use this pattern:
318
326
- **Multiple candidates found**: "I see columns `A` and `B` that could be the email — which one?" (present choices, not open-ended)
@@ -325,8 +333,10 @@ For each confirmed identity column also confirm:
325
333
326
334
**Critical:** If a JOIN table for users is NOT the same table used by an existing implementation, validate every column explicitly regardless of Pre-Analysis confidence. Column name heuristics alone are not sufficient for unknown tables.
327
335
328
-
After all identity fields are confirmed, summarize the full identity-building logic and ask:
329
-
> "Here is how identities will be built: [summary]. Does this look correct?"
336
+
After all identity fields are confirmed, summarize how `buildMemberIdentities()` will be called and ask:
- All string comparisons must be case-insensitive: use `.toLowerCase()` on both sides of comparison only; preserve the original value in the output
579
589
- No broad `else` statements — every branch must have an explicit condition
580
590
- All column names referenced in code must exactly match the schema registry — never assumed
581
-
- Identity fallback chain (always produces at least one USERNAME identity):
582
-
1. If platform-native username column present and non-null → push EMAIL + USERNAME identities for platform
583
-
2. Else if LFID present and non-null → push EMAIL for platform + LFID value as USERNAME for platform
584
-
3. Else → push EMAIL value as USERNAME for platform (email-as-username)
585
-
- After building platform identities, if LFID column is present and non-null → push separate LFID identity: `{ platform: PlatformType.LFID, value: lfid, type: MemberIdentityType.USERNAME, ... }`
591
+
-**Identity building — always use `this.buildMemberIdentities()` first (preferred):**
592
+
- Call `this.buildMemberIdentities({ email, sourceId, platformUsername, lfUsername })` from `TransformerBase`
593
+
- Always pass all 4 arguments explicitly, even when the value is `null` or `undefined` — never omit an argument
594
+
-`sourceId` = the user ID column from the source table (`undefined` if the table has no user ID column)
595
+
-`platformUsername` = the platform-native username column (`null` if absent — do NOT substitute `lfUsername` here)
596
+
-`lfUsername` = the LFID column value (`null` if absent)
597
+
-**Never pass `lfUsername` as `platformUsername`** — when a source only has an LFID column, pass `platformUsername: null`; the method's lfUsername-only path already produces the correct platform USERNAME from the lfUsername value
598
+
- The method handles the full fallback chain automatically (see the 4-case table in §3a)
599
+
- Do NOT import `IMemberData` or `MemberIdentityType` in the transformer — those are only needed if falling back to inline construction
600
+
-**Only use inline identity construction if the user explicitly requests it and justifies why `buildMemberIdentities()` cannot be used** (e.g., non-standard identity shape not covered by the method). Document the justification in a comment.
586
601
-`isIndividualNoAccount` must call `this.isIndividualNoAccount(displayName)` from `TransformerBase` — never reimplement
587
602
-**Do not set member attributes** (e.g., `MemberAttributeName.JOB_TITLE`, `AVATAR_URL`, `COUNTRY`) unless: (a) the user explicitly requested them, or (b) the same table and column are already used for that attribute in an existing implementation — in which case follow the existing pattern exactly
588
603
- Extends the platform base class if one was confirmed in Phase 3e; otherwise extends `TransformerBase` directly
0 commit comments