diff --git a/packages/database-jobs/Makefile b/packages/database-jobs/Makefile
index 85442957..5bc52142 100644
--- a/packages/database-jobs/Makefile
+++ b/packages/database-jobs/Makefile
@@ -1,5 +1,5 @@
EXTENSION = pgpm-database-jobs
-DATA = sql/pgpm-database-jobs--0.22.0.sql
+DATA = sql/pgpm-database-jobs--0.26.0.sql
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/packages/database-jobs/__tests__/__snapshots__/jobs.test.ts.snap b/packages/database-jobs/__tests__/__snapshots__/jobs.test.ts.snap
index 2a9114b7..46f25498 100644
--- a/packages/database-jobs/__tests__/__snapshots__/jobs.test.ts.snap
+++ b/packages/database-jobs/__tests__/__snapshots__/jobs.test.ts.snap
@@ -5,6 +5,7 @@ exports[`scheduled jobs schedule jobs 1`] = `
"actor_id": null,
"attempts": 0,
"database_id": "5b720132-17d5-424d-9bcb-ee7b17c13d43",
+ "entity_id": null,
"id": "1",
"is_available": true,
"key": null,
diff --git a/packages/database-jobs/deploy/schemas/app_jobs/procedures/add_job.sql b/packages/database-jobs/deploy/schemas/app_jobs/procedures/add_job.sql
index 8165d50e..ccd99621 100644
--- a/packages/database-jobs/deploy/schemas/app_jobs/procedures/add_job.sql
+++ b/packages/database-jobs/deploy/schemas/app_jobs/procedures/add_job.sql
@@ -13,7 +13,8 @@ CREATE FUNCTION app_jobs.add_job (
queue_name text DEFAULT NULL,
run_at timestamptz DEFAULT now(),
max_attempts integer DEFAULT 25,
- priority integer DEFAULT 0
+ priority integer DEFAULT 0,
+ entity_id uuid DEFAULT NULL
)
RETURNS app_jobs.jobs
AS $$
@@ -31,6 +32,7 @@ BEGIN
INSERT INTO app_jobs.jobs (
database_id,
actor_id,
+ entity_id,
task_identifier,
payload,
queue_name,
@@ -41,6 +43,7 @@ BEGIN
) VALUES (
v_database_id,
v_actor_id,
+ add_job.entity_id,
identifier,
coalesce(payload, '{}'::json),
queue_name,
@@ -84,6 +87,7 @@ BEGIN
INSERT INTO app_jobs.jobs (
database_id,
actor_id,
+ entity_id,
task_identifier,
payload,
queue_name,
@@ -93,6 +97,7 @@ BEGIN
) VALUES (
v_database_id,
v_actor_id,
+ add_job.entity_id,
identifier,
payload,
queue_name,
diff --git a/packages/database-jobs/deploy/schemas/app_jobs/procedures/add_scheduled_job.sql b/packages/database-jobs/deploy/schemas/app_jobs/procedures/add_scheduled_job.sql
index c5c730c9..e9d86777 100644
--- a/packages/database-jobs/deploy/schemas/app_jobs/procedures/add_scheduled_job.sql
+++ b/packages/database-jobs/deploy/schemas/app_jobs/procedures/add_scheduled_job.sql
@@ -14,7 +14,8 @@ CREATE FUNCTION app_jobs.add_scheduled_job(
job_key text DEFAULT NULL,
queue_name text DEFAULT NULL,
max_attempts integer DEFAULT 25,
- priority integer DEFAULT 0
+ priority integer DEFAULT 0,
+ entity_id uuid DEFAULT NULL
)
RETURNS app_jobs.scheduled_jobs
AS $$
@@ -32,6 +33,7 @@ BEGIN
INSERT INTO app_jobs.scheduled_jobs (
database_id,
actor_id,
+ entity_id,
task_identifier,
payload,
queue_name,
@@ -42,6 +44,7 @@ BEGIN
) VALUES (
v_database_id,
v_actor_id,
+ add_scheduled_job.entity_id,
identifier,
coalesce(payload, '{}'::json),
queue_name,
@@ -81,6 +84,7 @@ BEGIN
INSERT INTO app_jobs.scheduled_jobs (
database_id,
actor_id,
+ entity_id,
task_identifier,
payload,
queue_name,
@@ -90,6 +94,7 @@ BEGIN
) VALUES (
v_database_id,
v_actor_id,
+ add_scheduled_job.entity_id,
identifier,
payload,
queue_name,
diff --git a/packages/database-jobs/deploy/schemas/app_jobs/procedures/run_scheduled_job.sql b/packages/database-jobs/deploy/schemas/app_jobs/procedures/run_scheduled_job.sql
index 7a4d5831..7bdb4399 100644
--- a/packages/database-jobs/deploy/schemas/app_jobs/procedures/run_scheduled_job.sql
+++ b/packages/database-jobs/deploy/schemas/app_jobs/procedures/run_scheduled_job.sql
@@ -42,6 +42,7 @@ BEGIN
INSERT INTO app_jobs.jobs (
database_id,
actor_id,
+ entity_id,
queue_name,
task_identifier,
payload,
@@ -51,6 +52,7 @@ BEGIN
) SELECT
database_id,
actor_id,
+ entity_id,
queue_name,
task_identifier,
payload,
diff --git a/packages/database-jobs/deploy/schemas/app_jobs/tables/jobs/table.sql b/packages/database-jobs/deploy/schemas/app_jobs/tables/jobs/table.sql
index 3083bb68..92933621 100644
--- a/packages/database-jobs/deploy/schemas/app_jobs/tables/jobs/table.sql
+++ b/packages/database-jobs/deploy/schemas/app_jobs/tables/jobs/table.sql
@@ -6,6 +6,7 @@ CREATE TABLE app_jobs.jobs (
id bigserial PRIMARY KEY,
database_id uuid,
actor_id uuid,
+ entity_id uuid,
queue_name text DEFAULT NULL,
task_identifier text NOT NULL,
payload json DEFAULT '{}' ::json NOT NULL,
@@ -30,6 +31,7 @@ COMMENT ON TABLE app_jobs.jobs IS 'Background job queue: each row is a pending o
COMMENT ON COLUMN app_jobs.jobs.id IS 'Auto-incrementing job identifier';
COMMENT ON COLUMN app_jobs.jobs.database_id IS 'Database this job belongs to (nullable for system-level jobs without tenant context)';
COMMENT ON COLUMN app_jobs.jobs.actor_id IS 'User who triggered this job, read from JWT claims at enqueue time';
+COMMENT ON COLUMN app_jobs.jobs.entity_id IS 'Entity (org/team) this job is scoped to for billing; NULL means platform-level (resolved via database_id → owner_id)';
COMMENT ON COLUMN app_jobs.jobs.queue_name IS 'Name of the queue this job belongs to; used for worker routing and concurrency control';
COMMENT ON COLUMN app_jobs.jobs.task_identifier IS 'Identifier for the task type (maps to a worker handler function)';
COMMENT ON COLUMN app_jobs.jobs.payload IS 'JSON payload of arguments passed to the task handler';
diff --git a/packages/database-jobs/deploy/schemas/app_jobs/tables/scheduled_jobs/table.sql b/packages/database-jobs/deploy/schemas/app_jobs/tables/scheduled_jobs/table.sql
index 74ce5584..bbf7820a 100644
--- a/packages/database-jobs/deploy/schemas/app_jobs/tables/scheduled_jobs/table.sql
+++ b/packages/database-jobs/deploy/schemas/app_jobs/tables/scheduled_jobs/table.sql
@@ -6,6 +6,7 @@ CREATE TABLE app_jobs.scheduled_jobs (
id bigserial PRIMARY KEY,
database_id uuid,
actor_id uuid,
+ entity_id uuid,
queue_name text DEFAULT NULL,
task_identifier text NOT NULL,
payload json DEFAULT '{}' ::json NOT NULL,
@@ -29,6 +30,7 @@ COMMENT ON TABLE app_jobs.scheduled_jobs IS 'Recurring/cron-style job definition
COMMENT ON COLUMN app_jobs.scheduled_jobs.id IS 'Auto-incrementing scheduled job identifier';
COMMENT ON COLUMN app_jobs.scheduled_jobs.database_id IS 'Database this scheduled job belongs to (nullable for system-level schedules without tenant context)';
COMMENT ON COLUMN app_jobs.scheduled_jobs.actor_id IS 'User who created this scheduled job, read from JWT claims at creation time';
+COMMENT ON COLUMN app_jobs.scheduled_jobs.entity_id IS 'Entity (org/team) this scheduled job is scoped to for billing; NULL means platform-level (resolved via database_id → owner_id)';
COMMENT ON COLUMN app_jobs.scheduled_jobs.queue_name IS 'Name of the queue spawned jobs are placed into';
COMMENT ON COLUMN app_jobs.scheduled_jobs.task_identifier IS 'Task type identifier for spawned jobs';
COMMENT ON COLUMN app_jobs.scheduled_jobs.payload IS 'JSON payload passed to each spawned job';
diff --git a/packages/database-jobs/package.json b/packages/database-jobs/package.json
index 1ef57643..10b0a793 100644
--- a/packages/database-jobs/package.json
+++ b/packages/database-jobs/package.json
@@ -35,4 +35,4 @@
"bugs": {
"url": "https://github.com/constructive-io/pgpm-modules/issues"
}
-}
+}
\ No newline at end of file
diff --git a/packages/database-jobs/pgpm-database-jobs.control b/packages/database-jobs/pgpm-database-jobs.control
index 3ccad9d7..d1944d01 100644
--- a/packages/database-jobs/pgpm-database-jobs.control
+++ b/packages/database-jobs/pgpm-database-jobs.control
@@ -1,6 +1,6 @@
# pgpm-database-jobs extension
comment = 'pgpm-database-jobs extension'
-default_version = '0.22.0'
+default_version = '0.26.0'
module_pathname = '$libdir/pgpm-database-jobs'
requires = 'plpgsql,pgcrypto,pgpm-verify,pgpm-jwt-claims'
relocatable = false
diff --git a/packages/database-jobs/sql/pgpm-database-jobs--0.22.0.sql b/packages/database-jobs/sql/pgpm-database-jobs--0.26.0.sql
similarity index 87%
rename from packages/database-jobs/sql/pgpm-database-jobs--0.22.0.sql
rename to packages/database-jobs/sql/pgpm-database-jobs--0.26.0.sql
index ccf7a4db..390c4b7e 100644
--- a/packages/database-jobs/sql/pgpm-database-jobs--0.22.0.sql
+++ b/packages/database-jobs/sql/pgpm-database-jobs--0.26.0.sql
@@ -53,7 +53,9 @@ $EOFCODE$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
COMMENT ON FUNCTION app_jobs.tg_add_job_with_row IS 'Useful shortcut to create a job on insert or update. Pass the task name as the trigger argument, and the record data will automatically be available on the JSON payload.';
-CREATE FUNCTION app_jobs.json_build_object_apply(arguments text[]) RETURNS pg_catalog.json AS $EOFCODE$
+CREATE FUNCTION app_jobs.json_build_object_apply(
+ arguments text[]
+) RETURNS pg_catalog.json AS $EOFCODE$
DECLARE
arg text;
_sql text;
@@ -116,6 +118,7 @@ CREATE TABLE app_jobs.scheduled_jobs (
id bigserial PRIMARY KEY,
database_id uuid,
actor_id uuid,
+ entity_id uuid,
queue_name text DEFAULT NULL,
task_identifier text NOT NULL,
payload pg_catalog.json DEFAULT '{}'::json NOT NULL,
@@ -143,6 +146,8 @@ COMMENT ON COLUMN app_jobs.scheduled_jobs.database_id IS 'Database this schedule
COMMENT ON COLUMN app_jobs.scheduled_jobs.actor_id IS 'User who created this scheduled job, read from JWT claims at creation time';
+COMMENT ON COLUMN app_jobs.scheduled_jobs.entity_id IS 'Entity (org/team) this scheduled job is scoped to for billing; NULL means platform-level (resolved via database_id → owner_id)';
+
COMMENT ON COLUMN app_jobs.scheduled_jobs.queue_name IS 'Name of the queue spawned jobs are placed into';
COMMENT ON COLUMN app_jobs.scheduled_jobs.task_identifier IS 'Task type identifier for spawned jobs';
@@ -189,6 +194,7 @@ CREATE TABLE app_jobs.jobs (
id bigserial PRIMARY KEY,
database_id uuid,
actor_id uuid,
+ entity_id uuid,
queue_name text DEFAULT NULL,
task_identifier text NOT NULL,
payload pg_catalog.json DEFAULT '{}'::json NOT NULL,
@@ -218,6 +224,8 @@ COMMENT ON COLUMN app_jobs.jobs.database_id IS 'Database this job belongs to (nu
COMMENT ON COLUMN app_jobs.jobs.actor_id IS 'User who triggered this job, read from JWT claims at enqueue time';
+COMMENT ON COLUMN app_jobs.jobs.entity_id IS 'Entity (org/team) this job is scoped to for billing; NULL means platform-level (resolved via database_id → owner_id)';
+
COMMENT ON COLUMN app_jobs.jobs.queue_name IS 'Name of the queue this job belongs to; used for worker routing and concurrency control';
COMMENT ON COLUMN app_jobs.jobs.task_identifier IS 'Identifier for the task type (maps to a worker handler function)';
@@ -366,7 +374,10 @@ CREATE INDEX job_queues_locked_by_idx ON app_jobs.job_queues (locked_by);
GRANT SELECT, INSERT, UPDATE, DELETE ON app_jobs.job_queues TO administrator;
-CREATE FUNCTION app_jobs.run_scheduled_job(id bigint, job_expiry interval DEFAULT '1 hours') RETURNS app_jobs.jobs AS $EOFCODE$
+CREATE FUNCTION app_jobs.run_scheduled_job(
+ id bigint,
+ job_expiry interval DEFAULT '1 hours'
+) RETURNS app_jobs.jobs AS $EOFCODE$
DECLARE
j app_jobs.jobs;
last_id bigint;
@@ -402,6 +413,7 @@ BEGIN
INSERT INTO app_jobs.jobs (
database_id,
actor_id,
+ entity_id,
queue_name,
task_identifier,
payload,
@@ -411,6 +423,7 @@ BEGIN
) SELECT
database_id,
actor_id,
+ entity_id,
queue_name,
task_identifier,
payload,
@@ -435,7 +448,13 @@ BEGIN
END;
$EOFCODE$ LANGUAGE plpgsql VOLATILE;
-CREATE FUNCTION app_jobs.reschedule_jobs(job_ids bigint[], run_at timestamptz DEFAULT NULL, priority int DEFAULT NULL, attempts int DEFAULT NULL, max_attempts int DEFAULT NULL) RETURNS SETOF app_jobs.jobs LANGUAGE sql AS $EOFCODE$
+CREATE FUNCTION app_jobs.reschedule_jobs(
+ job_ids bigint[],
+ run_at timestamptz DEFAULT NULL,
+ priority int DEFAULT NULL,
+ attempts int DEFAULT NULL,
+ max_attempts int DEFAULT NULL
+) RETURNS SETOF app_jobs.jobs LANGUAGE sql AS $EOFCODE$
UPDATE
app_jobs.jobs
SET
@@ -451,7 +470,10 @@ CREATE FUNCTION app_jobs.reschedule_jobs(job_ids bigint[], run_at timestamptz DE
*;
$EOFCODE$;
-CREATE FUNCTION app_jobs.release_scheduled_jobs(worker_id text, ids bigint[] DEFAULT NULL) RETURNS void AS $EOFCODE$
+CREATE FUNCTION app_jobs.release_scheduled_jobs(
+ worker_id text,
+ ids bigint[] DEFAULT NULL
+) RETURNS void AS $EOFCODE$
DECLARE
BEGIN
-- clear the scheduled job
@@ -467,7 +489,9 @@ BEGIN
END;
$EOFCODE$ LANGUAGE plpgsql VOLATILE;
-CREATE FUNCTION app_jobs.release_jobs(worker_id text) RETURNS void AS $EOFCODE$
+CREATE FUNCTION app_jobs.release_jobs(
+ worker_id text
+) RETURNS void AS $EOFCODE$
DECLARE
BEGIN
-- clear the job
@@ -490,7 +514,10 @@ BEGIN
END;
$EOFCODE$ LANGUAGE plpgsql VOLATILE;
-CREATE FUNCTION app_jobs.permanently_fail_jobs(job_ids bigint[], error_message text DEFAULT NULL) RETURNS SETOF app_jobs.jobs LANGUAGE sql AS $EOFCODE$
+CREATE FUNCTION app_jobs.permanently_fail_jobs(
+ job_ids bigint[],
+ error_message text DEFAULT NULL
+) RETURNS SETOF app_jobs.jobs LANGUAGE sql AS $EOFCODE$
UPDATE
app_jobs.jobs
SET
@@ -504,7 +531,10 @@ CREATE FUNCTION app_jobs.permanently_fail_jobs(job_ids bigint[], error_message t
*;
$EOFCODE$;
-CREATE FUNCTION app_jobs.get_scheduled_job(worker_id text, task_identifiers text[] DEFAULT NULL) RETURNS app_jobs.scheduled_jobs LANGUAGE plpgsql AS $EOFCODE$
+CREATE FUNCTION app_jobs.get_scheduled_job(
+ worker_id text,
+ task_identifiers text[] DEFAULT NULL
+) RETURNS app_jobs.scheduled_jobs LANGUAGE plpgsql AS $EOFCODE$
DECLARE
v_job_id bigint;
v_row app_jobs.scheduled_jobs;
@@ -556,7 +586,11 @@ BEGIN
END;
$EOFCODE$;
-CREATE FUNCTION app_jobs.get_job(worker_id text, task_identifiers text[] DEFAULT NULL, job_expiry interval DEFAULT '4 hours') RETURNS app_jobs.jobs LANGUAGE plpgsql AS $EOFCODE$
+CREATE FUNCTION app_jobs.get_job(
+ worker_id text,
+ task_identifiers text[] DEFAULT NULL,
+ job_expiry interval DEFAULT '4 hours'
+) RETURNS app_jobs.jobs LANGUAGE plpgsql AS $EOFCODE$
DECLARE
v_job_id bigint;
v_queue_name text;
@@ -611,7 +645,11 @@ BEGIN
END;
$EOFCODE$;
-CREATE FUNCTION app_jobs.fail_job(worker_id text, job_id bigint, error_message text) RETURNS app_jobs.jobs LANGUAGE plpgsql STRICT AS $EOFCODE$
+CREATE FUNCTION app_jobs.fail_job(
+ worker_id text,
+ job_id bigint,
+ error_message text
+) RETURNS app_jobs.jobs LANGUAGE plpgsql STRICT AS $EOFCODE$
DECLARE
v_row app_jobs.jobs;
BEGIN
@@ -641,7 +679,9 @@ BEGIN
END;
$EOFCODE$;
-CREATE FUNCTION app_jobs.complete_jobs(job_ids bigint[]) RETURNS SETOF app_jobs.jobs LANGUAGE sql AS $EOFCODE$
+CREATE FUNCTION app_jobs.complete_jobs(
+ job_ids bigint[]
+) RETURNS SETOF app_jobs.jobs LANGUAGE sql AS $EOFCODE$
DELETE FROM app_jobs.jobs
WHERE id = ANY (job_ids)
AND (locked_by IS NULL
@@ -650,7 +690,10 @@ CREATE FUNCTION app_jobs.complete_jobs(job_ids bigint[]) RETURNS SETOF app_jobs.
*;
$EOFCODE$;
-CREATE FUNCTION app_jobs.complete_job(worker_id text, job_id bigint) RETURNS app_jobs.jobs LANGUAGE plpgsql AS $EOFCODE$
+CREATE FUNCTION app_jobs.complete_job(
+ worker_id text,
+ job_id bigint
+) RETURNS app_jobs.jobs LANGUAGE plpgsql AS $EOFCODE$
DECLARE
v_row app_jobs.jobs;
BEGIN
@@ -672,7 +715,16 @@ BEGIN
END;
$EOFCODE$;
-CREATE FUNCTION app_jobs.add_scheduled_job(identifier text, payload pg_catalog.json DEFAULT '{}'::json, schedule_info pg_catalog.json DEFAULT '{}'::json, job_key text DEFAULT NULL, queue_name text DEFAULT NULL, max_attempts int DEFAULT 25, priority int DEFAULT 0) RETURNS app_jobs.scheduled_jobs AS $EOFCODE$
+CREATE FUNCTION app_jobs.add_scheduled_job(
+ identifier text,
+ payload pg_catalog.json DEFAULT '{}'::json,
+ schedule_info pg_catalog.json DEFAULT '{}'::json,
+ job_key text DEFAULT NULL,
+ queue_name text DEFAULT NULL,
+ max_attempts int DEFAULT 25,
+ priority int DEFAULT 0,
+ entity_id uuid DEFAULT NULL
+) RETURNS app_jobs.scheduled_jobs AS $EOFCODE$
DECLARE
v_job app_jobs.scheduled_jobs;
v_database_id uuid;
@@ -687,6 +739,7 @@ BEGIN
INSERT INTO app_jobs.scheduled_jobs (
database_id,
actor_id,
+ entity_id,
task_identifier,
payload,
queue_name,
@@ -697,6 +750,7 @@ BEGIN
) VALUES (
v_database_id,
v_actor_id,
+ add_scheduled_job.entity_id,
identifier,
coalesce(payload, '{}'::json),
queue_name,
@@ -736,6 +790,7 @@ BEGIN
INSERT INTO app_jobs.scheduled_jobs (
database_id,
actor_id,
+ entity_id,
task_identifier,
payload,
queue_name,
@@ -745,6 +800,7 @@ BEGIN
) VALUES (
v_database_id,
v_actor_id,
+ add_scheduled_job.entity_id,
identifier,
payload,
queue_name,
@@ -756,7 +812,16 @@ BEGIN
END;
$EOFCODE$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
-CREATE FUNCTION app_jobs.add_job(identifier text, payload pg_catalog.json DEFAULT '{}'::json, job_key text DEFAULT NULL, queue_name text DEFAULT NULL, run_at timestamptz DEFAULT now(), max_attempts int DEFAULT 25, priority int DEFAULT 0) RETURNS app_jobs.jobs AS $EOFCODE$
+CREATE FUNCTION app_jobs.add_job(
+ identifier text,
+ payload pg_catalog.json DEFAULT '{}'::json,
+ job_key text DEFAULT NULL,
+ queue_name text DEFAULT NULL,
+ run_at timestamptz DEFAULT now(),
+ max_attempts int DEFAULT 25,
+ priority int DEFAULT 0,
+ entity_id uuid DEFAULT NULL
+) RETURNS app_jobs.jobs AS $EOFCODE$
DECLARE
v_job app_jobs.jobs;
v_database_id uuid;
@@ -771,6 +836,7 @@ BEGIN
INSERT INTO app_jobs.jobs (
database_id,
actor_id,
+ entity_id,
task_identifier,
payload,
queue_name,
@@ -781,6 +847,7 @@ BEGIN
) VALUES (
v_database_id,
v_actor_id,
+ add_job.entity_id,
identifier,
coalesce(payload, '{}'::json),
queue_name,
@@ -824,6 +891,7 @@ BEGIN
INSERT INTO app_jobs.jobs (
database_id,
actor_id,
+ entity_id,
task_identifier,
payload,
queue_name,
@@ -833,6 +901,7 @@ BEGIN
) VALUES (
v_database_id,
v_actor_id,
+ add_job.entity_id,
identifier,
payload,
queue_name,
@@ -846,7 +915,9 @@ BEGIN
END;
$EOFCODE$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
-CREATE FUNCTION app_jobs.remove_job(job_key text) RETURNS app_jobs.jobs LANGUAGE plpgsql STRICT AS $EOFCODE$
+CREATE FUNCTION app_jobs.remove_job(
+ job_key text
+) RETURNS app_jobs.jobs LANGUAGE plpgsql STRICT AS $EOFCODE$
DECLARE
v_job app_jobs.jobs;
BEGIN
@@ -871,7 +942,9 @@ BEGIN
END;
$EOFCODE$;
-CREATE FUNCTION app_jobs.force_unlock_workers(worker_ids text[]) RETURNS void LANGUAGE sql VOLATILE AS $EOFCODE$
+CREATE FUNCTION app_jobs.force_unlock_workers(
+ worker_ids text[]
+) RETURNS void LANGUAGE sql VOLATILE AS $EOFCODE$
UPDATE app_jobs.jobs
SET locked_at = NULL, locked_by = NULL
WHERE locked_by = ANY (worker_ids);
diff --git a/packages/metaschema-modules/Makefile b/packages/metaschema-modules/Makefile
index 83482a99..9f0f6cf5 100644
--- a/packages/metaschema-modules/Makefile
+++ b/packages/metaschema-modules/Makefile
@@ -1,5 +1,5 @@
EXTENSION = metaschema-modules
-DATA = sql/metaschema-modules--0.15.5.sql
+DATA = sql/metaschema-modules--0.26.0.sql
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/packages/metaschema-modules/__tests__/__snapshots__/modules.test.ts.snap b/packages/metaschema-modules/__tests__/__snapshots__/modules.test.ts.snap
index b6dfa157..2cedd053 100644
--- a/packages/metaschema-modules/__tests__/__snapshots__/modules.test.ts.snap
+++ b/packages/metaschema-modules/__tests__/__snapshots__/modules.test.ts.snap
@@ -115,7 +115,7 @@ exports[`db_meta_modules should verify module table structures have database_id
exports[`db_meta_modules should verify module tables have proper foreign key relationships 1`] = `
{
- "constraintCount": 394602,
+ "constraintCount": 394604,
"foreignTables": [
"database",
"field",
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/agent_module/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/agent_module/table.sql
index bc1a2ffe..2f53b0f2 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/agent_module/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/agent_module/table.sql
@@ -41,6 +41,20 @@ CREATE TABLE metaschema_modules_public.agent_module (
-- Configurable security policies (NULL = use defaults based on membership_type)
policies jsonb NULL,
+ -- Knowledge RAG config (dimensions, chunk_size, chunk_strategy, search_indexes, etc.)
+ -- NULL = use sensible defaults (768d, 1000 chars, paragraph, bm25)
+ knowledge_config jsonb NULL,
+
+ -- Custom RLS policies for knowledge table (provisions.knowledge.policies)
+ -- NULL = use defaults (AuthzEntityMembership or AuthzAppMembership)
+ knowledge_policies jsonb NULL,
+
+ -- Per-table provisions overrides from blueprint config.
+ -- Keys are table keys (thread, message, task, prompt, knowledge).
+ -- When a key is present, the module trigger skips default security for that table;
+ -- secure_table_provision applies the custom grants/policies instead.
+ provisions jsonb NULL,
+
-- Constraints
CONSTRAINT agent_module_db_fkey FOREIGN KEY (database_id) REFERENCES metaschema_public.database (id) ON DELETE CASCADE,
CONSTRAINT agent_module_schema_fkey FOREIGN KEY (schema_id) REFERENCES metaschema_public.schema (id) ON DELETE CASCADE,
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/billing_module/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/billing_module/table.sql
index f13957e9..00dcdef9 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/billing_module/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/billing_module/table.sql
@@ -31,6 +31,10 @@ CREATE TABLE metaschema_modules_public.billing_module (
meter_credits_table_id uuid NOT NULL DEFAULT uuid_nil(),
meter_credits_table_name text NOT NULL DEFAULT '',
+ -- Meter sources table: maps billing meters to typed daily summary table columns
+ meter_sources_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ meter_sources_table_name text NOT NULL DEFAULT '',
+
-- Generated functions
record_usage_function text NOT NULL DEFAULT '',
@@ -44,6 +48,7 @@ CREATE TABLE metaschema_modules_public.billing_module (
CONSTRAINT ledger_table_fkey FOREIGN KEY (ledger_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
CONSTRAINT balances_table_fkey FOREIGN KEY (balances_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
CONSTRAINT meter_credits_table_fkey FOREIGN KEY (meter_credits_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
+ CONSTRAINT meter_sources_table_fkey FOREIGN KEY (meter_sources_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
CONSTRAINT billing_module_database_id_unique UNIQUE (database_id)
);
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/entity_type_provision/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/entity_type_provision/table.sql
index ec8141cf..ebbe5dd3 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/entity_type_provision/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/entity_type_provision/table.sql
@@ -47,8 +47,6 @@ CREATE TABLE metaschema_modules_public.entity_type_provision (
has_levels boolean NOT NULL DEFAULT false,
- has_storage boolean NOT NULL DEFAULT false,
-
has_invites boolean NOT NULL DEFAULT false,
has_invite_achievements boolean NOT NULL DEFAULT false,
@@ -56,8 +54,9 @@ CREATE TABLE metaschema_modules_public.entity_type_provision (
-- =========================================================================
-- Storage configuration: JSON array of storage module definitions.
-- Each element provisions a separate storage module with its own tables,
- -- RLS policies, and feature flags. Only used when has_storage = true.
- -- NULL = provision a single default storage module with default settings.
+ -- RLS policies, and feature flags. Presence triggers provisioning
+ -- (same inference model as namespaces, functions, agents).
+ -- NULL = do not provision. '[{}]' = provision one default storage module.
-- =========================================================================
storage jsonb DEFAULT NULL,
@@ -126,6 +125,8 @@ CREATE TABLE metaschema_modules_public.entity_type_provision (
out_namespaces_table_id uuid DEFAULT NULL,
+ out_namespace_events_table_id uuid DEFAULT NULL,
+
out_function_module_id uuid DEFAULT NULL,
out_definitions_table_id uuid DEFAULT NULL,
@@ -238,20 +239,14 @@ COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.has_levels IS
Levels provide gamification/achievement tracking for members.
When true, creates level steps, achievements, and level tables with security.';
-COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.has_storage IS
- 'Whether to provision storage_module for this type. Defaults to false.
- When true, creates {prefix}_buckets and {prefix}_files tables
- with entity-scoped RLS (AuthzEntityMembership) using the entity''s membership_type.
- Storage tables get owner_id FK to the entity table, so files are owned by the entity.';
-
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.has_invites IS
'Whether to provision invites_module for this type. Defaults to false.
When true, the trigger inserts a row into invites_module which in turn
(via insert_invites_module BEFORE INSERT) creates {prefix}_invites and
{prefix}_claimed_invites tables plus the submit_{prefix}_invite_code() function.
- Symmetric counterpart of has_storage. Re-provisioning is idempotent: the
- UNIQUE (database_id, membership_type) constraint on invites_module combined with
- ON CONFLICT DO NOTHING in the fan-out makes repeated INSERTs safe.';
+ Re-provisioning is idempotent: the UNIQUE (database_id, membership_type) constraint
+ on invites_module combined with ON CONFLICT DO NOTHING in the fan-out makes
+ repeated INSERTs safe.';
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.has_invite_achievements IS
'Whether to auto-attach an EventTracker to the claimed_invites table for invite-based
@@ -330,10 +325,11 @@ COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_installed_
Populated by the trigger. Useful for verifying which modules were provisioned.';
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.storage IS
- 'Optional JSON array of storage module definitions. Each element provisions a separate
- storage module with its own tables ({prefix}_{storage_key}_buckets/files), RLS policies,
- and feature flags. Only used when has_storage = true; ignored otherwise.
- NULL = provision a single default storage module with all defaults.
+ 'Optional JSON array of storage module definitions. Presence triggers provisioning
+ (same inference model as namespaces, functions, agents).
+ Each element provisions a separate storage module with its own tables
+ ({prefix}_{storage_key}_buckets/files), RLS policies, and feature flags.
+ NULL = do not provision storage. ''[{}]'' = provision one default storage module.
Each array element recognizes (all optional):
- storage_key (text) module discriminator, max 16 chars, lowercase snake_case.
Defaults to ''default'' (omitted from table names).
@@ -360,13 +356,13 @@ COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.storage IS
storage := ''[{"has_path_shares": true, "buckets": [{"name": "documents"}]}, {"storage_key": "fn", "has_custom_keys": true, "buckets": [{"name": "functions"}]}]''::jsonb';
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_storage_module_id IS
- 'Output: the UUID of the storage_module row created for this entity type. Populated by the trigger when has_storage=true.';
+ 'Output: the UUID of the storage_module row created for this entity type. Populated by the trigger when storage is non-NULL and non-empty.';
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_buckets_table_id IS
- 'Output: the UUID of the generated buckets table (e.g. data_room_buckets). Populated by the trigger when has_storage=true.';
+ 'Output: the UUID of the generated buckets table (e.g. data_room_buckets). Populated by the trigger when storage is non-NULL and non-empty.';
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_files_table_id IS
- 'Output: the UUID of the generated files table (e.g. data_room_files). Populated by the trigger when has_storage=true.';
+ 'Output: the UUID of the generated files table (e.g. data_room_files). Populated by the trigger when storage is non-NULL and non-empty.';
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_invites_module_id IS
'Output: the UUID of the invites_module row created for this entity type. Populated by the trigger when has_invites=true.
@@ -415,4 +411,8 @@ COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_namespaces
'Output: the UUID of the generated namespaces table (e.g. data_room_namespaces).
Populated by the trigger when namespaces is non-NULL. NULL otherwise.';
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_namespace_events_table_id IS
+ 'Output: the UUID of the generated namespace_events partitioned table (e.g. data_room_namespace_events).
+ Monthly partitioned, 12-month retention. Populated by the trigger when namespaces is non-NULL. NULL otherwise.';
+
COMMIT;
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/function_module/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/function_module/table.sql
index ad638a06..c4d72345 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/function_module/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/function_module/table.sql
@@ -42,6 +42,12 @@ CREATE TABLE metaschema_modules_public.function_module (
-- {"$type": "AuthzEntityMembership", "privileges": ["select", "update"], "data": {...}}
policies jsonb NULL,
+ -- Per-table provisions overrides from blueprint config.
+ -- Keys are table keys (definitions, invocations, execution_logs).
+ -- When a key is present, the module trigger skips default security for that table;
+ -- secure_table_provision applies the custom grants/policies instead.
+ provisions jsonb NULL,
+
-- Constraints
CONSTRAINT function_module_db_fkey FOREIGN KEY (database_id) REFERENCES metaschema_public.database (id) ON DELETE CASCADE,
CONSTRAINT function_module_schema_fkey FOREIGN KEY (schema_id) REFERENCES metaschema_public.schema (id) ON DELETE CASCADE,
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/graph_module/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/graph_module/table.sql
index 72f0683e..90f6101c 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/graph_module/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/graph_module/table.sql
@@ -27,7 +27,7 @@ CREATE TABLE metaschema_modules_public.graph_module (
-- Generated table IDs (populated by BEFORE INSERT trigger)
graphs_table_id uuid NOT NULL DEFAULT uuid_nil(),
executions_table_id uuid NOT NULL DEFAULT uuid_nil(),
- exec_object_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ outputs_table_id uuid NOT NULL DEFAULT uuid_nil(),
-- API routing (get-or-create: if set, schema is added to this API; if NULL, no API is added)
api_name text,
@@ -45,6 +45,12 @@ CREATE TABLE metaschema_modules_public.graph_module (
-- {"$type": "AuthzEntityMembership", "privileges": ["select", "update"], "data": {...}}
policies jsonb NULL,
+ -- Per-table provisions overrides from blueprint config.
+ -- Keys are table keys (graphs, executions, outputs).
+ -- When a key is present, the module trigger skips default security for that table;
+ -- secure_table_provision applies the custom grants/policies instead.
+ provisions jsonb NULL,
+
-- Timestamps
created_at timestamptz NOT NULL DEFAULT now(),
@@ -55,7 +61,7 @@ CREATE TABLE metaschema_modules_public.graph_module (
CONSTRAINT merkle_store_fkey FOREIGN KEY (merkle_store_module_id) REFERENCES metaschema_modules_public.merkle_store_module (id) ON DELETE CASCADE,
CONSTRAINT graphs_table_fkey FOREIGN KEY (graphs_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
CONSTRAINT executions_table_fkey FOREIGN KEY (executions_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
- CONSTRAINT exec_object_table_fkey FOREIGN KEY (exec_object_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
+ CONSTRAINT outputs_table_fkey FOREIGN KEY (outputs_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
CONSTRAINT graph_module_entity_table_fkey FOREIGN KEY (entity_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
-- Only one graph module per database + merkle store combination
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/inference_log_module/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/inference_log_module/table.sql
index c12f26e9..fa4a830f 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/inference_log_module/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/inference_log_module/table.sql
@@ -21,9 +21,14 @@ CREATE TABLE metaschema_modules_public.inference_log_module (
-- Partition lifecycle configuration
"interval" text NOT NULL DEFAULT '1 month',
- retention text NULL,
+ retention text NOT NULL DEFAULT '12 months',
premake int NOT NULL DEFAULT 2,
+ -- Scope configuration: 'app' = per-app usage (actor_id RLS), 'platform' = tenant metering (database_id RLS)
+ scope text NOT NULL DEFAULT 'app',
+ actor_fk_table_id uuid NULL,
+ entity_fk_table_id uuid NULL,
+
prefix text NULL,
CONSTRAINT db_fkey FOREIGN KEY (database_id) REFERENCES metaschema_public.database (id) ON DELETE CASCADE,
@@ -31,7 +36,7 @@ CREATE TABLE metaschema_modules_public.inference_log_module (
CONSTRAINT private_schema_fkey FOREIGN KEY (private_schema_id) REFERENCES metaschema_public.schema (id) ON DELETE CASCADE,
CONSTRAINT inference_log_table_fkey FOREIGN KEY (inference_log_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
CONSTRAINT usage_daily_table_fkey FOREIGN KEY (usage_daily_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
- CONSTRAINT inference_log_module_database_id_unique UNIQUE (database_id)
+ CONSTRAINT inference_log_module_database_id_prefix_unique UNIQUE NULLS NOT DISTINCT (database_id, prefix)
);
CREATE INDEX inference_log_module_database_id_idx ON metaschema_modules_public.inference_log_module ( database_id );
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/namespace_module/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/namespace_module/table.sql
index 3aeb7344..6e0c2f8b 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/namespace_module/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/namespace_module/table.sql
@@ -16,11 +16,13 @@ CREATE TABLE metaschema_modules_public.namespace_module (
public_schema_name text,
private_schema_name text,
- -- Generated table ID (populated by the generator)
+ -- Generated table IDs (populated by the generator)
namespaces_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ namespace_events_table_id uuid NOT NULL DEFAULT uuid_nil(),
- -- Table name (input to the generator)
+ -- Table names (input to the generator)
namespaces_table_name text NOT NULL DEFAULT 'namespaces',
+ namespace_events_table_name text NOT NULL DEFAULT 'namespace_events',
-- API routing (get-or-create: if set, schema is added to this API; if NULL, no API is added)
api_name text,
@@ -38,11 +40,18 @@ CREATE TABLE metaschema_modules_public.namespace_module (
-- {"$type": "AuthzEntityMembership", "privileges": ["select", "update"], "data": {...}}
policies jsonb NULL,
+ -- Per-table provisions overrides from blueprint config.
+ -- Keys are table keys (namespaces, namespace_events).
+ -- When a key is present, the module trigger skips default security for that table;
+ -- secure_table_provision applies the custom grants/policies instead.
+ provisions jsonb NULL,
+
-- Constraints
CONSTRAINT namespace_module_db_fkey FOREIGN KEY (database_id) REFERENCES metaschema_public.database (id) ON DELETE CASCADE,
CONSTRAINT namespace_module_schema_fkey FOREIGN KEY (schema_id) REFERENCES metaschema_public.schema (id) ON DELETE CASCADE,
CONSTRAINT namespace_module_private_schema_fkey FOREIGN KEY (private_schema_id) REFERENCES metaschema_public.schema (id) ON DELETE CASCADE,
CONSTRAINT namespace_module_namespaces_table_fkey FOREIGN KEY (namespaces_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
+ CONSTRAINT namespace_module_events_table_fkey FOREIGN KEY (namespace_events_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE,
CONSTRAINT namespace_module_entity_table_fkey FOREIGN KEY (entity_table_id) REFERENCES metaschema_public.table (id) ON DELETE CASCADE
);
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/storage_module/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/storage_module/table.sql
index 7e80b5f1..4a1611a8 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/storage_module/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/storage_module/table.sql
@@ -35,12 +35,11 @@ CREATE TABLE metaschema_modules_public.storage_module (
-- {"$type": "AuthzEntityMembership", "privileges": ["select", "update"], "data": {...}}
policies jsonb NULL,
- -- Per-table skip list for apply_storage_security default policies.
- -- When a table role name ("files", "buckets") is listed here,
- -- apply_storage_security skips its default policies for that table.
- -- Used by entity_type_provision to mark tables whose policies are
- -- supplied via provisions (secure_table_provision).
- skip_default_policy_tables text[] NOT NULL DEFAULT '{}',
+ -- Per-table provisions overrides from blueprint config.
+ -- Keys are table keys (files, buckets).
+ -- When a key is present, the module trigger skips default security for that table;
+ -- secure_table_provision applies the custom grants/policies instead.
+ provisions jsonb NULL,
-- Entity table for RLS (NULL for app-level storage, entity table for entity-scoped storage)
entity_table_id uuid NULL,
diff --git a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/user_auth_module/table.sql b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/user_auth_module/table.sql
index 7952b72e..d4608cb0 100644
--- a/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/user_auth_module/table.sql
+++ b/packages/metaschema-modules/deploy/schemas/metaschema_modules_public/tables/user_auth_module/table.sql
@@ -19,7 +19,7 @@ CREATE TABLE metaschema_modules_public.user_auth_module (
session_credentials_table_id uuid NOT NULL DEFAULT uuid_nil(),
audits_table_id uuid NOT NULL DEFAULT uuid_nil(),
- audits_table_name text NOT NULL DEFAULT 'audit_logs',
+ audits_table_name text NOT NULL DEFAULT 'audit_log_auth',
-- api_id uuid NOT NULL REFERENCES services_public.apis (id),
diff --git a/packages/metaschema-modules/metaschema-modules.control b/packages/metaschema-modules/metaschema-modules.control
index e0ea0b88..5afb7d6d 100644
--- a/packages/metaschema-modules/metaschema-modules.control
+++ b/packages/metaschema-modules/metaschema-modules.control
@@ -1,6 +1,6 @@
# metaschema-modules extension
comment = 'metaschema-modules extension'
-default_version = '0.15.5'
+default_version = '0.26.0'
module_pathname = '$libdir/metaschema-modules'
requires = 'plpgsql,uuid-ossp,metaschema-schema,services,pgpm-verify'
relocatable = false
diff --git a/packages/metaschema-modules/package.json b/packages/metaschema-modules/package.json
index 4f2ae229..a7456bba 100644
--- a/packages/metaschema-modules/package.json
+++ b/packages/metaschema-modules/package.json
@@ -35,4 +35,4 @@
"bugs": {
"url": "https://github.com/constructive-io/pgpm-modules/issues"
}
-}
+}
\ No newline at end of file
diff --git a/packages/metaschema-modules/sql/metaschema-modules--0.15.5.sql b/packages/metaschema-modules/sql/metaschema-modules--0.26.0.sql
similarity index 83%
rename from packages/metaschema-modules/sql/metaschema-modules--0.15.5.sql
rename to packages/metaschema-modules/sql/metaschema-modules--0.26.0.sql
index 0c7cf0dd..1ade7ee4 100644
--- a/packages/metaschema-modules/sql/metaschema-modules--0.15.5.sql
+++ b/packages/metaschema-modules/sql/metaschema-modules--0.26.0.sql
@@ -894,7 +894,7 @@ CREATE TABLE metaschema_modules_public.user_auth_module (
sessions_table_id uuid NOT NULL DEFAULT uuid_nil(),
session_credentials_table_id uuid NOT NULL DEFAULT uuid_nil(),
audits_table_id uuid NOT NULL DEFAULT uuid_nil(),
- audits_table_name text NOT NULL DEFAULT 'audit_logs',
+ audits_table_name text NOT NULL DEFAULT 'audit_log_auth',
sign_in_function text NOT NULL DEFAULT 'sign_in',
sign_up_function text NOT NULL DEFAULT 'sign_up',
sign_out_function text NOT NULL DEFAULT 'sign_out',
@@ -1459,7 +1459,7 @@ CREATE TABLE metaschema_modules_public.storage_module (
membership_type int DEFAULT NULL,
storage_key text NOT NULL DEFAULT 'default',
policies jsonb NULL,
- skip_default_policy_tables text[] NOT NULL DEFAULT '{}',
+ provisions jsonb NULL,
entity_table_id uuid NULL,
endpoint text NULL,
public_url_prefix text NULL,
@@ -1532,10 +1532,13 @@ CREATE TABLE metaschema_modules_public.entity_type_provision (
has_limits boolean NOT NULL DEFAULT false,
has_profiles boolean NOT NULL DEFAULT false,
has_levels boolean NOT NULL DEFAULT false,
- has_storage boolean NOT NULL DEFAULT false,
has_invites boolean NOT NULL DEFAULT false,
has_invite_achievements boolean NOT NULL DEFAULT false,
- storage_config jsonb DEFAULT NULL,
+ storage jsonb DEFAULT NULL,
+ namespaces jsonb DEFAULT NULL,
+ functions jsonb DEFAULT NULL,
+ graphs jsonb DEFAULT NULL,
+ agents jsonb DEFAULT NULL,
skip_entity_policies boolean NOT NULL DEFAULT false,
table_provision jsonb DEFAULT NULL,
out_membership_type int DEFAULT NULL,
@@ -1547,6 +1550,16 @@ CREATE TABLE metaschema_modules_public.entity_type_provision (
out_files_table_id uuid DEFAULT NULL,
out_path_shares_table_id uuid DEFAULT NULL,
out_invites_module_id uuid DEFAULT NULL,
+ out_namespace_module_id uuid DEFAULT NULL,
+ out_namespaces_table_id uuid DEFAULT NULL,
+ out_namespace_events_table_id uuid DEFAULT NULL,
+ out_function_module_id uuid DEFAULT NULL,
+ out_definitions_table_id uuid DEFAULT NULL,
+ out_invocations_table_id uuid DEFAULT NULL,
+ out_execution_logs_table_id uuid DEFAULT NULL,
+ out_graph_module_id uuid DEFAULT NULL,
+ out_graphs_table_id uuid DEFAULT NULL,
+ out_agent_module_id uuid DEFAULT NULL,
CONSTRAINT entity_type_provision_unique_prefix
UNIQUE (database_id, prefix),
CONSTRAINT entity_type_provision_db_fkey
@@ -1608,18 +1621,13 @@ COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.has_levels IS
Levels provide gamification/achievement tracking for members.
When true, creates level steps, achievements, and level tables with security.';
-COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.has_storage IS 'Whether to provision storage_module for this type. Defaults to false.
- When true, creates {prefix}_buckets and {prefix}_files tables
- with entity-scoped RLS (AuthzEntityMembership) using the entity''s membership_type.
- Storage tables get owner_id FK to the entity table, so files are owned by the entity.';
-
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.has_invites IS 'Whether to provision invites_module for this type. Defaults to false.
When true, the trigger inserts a row into invites_module which in turn
(via insert_invites_module BEFORE INSERT) creates {prefix}_invites and
{prefix}_claimed_invites tables plus the submit_{prefix}_invite_code() function.
- Symmetric counterpart of has_storage. Re-provisioning is idempotent: the
- UNIQUE (database_id, membership_type) constraint on invites_module combined with
- ON CONFLICT DO NOTHING in the fan-out makes repeated INSERTs safe.';
+ Re-provisioning is idempotent: the UNIQUE (database_id, membership_type) constraint
+ on invites_module combined with ON CONFLICT DO NOTHING in the fan-out makes
+ repeated INSERTs safe.';
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.has_invite_achievements IS 'Whether to auto-attach an EventTracker to the claimed_invites table for invite-based
achievements. Defaults to false. Requires has_invites=true AND has_levels=true.
@@ -1682,10 +1690,11 @@ COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_entity_tab
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_installed_modules IS 'Output: array of installed module labels (e.g. ARRAY[''permissions_module:data_room'', ''memberships_module:data_room'', ''invites_module:data_room'']).
Populated by the trigger. Useful for verifying which modules were provisioned.';
-COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.storage_config IS 'Optional JSON array of storage module definitions. Each element provisions a separate
- storage module with its own tables ({prefix}_{storage_key}_buckets/files), RLS policies,
- and feature flags. Only used when has_storage = true; ignored otherwise.
- NULL = provision a single default storage module with all defaults.
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.storage IS 'Optional JSON array of storage module definitions. Presence triggers provisioning
+ (same inference model as namespaces, functions, agents).
+ Each element provisions a separate storage module with its own tables
+ ({prefix}_{storage_key}_buckets/files), RLS policies, and feature flags.
+ NULL = do not provision storage. ''[{}]'' = provision one default storage module.
Each array element recognizes (all optional):
- storage_key (text) module discriminator, max 16 chars, lowercase snake_case.
Defaults to ''default'' (omitted from table names).
@@ -1707,20 +1716,60 @@ COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.storage_config
- provisions (jsonb object) per-table customization keyed by "files" or "buckets".
Each value: { nodes, fields, grants, use_rls, policies }.
Example (single module, backward compat):
- storage_config := ''[{"buckets": [{"name": "documents"}]}]''::jsonb
+ storage := ''[{"buckets": [{"name": "documents"}]}]''::jsonb
Example (multi-module):
- storage_config := ''[{"has_path_shares": true, "buckets": [{"name": "documents"}]}, {"storage_key": "fn", "has_custom_keys": true, "buckets": [{"name": "functions"}]}]''::jsonb';
+ storage := ''[{"has_path_shares": true, "buckets": [{"name": "documents"}]}, {"storage_key": "fn", "has_custom_keys": true, "buckets": [{"name": "functions"}]}]''::jsonb';
-COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_storage_module_id IS 'Output: the UUID of the storage_module row created for this entity type. Populated by the trigger when has_storage=true.';
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_storage_module_id IS 'Output: the UUID of the storage_module row created for this entity type. Populated by the trigger when storage is non-NULL and non-empty.';
-COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_buckets_table_id IS 'Output: the UUID of the generated buckets table (e.g. data_room_buckets). Populated by the trigger when has_storage=true.';
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_buckets_table_id IS 'Output: the UUID of the generated buckets table (e.g. data_room_buckets). Populated by the trigger when storage is non-NULL and non-empty.';
-COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_files_table_id IS 'Output: the UUID of the generated files table (e.g. data_room_files). Populated by the trigger when has_storage=true.';
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_files_table_id IS 'Output: the UUID of the generated files table (e.g. data_room_files). Populated by the trigger when storage is non-NULL and non-empty.';
COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_invites_module_id IS 'Output: the UUID of the invites_module row created for this entity type. Populated by the trigger when has_invites=true.
NULL when has_invites=false, or when re-provisioning hits ON CONFLICT DO NOTHING
(i.e. the invites_module row was created in a previous run).';
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.namespaces IS 'Optional JSON array of namespace module definitions. Presence triggers provisioning.
+ NULL = do not provision namespaces. ''[{}]'' = provision one default namespace module.
+ Each element recognizes (all optional):
+ - key (text) module discriminator. Defaults to ''default''.
+ - policies (jsonb array) RLS policy overrides. NULL = apply defaults from apply_namespace_security().
+ Creates {prefix}_namespaces (or {prefix}_{key}_namespaces for non-default keys)
+ with entity-scoped RLS (AuthzEntityMembership) and a rename proxy trigger.
+ Registers manage_namespaces permission bit on first provision.
+ Example: namespaces := ''[{}]''::jsonb';
+
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.functions IS 'Optional JSON array of function module definitions. Presence triggers provisioning.
+ NULL = do not provision functions. ''[{}]'' = provision one default function module.
+ Each element recognizes (all optional):
+ - key (text) module discriminator. Defaults to ''default''.
+ - policies (jsonb array) RLS policy overrides. NULL = apply defaults from apply_function_security().
+ Creates {prefix}_function_definitions (or {prefix}_{key}_function_definitions for non-default keys)
+ with entity-scoped RLS and a job trigger dispatching function:provision tasks.
+ Registers manage_functions + invoke_functions permission bits on first provision.
+ Example: functions := ''[{}]''::jsonb';
+
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.graphs IS 'Optional JSON array of graph module definitions. Presence triggers provisioning.
+ NULL = do not provision graphs. ''[{}]'' = provision one default graph module.
+ Each element recognizes (all optional):
+ - key (text) module discriminator. Defaults to ''default''.
+ - policies (jsonb array) RLS policy overrides. NULL = apply defaults from apply_graph_security().
+ Registers manage_graphs + execute_graphs permission bits on first provision.
+ Graph module requires a merkle_store_module_id dependency, so entity_type_provision
+ only registers permissions here. The graph module itself must be provisioned
+ separately with the merkle store dependency resolved.
+ Example: graphs := ''[{}]''::jsonb';
+
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_namespace_module_id IS 'Output: the UUID of the namespace_module row created (or found) for this entity type.
+ Populated by the trigger when namespaces is non-NULL. NULL otherwise.';
+
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_namespaces_table_id IS 'Output: the UUID of the generated namespaces table (e.g. data_room_namespaces).
+ Populated by the trigger when namespaces is non-NULL. NULL otherwise.';
+
+COMMENT ON COLUMN metaschema_modules_public.entity_type_provision.out_namespace_events_table_id IS 'Output: the UUID of the generated namespace_events partitioned table (e.g. data_room_namespace_events).
+ Monthly partitioned, 12-month retention. Populated by the trigger when namespaces is non-NULL. NULL otherwise.';
+
CREATE TABLE metaschema_modules_public.rate_limits_module (
id uuid PRIMARY KEY DEFAULT uuidv7(),
database_id uuid NOT NULL,
@@ -2118,6 +2167,8 @@ CREATE TABLE metaschema_modules_public.billing_module (
balances_table_name text NOT NULL DEFAULT '',
meter_credits_table_id uuid NOT NULL DEFAULT uuid_nil(),
meter_credits_table_name text NOT NULL DEFAULT '',
+ meter_sources_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ meter_sources_table_name text NOT NULL DEFAULT '',
record_usage_function text NOT NULL DEFAULT '',
prefix text NULL,
CONSTRAINT db_fkey
@@ -2152,6 +2203,10 @@ CREATE TABLE metaschema_modules_public.billing_module (
FOREIGN KEY(meter_credits_table_id)
REFERENCES metaschema_public.table (id)
ON DELETE CASCADE,
+ CONSTRAINT meter_sources_table_fkey
+ FOREIGN KEY(meter_sources_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
CONSTRAINT billing_module_database_id_unique
UNIQUE (database_id)
);
@@ -2363,4 +2418,490 @@ CREATE INDEX config_secrets_org_module_schema_id_idx ON metaschema_modules_publi
CREATE INDEX config_secrets_org_module_table_id_idx ON metaschema_modules_public.config_secrets_org_module (table_id);
-COMMENT ON TABLE metaschema_modules_public.config_secrets_org_module IS 'Config row for the config_secrets_org_module, which provisions an organization-scoped encrypted key-value secrets store with manage_secrets permission and entity-membership RLS.';
\ No newline at end of file
+COMMENT ON TABLE metaschema_modules_public.config_secrets_org_module IS 'Config row for the config_secrets_org_module, which provisions an organization-scoped encrypted key-value secrets store with manage_secrets permission and entity-membership RLS.';
+
+CREATE TABLE metaschema_modules_public.inference_log_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ inference_log_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ inference_log_table_name text NOT NULL DEFAULT '',
+ usage_daily_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ usage_daily_table_name text NOT NULL DEFAULT '',
+ "interval" text NOT NULL DEFAULT '1 month',
+ retention text NOT NULL DEFAULT '12 months',
+ premake int NOT NULL DEFAULT 2,
+ scope text NOT NULL DEFAULT 'app',
+ actor_fk_table_id uuid NULL,
+ entity_fk_table_id uuid NULL,
+ prefix text NULL,
+ CONSTRAINT db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT inference_log_table_fkey
+ FOREIGN KEY(inference_log_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT usage_daily_table_fkey
+ FOREIGN KEY(usage_daily_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT inference_log_module_database_id_prefix_unique
+ UNIQUE NULLS NOT DISTINCT (database_id, prefix)
+);
+
+CREATE INDEX inference_log_module_database_id_idx ON metaschema_modules_public.inference_log_module (database_id);
+
+CREATE TABLE metaschema_modules_public.compute_log_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ compute_log_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ compute_log_table_name text NOT NULL DEFAULT '',
+ usage_daily_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ usage_daily_table_name text NOT NULL DEFAULT '',
+ "interval" text NOT NULL DEFAULT '1 month',
+ retention text NOT NULL DEFAULT '12 months',
+ premake int NOT NULL DEFAULT 2,
+ scope text NOT NULL DEFAULT 'app',
+ actor_fk_table_id uuid NULL,
+ entity_fk_table_id uuid NULL,
+ prefix text NULL,
+ CONSTRAINT db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT compute_log_table_fkey
+ FOREIGN KEY(compute_log_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT usage_daily_table_fkey
+ FOREIGN KEY(usage_daily_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT compute_log_module_database_id_prefix_unique
+ UNIQUE NULLS NOT DISTINCT (database_id, prefix)
+);
+
+CREATE INDEX compute_log_module_database_id_idx ON metaschema_modules_public.compute_log_module (database_id);
+
+CREATE TABLE metaschema_modules_public.transfer_log_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ transfer_log_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ transfer_log_table_name text NOT NULL DEFAULT '',
+ usage_daily_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ usage_daily_table_name text NOT NULL DEFAULT '',
+ "interval" text NOT NULL DEFAULT '1 month',
+ retention text NOT NULL DEFAULT '12 months',
+ premake int NOT NULL DEFAULT 2,
+ scope text NOT NULL DEFAULT 'app',
+ actor_fk_table_id uuid NULL,
+ entity_fk_table_id uuid NULL,
+ prefix text NULL,
+ CONSTRAINT db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT transfer_log_table_fkey
+ FOREIGN KEY(transfer_log_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT usage_daily_table_fkey
+ FOREIGN KEY(usage_daily_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT transfer_log_module_database_id_prefix_unique
+ UNIQUE NULLS NOT DISTINCT (database_id, prefix)
+);
+
+CREATE INDEX transfer_log_module_database_id_idx ON metaschema_modules_public.transfer_log_module (database_id);
+
+CREATE TABLE metaschema_modules_public.storage_log_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ storage_log_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ storage_log_table_name text NOT NULL DEFAULT '',
+ usage_daily_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ usage_daily_table_name text NOT NULL DEFAULT '',
+ "interval" text NOT NULL DEFAULT '1 month',
+ retention text NOT NULL DEFAULT '12 months',
+ premake int NOT NULL DEFAULT 2,
+ scope text NOT NULL DEFAULT 'app',
+ actor_fk_table_id uuid NULL,
+ entity_fk_table_id uuid NULL,
+ prefix text NULL,
+ CONSTRAINT db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT storage_log_table_fkey
+ FOREIGN KEY(storage_log_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT usage_daily_table_fkey
+ FOREIGN KEY(usage_daily_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT storage_log_module_database_id_prefix_unique
+ UNIQUE NULLS NOT DISTINCT (database_id, prefix)
+);
+
+CREATE INDEX storage_log_module_database_id_idx ON metaschema_modules_public.storage_log_module (database_id);
+
+CREATE TABLE metaschema_modules_public.db_usage_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ table_stats_log_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ table_stats_log_table_name text NOT NULL DEFAULT '',
+ table_stats_daily_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ table_stats_daily_table_name text NOT NULL DEFAULT '',
+ query_stats_log_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ query_stats_log_table_name text NOT NULL DEFAULT '',
+ query_stats_daily_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ query_stats_daily_table_name text NOT NULL DEFAULT '',
+ "interval" text NOT NULL DEFAULT '1 month',
+ retention text NOT NULL DEFAULT '12 months',
+ premake int NOT NULL DEFAULT 2,
+ scope text NOT NULL DEFAULT 'app',
+ prefix text NULL,
+ CONSTRAINT db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT table_stats_log_table_fkey
+ FOREIGN KEY(table_stats_log_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT table_stats_daily_table_fkey
+ FOREIGN KEY(table_stats_daily_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT query_stats_log_table_fkey
+ FOREIGN KEY(query_stats_log_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT query_stats_daily_table_fkey
+ FOREIGN KEY(query_stats_daily_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT db_usage_module_database_id_prefix_unique
+ UNIQUE NULLS NOT DISTINCT (database_id, prefix)
+);
+
+CREATE INDEX db_usage_module_database_id_idx ON metaschema_modules_public.db_usage_module (database_id);
+
+CREATE TABLE metaschema_modules_public.agent_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ thread_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ message_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ task_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ prompts_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ knowledge_table_id uuid DEFAULT NULL,
+ thread_table_name text NOT NULL DEFAULT 'agent_thread',
+ message_table_name text NOT NULL DEFAULT 'agent_message',
+ task_table_name text NOT NULL DEFAULT 'agent_task',
+ prompts_table_name text NOT NULL DEFAULT 'agent_prompt',
+ knowledge_table_name text NOT NULL DEFAULT 'agent_knowledge',
+ has_knowledge boolean NOT NULL DEFAULT false,
+ api_name text DEFAULT 'agent',
+ membership_type int DEFAULT NULL,
+ entity_table_id uuid NULL,
+ policies jsonb NULL,
+ knowledge_config jsonb NULL,
+ knowledge_policies jsonb NULL,
+ provisions jsonb NULL,
+ CONSTRAINT agent_module_db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT agent_module_schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT agent_module_private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT agent_module_thread_table_fkey
+ FOREIGN KEY(thread_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT agent_module_message_table_fkey
+ FOREIGN KEY(message_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT agent_module_task_table_fkey
+ FOREIGN KEY(task_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT agent_module_prompts_table_fkey
+ FOREIGN KEY(prompts_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT agent_module_knowledge_table_fkey
+ FOREIGN KEY(knowledge_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT agent_module_entity_table_fkey
+ FOREIGN KEY(entity_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE
+);
+
+CREATE INDEX agent_module_database_id_idx ON metaschema_modules_public.agent_module (database_id);
+
+CREATE UNIQUE INDEX agent_module_unique_scope ON metaschema_modules_public.agent_module (database_id, (COALESCE(membership_type, -1)));
+
+CREATE TABLE metaschema_modules_public.merkle_store_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ public_schema_name text,
+ object_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ store_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ commit_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ ref_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ prefix text NOT NULL DEFAULT '',
+ api_name text,
+ scope_field text NOT NULL DEFAULT 'scope_id',
+ created_at timestamptz NOT NULL DEFAULT now(),
+ CONSTRAINT db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT object_table_fkey
+ FOREIGN KEY(object_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT store_table_fkey
+ FOREIGN KEY(store_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT commit_table_fkey
+ FOREIGN KEY(commit_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT ref_table_fkey
+ FOREIGN KEY(ref_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT merkle_store_module_database_prefix_unique
+ UNIQUE (database_id, prefix)
+);
+
+CREATE INDEX merkle_store_module_database_id_idx ON metaschema_modules_public.merkle_store_module (database_id);
+
+CREATE TABLE metaschema_modules_public.graph_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ public_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ public_schema_name text,
+ private_schema_name text,
+ prefix text NOT NULL DEFAULT '',
+ merkle_store_module_id uuid NOT NULL,
+ graphs_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ executions_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ outputs_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ api_name text,
+ private_api_name text,
+ scope_field text NOT NULL DEFAULT 'scope_id',
+ membership_type int DEFAULT NULL,
+ entity_table_id uuid NULL,
+ policies jsonb NULL,
+ provisions jsonb NULL,
+ created_at timestamptz NOT NULL DEFAULT now(),
+ CONSTRAINT db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT public_schema_fkey
+ FOREIGN KEY(public_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT merkle_store_fkey
+ FOREIGN KEY(merkle_store_module_id)
+ REFERENCES metaschema_modules_public.merkle_store_module (id)
+ ON DELETE CASCADE,
+ CONSTRAINT graphs_table_fkey
+ FOREIGN KEY(graphs_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT executions_table_fkey
+ FOREIGN KEY(executions_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT outputs_table_fkey
+ FOREIGN KEY(outputs_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT graph_module_entity_table_fkey
+ FOREIGN KEY(entity_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT graph_module_database_merkle_unique
+ UNIQUE (database_id, merkle_store_module_id)
+);
+
+CREATE INDEX graph_module_database_id_idx ON metaschema_modules_public.graph_module (database_id);
+
+CREATE TABLE metaschema_modules_public.namespace_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ public_schema_name text,
+ private_schema_name text,
+ namespaces_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ namespace_events_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ namespaces_table_name text NOT NULL DEFAULT 'namespaces',
+ namespace_events_table_name text NOT NULL DEFAULT 'namespace_events',
+ api_name text,
+ private_api_name text,
+ membership_type int DEFAULT NULL,
+ entity_table_id uuid NULL,
+ policies jsonb NULL,
+ provisions jsonb NULL,
+ CONSTRAINT namespace_module_db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT namespace_module_schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT namespace_module_private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT namespace_module_namespaces_table_fkey
+ FOREIGN KEY(namespaces_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT namespace_module_events_table_fkey
+ FOREIGN KEY(namespace_events_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT namespace_module_entity_table_fkey
+ FOREIGN KEY(entity_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE
+);
+
+CREATE INDEX namespace_module_database_id_idx ON metaschema_modules_public.namespace_module (database_id);
+
+CREATE UNIQUE INDEX namespace_module_unique_scope ON metaschema_modules_public.namespace_module (database_id, (COALESCE(membership_type, -1)));
+
+CREATE TABLE metaschema_modules_public.function_module (
+ id uuid PRIMARY KEY DEFAULT uuidv7(),
+ database_id uuid NOT NULL,
+ schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ private_schema_id uuid NOT NULL DEFAULT uuid_nil(),
+ public_schema_name text,
+ private_schema_name text,
+ definitions_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ invocations_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ execution_logs_table_id uuid NOT NULL DEFAULT uuid_nil(),
+ definitions_table_name text NOT NULL DEFAULT 'function_definitions',
+ invocations_table_name text NOT NULL DEFAULT 'function_invocations',
+ execution_logs_table_name text NOT NULL DEFAULT 'function_execution_logs',
+ api_name text,
+ private_api_name text,
+ membership_type int DEFAULT NULL,
+ entity_table_id uuid NULL,
+ policies jsonb NULL,
+ provisions jsonb NULL,
+ CONSTRAINT function_module_db_fkey
+ FOREIGN KEY(database_id)
+ REFERENCES metaschema_public.database (id)
+ ON DELETE CASCADE,
+ CONSTRAINT function_module_schema_fkey
+ FOREIGN KEY(schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT function_module_private_schema_fkey
+ FOREIGN KEY(private_schema_id)
+ REFERENCES metaschema_public.schema (id)
+ ON DELETE CASCADE,
+ CONSTRAINT function_module_definitions_table_fkey
+ FOREIGN KEY(definitions_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT function_module_invocations_table_fkey
+ FOREIGN KEY(invocations_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT function_module_execution_logs_table_fkey
+ FOREIGN KEY(execution_logs_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE,
+ CONSTRAINT function_module_entity_table_fkey
+ FOREIGN KEY(entity_table_id)
+ REFERENCES metaschema_public.table (id)
+ ON DELETE CASCADE
+);
+
+CREATE INDEX function_module_database_id_idx ON metaschema_modules_public.function_module (database_id);
+
+CREATE UNIQUE INDEX function_module_unique_scope ON metaschema_modules_public.function_module (database_id, (COALESCE(membership_type, -1)));
\ No newline at end of file
diff --git a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/billing_module/table.sql b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/billing_module/table.sql
index 3282037d..aa1c1c91 100644
--- a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/billing_module/table.sql
+++ b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/billing_module/table.sql
@@ -15,6 +15,8 @@ SELECT
ledger_table_name,
balances_table_id,
balances_table_name,
+ meter_sources_table_id,
+ meter_sources_table_name,
record_usage_function,
prefix
FROM metaschema_modules_public.billing_module
diff --git a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/compute_log_module/table.sql b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/compute_log_module/table.sql
index fbdce50f..de44722a 100644
--- a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/compute_log_module/table.sql
+++ b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/compute_log_module/table.sql
@@ -3,8 +3,7 @@
SELECT id, database_id, schema_id, private_schema_id,
compute_log_table_id, compute_log_table_name,
usage_daily_table_id, usage_daily_table_name,
- "interval", retention, premake, scope,
- actor_fk_table_id, entity_fk_table_id,
+ retention, scope, actor_fk_table_id, entity_fk_table_id,
prefix
FROM metaschema_modules_public.compute_log_module
WHERE FALSE;
diff --git a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/db_usage_module/table.sql b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/db_usage_module/table.sql
index b7ec9d21..57f884fe 100644
--- a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/db_usage_module/table.sql
+++ b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/db_usage_module/table.sql
@@ -5,7 +5,6 @@ SELECT id, database_id, schema_id, private_schema_id,
table_stats_daily_table_id, table_stats_daily_table_name,
query_stats_log_table_id, query_stats_log_table_name,
query_stats_daily_table_id, query_stats_daily_table_name,
- "interval", retention, premake, scope,
- prefix
+ retention, scope, prefix
FROM metaschema_modules_public.db_usage_module
WHERE FALSE;
diff --git a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/inference_log_module/table.sql b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/inference_log_module/table.sql
index a5c1c2aa..eaf4c39c 100644
--- a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/inference_log_module/table.sql
+++ b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/inference_log_module/table.sql
@@ -11,9 +11,10 @@ SELECT
inference_log_table_name,
usage_daily_table_id,
usage_daily_table_name,
- "interval",
retention,
- premake,
+ scope,
+ actor_fk_table_id,
+ entity_fk_table_id,
prefix
FROM metaschema_modules_public.inference_log_module
WHERE FALSE;
diff --git a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/namespace_module/table.sql b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/namespace_module/table.sql
index da2fdc7e..ee614746 100644
--- a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/namespace_module/table.sql
+++ b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/namespace_module/table.sql
@@ -4,9 +4,10 @@ BEGIN;
SELECT id, database_id, schema_id, private_schema_id,
public_schema_name, private_schema_name,
- namespaces_table_id, namespaces_table_name,
+ namespaces_table_id, namespace_events_table_id,
+ namespaces_table_name, namespace_events_table_name,
api_name, private_api_name,
- membership_type, entity_table_id, policies
+ entity_table_id, policies, provisions
FROM metaschema_modules_public.namespace_module
WHERE false;
diff --git a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/profiles_module/table.sql b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/profiles_module/table.sql
index 64810749..9c52869f 100644
--- a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/profiles_module/table.sql
+++ b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/profiles_module/table.sql
@@ -6,7 +6,8 @@ SELECT id, database_id, schema_id, private_schema_id, table_id, table_name,
profile_permissions_table_id, profile_permissions_table_name,
profile_grants_table_id, profile_grants_table_name,
profile_definition_grants_table_id, profile_definition_grants_table_name,
- membership_type, entity_table_id, actor_table_id,
+ profile_templates_table_id, profile_templates_table_name,
+ entity_table_id, actor_table_id,
permissions_table_id, memberships_table_id, prefix
FROM metaschema_modules_public.profiles_module
WHERE FALSE;
diff --git a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/storage_log_module/table.sql b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/storage_log_module/table.sql
index 3ef40c68..adbf9ac7 100644
--- a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/storage_log_module/table.sql
+++ b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/storage_log_module/table.sql
@@ -3,7 +3,7 @@
SELECT id, database_id, schema_id, private_schema_id,
storage_log_table_id, storage_log_table_name,
usage_daily_table_id, usage_daily_table_name,
- "interval", retention, premake, scope,
+ retention, scope,
actor_fk_table_id, entity_fk_table_id,
prefix
FROM metaschema_modules_public.storage_log_module
diff --git a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/transfer_log_module/table.sql b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/transfer_log_module/table.sql
index 58758b2f..6a17ba16 100644
--- a/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/transfer_log_module/table.sql
+++ b/packages/metaschema-modules/verify/schemas/metaschema_modules_public/tables/transfer_log_module/table.sql
@@ -3,7 +3,7 @@
SELECT id, database_id, schema_id, private_schema_id,
transfer_log_table_id, transfer_log_table_name,
usage_daily_table_id, usage_daily_table_name,
- "interval", retention, premake, scope,
+ retention, scope,
actor_fk_table_id, entity_fk_table_id,
prefix
FROM metaschema_modules_public.transfer_log_module
diff --git a/packages/metaschema-schema/deploy/schemas/metaschema_public/tables/table_grant/table.sql b/packages/metaschema-schema/deploy/schemas/metaschema_public/tables/table_grant/table.sql
index 68273ad2..9b4ccc4b 100644
--- a/packages/metaschema-schema/deploy/schemas/metaschema_public/tables/table_grant/table.sql
+++ b/packages/metaschema-schema/deploy/schemas/metaschema_public/tables/table_grant/table.sql
@@ -26,4 +26,11 @@ CREATE TABLE metaschema_public.table_grant (
CREATE INDEX table_grant_table_id_idx ON metaschema_public.table_grant ( table_id );
CREATE INDEX table_grant_database_id_idx ON metaschema_public.table_grant ( database_id );
+CREATE UNIQUE INDEX table_grant_unique_idx ON metaschema_public.table_grant (
+ table_id,
+ privilege,
+ grantee_name,
+ COALESCE(field_ids, '{}'::uuid[])
+);
+
COMMIT;
diff --git a/packages/metaschema-schema/sql/metaschema-schema--0.26.0.sql b/packages/metaschema-schema/sql/metaschema-schema--0.26.0.sql
index f1ad26b8..c5781558 100644
--- a/packages/metaschema-schema/sql/metaschema-schema--0.26.0.sql
+++ b/packages/metaschema-schema/sql/metaschema-schema--0.26.0.sql
@@ -388,6 +388,8 @@ CREATE INDEX table_grant_table_id_idx ON metaschema_public.table_grant (table_id
CREATE INDEX table_grant_database_id_idx ON metaschema_public.table_grant (database_id);
+CREATE UNIQUE INDEX table_grant_unique_idx ON metaschema_public.table_grant (table_id, privilege, grantee_name, (COALESCE(field_ids, CAST('{}' AS uuid[]))));
+
CREATE FUNCTION metaschema_private.table_name_hash(
name text
) RETURNS bytea AS $EOFCODE$
diff --git a/packages/object-store/README.md b/packages/object-store/README.md
index 2b46009f..1d882f62 100644
--- a/packages/object-store/README.md
+++ b/packages/object-store/README.md
@@ -12,28 +12,19 @@