Skip to content

fix(db): backfill 4 orphan migration versions to repair prod integration#334

Merged
adm01-debug merged 1 commit into
mainfrom
claude/backfill-orphan-migrations
May 25, 2026
Merged

fix(db): backfill 4 orphan migration versions to repair prod integration#334
adm01-debug merged 1 commit into
mainfrom
claude/backfill-orphan-migrations

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented May 25, 2026

Objetivo

Reparar a integração Supabase→produção no main, que falha a cada commit com "Remote migration versions not found in local migrations directory".

Causa

4 versões foram aplicadas em produção via MCP apply_migration (sessão paralela "colapso fase5" + restore de trigger) sem commitar os arquivos. A integração, ao comparar o schema_migrations de prod com o repo, encontra essas versões sem arquivo local → history mismatch → MIGRATIONS: FAILED.

Versão (em prod, sem arquivo) Nome
20260525005350 colapso_fase5_smoke_tests_mensal_history_v2
20260525005426 colapso_fase5_smoke_tests_fix_emoji_parser
20260525005954 colapso_fase5_kill_switch_rollout_gradual
20260525021830 restore_set_quote_number_trigger

Mudança

Back-fill verbatim dos 4 arquivos a partir de supabase_migrations.schema_migrations.statements de produção (mesmos version+name), para o ledger do repo casar com prod. O conteúdo é idempotente (CREATE ... IF NOT EXISTS / OR REPLACE / DROP ... IF EXISTS), seguro para replay limpo. Nenhuma alteração em produção — só reflete no repo o que já rodou lá.

Após o merge, a integração deve parar de acusar "Remote migration versions not found". (Se restar uma 2ª camada — migrations locais pendentes que falhem ao aplicar em prod — investigo em seguida.)

https://claude.ai/code/session_01MBTzmQYmrgwLnwfxRS3PNU


Generated by Claude Code


Summary by cubic

Backfilled four orphan Supabase migration files so the prod integration stops failing on main. This aligns the repo’s migration history with production without changing prod state.

  • Bug Fixes
    • Added missing migrations exactly as applied in prod: 20260525005350, 20260525005426, 20260525005954, 20260525021830.
    • Idempotent SQL (CREATE IF NOT EXISTS / OR REPLACE / DROP IF EXISTS); safe to replay locally; no-op for prod.
    • Resolves Supabase→prod error: "Remote migration versions not found in local migrations directory".

Written for commit 9429982. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Sistema de histórico mensal de testes de integridade com armazenamento persistente, limpeza automática e relatórios de tendência.
    • Implantação gradual configurável para o sistema de kill-switches, permitindo controle de rollout em percentuais.
  • Bug Fixes

    • Corrigida classificação de resultados de testes com suporte a análise de emojis.
    • Restaurado gatilho de geração automática de números de orçamento.

Review Change Stack

These 4 versions were applied to production via MCP apply_migration but their
files were never committed, so the Supabase->prod integration on every main
commit failed with "Remote migration versions not found in local migrations
directory" (history mismatch):

  20260525005350 colapso_fase5_smoke_tests_mensal_history_v2
  20260525005426 colapso_fase5_smoke_tests_fix_emoji_parser
  20260525005954 colapso_fase5_kill_switch_rollout_gradual
  20260525021830 restore_set_quote_number_trigger

Back-filled verbatim from production's schema_migrations.statements (same
version+name), so the repo ledger matches prod. Content is idempotent
(CREATE ... IF NOT EXISTS / OR REPLACE / DROP ... IF EXISTS) for clean replay.

https://claude.ai/code/session_01MBTzmQYmrgwLnwfxRS3PNU
@vercel
Copy link
Copy Markdown

vercel Bot commented May 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Ready Ready Preview, Comment May 25, 2026 11:28am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f5aca3d0-ad5a-4239-ae33-94e65daf9c76

📥 Commits

Reviewing files that changed from the base of the PR and between 1a539e7 and 9429982.

📒 Files selected for processing (4)
  • supabase/migrations/20260525005350_colapso_fase5_smoke_tests_mensal_history_v2.sql
  • supabase/migrations/20260525005426_colapso_fase5_smoke_tests_fix_emoji_parser.sql
  • supabase/migrations/20260525005954_colapso_fase5_kill_switch_rollout_gradual.sql
  • supabase/migrations/20260525021830_restore_set_quote_number_trigger.sql

Walkthrough

Quatro migrações Supabase entregam um novo sistema de histórico de smoke tests com automação mensal, correção de parser emoji para resultados de testes, mecanismo de rollout gradual para kill switches, e restauração de um trigger de auto-geração de números de cotação.

Changes

Smoke Tests Monthly History

