-- Tenant data is not in use yet, so replace the earlier opaque tenant_key -- column name with the relational tenant_id convention everywhere. do $$ declare tbl text; con text; begin foreach tbl in array array[ 'projects', 'thoughts', 'stored_files', 'learnings', 'plans', 'chat_histories', 'agent_skills', 'agent_guardrails', 'agent_personas', 'agent_parts', 'agent_traits', 'character_arcs' ] loop -- Fresh installs already have tenant_id from the regenerated schema; -- discard that empty column so the historical migration chain converges. if exists ( select 1 from information_schema.columns where table_schema = 'public' and table_name = tbl and column_name = 'tenant_id' ) and exists ( select 1 from information_schema.columns where table_schema = 'public' and table_name = tbl and column_name = 'tenant_key' ) then execute format('alter table %I drop column tenant_id', tbl); end if; if exists ( select 1 from information_schema.columns where table_schema = 'public' and table_name = tbl and column_name = 'tenant_key' ) then execute format('alter table %I rename column tenant_key to tenant_id', tbl); end if; for con in select c.conname from pg_constraint c join pg_class r on r.oid = c.conrelid join pg_namespace n on n.oid = r.relnamespace join unnest(c.conkey) as k(attnum) on true join pg_attribute a on a.attrelid = r.oid and a.attnum = k.attnum where n.nspname = 'public' and r.relname = tbl and c.contype = 'f' and a.attname = 'tenant_id' loop execute format('alter table %I drop constraint %I', tbl, con); end loop; execute format('alter table %I add constraint %I foreign key (tenant_id) references tenants(id)', tbl, 'fk_' || tbl || '_tenant_id'); end loop; end $$;