node-type-registry 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -327,6 +327,12 @@ export interface JobTriggerParams {
327
327
  condition_value?: string;
328
328
  conditions?: TriggerCondition | TriggerCondition[];
329
329
  watch_fields?: string[];
330
+ entity_field?: string;
331
+ entity_lookup?: {
332
+ obj_table: string;
333
+ obj_schema?: string;
334
+ obj_field: string;
335
+ };
330
336
  job_key?: string;
331
337
  queue_name?: string;
332
338
  priority?: number;
@@ -343,6 +349,13 @@ export interface ProcessChunksParams {
343
349
  metric?: 'cosine' | 'l2' | 'ip';
344
350
  chunks_table_name?: string;
345
351
  metadata_fields?: string[];
352
+ search_indexes?: ('fulltext' | 'bm25' | 'trigram')[];
353
+ entity_field?: string;
354
+ entity_lookup?: {
355
+ obj_table: string;
356
+ obj_schema?: string;
357
+ obj_field: string;
358
+ };
346
359
  enqueue_chunking_job?: boolean;
347
360
  chunking_task_name?: string;
348
361
  }
@@ -362,6 +375,12 @@ export interface ProcessFileEmbeddingParams {
362
375
  [key: string]: unknown;
363
376
  };
364
377
  trigger_conditions?: TriggerCondition | TriggerCondition[];
378
+ entity_field?: string;
379
+ entity_lookup?: {
380
+ obj_table: string;
381
+ obj_schema?: string;
382
+ obj_field: string;
383
+ };
365
384
  extraction?: {
366
385
  text_field?: string;
367
386
  metadata_field?: string;
@@ -393,6 +412,12 @@ export interface ProcessImageEmbeddingParams {
393
412
  [key: string]: unknown;
394
413
  };
395
414
  trigger_conditions?: TriggerCondition | TriggerCondition[];
415
+ entity_field?: string;
416
+ entity_lookup?: {
417
+ obj_table: string;
418
+ obj_schema?: string;
419
+ obj_field: string;
420
+ };
396
421
  extraction?: {
397
422
  text_field?: string;
398
423
  metadata_field?: string;
@@ -420,6 +445,12 @@ export interface ProcessExtractionParams {
420
445
  [key: string]: unknown;
421
446
  };
422
447
  trigger_conditions?: TriggerCondition | TriggerCondition[];
448
+ entity_field?: string;
449
+ entity_lookup?: {
450
+ obj_table: string;
451
+ obj_schema?: string;
452
+ obj_field: string;
453
+ };
423
454
  queue_name?: string;
424
455
  max_attempts?: number;
425
456
  priority?: number;
@@ -441,6 +472,12 @@ export interface ProcessImageVersionsParams {
441
472
  [key: string]: unknown;
442
473
  };
443
474
  trigger_conditions?: TriggerCondition | TriggerCondition[];
475
+ entity_field?: string;
476
+ entity_lookup?: {
477
+ obj_table: string;
478
+ obj_schema?: string;
479
+ obj_field: string;
480
+ };
444
481
  queue_name?: string;
445
482
  max_attempts?: number;
446
483
  priority?: number;
@@ -327,6 +327,12 @@ export interface JobTriggerParams {
327
327
  condition_value?: string;
328
328
  conditions?: TriggerCondition | TriggerCondition[];
329
329
  watch_fields?: string[];
330
+ entity_field?: string;
331
+ entity_lookup?: {
332
+ obj_table: string;
333
+ obj_schema?: string;
334
+ obj_field: string;
335
+ };
330
336
  job_key?: string;
331
337
  queue_name?: string;
332
338
  priority?: number;
@@ -343,6 +349,13 @@ export interface ProcessChunksParams {
343
349
  metric?: 'cosine' | 'l2' | 'ip';
344
350
  chunks_table_name?: string;
345
351
  metadata_fields?: string[];
352
+ search_indexes?: ('fulltext' | 'bm25' | 'trigram')[];
353
+ entity_field?: string;
354
+ entity_lookup?: {
355
+ obj_table: string;
356
+ obj_schema?: string;
357
+ obj_field: string;
358
+ };
346
359
  enqueue_chunking_job?: boolean;
347
360
  chunking_task_name?: string;
348
361
  }
@@ -362,6 +375,12 @@ export interface ProcessFileEmbeddingParams {
362
375
  [key: string]: unknown;
363
376
  };
364
377
  trigger_conditions?: TriggerCondition | TriggerCondition[];
378
+ entity_field?: string;
379
+ entity_lookup?: {
380
+ obj_table: string;
381
+ obj_schema?: string;
382
+ obj_field: string;
383
+ };
365
384
  extraction?: {
366
385
  text_field?: string;
367
386
  metadata_field?: string;
@@ -393,6 +412,12 @@ export interface ProcessImageEmbeddingParams {
393
412
  [key: string]: unknown;
394
413
  };
395
414
  trigger_conditions?: TriggerCondition | TriggerCondition[];
415
+ entity_field?: string;
416
+ entity_lookup?: {
417
+ obj_table: string;
418
+ obj_schema?: string;
419
+ obj_field: string;
420
+ };
396
421
  extraction?: {
397
422
  text_field?: string;
398
423
  metadata_field?: string;
@@ -420,6 +445,12 @@ export interface ProcessExtractionParams {
420
445
  [key: string]: unknown;
421
446
  };
422
447
  trigger_conditions?: TriggerCondition | TriggerCondition[];
448
+ entity_field?: string;
449
+ entity_lookup?: {
450
+ obj_table: string;
451
+ obj_schema?: string;
452
+ obj_field: string;
453
+ };
423
454
  queue_name?: string;
424
455
  max_attempts?: number;
425
456
  priority?: number;
@@ -441,6 +472,12 @@ export interface ProcessImageVersionsParams {
441
472
  [key: string]: unknown;
442
473
  };
443
474
  trigger_conditions?: TriggerCondition | TriggerCondition[];
475
+ entity_field?: string;
476
+ entity_lookup?: {
477
+ obj_table: string;
478
+ obj_schema?: string;
479
+ obj_field: string;
480
+ };
444
481
  queue_name?: string;
445
482
  max_attempts?: number;
446
483
  priority?: number;
@@ -67,6 +67,34 @@ export const JobTrigger = {
67
67
  default: false
68
68
  },
69
69
  ...conditionProperties,
70
+ entity_field: {
71
+ type: 'string',
72
+ format: 'column-ref',
73
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. For direct entity_id columns, just set this field. For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.'
74
+ },
75
+ entity_lookup: {
76
+ type: 'object',
77
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
78
+ properties: {
79
+ obj_table: {
80
+ type: 'string',
81
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
82
+ },
83
+ obj_schema: {
84
+ type: 'string',
85
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
86
+ },
87
+ obj_field: {
88
+ type: 'string',
89
+ format: 'column-ref',
90
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
91
+ }
92
+ },
93
+ required: [
94
+ 'obj_table',
95
+ 'obj_field'
96
+ ]
97
+ },
70
98
  job_key: {
71
99
  type: 'string',
72
100
  description: 'Static job key for upsert semantics (prevents duplicate jobs)'
@@ -1,13 +1,13 @@
1
1
  import type { ModulePreset } from './types';
2
2
  /**
3
- * `full` — install everything. Equivalent to the default
4
- * `provision_database_modules(v_modules => ARRAY['all'])` behavior.
3
+ * `full` — install every standard module.
5
4
  *
6
5
  * This is the maximalist preset: every module Constructive ships, including
7
- * `storage_module` for file uploads and `crypto_addresses_module` for
8
- * wallet-based sign-in. Use it for greenfield apps where you'd rather
9
- * disable features via `app_settings_auth` toggles than uninstall modules,
10
- * or for the "kitchen sink" example / demo databases.
6
+ * `storage_module:full` for file uploads with all feature flags and
7
+ * `crypto_addresses_module` for wallet-based sign-in.
8
+ *
9
+ * Usage logging modules (compute_log, inference_log, transfer_log,
10
+ * storage_log, db_usage) are NOT included — they are opt-in only.
11
11
  *
12
12
  * Prefer a more targeted preset for anything production-bound — installing
13
13
  * a module you'll never use still costs tables, triggers, and grants.
@@ -1,12 +1,12 @@
1
1
  /**
2
- * `full` — install everything. Equivalent to the default
3
- * `provision_database_modules(v_modules => ARRAY['all'])` behavior.
2
+ * `full` — install every standard module.
4
3
  *
5
4
  * This is the maximalist preset: every module Constructive ships, including
6
- * `storage_module` for file uploads and `crypto_addresses_module` for
7
- * wallet-based sign-in. Use it for greenfield apps where you'd rather
8
- * disable features via `app_settings_auth` toggles than uninstall modules,
9
- * or for the "kitchen sink" example / demo databases.
5
+ * `storage_module:full` for file uploads with all feature flags and
6
+ * `crypto_addresses_module` for wallet-based sign-in.
7
+ *
8
+ * Usage logging modules (compute_log, inference_log, transfer_log,
9
+ * storage_log, db_usage) are NOT included — they are opt-in only.
10
10
  *
11
11
  * Prefer a more targeted preset for anything production-bound — installing
12
12
  * a module you'll never use still costs tables, triggers, and grants.
@@ -14,25 +14,80 @@
14
14
  export const PresetFull = {
15
15
  name: 'full',
16
16
  display_name: 'Full (every module)',
17
- summary: "Install every Constructive module. Equivalent to v_modules => ARRAY['all'].",
18
- description: 'Installs every module in the catalog: everything in `b2b` plus `storage_module` ' +
19
- 'for file uploads and `crypto_addresses_module` / `crypto_auth_module` for ' +
20
- 'wallet-based sign-in. This matches the current default when `provision_database_modules` ' +
21
- 'is called without an explicit `v_modules` argument. Use it for fully-featured ' +
22
- 'demo/example databases, kitchen-sink reference deployments, or greenfield apps that ' +
23
- 'would rather feature-flag at the app_settings level than uninstall modules.',
17
+ summary: 'Install every standard Constructive module with explicit module list.',
18
+ description: 'Installs every standard module in the catalog: everything in `b2b` plus ' +
19
+ '`storage_module:full` for file uploads (versioning, content hash, custom keys, audit log), ' +
20
+ '`crypto_addresses_module` for wallet-based sign-in, `plans_module` and `billing_module` ' +
21
+ 'for subscription management, `notifications_module` for in-app notifications, and ' +
22
+ '`events_module` at both app and org scopes. Usage logging modules are opt-in only — ' +
23
+ 'add them explicitly if needed.',
24
24
  good_for: [
25
25
  'Reference / demo databases that showcase every Constructive feature',
26
26
  'Greenfield apps where the product scope is still open-ended',
27
- 'Keeping the provisioning call identical to the pre-preset default'
27
+ 'Integration tests that need the full module stack'
28
28
  ],
29
29
  not_for: [
30
30
  'Production apps with a defined feature set — pick the narrowest preset that fits',
31
31
  'Resource-constrained environments — every module costs schema bloat, RLS policies, and grants'
32
32
  ],
33
- modules: ['all'],
33
+ modules: [
34
+ // Core
35
+ 'users_module',
36
+ 'membership_types_module',
37
+ // App-level (membership_type = 1)
38
+ 'permissions_module:app',
39
+ 'limits_module:app',
40
+ 'memberships_module:app',
41
+ 'events_module:app',
42
+ 'profiles_module:app',
43
+ // Org-level (membership_type = 2)
44
+ 'permissions_module:org',
45
+ 'limits_module:org',
46
+ 'memberships_module:org',
47
+ 'events_module:org',
48
+ 'profiles_module:org',
49
+ // Hierarchy
50
+ 'hierarchy_module:org',
51
+ // Billing & Plans
52
+ 'plans_module',
53
+ 'billing_module',
54
+ 'rate_limit_meters_module',
55
+ 'billing_provider_module',
56
+ // Auth infrastructure
57
+ 'user_state_module',
58
+ 'sessions_module',
59
+ 'session_secrets_module',
60
+ 'rate_limits_module',
61
+ 'devices_module',
62
+ 'config_secrets_user_module',
63
+ 'rls_module',
64
+ // Contact modules
65
+ 'emails_module',
66
+ 'phone_numbers_module',
67
+ 'crypto_addresses_module',
68
+ 'webauthn_credentials_module',
69
+ 'notifications_module',
70
+ // Connected accounts
71
+ 'connected_accounts_module',
72
+ 'identity_providers_module',
73
+ // Invites & Auth
74
+ 'invites_module:app',
75
+ 'invites_module:org',
76
+ 'user_auth_module',
77
+ 'webauthn_auth_module',
78
+ // Storage (full features)
79
+ 'storage_module:full',
80
+ ],
34
81
  includes_notes: {
35
- all: "Sentinel the provisioner installs every known module when `modules = ['all']`."
82
+ 'storage_module:full': 'All storage feature flags enabled: versioning, content hash, custom keys, audit log.',
83
+ billing_module: 'Metered billing with credits waterfall and period reset.',
84
+ plans_module: 'Subscription plan management with plan-governed caps.',
85
+ notifications_module: 'In-app notification system with read/unread tracking.'
86
+ },
87
+ omits_notes: {
88
+ compute_log_module: 'Usage logging is opt-in. Add explicitly if needed.',
89
+ inference_log_module: 'Usage logging is opt-in. Add explicitly if needed.',
90
+ agent_chat_module: 'Agent infrastructure is opt-in.'
36
91
  },
37
92
  extends: ['b2b']
38
93
  };
@@ -93,6 +93,22 @@ export const ProcessChunks = {
93
93
  'Omit to mirror the parent table\'s text search indexes. ' +
94
94
  'Set explicitly to override (e.g. ["fulltext", "bm25"]).'
95
95
  },
96
+ // ── Entity billing scope ──────────────────────────────────────
97
+ entity_field: {
98
+ type: 'string',
99
+ format: 'column-ref',
100
+ description: 'Column on the parent table that holds (or references) the entity_id for billing scope. Forwarded to the chunking job trigger.'
101
+ },
102
+ entity_lookup: {
103
+ type: 'object',
104
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the chunking job trigger.',
105
+ properties: {
106
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
107
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
108
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
109
+ },
110
+ required: ['obj_table', 'obj_field']
111
+ },
96
112
  // ── Job trigger ────────────────────────────────────────────────
97
113
  enqueue_chunking_job: {
98
114
  type: 'boolean',
@@ -82,6 +82,22 @@ export const ProcessExtraction = {
82
82
  }
83
83
  },
84
84
  trigger_conditions: triggerConditionsProperty,
85
+ // ── Entity billing scope ──────────────────────────────────────
86
+ entity_field: {
87
+ type: 'string',
88
+ format: 'column-ref',
89
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. Forwarded to the composed JobTrigger.'
90
+ },
91
+ entity_lookup: {
92
+ type: 'object',
93
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the composed JobTrigger.',
94
+ properties: {
95
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
96
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
97
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
98
+ },
99
+ required: ['obj_table', 'obj_field']
100
+ },
85
101
  // ── Job options ───────────────────────────────────────────────
86
102
  queue_name: {
87
103
  type: 'string',
@@ -89,6 +89,22 @@ export const ProcessFileEmbedding = {
89
89
  }
90
90
  },
91
91
  trigger_conditions: triggerConditionsProperty,
92
+ // ── Entity billing scope ──────────────────────────────────────
93
+ entity_field: {
94
+ type: 'string',
95
+ format: 'column-ref',
96
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. Forwarded to the composed JobTrigger.'
97
+ },
98
+ entity_lookup: {
99
+ type: 'object',
100
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the composed JobTrigger.',
101
+ properties: {
102
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
103
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
104
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
105
+ },
106
+ required: ['obj_table', 'obj_field']
107
+ },
92
108
  // ── Extraction config (optional — enables extract mode) ────────
93
109
  extraction: {
94
110
  type: 'object',
@@ -96,6 +96,22 @@ export const ProcessImageEmbedding = {
96
96
  }
97
97
  },
98
98
  trigger_conditions: triggerConditionsProperty,
99
+ // ── Entity billing scope ──────────────────────────────────────
100
+ entity_field: {
101
+ type: 'string',
102
+ format: 'column-ref',
103
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. Forwarded to the composed JobTrigger.'
104
+ },
105
+ entity_lookup: {
106
+ type: 'object',
107
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the composed JobTrigger.',
108
+ properties: {
109
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
110
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
111
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
112
+ },
113
+ required: ['obj_table', 'obj_field']
114
+ },
99
115
  // ── Extraction config (optional — enables extract mode) ────────
100
116
  extraction: {
101
117
  type: 'object',
@@ -101,6 +101,22 @@ export const ProcessImageVersions = {
101
101
  }
102
102
  },
103
103
  trigger_conditions: triggerConditionsProperty,
104
+ // ── Entity billing scope ──────────────────────────────────────
105
+ entity_field: {
106
+ type: 'string',
107
+ format: 'column-ref',
108
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. Forwarded to the composed JobTrigger.'
109
+ },
110
+ entity_lookup: {
111
+ type: 'object',
112
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the composed JobTrigger.',
113
+ properties: {
114
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
115
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
116
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
117
+ },
118
+ required: ['obj_table', 'obj_field']
119
+ },
104
120
  // ── Job options ───────────────────────────────────────────────
105
121
  queue_name: {
106
122
  type: 'string',
package/job/trigger.js CHANGED
@@ -70,6 +70,34 @@ exports.JobTrigger = {
70
70
  default: false
71
71
  },
72
72
  ...conditions_1.conditionProperties,
73
+ entity_field: {
74
+ type: 'string',
75
+ format: 'column-ref',
76
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. For direct entity_id columns, just set this field. For FK lookups (e.g., channel_id → channels.entity_id), combine with entity_lookup.'
77
+ },
78
+ entity_lookup: {
79
+ type: 'object',
80
+ description: 'FK lookup configuration for resolving entity_id through a related table. Used when entity_field is a FK (e.g., channel_id) rather than a direct entity_id. The generator validates all fields against metaschema within the same database_id.',
81
+ properties: {
82
+ obj_table: {
83
+ type: 'string',
84
+ description: 'Name of the related table to look up entity_id from (e.g., "channels"). Required.'
85
+ },
86
+ obj_schema: {
87
+ type: 'string',
88
+ description: 'Schema of the related table (user-facing name, e.g., "public"). Optional — if omitted, resolved by table name within the same database_id (raises error if ambiguous).'
89
+ },
90
+ obj_field: {
91
+ type: 'string',
92
+ format: 'column-ref',
93
+ description: 'Column on the related table that holds the entity_id (e.g., "entity_id"). Required.'
94
+ }
95
+ },
96
+ required: [
97
+ 'obj_table',
98
+ 'obj_field'
99
+ ]
100
+ },
73
101
  job_key: {
74
102
  type: 'string',
75
103
  description: 'Static job key for upsert semantics (prevents duplicate jobs)'
@@ -1,13 +1,13 @@
1
1
  import type { ModulePreset } from './types';
2
2
  /**
3
- * `full` — install everything. Equivalent to the default
4
- * `provision_database_modules(v_modules => ARRAY['all'])` behavior.
3
+ * `full` — install every standard module.
5
4
  *
6
5
  * This is the maximalist preset: every module Constructive ships, including
7
- * `storage_module` for file uploads and `crypto_addresses_module` for
8
- * wallet-based sign-in. Use it for greenfield apps where you'd rather
9
- * disable features via `app_settings_auth` toggles than uninstall modules,
10
- * or for the "kitchen sink" example / demo databases.
6
+ * `storage_module:full` for file uploads with all feature flags and
7
+ * `crypto_addresses_module` for wallet-based sign-in.
8
+ *
9
+ * Usage logging modules (compute_log, inference_log, transfer_log,
10
+ * storage_log, db_usage) are NOT included — they are opt-in only.
11
11
  *
12
12
  * Prefer a more targeted preset for anything production-bound — installing
13
13
  * a module you'll never use still costs tables, triggers, and grants.
@@ -2,14 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PresetFull = void 0;
4
4
  /**
5
- * `full` — install everything. Equivalent to the default
6
- * `provision_database_modules(v_modules => ARRAY['all'])` behavior.
5
+ * `full` — install every standard module.
7
6
  *
8
7
  * This is the maximalist preset: every module Constructive ships, including
9
- * `storage_module` for file uploads and `crypto_addresses_module` for
10
- * wallet-based sign-in. Use it for greenfield apps where you'd rather
11
- * disable features via `app_settings_auth` toggles than uninstall modules,
12
- * or for the "kitchen sink" example / demo databases.
8
+ * `storage_module:full` for file uploads with all feature flags and
9
+ * `crypto_addresses_module` for wallet-based sign-in.
10
+ *
11
+ * Usage logging modules (compute_log, inference_log, transfer_log,
12
+ * storage_log, db_usage) are NOT included — they are opt-in only.
13
13
  *
14
14
  * Prefer a more targeted preset for anything production-bound — installing
15
15
  * a module you'll never use still costs tables, triggers, and grants.
@@ -17,25 +17,80 @@ exports.PresetFull = void 0;
17
17
  exports.PresetFull = {
18
18
  name: 'full',
19
19
  display_name: 'Full (every module)',
20
- summary: "Install every Constructive module. Equivalent to v_modules => ARRAY['all'].",
21
- description: 'Installs every module in the catalog: everything in `b2b` plus `storage_module` ' +
22
- 'for file uploads and `crypto_addresses_module` / `crypto_auth_module` for ' +
23
- 'wallet-based sign-in. This matches the current default when `provision_database_modules` ' +
24
- 'is called without an explicit `v_modules` argument. Use it for fully-featured ' +
25
- 'demo/example databases, kitchen-sink reference deployments, or greenfield apps that ' +
26
- 'would rather feature-flag at the app_settings level than uninstall modules.',
20
+ summary: 'Install every standard Constructive module with explicit module list.',
21
+ description: 'Installs every standard module in the catalog: everything in `b2b` plus ' +
22
+ '`storage_module:full` for file uploads (versioning, content hash, custom keys, audit log), ' +
23
+ '`crypto_addresses_module` for wallet-based sign-in, `plans_module` and `billing_module` ' +
24
+ 'for subscription management, `notifications_module` for in-app notifications, and ' +
25
+ '`events_module` at both app and org scopes. Usage logging modules are opt-in only — ' +
26
+ 'add them explicitly if needed.',
27
27
  good_for: [
28
28
  'Reference / demo databases that showcase every Constructive feature',
29
29
  'Greenfield apps where the product scope is still open-ended',
30
- 'Keeping the provisioning call identical to the pre-preset default'
30
+ 'Integration tests that need the full module stack'
31
31
  ],
32
32
  not_for: [
33
33
  'Production apps with a defined feature set — pick the narrowest preset that fits',
34
34
  'Resource-constrained environments — every module costs schema bloat, RLS policies, and grants'
35
35
  ],
36
- modules: ['all'],
36
+ modules: [
37
+ // Core
38
+ 'users_module',
39
+ 'membership_types_module',
40
+ // App-level (membership_type = 1)
41
+ 'permissions_module:app',
42
+ 'limits_module:app',
43
+ 'memberships_module:app',
44
+ 'events_module:app',
45
+ 'profiles_module:app',
46
+ // Org-level (membership_type = 2)
47
+ 'permissions_module:org',
48
+ 'limits_module:org',
49
+ 'memberships_module:org',
50
+ 'events_module:org',
51
+ 'profiles_module:org',
52
+ // Hierarchy
53
+ 'hierarchy_module:org',
54
+ // Billing & Plans
55
+ 'plans_module',
56
+ 'billing_module',
57
+ 'rate_limit_meters_module',
58
+ 'billing_provider_module',
59
+ // Auth infrastructure
60
+ 'user_state_module',
61
+ 'sessions_module',
62
+ 'session_secrets_module',
63
+ 'rate_limits_module',
64
+ 'devices_module',
65
+ 'config_secrets_user_module',
66
+ 'rls_module',
67
+ // Contact modules
68
+ 'emails_module',
69
+ 'phone_numbers_module',
70
+ 'crypto_addresses_module',
71
+ 'webauthn_credentials_module',
72
+ 'notifications_module',
73
+ // Connected accounts
74
+ 'connected_accounts_module',
75
+ 'identity_providers_module',
76
+ // Invites & Auth
77
+ 'invites_module:app',
78
+ 'invites_module:org',
79
+ 'user_auth_module',
80
+ 'webauthn_auth_module',
81
+ // Storage (full features)
82
+ 'storage_module:full',
83
+ ],
37
84
  includes_notes: {
38
- all: "Sentinel the provisioner installs every known module when `modules = ['all']`."
85
+ 'storage_module:full': 'All storage feature flags enabled: versioning, content hash, custom keys, audit log.',
86
+ billing_module: 'Metered billing with credits waterfall and period reset.',
87
+ plans_module: 'Subscription plan management with plan-governed caps.',
88
+ notifications_module: 'In-app notification system with read/unread tracking.'
89
+ },
90
+ omits_notes: {
91
+ compute_log_module: 'Usage logging is opt-in. Add explicitly if needed.',
92
+ inference_log_module: 'Usage logging is opt-in. Add explicitly if needed.',
93
+ agent_chat_module: 'Agent infrastructure is opt-in.'
39
94
  },
40
95
  extends: ['b2b']
41
96
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-type-registry",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "Node type definitions for the Constructive blueprint system. Single source of truth for all Authz*, Data*, Relation*, and View* node types.",
5
5
  "author": "Constructive <developers@constructive.io>",
6
6
  "main": "index.js",
@@ -33,8 +33,8 @@
33
33
  "@babel/generator": "^7.29.0",
34
34
  "@babel/types": "^7.29.0",
35
35
  "@pgsql/types": "^17.6.2",
36
- "@pgsql/utils": "^17.8.15",
37
- "pgsql-deparser": "^17.18.2",
36
+ "@pgsql/utils": "^17.8.17",
37
+ "pgsql-deparser": "^17.18.3",
38
38
  "schema-typescript": "^0.14.3"
39
39
  },
40
40
  "devDependencies": {
@@ -47,5 +47,5 @@
47
47
  "registry",
48
48
  "graphile"
49
49
  ],
50
- "gitHead": "35e09818297d7ef14a0aa1ed723d7dd0de7cb83a"
50
+ "gitHead": "030e1144acbd4e288ee74eff2ac0021ca0382ef7"
51
51
  }
package/process/chunks.js CHANGED
@@ -96,6 +96,22 @@ exports.ProcessChunks = {
96
96
  'Omit to mirror the parent table\'s text search indexes. ' +
97
97
  'Set explicitly to override (e.g. ["fulltext", "bm25"]).'
98
98
  },
99
+ // ── Entity billing scope ──────────────────────────────────────
100
+ entity_field: {
101
+ type: 'string',
102
+ format: 'column-ref',
103
+ description: 'Column on the parent table that holds (or references) the entity_id for billing scope. Forwarded to the chunking job trigger.'
104
+ },
105
+ entity_lookup: {
106
+ type: 'object',
107
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the chunking job trigger.',
108
+ properties: {
109
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
110
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
111
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
112
+ },
113
+ required: ['obj_table', 'obj_field']
114
+ },
99
115
  // ── Job trigger ────────────────────────────────────────────────
100
116
  enqueue_chunking_job: {
101
117
  type: 'boolean',
@@ -85,6 +85,22 @@ exports.ProcessExtraction = {
85
85
  }
86
86
  },
87
87
  trigger_conditions: conditions_1.triggerConditionsProperty,
88
+ // ── Entity billing scope ──────────────────────────────────────
89
+ entity_field: {
90
+ type: 'string',
91
+ format: 'column-ref',
92
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. Forwarded to the composed JobTrigger.'
93
+ },
94
+ entity_lookup: {
95
+ type: 'object',
96
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the composed JobTrigger.',
97
+ properties: {
98
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
99
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
100
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
101
+ },
102
+ required: ['obj_table', 'obj_field']
103
+ },
88
104
  // ── Job options ───────────────────────────────────────────────
89
105
  queue_name: {
90
106
  type: 'string',
@@ -92,6 +92,22 @@ exports.ProcessFileEmbedding = {
92
92
  }
93
93
  },
94
94
  trigger_conditions: conditions_1.triggerConditionsProperty,
95
+ // ── Entity billing scope ──────────────────────────────────────
96
+ entity_field: {
97
+ type: 'string',
98
+ format: 'column-ref',
99
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. Forwarded to the composed JobTrigger.'
100
+ },
101
+ entity_lookup: {
102
+ type: 'object',
103
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the composed JobTrigger.',
104
+ properties: {
105
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
106
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
107
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
108
+ },
109
+ required: ['obj_table', 'obj_field']
110
+ },
95
111
  // ── Extraction config (optional — enables extract mode) ────────
96
112
  extraction: {
97
113
  type: 'object',
@@ -99,6 +99,22 @@ exports.ProcessImageEmbedding = {
99
99
  }
100
100
  },
101
101
  trigger_conditions: conditions_1.triggerConditionsProperty,
102
+ // ── Entity billing scope ──────────────────────────────────────
103
+ entity_field: {
104
+ type: 'string',
105
+ format: 'column-ref',
106
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. Forwarded to the composed JobTrigger.'
107
+ },
108
+ entity_lookup: {
109
+ type: 'object',
110
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the composed JobTrigger.',
111
+ properties: {
112
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
113
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
114
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
115
+ },
116
+ required: ['obj_table', 'obj_field']
117
+ },
102
118
  // ── Extraction config (optional — enables extract mode) ────────
103
119
  extraction: {
104
120
  type: 'object',
@@ -104,6 +104,22 @@ exports.ProcessImageVersions = {
104
104
  }
105
105
  },
106
106
  trigger_conditions: conditions_1.triggerConditionsProperty,
107
+ // ── Entity billing scope ──────────────────────────────────────
108
+ entity_field: {
109
+ type: 'string',
110
+ format: 'column-ref',
111
+ description: 'Column on the trigger table that holds (or references) the entity_id for billing scope. Forwarded to the composed JobTrigger.'
112
+ },
113
+ entity_lookup: {
114
+ type: 'object',
115
+ description: 'FK lookup configuration for resolving entity_id through a related table. Forwarded to the composed JobTrigger.',
116
+ properties: {
117
+ obj_table: { type: 'string', description: 'Name of the related table to look up entity_id from' },
118
+ obj_schema: { type: 'string', description: 'Schema of the related table (user-facing name, optional)' },
119
+ obj_field: { type: 'string', format: 'column-ref', description: 'Column on the related table that holds the entity_id' }
120
+ },
121
+ required: ['obj_table', 'obj_field']
122
+ },
107
123
  // ── Job options ───────────────────────────────────────────────
108
124
  queue_name: {
109
125
  type: 'string',