065b6efe11
## Problem
Partner applications **502** for any applicant whose company is already
in the CRM.
The `submit-partner-application` logic function dedupes applicants
**only by person email**. When no person matches that email, it takes
the create path and calls `createCompany` unconditionally. But
`Company.domainName` has a **UNIQUE index**, so whenever a company with
the applicant's domain already exists — which is common, since the **TFT
import seeds companies** — the mutation throws `"duplicate entry"`. The
handler's `catch` returns `{ ok: false }`, and the website
`/api/partner-application` route surfaces it as a **502**. The applicant
can never be submitted.
Real case that surfaced this: an applicant whose company (`BKG
Integration UG`, domain `bkg-integration.de`) was already present from
the TFT import with no Partner/Person attached.
## Fix
Extract `findOrCreateCompanyId`:
- Look the company up by **exact domain** (`domainName.primaryLinkUrl
eq`) and **reuse** it when found.
- Only `createCompany` when no domain matches.
- The matched company is **never renamed** — the existing CRM name wins
over the applicant's free-text `companyName`.
Person-email dedup is unchanged (already handled upstream in the
handler).
### Known limitation
Matches **active** rows only. A *soft-deleted* company still holds the
unique index and would re-collide; clear those with `yarn purge:prod`.
Noted inline.
## Tests
Adds an integration test: pre-seed a company by domain → submit an
application with the same domain → assert the partner reuses the same
company id and the company name is untouched.
## Version
`twenty-partners` 0.5.1 → **0.5.2** (patch: bug fix, no schema change).
<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21615?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
50 lines
1.7 KiB
JSON
50 lines
1.7 KiB
JSON
{
|
|
"name": "twenty-partners",
|
|
"version": "0.5.2",
|
|
"license": "MIT",
|
|
"engines": {
|
|
"node": "^24.5.0",
|
|
"npm": "please-use-yarn",
|
|
"yarn": ">=4.0.2"
|
|
},
|
|
"keywords": [],
|
|
"packageManager": "yarn@4.13.0",
|
|
"scripts": {
|
|
"twenty": "twenty",
|
|
"lint": "oxlint -c .oxlintrc.json .",
|
|
"lint:fix": "oxlint --fix -c .oxlintrc.json .",
|
|
"test": "vitest run",
|
|
"test:unit": "vitest run --config vitest.unit.config.ts",
|
|
"test:watch": "vitest",
|
|
"seed": "tsx src/scripts/seed.ts",
|
|
"seed:prod": "ENV_FILE=.env.prod tsx src/scripts/seed.ts",
|
|
"purge": "tsx src/scripts/purge-soft-deleted.ts",
|
|
"purge:prod": "ENV_FILE=.env.prod tsx src/scripts/purge-soft-deleted.ts",
|
|
"import:dryrun": "tsx src/scripts/import-from-tft.ts",
|
|
"import:dryrun:prod": "ENV_FILE=.env.prod tsx src/scripts/import-from-tft.ts",
|
|
"import:apply": "IMPORT_APPLY=1 tsx src/scripts/import-from-tft.ts",
|
|
"import:apply:prod": "ENV_FILE=.env.prod IMPORT_APPLY=1 tsx src/scripts/import-from-tft.ts",
|
|
"migrate:partner-scope": "tsx src/scripts/migrate-partner-scope.ts",
|
|
"migrate:partner-scope:prod": "ENV_FILE=.env.prod tsx src/scripts/migrate-partner-scope.ts",
|
|
"rls:configure": "tsx src/scripts/configure-partner-rls.ts",
|
|
"rls:configure:prod": "ENV_FILE=.env.prod tsx src/scripts/configure-partner-rls.ts"
|
|
},
|
|
"dependencies": {
|
|
"twenty-client-sdk": "2.13.0",
|
|
"twenty-sdk": "2.13.0",
|
|
"zod": "^4.1.11"
|
|
},
|
|
"devDependencies": {
|
|
"@types/node": "^24.7.2",
|
|
"@types/react": "^19.0.0",
|
|
"dotenv": "^16.0.0",
|
|
"oxlint": "^0.16.0",
|
|
"react": "^19.0.0",
|
|
"react-dom": "^19.0.0",
|
|
"tsx": "^4.0.0",
|
|
"typescript": "^5.9.3",
|
|
"vite-tsconfig-paths": "^4.2.1",
|
|
"vitest": "^4.0.0"
|
|
}
|
|
}
|