From 8406f9ee21f6629cd5f926415adc3fb7deba6e6e Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 05:26:53 +0000 Subject: [PATCH 1/2] Revert "Merge pull request #1278 from constructive-io/feat/check-scoped-foreign-key" This reverts commit fb2f40ed60d3173362cb47bbc42f4fd1db8b9bdd, reversing changes made to 659c7776183c8dc497e640c384e8d1af45965065. --- .../src/data/check-scoped-foreign-key.ts | 59 ---------------- .../src/data/data-denormalized.ts | 70 ------------------- packages/node-type-registry/src/data/index.ts | 2 - 3 files changed, 131 deletions(-) delete mode 100644 packages/node-type-registry/src/data/check-scoped-foreign-key.ts delete mode 100644 packages/node-type-registry/src/data/data-denormalized.ts diff --git a/packages/node-type-registry/src/data/check-scoped-foreign-key.ts b/packages/node-type-registry/src/data/check-scoped-foreign-key.ts deleted file mode 100644 index b015ad5e3..000000000 --- a/packages/node-type-registry/src/data/check-scoped-foreign-key.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { NodeTypeDefinition } from '../types'; - -export const CheckScopedForeignKey: NodeTypeDefinition = { - name: 'CheckScopedForeignKey', - slug: 'check_scoped_foreign_key', - category: 'check', - display_name: 'Check Scoped Foreign Key', - description: - 'BEFORE INSERT trigger that validates all FK references resolve to the same scope value (e.g. database_id). Prevents cross-scope linking where a user with access to multiple scopes could create invalid cross-scope references. Works on junction tables (2+ FKs) and child tables (1 FK validated against the row\'s own scope field).', - parameter_schema: { - type: 'object', - properties: { - scope_field: { - type: 'string', - format: 'column-ref', - description: - 'Scope field on this table to validate against (e.g. "database_id"). If set, the trigger also checks that all referenced scope values match NEW.scope_field. If omitted, only checks that all references match each other.', - default: 'database_id' - }, - references: { - type: 'array', - items: { - type: 'object', - properties: { - field: { - type: 'string', - format: 'column-ref', - description: 'FK field on this table (e.g. "view_id")' - }, - ref_table: { - type: 'string', - description: - 'Target table name (e.g. "view"). Schema is resolved from the table registry.' - }, - ref_field: { - type: 'string', - format: 'column-ref', - description: 'PK field on the target table (e.g. "id")', - default: 'id' - }, - ref_scope_field: { - type: 'string', - format: 'column-ref', - description: - 'Scope field on the target table to read (e.g. "database_id")', - default: 'database_id' - } - }, - required: ['field', 'ref_table'] - }, - description: - 'FK references to validate. Each target\'s scope field must resolve to the same value.', - minItems: 1 - } - }, - required: ['references'] - }, - tags: ['check', 'trigger', 'security', 'scope-isolation', 'foreign-key'] -}; diff --git a/packages/node-type-registry/src/data/data-denormalized.ts b/packages/node-type-registry/src/data/data-denormalized.ts deleted file mode 100644 index a67fb5964..000000000 --- a/packages/node-type-registry/src/data/data-denormalized.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { NodeTypeDefinition } from '../types'; - -export const DataDenormalized: NodeTypeDefinition = { - name: 'DataDenormalized', - slug: 'data_denormalized', - category: 'data', - display_name: 'Denormalized Field', - description: 'Creates INSERT and UPDATE triggers that copy field values from a referenced (parent) table into the current table whenever the FK changes. Used to denormalize frequently-read columns (e.g. database_id on junction tables) so that RLS and queries can filter locally without joining.', - parameter_schema: { - type: 'object', - properties: { - field: { - type: 'string', - format: 'column-ref', - description: 'FK field on this table that references the parent row (e.g. view_id)' - }, - set_fields: { - type: 'array', - items: { - type: 'string', - format: 'column-ref' - }, - description: 'Field names on this table to be populated from the parent (e.g. ["database_id"])' - }, - ref_field: { - type: 'string', - format: 'column-ref', - description: 'Field on the parent table that is the FK target (e.g. id)' - }, - ref_fields: { - type: 'array', - items: { - type: 'string', - format: 'column-ref' - }, - description: 'Field names on the parent table to copy from (e.g. ["database_id"])' - }, - use_updates: { - type: 'boolean', - description: 'If true, also creates an UPDATE trigger so changes to the FK re-copy values', - default: true - }, - update_defaults: { - type: 'boolean', - description: 'If true, sets the default value of set_fields to uuid_nil() so they are populated by the trigger', - default: true - }, - func_name: { - type: 'string', - description: 'Custom function name suffix (defaults to the FK field name)' - }, - func_order: { - type: 'integer', - description: 'Trigger ordering (0-padded). Lower numbers fire first', - default: 0 - } - }, - required: [ - 'field', - 'set_fields', - 'ref_field', - 'ref_fields' - ] - }, - tags: [ - 'trigger', - 'denormalization', - 'schema' - ] -}; diff --git a/packages/node-type-registry/src/data/index.ts b/packages/node-type-registry/src/data/index.ts index 5ac4b747d..11a853131 100644 --- a/packages/node-type-registry/src/data/index.ts +++ b/packages/node-type-registry/src/data/index.ts @@ -2,10 +2,8 @@ export { CheckGreaterThan } from './check-greater-than'; export { CheckLessThan } from './check-less-than'; export { CheckNotEqual } from './check-not-equal'; export { CheckOneOf } from './check-one-of'; -export { CheckScopedForeignKey } from './check-scoped-foreign-key'; export { DataBulk } from './data-bulk'; export { DataCompositeField } from './data-composite-field'; -export { DataDenormalized } from './data-denormalized'; export { DataDirectOwner } from './data-direct-owner'; export { DataEntityMembership } from './data-entity-membership'; export { DataForceCurrentUser } from './data-force-current-user'; From e948130035750c976272848eed6b98391070df27 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Sun, 7 Jun 2026 05:27:41 +0000 Subject: [PATCH 2/2] restore DataDenormalized (was incorrectly removed by revert of CheckScopedForeignKey) --- .../src/data/data-denormalized.ts | 70 +++++++++++++++++++ packages/node-type-registry/src/data/index.ts | 1 + 2 files changed, 71 insertions(+) create mode 100644 packages/node-type-registry/src/data/data-denormalized.ts diff --git a/packages/node-type-registry/src/data/data-denormalized.ts b/packages/node-type-registry/src/data/data-denormalized.ts new file mode 100644 index 000000000..a67fb5964 --- /dev/null +++ b/packages/node-type-registry/src/data/data-denormalized.ts @@ -0,0 +1,70 @@ +import type { NodeTypeDefinition } from '../types'; + +export const DataDenormalized: NodeTypeDefinition = { + name: 'DataDenormalized', + slug: 'data_denormalized', + category: 'data', + display_name: 'Denormalized Field', + description: 'Creates INSERT and UPDATE triggers that copy field values from a referenced (parent) table into the current table whenever the FK changes. Used to denormalize frequently-read columns (e.g. database_id on junction tables) so that RLS and queries can filter locally without joining.', + parameter_schema: { + type: 'object', + properties: { + field: { + type: 'string', + format: 'column-ref', + description: 'FK field on this table that references the parent row (e.g. view_id)' + }, + set_fields: { + type: 'array', + items: { + type: 'string', + format: 'column-ref' + }, + description: 'Field names on this table to be populated from the parent (e.g. ["database_id"])' + }, + ref_field: { + type: 'string', + format: 'column-ref', + description: 'Field on the parent table that is the FK target (e.g. id)' + }, + ref_fields: { + type: 'array', + items: { + type: 'string', + format: 'column-ref' + }, + description: 'Field names on the parent table to copy from (e.g. ["database_id"])' + }, + use_updates: { + type: 'boolean', + description: 'If true, also creates an UPDATE trigger so changes to the FK re-copy values', + default: true + }, + update_defaults: { + type: 'boolean', + description: 'If true, sets the default value of set_fields to uuid_nil() so they are populated by the trigger', + default: true + }, + func_name: { + type: 'string', + description: 'Custom function name suffix (defaults to the FK field name)' + }, + func_order: { + type: 'integer', + description: 'Trigger ordering (0-padded). Lower numbers fire first', + default: 0 + } + }, + required: [ + 'field', + 'set_fields', + 'ref_field', + 'ref_fields' + ] + }, + tags: [ + 'trigger', + 'denormalization', + 'schema' + ] +}; diff --git a/packages/node-type-registry/src/data/index.ts b/packages/node-type-registry/src/data/index.ts index 11a853131..a0b8c3677 100644 --- a/packages/node-type-registry/src/data/index.ts +++ b/packages/node-type-registry/src/data/index.ts @@ -3,6 +3,7 @@ export { CheckLessThan } from './check-less-than'; export { CheckNotEqual } from './check-not-equal'; export { CheckOneOf } from './check-one-of'; export { DataBulk } from './data-bulk'; +export { DataDenormalized } from './data-denormalized'; export { DataCompositeField } from './data-composite-field'; export { DataDirectOwner } from './data-direct-owner'; export { DataEntityMembership } from './data-entity-membership';