adbd78767e
## What Tightens the **Partner** self-service role's field-level permissions so a partner can edit its own profile but not admin/ops-controlled or ownership fields. All locks are `canUpdateFieldValue: false` on the Partner object. **Admin-managed scalar fields (7):** `slug`, `validationStage`, `reviewed`, `ranking`, `partnerTier`, `applicationNotes`, `lastMatchAt` **Ownership relation FKs (2):** `partnerUser`, `company` ## Why - The 7 scalar fields are admin/ops-controlled (validation, ranking, tiering, internal notes) — a partner must not be able to self-promote or alter ops data. - `partnerUser` is the **RLS pivot**: the row-level predicate scopes a partner to records where `partnerUser IS <their workspace member>`. If a partner could clear or repoint it, they'd drop their own record out of scope (an orphan only admins can see). It is already locked on Opportunity; this brings Partner in line. - `company` is read-only at the object level for partners, so its FK link must not be repointable from the Partner side either. The remaining Partner relations (`opportunities`, `persons`, `partnerContents`) need no lock — they are already protected by inverse-side field locks or object-level read-only / no-access rules. ## Scope - One source file: `src/roles/partner.role.ts` (9 field-permission entries). - No schema changes — additive permission tightening; upgrades cleanly via `deploy` + `install`. - Version: patch bump `0.5.0 → 0.5.1`.
50 lines
1.7 KiB
JSON
50 lines
1.7 KiB
JSON
{
|
|
"name": "twenty-partners",
|
|
"version": "0.5.1",
|
|
"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.10.1",
|
|
"twenty-sdk": "2.10.1",
|
|
"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": "^3.2.6"
|
|
}
|
|
}
|