Layer / File(s) Summary
Table, RLS, and security policy
supabase/migrations/20260525005350_colapso_fase5_smoke_tests_mensal_history_v2.sql
Tabela smoke_tests_runs com índices para ran_at e (test_name, result). RLS habilitado, política SELECT restrita a admin autenticados via is_admin_or_above(). Grants de leitura/sequência a authenticated, revogação de anon.
Persistence function with emoji result classification
supabase/migrations/20260525005350_colapso_fase5_smoke_tests_mensal_history_v2.sql, 20260525005426_colapso_fase5_smoke_tests_fix_emoji_parser.sql
Função fn_run_and_persist_smoke_tests() executa fn_run_smoke_tests() e classifica resultados usando ILIKE para PASS/FAIL/WARN (com variantes emoji). Persiste cada teste, acumula failed_tests, retorna agregação (total, pass, fail, warn, failed_tests). Fix de emoji parser aplicado na segunda migração.
Latest run and trend analysis views
supabase/migrations/20260525005350_colapso_fase5_smoke_tests_mensal_history_v2.sql, 20260525005426_colapso_fase5_smoke_tests_fix_emoji_parser.sql
v_smoke_tests_latest_run ordena por ran_at recente com severidade (FAIL/WARN/PASS via ILIKE). v_smoke_tests_trend agrega por ran_at contadores pass/fail/warn e duração média, limitado a 12 runs. Ambas SECURITY INVOKER, grants a authenticated.
Monthly execution and retention cron jobs
supabase/migrations/20260525005350_colapso_fase5_smoke_tests_mensal_history_v2.sql
Cron smoke_tests_monthly executa função no 1º dia (0 3 1 * *). Cron smoke_tests_runs_purge deleta rows antigos mantendo 24 ran_at recentes (0 4 1 * *).

Kill Switch Gradual Rollout

Layer / File(s) Summary
Rollout percentage column and application function
supabase/migrations/20260525005954_colapso_fase5_kill_switch_rollout_gradual.sql
Coluna rollout_percentage (0–100, default 100, validado) adicionada a system_kill_switches. Função fn_should_apply_kill_switch(p_switch_name, p_bucket_key) determinística via hashtext(bucket_key): retorna false se switch não existe ou enabled=true; se enabled=false, retorna true quando hash cai no percentual de rollout. Grants a anon e authenticated, inclui validação de teste.

Quote Number Trigger Restore

Layer / File(s) Summary
Quote number generation trigger
supabase/migrations/20260525021830_restore_set_quote_number_trigger.sql
Trigger set_quote_number BEFORE INSERT na tabela quotes: executa generate_quote_number() quando NEW.quote_number é NULL ou vazio, preenchendo o campo automaticamente.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

codex

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/backfill-orphan-migrations

Comment @coderabbitai help to get the list of available commands and usage tips.

@supabase
Copy link
Copy Markdown

supabase Bot commented May 25, 2026

This pull request has been ignored for the connected project doufsxqlfjyuvxuezpln due to reaching the limit of concurrent preview branches.
Go to Project Integrations Settings ↗︎ if you wish to update this limit.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@adm01-debug adm01-debug marked this pull request as ready for review May 25, 2026 11:28
Copilot AI review requested due to automatic review settings May 25, 2026 11:28
@adm01-debug adm01-debug merged commit ae8e2ec into main May 25, 2026
28 of 31 checks passed
@adm01-debug adm01-debug deleted the claude/backfill-orphan-migrations branch May 25, 2026 11:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds/repairs several Supabase Postgres migrations to restore quote inserts, add gradual kill-switch rollout logic, and improve smoke-test persistence/reporting.

Changes:

  • Restores the set_quote_number trigger to auto-populate public.quotes.quote_number on insert.
  • Introduces gradual (bucketed) kill-switch rollout via rollout_percentage and fn_should_apply_kill_switch.
  • Adds smoke-test run history persistence plus views, then adjusts parsing to handle emoji-prefixed results.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 9 comments.

File Description
supabase/migrations/20260525021830_restore_set_quote_number_trigger.sql Recreates trigger to populate quote_number on insert.
supabase/migrations/20260525005954_colapso_fase5_kill_switch_rollout_gradual.sql Adds rollout percentage + routing function for gradual kill-switch application.
supabase/migrations/20260525005426_colapso_fase5_smoke_tests_fix_emoji_parser.sql Updates smoke-test aggregation/views to parse emoji-prefixed results.
supabase/migrations/20260525005350_colapso_fase5_smoke_tests_mensal_history_v2.sql Creates smoke-test run table/RLS, wrapper function, views, and cron jobs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


