-- Simula RLS: tenant B no ve PRY-0001 de tenant A pero el código debe ser global. DROP SCHEMA IF EXISTS core CASCADE; CREATE SCHEMA core; SET search_path = core; CREATE FUNCTION rpc_assert_message(p_message text) RETURNS void LANGUAGE plpgsql IMMUTABLE AS $$ BEGIN IF p_message IS NULL OR btrim(p_message) = '' THEN RAISE EXCEPTION 'empty'; END IF; END; $$; CREATE FUNCTION rpc_ok(p_data jsonb, p_message text, p_ctx jsonb DEFAULT '{}'::jsonb) RETURNS jsonb LANGUAGE plpgsql IMMUTABLE AS $$ BEGIN PERFORM rpc_assert_message(p_message); RETURN jsonb_build_object('ok', true, 'data', p_data); END; $$; CREATE FUNCTION rpc_created(p_data jsonb, p_message text, p_ctx jsonb DEFAULT '{}'::jsonb) RETURNS jsonb LANGUAGE plpgsql IMMUTABLE AS $$ BEGIN PERFORM rpc_assert_message(p_message); RETURN jsonb_build_object('ok', true, 'data', p_data); END; $$; CREATE FUNCTION rpc_err(p_code text, p_message text, p_ctx jsonb DEFAULT '{}'::jsonb, p_errors jsonb DEFAULT NULL) RETURNS jsonb LANGUAGE plpgsql IMMUTABLE AS $$ BEGIN PERFORM rpc_assert_message(p_message); RETURN jsonb_build_object('ok', false, 'message', p_message); END; $$; CREATE FUNCTION rpc_from_exception(p_fn text, p_sqlstate text, p_message text, p_detail text DEFAULT NULL) RETURNS jsonb LANGUAGE plpgsql IMMUTABLE AS $$ BEGIN RETURN rpc_err('INTERNAL', format('%s %s', p_fn, p_message), '{}'::jsonb); END; $$; CREATE TABLE companies (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name text); CREATE TABLE projects ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, code text NOT NULL UNIQUE, name text NOT NULL, address text DEFAULT '', theme_id text NOT NULL DEFAULT 'arctec-dos-logos-fold', status text DEFAULT 'activo', company_id bigint, tenant_id int ); ALTER TABLE projects ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation ON projects USING (tenant_id = NULLIF(current_setting('app.tenant_id', true), '')::integer) WITH CHECK (tenant_id = NULLIF(current_setting('app.tenant_id', true), '')::integer); INSERT INTO companies (name) VALUES ('Co A'), ('Co B'); -- PRY-0001 ya existe (otro tenant / seed) INSERT INTO projects (code, name, theme_id, company_id, tenant_id) VALUES ('PRY-0001', 'Obra seed', 'arctec-dos-logos-fold', 1, 1);