From bd780ff14493533df60781943ef1841e55abe8b9 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Sun, 10 May 2026 20:45:37 +0000 Subject: [PATCH] feat: add DataBillingMeter and DataAggregateLimitCounter node types Add upstream node type definitions for billing/metering: - DataBillingMeter: attaches record_usage triggers to tables for billing meter tracking (increment on INSERT, decrement on DELETE, transfer on UPDATE when entity_field changes) - DataAggregateLimitCounter: attaches org_limit_aggregates_inc/dec triggers for per-entity aggregate limit tracking (vs per-user limits in DataLimitCounter) --- .../src/data/data-aggregate-limit-counter.ts | 38 ++++++++++++++++ .../src/data/data-billing-meter.ts | 43 +++++++++++++++++++ packages/node-type-registry/src/data/index.ts | 2 + 3 files changed, 83 insertions(+) create mode 100644 packages/node-type-registry/src/data/data-aggregate-limit-counter.ts create mode 100644 packages/node-type-registry/src/data/data-billing-meter.ts diff --git a/packages/node-type-registry/src/data/data-aggregate-limit-counter.ts b/packages/node-type-registry/src/data/data-aggregate-limit-counter.ts new file mode 100644 index 000000000..0b9ba25ab --- /dev/null +++ b/packages/node-type-registry/src/data/data-aggregate-limit-counter.ts @@ -0,0 +1,38 @@ +import type { NodeTypeDefinition } from '../types'; + +export const DataAggregateLimitCounter: NodeTypeDefinition = { + name: 'DataAggregateLimitCounter', + slug: 'data_aggregate_limit_counter', + category: 'data', + display_name: 'Aggregate Limit Counter', + description: + 'Declaratively attaches aggregate limit-tracking triggers to a table. On INSERT the named limit is incremented per entity; on DELETE it is decremented. Uses org_limit_aggregates_inc/dec for per-entity (org-level) aggregate limits rather than per-user limits. Requires a provisioned limits_module for the target database.', + parameter_schema: { + type: 'object', + properties: { + limit_name: { + type: 'string', + description: + 'Name of the aggregate limit to track (must match a default_limits entry, e.g. "databases", "members")', + }, + entity_field: { + type: 'string', + format: 'column-ref', + description: + 'Column on the target table that holds the entity id for aggregate limit lookup', + default: 'entity_id', + }, + events: { + type: 'array', + items: { + type: 'string', + enum: ['INSERT', 'DELETE', 'UPDATE'], + }, + description: 'Which DML events to attach triggers for', + default: ['INSERT', 'DELETE'], + }, + }, + required: ['limit_name'], + }, + tags: ['limits', 'triggers', 'aggregates', 'billing'], +}; diff --git a/packages/node-type-registry/src/data/data-billing-meter.ts b/packages/node-type-registry/src/data/data-billing-meter.ts new file mode 100644 index 000000000..e03e45642 --- /dev/null +++ b/packages/node-type-registry/src/data/data-billing-meter.ts @@ -0,0 +1,43 @@ +import type { NodeTypeDefinition } from '../types'; + +export const DataBillingMeter: NodeTypeDefinition = { + name: 'DataBillingMeter', + slug: 'data_billing_meter', + category: 'data', + display_name: 'Billing Meter', + description: + 'Declaratively attaches billing usage-recording triggers to a table. On INSERT the named meter is incremented via record_usage; on DELETE it is decremented (reversal). On UPDATE, if the entity_field changes, the old entity is decremented and the new entity is incremented. Requires a provisioned billing_module for the target database.', + parameter_schema: { + type: 'object', + properties: { + meter_slug: { + type: 'string', + description: + 'Slug of the billing meter to record usage against (must match a meters table entry, e.g. "databases", "seats")', + }, + entity_field: { + type: 'string', + format: 'column-ref', + description: + 'Column on the target table that holds the entity id for billing', + default: 'entity_id', + }, + quantity: { + type: 'integer', + description: 'Units to record per event (default 1)', + default: 1, + }, + events: { + type: 'array', + items: { + type: 'string', + enum: ['INSERT', 'DELETE', 'UPDATE'], + }, + description: 'Which DML events to attach triggers for', + default: ['INSERT', 'DELETE'], + }, + }, + required: ['meter_slug'], + }, + tags: ['billing', 'triggers', 'metering', 'usage'], +}; diff --git a/packages/node-type-registry/src/data/index.ts b/packages/node-type-registry/src/data/index.ts index aec3d6dae..a2ce6c0e7 100644 --- a/packages/node-type-registry/src/data/index.ts +++ b/packages/node-type-registry/src/data/index.ts @@ -1,3 +1,5 @@ +export { DataAggregateLimitCounter } from './data-aggregate-limit-counter'; +export { DataBillingMeter } from './data-billing-meter'; export { DataChunks } from './data-chunks'; export { DataCompositeField } from './data-composite-field'; export { DataDirectOwner } from './data-direct-owner';