fix: catch name variants when auto-blocking LF project orgs (CM-1199) - #4500
fix: catch name variants when auto-blocking LF project orgs (CM-1199)#4500skwowet wants to merge 3 commits into
Conversation
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Expands LF project organization matching while preserving exact-name deduplication.
Changes:
- Adds reusable organization-name variant generation.
- Adds multi-name DAL lookups for organizations and LF segments.
- Applies variant matching during project and organization creation.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
services/libs/common/src/organization.ts |
Generates normalized name variants. |
services/libs/common/src/index.ts |
Exports the new utility. |
services/libs/data-access-layer/src/segments/index.ts |
Finds LF segments by name variants. |
services/libs/data-access-layer/src/organizations/base.ts |
Adds multi-name lookup and affiliation blocking. |
backend/src/services/segmentService.ts |
Blocks matching organizations during project creation. |
backend/src/services/organizationService.ts |
Blocks new organizations matching LF segments. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if (!existing) { | ||
| const organizations = await logExecutionTimeV2( | ||
| async () => findOrganizationsByName(qe, data.displayName, { limit: 1 }), | ||
| async () => findManyOrganizationsByNames(qe, [data.displayName]), |
| for (const value of [...variants]) { | ||
| for (const suffix of ['project', 'foundation', 'initiative']) { | ||
| const token = ` ${suffix}` | ||
| if (value.endsWith(token)) { | ||
| const base = value.slice(0, -token.length).trim() | ||
| if (base.length >= 6) { | ||
| add(base) | ||
| } | ||
| } else if (value.length >= 4 && !value.includes('(')) { | ||
| add(`${value}${token}`) | ||
| } | ||
| } | ||
| } |
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (2)
Previously missed (1) — in code that hasn't changed since the last review.
services/libs/common/src/organization.ts:50
- These transformations are not composable because each earlier loop iterates a snapshot before punctuation variants are added here. For example,
Acme-Tech-Foundationproducesacme tech foundationbut neveracme tech, andThe-Acme-Technever producesacme tech; those combined near-name cases remain unblocked despite using the transformations this helper advertises. Generate punctuation forms before applying article/suffix rules (and retain final punctuation expansion), or otherwise build the cross-product of supported transformations.
for (const value of [...variants]) {
if (value.includes('-')) {
add(value.replace(/-/g, ' '))
}
if (value.includes(' ')) {
services/libs/data-access-layer/src/organizations/base.ts:586
- This regresses exact-name deduplication for normal mixed-case display names. The new helper compares
trim(lower("displayName"))with the CSV values verbatim, while this caller passes the original display name (for example,Apache Software Foundation), so it will not find the existing lowercase comparison value and may create a duplicate. Normalize this single exact name before calling the helper; do not use the full variant set here because deduplication is intentionally exact.
async () => findManyOrganizationsByNames(qe, [data.displayName]),
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
services/libs/common/src/organization.ts:13
- The variant set drops the original spacing because
exactcollapses every whitespace run, while both DAL predicates only applytrim(lower(...))to stored names. A project/org pair stored as"Foo Foundation"previously matched exactly but now generates only"foo foundation", so neither creation direction blocks it. Preserve the trimmed/lowercased exact value and add the whitespace-collapsed form as an additional variant.
const exact = name.trim().toLowerCase().replace(/\s+/g, ' ')
backend/src/services/segmentService.ts:733
- Trailing parenthetical variants are still missed in this direction. For example, creating segment
Cloud Native Computing Foundationwill not return an existing organization namedCloud Native Computing Foundation (CNCF): variants can remove an acronym only from the input, and this organization query never strips one from stored display names. The segment lookup handles the reverse direction withregexp_replace, so this contradicts the stated support for new projects and new orgs. Please add an affiliation-specific organization lookup (or an opt-in mode) that strips a trailing parenthetical value without changing the exact-only find-or-create call.
const organizations = await findManyOrganizationsByNames(
qx,
generateOrganizationNameVariants(segmentName),
)
Summary
Creating an LF project already blocks affiliation for an org with the same name, so it does not show up as a company on leaderboards. That check was exact-only, so close names were missed (extra "Project", a trailing acronym, hyphen vs space).
This uses those close names for new projects and new orgs. Existing rows are unchanged.
Changes