Skip to content

Triagem por criticidade da duplicação de artigos após falha do Core + testes automatizados de conectividade#951

Draft
Copilot wants to merge 2 commits into
mainfrom
copilot/fix-duplicate-articles-migration
Draft

Triagem por criticidade da duplicação de artigos após falha do Core + testes automatizados de conectividade#951
Copilot wants to merge 2 commits into
mainfrom
copilot/fix-duplicate-articles-migration

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 29, 2026

O que esse PR faz?

Conforme solicitado nos comentários da issue, este PR entrega:

  1. Triagem por criticidade dos problemas que levam à duplicação de artigos (mesmo PID v2, PIDs v3 diferentes) quando o Core fica indisponível durante a migração. O objetivo é permitir decidir o escopo da correção antes de implementá-la. Não há alterações em código de produção.
  2. Dois testes automatizados (pid_provider/test_requester.py) que cobrem os cenários de conectividade com o Core durante a migração, conforme solicitado no review.

Resumo dos achados, ordenados por criticidade:

  • 🔴 Crítico — causa raiz

    • Cria as apps upload, journals e migration #1 pid_provider/requester.py:102-119 — em request_pid_for_xml_with_pre, o error_type retornado por remote_registration fica apenas em remote_response e nunca é copiado para registered. A guarda if registered.get("error_type") não dispara, e o fluxo segue para local_registration, que gera um PID v3 local via PidProviderXML.register. Esse PID nunca é conhecido pelo Core e dá origem a toda divergência futura.
    • Adiciona templates para preencher issues e PR #2 proc/models.py:2094-2146 (ArticleProc.generate_sps_package) — no reprocessamento (status REPROC por registered_in_core=False), o xml_with_pre é reconstruído a partir de processed_xml sem injetar self.sps_pkg.pid_v3. O Core então emite novo PID v3 e SPSPkg._get_or_create cria um SPSPkg paralelo ao antigo.
  • 🟠 Alto — reconciliação sem reexecutar migração (atende explicitamente a instrução do agente)

    • Crear un perfil de journal_profile #3 package/models.py:422-437, 549-597SPSPkg._get_or_create cria novo registro quando o Core devolve PID v3 diferente do já vinculado ao mesmo ArticleProc. Deveria atualizar o SPSPkg/Article existente para o novo PID v3 e remover o antigo na hora, em vez de depender da próxima execução de task_exclude_article_repetition_by_issue (hoje disparada apenas no início de task_migrate_and_publish_articles_by_issue, proc/tasks.py:1054).
  • 🟡 Médio — robustez

  • 🔵 Baixo — defesa em profundidade

  • 🟢 Muito baixo — observabilidade

Plano sugerido: implementar #1 + #2 + #3 resolve completamente o defeito do issue e o pedido do agente. Demais itens são melhorias incrementais.

Testes adicionados (pid_provider/test_requester.py) — seguindo o padrão de article/test_models.py (unittest puro + MagicMock), isolam o orquestrador request_pid_for_xml_with_pre ao mockar get_registration_demand, remote_registration e local_registration:

  • test_request_pid_when_core_is_unreachable — simula remote_registration retornando {"error_type", "error_msg"} (Core indisponível). Verifica o comportamento correto: o erro deve ser propagado e local_registration não deve ser chamado, evitando a criação de PID v3 local que causa a duplicação. Marcado com @unittest.expectedFailure enquanto o bug crítico Cria as apps upload, journals e migration #1 não é corrigido — atua como documentação executável do defeito. Quando Cria as apps upload, journals e migration #1 for corrigido, basta remover o decorator e o teste passa a servir como teste de regressão.
  • test_request_pid_when_core_is_reachable — caminho feliz: remote_registration devolve PID v3 do Core e atualiza registered in-place; local_registration é chamado em seguida com o mesmo PID v3; o resultado final tem registered_in_core=True, registered_in_upload=True e synchronized=True, sem error_type.

Onde a revisão poderia começar?

  1. pid_provider/test_requester.py — único arquivo novo desta PR; valida ambos os cenários de conectividade com o Core.
  2. Para validar a triagem analítica, ler nesta ordem:
    • pid_provider/requester.pyrequest_pid_for_xml_with_pre (ll. 77–126), remote_registration (ll. 176–213), local_registration (ll. 215–264).
    • proc/models.pyArticleProc.generate_sps_package (ll. 2094–2146), update_sps_pkg_status (ll. 2162–2170).
    • package/models.pySPSPkg._get_or_create (ll. 422–437) e _add_pid_v3_to_zip (ll. 549–597).
    • proc/tasks.py:1054 — invocação síncrona de task_exclude_article_repetition_by_issue.

