panels-origin/scripts/verify-project-code-next-run.sql
Cursor Agent 5147027716
fix: evitar código PRY duplicado al crear proyecto (RLS vs UNIQUE global)
fn_next_project_code contaba solo proyectos visibles del tenant; projects.code
es UNIQUE en toda la base. El siguiente PRY-0001 chocaba con otra obra/seed.
Secuencia global con SECURITY DEFINER y lock al crear.

Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
2026-09-16 20:55:11 +00:00

45 lines
1.2 KiB
PL/PgSQL

SET search_path = core;
SELECT set_config('app.tenant_id', '2', true);
CREATE OR REPLACE FUNCTION fn_next_project_code_old()
RETURNS text
LANGUAGE plpgsql
SECURITY INVOKER
SET search_path = core
AS $$
DECLARE v_n integer; v_code text;
BEGIN
SELECT COALESCE(MAX(substring(code FROM 5)::integer), 0) + 1 INTO v_n
FROM projects WHERE code ~ '^PRY-[0-9]{4}' OR code ~ '^OBR-[0-9]{4}';
RETURN 'PRY-' || lpad(v_n::text, 4, '0');
END;
$$;
CREATE OR REPLACE FUNCTION fn_next_project_code_new()
RETURNS text
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = core
AS $$
DECLARE v_n integer; v_code text;
BEGIN
SELECT COALESCE(MAX(substring(code FROM 5)::integer), 0) + 1 INTO v_n
FROM projects WHERE code ~ '^(PRY|OBR)-[0-9]+$';
RETURN 'PRY-' || lpad(v_n::text, 4, '0');
END;
$$;
DO $$
DECLARE old_code text; new_code text;
BEGIN
old_code := fn_next_project_code_old();
new_code := fn_next_project_code_new();
IF old_code <> 'PRY-0001' THEN
RAISE EXCEPTION 'RLS bug demo: old should propose PRY-0001, got %', old_code;
END IF;
IF new_code <> 'PRY-0002' THEN
RAISE EXCEPTION 'fix should propose PRY-0002, got %', new_code;
END IF;
RAISE NOTICE 'OK old=% (conflict) new=% (safe)', old_code, new_code;
END;
$$;