Files

231 lines
11 KiB
SQL
Raw Permalink Normal View History

\set ON_ERROR_STOP on
DO $assertions$
DECLARE
actual_columns text[];
default_quota integer;
initial_version bigint;
updated_version bigint;
area_initial_version bigint;
area_updated_version bigint;
BEGIN
IF current_setting('server_version_num')::integer < 170000
OR current_setting('server_version_num')::integer >= 180000 THEN
RAISE EXCEPTION 'YoVision requires PostgreSQL 17.x';
END IF;
SELECT array_agg(column_name ORDER BY ordinal_position)
INTO actual_columns
FROM information_schema.columns
WHERE table_schema = 'bell' AND table_name = 'site_quota_v1';
IF actual_columns IS DISTINCT FROM ARRAY[
'tenant_id', 'site_id', 'max_video_channels', 'source_version', 'source_updated_at'
] THEN
RAISE EXCEPTION 'site_quota_v1 signature drift: %', actual_columns;
END IF;
IF NOT has_table_privilege('sense_app', 'bell.site_quota_v1', 'SELECT') THEN
RAISE EXCEPTION 'sense_app lacks SELECT on quota view';
END IF;
IF has_table_privilege('sense_app', 'bell.site_quota_v1', 'INSERT')
OR has_table_privilege('sense_app', 'bell.site_quota_v1', 'UPDATE')
OR has_table_privilege('sense_app', 'bell.site_quota_v1', 'DELETE') THEN
RAISE EXCEPTION 'sense_app has forbidden quota-view write privileges';
END IF;
IF has_table_privilege('sense_app', 'bell.sites', 'SELECT')
OR has_table_privilege('sense_app', 'bell.sites', 'INSERT')
OR has_table_privilege('sense_app', 'bell.sites', 'UPDATE')
OR has_table_privilege('sense_app', 'bell.sites', 'DELETE') THEN
RAISE EXCEPTION 'sense_app has forbidden Bell source-table privileges';
END IF;
SELECT array_agg(column_name ORDER BY ordinal_position)
INTO actual_columns
FROM information_schema.columns
WHERE table_schema = 'bell' AND table_name = 'area_policy_v1';
IF actual_columns IS DISTINCT FROM ARRAY[
'tenant_id', 'site_id', 'area_id', 'capture_policy',
'source_version', 'source_updated_at'
] THEN
RAISE EXCEPTION 'area_policy_v1 signature drift: %', actual_columns;
END IF;
IF NOT has_table_privilege('sense_app', 'bell.area_policy_v1', 'SELECT') THEN
RAISE EXCEPTION 'sense_app lacks SELECT on Area policy view';
END IF;
IF has_table_privilege('sense_app', 'bell.area_policy_v1', 'INSERT')
OR has_table_privilege('sense_app', 'bell.area_policy_v1', 'UPDATE')
OR has_table_privilege('sense_app', 'bell.area_policy_v1', 'DELETE')
OR has_table_privilege('sense_app', 'bell.areas', 'SELECT')
OR has_table_privilege('sense_app', 'bell.areas', 'INSERT')
OR has_table_privilege('sense_app', 'bell.areas', 'UPDATE')
OR has_table_privilege('sense_app', 'bell.areas', 'DELETE') THEN
RAISE EXCEPTION 'sense_app violates the Area projection boundary';
END IF;
IF has_function_privilege('sense_app', 'bell.bump_area_version()', 'EXECUTE') THEN
RAISE EXCEPTION 'sense_app can execute the Bell Area version trigger function';
END IF;
IF NOT has_table_privilege('sense_app', 'sense.device_operation_outbox', 'SELECT')
OR NOT has_table_privilege('sense_app', 'sense.device_operation_outbox', 'INSERT')
OR NOT has_table_privilege('sense_app', 'sense.device_operation_outbox', 'UPDATE')
OR NOT has_table_privilege('sense_app', 'sense.device_operation_outbox', 'DELETE') THEN
RAISE EXCEPTION 'sense_app lacks access to its local audit Outbox';
END IF;
2026-08-11 00:24:32 +08:00
IF (SELECT max(version) FROM bell.schema_migrations) <> 4
OR (SELECT max(version) FROM sense.schema_migrations) <> 6 THEN
RAISE EXCEPTION 'schema migration version drift';
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_roles
WHERE rolname = 'bell_runtime' AND NOT rolcanlogin AND NOT rolsuper
AND NOT rolcreatedb AND NOT rolcreaterole AND NOT rolreplication
) THEN
RAISE EXCEPTION 'bell_runtime role is missing or unsafe';
END IF;
IF NOT has_table_privilege('yovision_t015_bell', 'bell.events', 'SELECT,INSERT')
OR NOT has_table_privilege('yovision_t015_bell', 'bell.event_outcomes', 'SELECT,INSERT')
OR has_table_privilege('yovision_t015_bell', 'bell.events', 'UPDATE')
OR has_table_privilege('yovision_t015_bell', 'bell.events', 'DELETE')
OR has_table_privilege('yovision_t015_bell', 'bell.events', 'TRUNCATE')
OR has_table_privilege('yovision_t015_bell', 'bell.event_outcomes', 'UPDATE')
OR has_table_privilege('yovision_t015_bell', 'bell.event_outcomes', 'DELETE')
OR has_table_privilege('yovision_t015_bell', 'bell.event_outcomes', 'TRUNCATE') THEN
RAISE EXCEPTION 'Bell runtime violates immutable event privileges';
END IF;
IF has_table_privilege('public', 'bell.events', 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE')
OR has_table_privilege('public', 'bell.event_outcomes', 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE') THEN
RAISE EXCEPTION 'Bell event facts leaked to PUBLIC';
END IF;
INSERT INTO bell.sites(tenant_id, id, name)
VALUES ('assertion-tenant', 'assertion-site', 'Assertion Site')
RETURNING max_video_channels, version INTO default_quota, initial_version;
IF default_quota <> 16 OR initial_version <> 1 THEN
RAISE EXCEPTION 'Bell site default quota/version drift';
END IF;
UPDATE bell.sites SET name = 'Assertion Site Updated'
WHERE tenant_id = 'assertion-tenant' AND id = 'assertion-site'
RETURNING version INTO updated_version;
IF updated_version <> initial_version + 1 THEN
RAISE EXCEPTION 'Bell site source_version is not monotonic';
END IF;
INSERT INTO bell.areas(tenant_id, site_id, id, name, capture_policy)
VALUES (
'assertion-tenant', 'assertion-site', 'assertion-area',
'Assertion Area', 'video_allowed'
)
RETURNING version INTO area_initial_version;
UPDATE bell.areas SET capture_policy = 'non_imaging_only'
WHERE tenant_id = 'assertion-tenant' AND id = 'assertion-area'
RETURNING version INTO area_updated_version;
IF area_initial_version <> 1 OR area_updated_version <> area_initial_version + 1 THEN
RAISE EXCEPTION 'Bell Area source_version is not monotonic';
END IF;
BEGIN
INSERT INTO bell.areas(tenant_id, site_id, id, name, capture_policy)
VALUES ('assertion-tenant', 'assertion-site', 'invalid-area', 'Invalid', 'unknown');
RAISE EXCEPTION 'unknown capture_policy unexpectedly accepted';
EXCEPTION
WHEN check_violation THEN NULL;
END;
BEGIN
INSERT INTO bell.sites(tenant_id, id, name, max_video_channels)
VALUES ('assertion-tenant', 'invalid-site', 'Invalid', 129);
RAISE EXCEPTION 'quota 129 unexpectedly accepted';
EXCEPTION
WHEN check_violation THEN NULL;
END;
DELETE FROM bell.areas
WHERE tenant_id = 'assertion-tenant' AND id = 'assertion-area';
DELETE FROM bell.sites
WHERE tenant_id = 'assertion-tenant' AND id = 'assertion-site';
END
$assertions$;
DO $control_api$
BEGIN
IF NOT has_table_privilege('yovision_t012_sense', 'sense.control_idempotency_receipts', 'SELECT,INSERT,UPDATE,DELETE')
OR NOT has_table_privilege('yovision_t012_sense', 'sense.batch_operations', 'SELECT,INSERT,UPDATE,DELETE')
OR NOT has_table_privilege('yovision_t012_sense', 'sense.batch_operation_items', 'SELECT,INSERT,UPDATE,DELETE') THEN
RAISE EXCEPTION 'Sense runtime lacks Control API table privileges';
END IF;
IF has_table_privilege('public', 'sense.control_idempotency_receipts', 'SELECT')
OR has_table_privilege('public', 'sense.batch_operations', 'SELECT') THEN
RAISE EXCEPTION 'Control API durable state leaked to PUBLIC';
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'sense' AND table_name = 'devices'
AND column_name = 'resource_version'
) OR NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'sense' AND table_name = 'devices'
AND column_name = 'profile_token'
) THEN
RAISE EXCEPTION 'Control API device columns are missing';
END IF;
END
$control_api$;
DO $reconcile_safety$
DECLARE
target text;
BEGIN
FOREACH target IN ARRAY ARRAY[
'sense.media_path_ownership',
'sense.operational_leases',
'sense.orphan_scan_runs',
'sense.orphan_scan_findings',
'sense.orphan_cleanup_actions'
] LOOP
IF NOT has_table_privilege('yovision_t012_sense', target, 'SELECT,INSERT,UPDATE,DELETE') THEN
RAISE EXCEPTION 'Sense runtime lacks reconciliation safety privilege on %', target;
END IF;
IF has_table_privilege('public', target, 'SELECT,INSERT,UPDATE,DELETE') THEN
RAISE EXCEPTION 'Reconciliation safety state leaked to PUBLIC on %', target;
END IF;
END LOOP;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'sense' AND table_name = 'reconcile_state'
AND column_name = 'lease_token'
) THEN
RAISE EXCEPTION 'reconcile fencing columns are missing';
END IF;
END
$reconcile_safety$;
2026-08-11 00:24:32 +08:00
DO $audit_relay$
BEGIN
IF NOT has_table_privilege('yovision_t012_sense', 'sense.device_operation_outbox', 'SELECT,INSERT,UPDATE,DELETE')
OR has_table_privilege('yovision_t012_sense', 'bell.audit_events', 'SELECT,INSERT,UPDATE,DELETE')
OR has_table_privilege('yovision_t012_sense', 'bell.audit_relay_receipts', 'SELECT,INSERT,UPDATE,DELETE') THEN
RAISE EXCEPTION 'Sense runtime violates audit relay schema ownership';
END IF;
IF NOT has_table_privilege('yovision_t015_bell', 'bell.audit_events', 'SELECT,INSERT')
OR has_table_privilege('yovision_t015_bell', 'bell.audit_events', 'UPDATE,DELETE,TRUNCATE')
OR NOT has_table_privilege('yovision_t015_bell', 'bell.audit_relay_receipts', 'SELECT,INSERT,DELETE')
OR has_table_privilege('yovision_t015_bell', 'bell.audit_relay_receipts', 'UPDATE,TRUNCATE') THEN
RAISE EXCEPTION 'Bell runtime violates audit relay privileges';
END IF;
IF has_table_privilege('public', 'bell.audit_events', 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE')
OR has_table_privilege('public', 'bell.audit_relay_receipts', 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE') THEN
RAISE EXCEPTION 'Bell audit relay tables leaked to PUBLIC';
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='sense' AND table_name='device_operation_outbox'
AND column_name='relay_lease_token'
) THEN
RAISE EXCEPTION 'Sense audit relay fencing columns are missing';
END IF;
END
$audit_relay$;