Como este poderia ser testado manualmente?

Execução dos testes automatizados (no ambiente Docker do projeto, conforme .github/workflows/ci.yml):

docker-compose -f local.yml run django pytest pid_provider/test_requester.py -v

Esperado:

Reprodução manual do defeito original segue os passos do issue:

  1. Configurar fascículo novo com Core desligado.
  2. Executar migração — observar que artigos são publicados com PID v3 local.
  3. Religar Core e reexecutar migração — observar criação de registros adicionais com mesmo PID v2 e PID v3 distinto em Articles > Articles e no TOC do OPAC_5.

Algum cenário de contexto que queira dar?

Origem do bug: o pipeline de migração foi desenhado assumindo que o Core sempre estaria disponível como autoridade de PID v3. Quando o Core falha, o fluxo cai num caminho de fallback (local_registration) que silenciosamente gera PID v3 local; quando o Core volta, não há mecanismo para "casar" o PID local com o que o Core emitiria, então ambos coexistem como artigos distintos. A reconciliação atual depende de uma nova execução completa da migração para que a task de limpeza rode.

Os testes adicionados deixam ambos os comportamentos (esperado e bugado) versionados como especificação executável, facilitando o trabalho de quem implementar as correções dos itens #1, #2 e #3.

Screenshots

Não aplicável.

Quais são tickets relevantes?

Triagem referente ao issue de duplicação após falha do Core durante migração de fascículo (Upload v2.12.0rc4 / Core v3.12.5 / OPAC_5 v5.10.22-qa).

Referências

  • pid_provider/requester.pyPidRequester.request_pid_for_xml_with_pre, remote_registration, local_registration
  • article/test_models.py — padrão de testes unitários com mocks utilizado como referência para pid_provider/test_requester.py
  • proc/article_controller.pyClassicWebsiteArticlePidTracker
  • article/models.pyArticle.exclude_inconvenient_articles, get_repeated_items
  • article/migrations/0008_add_unique_pid_v3.py
  • docs/processing/guide_task_track_classic_website_article_pids_pt.md

Copilot AI changed the title [WIP] Fix duplicated articles with different PIDs in migration process Triagem por criticidade da duplicação de artigos após falha do Core Apr 29, 2026
Copilot AI requested a review from robertatakenaka April 29, 2026 22:40
@robertatakenaka
Copy link
Copy Markdown
Member

@copilot crie 1 teste automatizado que trata o caso de migração que não consegue conexão com o core e outro teste automatizado que consegue a conexão com o core

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 30, 2026

@copilot crie 1 teste automatizado que trata o caso de migração que não consegue conexão com o core e outro teste automatizado que consegue a conexão com o core

Adicionei dois testes automatizados em pid_provider/test_requester.py (commit 3e77fc2), seguindo o padrão de article/test_models.py (unittest + mocks):

  • test_request_pid_when_core_is_unreachable — simula remote_registration retornando {"error_type", "error_msg"} (Core fora do ar). Verifica o comportamento correto: o erro deve ser propagado e local_registration não deve ser chamado, evitando a criação de PID v3 local que causa a duplicação relatada na issue. Está marcado como @unittest.expectedFailure enquanto o bug Cria as apps upload, journals e migration #1 não é corrigido — funciona como documentação executável do defeito.
  • test_request_pid_when_core_is_reachable — caminho feliz: remote_registration devolve PID v3 do Core e atualiza registered in-place; local_registration é chamado em seguida com o mesmo PID v3; o resultado final tem registered_in_core=True, registered_in_upload=True e synchronized=True, sem error_type.

Quando os itens críticos #1/#2/#3 forem implementados, basta remover o @expectedFailure para que o primeiro teste passe e atue como teste de regressão.

Copilot AI changed the title Triagem por criticidade da duplicação de artigos após falha do Core Triagem por criticidade da duplicação de artigos após falha do Core + testes automatizados de conectividade Apr 30, 2026
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.

[Migração de Artigos] Artigos duplicados com mesmo PID v2 e PID v3 diferentes após falha de conexão com o Core

2 participants