-- Hash determinístico → bucket 0-99
-- Mesmo bucket_key sempre cai no mesmo bucket (estabilidade entre reloads)
v_bucket := abs(hashtext(coalesce(p_bucket_key, 'anonymous')) % 100);
Comment on lines +75 to +79
-- 3) Validar: switch atual está enabled=true, então sempre retorna false
SELECT
public.fn_should_apply_kill_switch('edge_external_db_bridge', 'test-user-1') AS rollout_test_1,
public.fn_should_apply_kill_switch('edge_external_db_bridge', 'test-user-2') AS rollout_test_2,
public.fn_should_apply_kill_switch('non_existent_switch', 'anyone') AS unknown_switch;
Comment on lines +22 to +30
ALTER TABLE public.smoke_tests_runs ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS smoke_tests_runs_read_admin ON public.smoke_tests_runs;
CREATE POLICY smoke_tests_runs_read_admin
ON public.smoke_tests_runs FOR SELECT
TO authenticated
USING (is_admin_or_above((SELECT auth.uid())));

GRANT SELECT ON public.smoke_tests_runs TO authenticated;
GRANT USAGE, SELECT ON SEQUENCE public.smoke_tests_runs_id_seq TO authenticated;

-- Wrapper SECURITY INVOKER (default)
CREATE OR REPLACE FUNCTION public.fn_run_and_persist_smoke_tests()
Comment on lines +60 to +64
INSERT INTO public.smoke_tests_runs (
ran_at, test_name, test_category, result, details, duration_ms
) VALUES (
v_ran_at, r.test_name, r.test_category, r.result, r.details, r.duration_ms
);

-- Grant para admin/postgres executar
GRANT EXECUTE ON FUNCTION public.fn_run_and_persist_smoke_tests() TO postgres;
GRANT EXECUTE ON FUNCTION public.fn_run_and_persist_smoke_tests() TO authenticated;
Comment on lines +66 to +71
IF upper(r.result) = 'PASS' THEN v_passed := v_passed + 1;
ELSIF upper(r.result) = 'FAIL' THEN
v_failed := v_failed + 1;
v_failed_tests := array_append(v_failed_tests, r.test_name);
ELSIF upper(r.result) IN ('WARN','WARNING') THEN v_warned := v_warned + 1;
END IF;
Comment on lines +97 to +99
CASE upper(r.result)
WHEN 'FAIL' THEN 1 WHEN 'WARN' THEN 2 WHEN 'PASS' THEN 3 ELSE 4
END, r.test_name;
Comment on lines +109 to +111
count(*) FILTER (WHERE upper(result) = 'PASS') AS passed,
count(*) FILTER (WHERE upper(result) = 'FAIL') AS failed,
count(*) FILTER (WHERE upper(result) IN ('WARN','WARNING')) AS warned,
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9429982d4e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


-- Wrapper SECURITY INVOKER (default)
CREATE OR REPLACE FUNCTION public.fn_run_and_persist_smoke_tests()
RETURNS TABLE(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Drop function before redefining return type

This migration introduces public.fn_run_and_persist_smoke_tests() as RETURNS TABLE (...), but a later migration already in the repo (supabase/migrations/20260525063000_restore_smoke_test_observability_contract.sql) redefines the same zero-argument function as RETURNS void using CREATE OR REPLACE FUNCTION. PostgreSQL does not allow CREATE OR REPLACE to change an existing function’s return type, so a clean migration replay will now fail when it reaches that later file with cannot change return type of existing function.

Useful? React with 👍 / 👎.

Comment on lines +24 to +28
DROP POLICY IF EXISTS smoke_tests_runs_read_admin ON public.smoke_tests_runs;
CREATE POLICY smoke_tests_runs_read_admin
ON public.smoke_tests_runs FOR SELECT
TO authenticated
USING (is_admin_or_above((SELECT auth.uid())));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add INSERT policy for smoke_tests_runs before INVOKER writes

RLS is enabled on public.smoke_tests_runs, but this migration only creates a FOR SELECT policy for authenticated. The same migration defines fn_run_and_persist_smoke_tests() as SECURITY INVOKER and grants it to authenticated, and that function performs INSERT into smoke_tests_runs; without a matching FOR INSERT policy, authenticated callers (including admin dashboard users) will hit an RLS violation and the RPC cannot persist results.

Useful? React with 👍 / 👎.

TO authenticated
USING (is_admin_or_above((SELECT auth.uid())));

GRANT SELECT ON public.smoke_tests_runs TO authenticated;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Grant INSERT on smoke_tests_runs for invoker RPC

The migration grants only SELECT on public.smoke_tests_runs to authenticated, but fn_run_and_persist_smoke_tests() is SECURITY INVOKER and executes INSERT into that table. Even if RLS policies are corrected, authenticated users invoking this RPC will still fail with table-permission errors until INSERT privilege is granted.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants