namespace Tiku.Infrastructure.Persistence; internal static class PostgreSqlSaasCatalogConstraintSql { public const string CreateOfferingVersionImmutabilityGuards = """ create or replace function tiku_guard_saas_offering_version_immutable() returns trigger language plpgsql as $$ begin if tg_op = 'DELETE' then if old.status in ('published', 'retired') then raise exception 'published or retired SaaS offering versions cannot be deleted' using errcode = '23514', constraint = 'ck_saas_offering_versions_published_immutable'; end if; return old; end if; if old.status not in ('published', 'retired') then return new; end if; if old.status = 'published' and new.status = 'retired' and new.retired_at is not null and new.id is not distinct from old.id and new.offering_id is not distinct from old.offering_id and new.version is not distinct from old.version and new.billing_cycle is not distinct from old.billing_cycle and new.original_amount_cents is not distinct from old.original_amount_cents and new.amount_cents is not distinct from old.amount_cents and new.currency is not distinct from old.currency and new.effective_at is not distinct from old.effective_at and new.published_at is not distinct from old.published_at and new.metadata is not distinct from old.metadata and new.created_at is not distinct from old.created_at then return new; end if; raise exception 'published or retired SaaS offering versions are immutable' using errcode = '23514', constraint = 'ck_saas_offering_versions_published_immutable'; end; $$; do $guard$ begin if to_regclass('saas_offering_versions') is not null then execute 'create trigger trg_saas_offering_versions_published_immutable before update or delete on saas_offering_versions for each row execute function tiku_guard_saas_offering_version_immutable()'; end if; end $guard$; """; public const string CreateOfferingVersionChildrenImmutabilityGuards = """ create or replace function tiku_guard_saas_offering_version_child_immutable() returns trigger language plpgsql as $$ declare version_status text; begin if tg_op = 'DELETE' then select status into version_status from saas_offering_versions where id = old.offering_version_id; if version_status is distinct from 'draft' then raise exception 'published or retired SaaS offering version children are immutable' using errcode = '23514', constraint = 'ck_saas_offering_versions_published_immutable'; end if; return old; end if; if tg_op = 'UPDATE' and old.offering_version_id <> new.offering_version_id then select status into version_status from saas_offering_versions where id = old.offering_version_id; if version_status is distinct from 'draft' then raise exception 'published or retired SaaS offering version children are immutable' using errcode = '23514', constraint = 'ck_saas_offering_versions_published_immutable'; end if; end if; select status into version_status from saas_offering_versions where id = new.offering_version_id; if version_status is distinct from 'draft' then raise exception 'published or retired SaaS offering version children are immutable' using errcode = '23514', constraint = 'ck_saas_offering_versions_published_immutable'; end if; return new; end; $$; do $guard$ begin if to_regclass('saas_offering_version_features') is not null then execute 'create trigger trg_saas_offering_version_features_published_immutable before insert or update or delete on saas_offering_version_features for each row execute function tiku_guard_saas_offering_version_child_immutable()'; end if; if to_regclass('saas_offering_version_limits') is not null then execute 'create trigger trg_saas_offering_version_limits_published_immutable before insert or update or delete on saas_offering_version_limits for each row execute function tiku_guard_saas_offering_version_child_immutable()'; end if; end $guard$; """; public const string CreateSubscriptionOfferingTypeGuards = """ create or replace function tiku_guard_saas_subscription_offering_type() returns trigger language plpgsql as $$ declare offering_type text; source_version_id uuid; begin if tg_table_name = 'tenant_saas_subscriptions' then select o.type into offering_type from saas_offering_versions v join saas_offerings o on o.id = v.offering_id where v.id = new.base_offering_version_id; if offering_type is distinct from 'base_plan' then raise exception 'subscription base offering version must belong to a base plan' using errcode = '23514', constraint = 'ck_tenant_saas_subscription_base_plan'; end if; if new.scheduled_base_offering_version_id is not null then select o.type into offering_type from saas_offering_versions v join saas_offerings o on o.id = v.offering_id where v.id = new.scheduled_base_offering_version_id; if offering_type is distinct from 'base_plan' then raise exception 'scheduled subscription offering version must belong to a base plan' using errcode = '23514', constraint = 'ck_tenant_saas_subscription_base_plan'; end if; end if; return new; end if; select o.type into offering_type from saas_offering_versions v join saas_offerings o on o.id = v.offering_id where v.id = new.offering_version_id; if offering_type is distinct from new.item_type::text then raise exception 'subscription item type must match its offering type' using errcode = '23514', constraint = 'ck_tenant_saas_subscription_item_offering_type'; end if; if new.source_order_item_id is not null then select offering_version_id into source_version_id from platform_billing_order_items where tenant_id = new.tenant_id and id = new.source_order_item_id; if source_version_id is distinct from new.offering_version_id then raise exception 'subscription item must match its order item snapshot' using errcode = '23514', constraint = 'ck_tenant_saas_subscription_item_order_snapshot'; end if; end if; return new; end; $$; do $guard$ begin if to_regclass('tenant_saas_subscriptions') is not null then execute 'create trigger trg_tenant_saas_subscriptions_base_plan before insert or update on tenant_saas_subscriptions for each row execute function tiku_guard_saas_subscription_offering_type()'; end if; if to_regclass('tenant_saas_subscription_items') is not null then execute 'create trigger trg_tenant_saas_subscription_items_offering_type before insert or update on tenant_saas_subscription_items for each row execute function tiku_guard_saas_subscription_offering_type()'; end if; end $guard$; """; public const string DropOfferingVersionImmutabilityGuards = """ do $guard$ begin if to_regclass('saas_offering_version_features') is not null then execute 'drop trigger if exists trg_saas_offering_version_features_published_immutable on saas_offering_version_features'; end if; if to_regclass('saas_offering_version_limits') is not null then execute 'drop trigger if exists trg_saas_offering_version_limits_published_immutable on saas_offering_version_limits'; end if; if to_regclass('saas_offering_versions') is not null then execute 'drop trigger if exists trg_saas_offering_versions_published_immutable on saas_offering_versions'; end if; if to_regclass('tenant_saas_subscription_items') is not null then execute 'drop trigger if exists trg_tenant_saas_subscription_items_offering_type on tenant_saas_subscription_items'; end if; if to_regclass('tenant_saas_subscriptions') is not null then execute 'drop trigger if exists trg_tenant_saas_subscriptions_base_plan on tenant_saas_subscriptions'; end if; end $guard$; drop function if exists tiku_guard_saas_offering_version_child_immutable(); drop function if exists tiku_guard_saas_offering_version_immutable(); drop function if exists tiku_guard_saas_subscription_offering_type(); """; }