Skip to content

feat: modal pro Checar Metadados e botão de sincronizar Update.latest - #1066

Merged
Winzen merged 5 commits into
mainfrom
feat/check-metadados-button
Aug 22, 2026
Merged

feat: modal pro Checar Metadados e botão de sincronizar Update.latest#1066
Winzen merged 5 commits into
mainfrom
feat/check-metadados-button

Conversation

@Winzen

@Winzen Winzen commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Nova funcionalidade: modal no Checar Metadados + botão Sincronizar Update.latest

Contexto

O botão "Checar Metadados" (introduzido nos PRs #1066/#1067) comparava o schema da Table no BigQuery com as Columns cadastradas na API, mas mostrava o resultado num alert() de texto solto — difícil de ler quando há várias discrepâncias.

Esse PR também adiciona um botão pra sincronizar Update.latest com o BigQuery direto da UI, sem precisar de acesso ao banco — contexto completo em #1069.

O que tem nesse PR

1. Checar Metadados — resultado num modal estruturado

A view agora devolve uma lista de discrepâncias estruturadas em vez de uma string já formatada, e o front renderiza cada uma como uma linha com um badge por tipo.

backend/apps/admin_data_tools/
├── views.py   # CheckMetadadosView devolve {"discrepancias": [{"coluna", "tipo", "bigquery"?, "api"?}]}
└── urls.py

backend/apps/core/static/core/
├── js/ferramentas.js   # mostrarResultadoMetadados() monta o modal a partir da lista
└── css/main.css        # badge por tipo de discrepância

backend/templates/admin/change_form.html   # markup do #metadadosModal

Diagrama de fluxo

Botão "Checar Metadados" (change_form.html)
        │
        │  onclick
        ▼
checarMetadados()                         (ferramentas.js)
        │
        │  POST /admin-tools/check-metadados/
        ▼
CheckMetadadosView.post()                 (views.py)
        │
        │  get_gbq_client().get_table(gbq_slug)
        ▼
BigQuery — basedosdados-dev fora de prod, basedosdados em prod
        │
        │  schema real da tabela
        ▼
compara com Column.objects (nome, tipo, descrição)
        │
        │  {"status", "discrepancias": [...]}
        ▼
mostrarResultadoMetadados() → modal com uma linha por discrepância

Tipos de discrepância

tipo Quando aparece Campos extra
somente_bigquery Coluna existe no BigQuery, não na API
somente_api Coluna existe na API, não no BigQuery
tipo_diferente bigquery_type da API não bate com o schema do BQ bigquery, api
descricao_diferente Descrição da coluna diverge entre os dois lados bigquery, api

Tradução de tipo legacy → standard SQL

field.field_type do client do BigQuery sempre reporta o nome legacy (INTEGER, FLOAT, RECORD), enquanto bigquery_type na API usa o nome standard SQL (INT64, FLOAT64, STRUCT). Sem tradução, toda coluna numérica dava falso positivo:

_BQ_LEGACY_TYPE_ALIASES: dict[str, str] = {
    "integer": "int64",
    "float": "float64",
    "record": "struct",
}


def _bq_type_to_api_type(field_type: str) -> str:
    field_type = field_type.lower()
    return _BQ_LEGACY_TYPE_ALIASES.get(field_type, field_type)

A tradução só se aplica ao lado do BigQuery — a API já usa o nome padrão (inclusive BOOLEAN, não BOOL, então esse alias foi deliberadamente deixado de fora).

2. Botão "Sincronizar com o BigQuery"

Aparece ao lado do link do Update, no campo "Update and Poll Info" da página de admin de uma Table — só quando há exatamente 1 Update vinculado (evita gravar no lugar errado se a tabela estiver com Updates duplicados/ambíguos).

class SyncUpdateLatestView(View):
    def post(self, request):
        ...
        updates = list(selected_table.updates.all())
        if len(updates) != 1:
            return JsonResponse({"status": "erro", "erro": "..."})
        update = updates[0]

        gbq_slug = _gbq_slug_for_table(cloud_table)
        bq_table = get_gbq_client().get_table(gbq_slug)

        update.latest = bq_table.modified
        update.save(update_fields=["latest"])

Diagrama de fluxo

Botão "Sincronizar com o BigQuery" (get_update_display, admin.py)
        │
        │  onclick (confirm + disable)
        ▼
syncUpdateLatest()                        (ferramentas.js)
        │
        │  POST /admin-tools/sync-update-latest/
        ▼
SyncUpdateLatestView.post()               (views.py)
        │
        │  resolve o único Update da Table
        │  get_gbq_client().get_table(gbq_slug).modified
        ▼
Update.latest = last_modified real do BigQuery
        │
        ▼
modal com spinner → mensagem de sucesso/erro → fecha e recarrega a página

_gbq_slug_for_table() foi extraído como helper compartilhado entre as duas views, pra manter a mesma lógica de projeto por ambiente (is_prd()):

def _gbq_slug_for_table(cloud_table) -> str:
    gcp_project_id = "basedosdados" if is_prd() else "basedosdados-dev"
    return f"{gcp_project_id}.{cloud_table.gcp_dataset_id}.{cloud_table.gcp_table_id}"

Proteção contra clique duplicado

Os dois fluxos abrem um modal com spinner assim que a requisição começa — o .modal cobre a tela inteira (position: fixed, z-index: 1000), então não dá pra clicar no botão de novo por baixo dele enquanto a chamada está em andamento. O botão do Sync também é desabilitado como reforço.

Benefícios

  • Legível: várias discrepâncias aparecem uma por linha, com badge, em vez de um bloco de texto com \n
  • Corrige metadados sem SQL direto em produção: o botão de sync substitui o processo manual (GraphQL pra achar o ID + psql via kubectl exec) documentado em Acesso direto ao banco de prod.md
  • Consistente por ambiente: os dois botões respeitam is_prd() — em staging/dev comparam/sincronizam contra basedosdados-dev, em prod contra basedosdados

Acompanhamento

Registro do que foi feito e test plan em #1069. Fecha os dois itens pendentes de #1050.

Compara o schema real da tabela no BigQuery (nome, tipo, descrição das
colunas) com o que está cadastrado na API, no mesmo padrão do botão
"Importar Colunas" já existente. Reaproveita a checagem já feita pelo
script check_metadata.py (repo pipelines), agora acionável direto do
admin sem precisar rodar a action manualmente.
@Winzen Winzen self-assigned this Aug 21, 2026
Checar Metadados agora usa is_prd() para escolher o projeto do BigQuery:
basedosdados-dev quando chamado de staging/dev, basedosdados quando
chamado de prod. Antes comparava sempre contra basedosdados (via
Table.gbq_slug, hardcoded), então staging comparava contra dados que
ainda nem tinham sido promovidos pra prod.
Winzen added 3 commits August 21, 2026 14:46
field.field_type do client do BigQuery retorna o nome legacy do tipo
(INTEGER, FLOAT, RECORD), enquanto bigquery_type na API usa o nome
standard SQL (INT64, FLOAT64, STRUCT) — mesma coluna dava falso positivo
de "tipo diferente". Mesmos aliases do check_metadata.py (repo
pipelines), que já lida com essa mesma divergência.
A tradução (INTEGER->INT64, FLOAT->FLOAT64, RECORD->STRUCT) só faz
sentido no lado do BigQuery — a API já usa o nome padrão. Normalizar os
dois lados pela mesma tabela de alias escondia um bug: o alias
"boolean"->"bool" (copiado do check_metadata.py) não vale pra essa API,
que usa BOOLEAN — teria dado falso positivo numa coluna booleana real.
Checar Metadados agora devolve discrepâncias estruturadas e mostra o
resultado num modal (uma linha por discrepância, com badge por tipo),
em vez de um alert() com texto solto.

Novo botão "Sincronizar com o BigQuery" ao lado do "Update and Poll
Info" na página de admin da Table: grava o last_modified real do
BigQuery em Update.latest sem precisar esperar o próximo flow rodar.
Só aparece quando há exatamente 1 Update vinculado à tabela, e usa o
mesmo helper de projeto/ambiente (basedosdados-dev fora de prod) do
Checar Metadados.

Os dois mostram progresso num modal com spinner e bloqueiam o botão
enquanto a requisição está em andamento, evitando cliques repetidos.
Winzen added a commit that referenced this pull request Aug 22, 2026
… - staging - #1068

O botão "Checar Metadados" (introduzido nos PRs #1066/#1067) comparava o schema da Table no BigQuery com as Columns cadastradas na API, mas mostrava o resultado num alert() de texto solto — difícil de ler quando há várias discrepâncias.

Esse PR também adiciona um botão pra sincronizar Update.latest com o BigQuery direto da UI, sem precisar de acesso ao banco — contexto completo em #1069.
@Winzen Winzen added the prod Indica que o Pull Request está com a branch de destino (base) apontando para main label Aug 22, 2026
@Winzen Winzen changed the title feat: adiciona botão "Checar Metadados" no admin de Table feat: modal pro Checar Metadados e botão de sincronizar Update.latest Aug 22, 2026
@Winzen Winzen linked an issue Aug 22, 2026 that may be closed by this pull request
5 tasks
@Winzen
Winzen merged commit 6cbb9d5 into main Aug 22, 2026
8 checks passed
@Winzen
Winzen deleted the feat/check-metadados-button branch August 22, 2026 08:34
github-actions Bot added a commit that referenced this pull request Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prod Indica que o Pull Request está com a branch de destino (base) apontando para main

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Checar Metadados em modal e botão Sincronizar Update.latest

1 participant