Skip to content

[Evolução do PR #1449] Atualiza o serviço de registro de XMLs do PID Provider com auditoria por documento e controle dinâmico no Wagtail - #1466

Merged
pitangainnovare merged 32 commits into
scieloorg:mainfrom
pitangainnovare:feature/pid-provider
Aug 7, 2026

Conversation

@pitangainnovare

Copy link
Copy Markdown
Contributor

O que esse PR faz?

Este PR consolida o novo serviço de registro e auditoria de documentos XML no PID Provider. Ele combina a reestruturação vinda do PR #1449 (rebaseada sobre a main atualizada com o PR #1460) com novas melhorias, correções de robustez e configurações dinâmicas desenvolvidas nesta branch.


🆕 Novas Implementações e Ajustes Criados Nesta Branch:

  1. Configuração Dinâmica no Wagtail Admin (PidProviderSetting):
    • Criação do modelo PidProviderSetting (BaseGenericSetting) e da migração 0018_pidprovidersetting.py.
    • Permite que administradores ativem/desativem a gravação de auditoria em fluxos limpos (created, updated, skipped) em tempo de execução via interface web (/admin/settings/pid_provider/pidprovidersetting/), sem necessidade de variáveis de ambiente ou reinicialização.
  2. Robustez na Representação do XMLVersion:
    • Adição de tratamento defensivo contra nulo no método XMLVersion.__str__ quando o relacionamento pid_provider_xml estiver ausente.
  3. Correções na Busca e Interface do Wagtail Admin:
    • Remoção do campo collections dos painéis de edição panel_a e panel_b no PidProviderXML.
    • Correção da propriedade search_fields em XMLVersionViewSet de file__path para file.
  4. Padronização de Status:
    • Atualização de LIGHTWEIGHT_STATUSES em PidProviderXMLRegistration para utilizar o termo oficial 'skipped'.
  5. Cobertura de Testes e Ajustes:
    • Criação da classe de teste RecordAllEventsSettingTest em test_register.py para validar o comportamento da configuração dinâmica.
    • Ajuste do teste partial_body_query em test_query_params.py utilizando assertDictEqual para evitar falhas por ordenação de chaves.
  6. Infraestrutura:
    • Atualização dos comandos do Makefile para a sintaxe moderna do Docker Compose v2 (docker compose).

📦 Estrutura Herdada e Rebaseada do PR #1449:

  • Reescrita do fluxo de correspondência e registro em etapas desacopladas (PidProviderXML.register).
  • Criação do novo modelo de auditoria orientada a eventos/documentos PidProviderXMLRegistration.
  • Refatoração do QueryBuilderPidProviderXML e suporte a hashes body_fingerprint e body_fragment_fingerprint.
  • Atualização da biblioteca packtools para 4.16.11.

Onde a revisão poderia começar?

  1. pid_provider/models.py:
    • Classe PidProviderSetting (configuração no Wagtail Admin).
    • Método PidProviderXML.register (verificação dinâmica de auditoria).
    • XMLVersion.__str__ (tratamento defensivo contra nulo).
  2. pid_provider/wagtail_hooks.py:
    • Correção do campo search_fields em XMLVersionViewSet.
  3. pid_provider/tests/test_register.py:
    • Testes unitários da configuração dinâmica RecordAllEventsSettingTest.

Como este poderia ser testado manualmente?

  1. Configuração Dinâmica no Wagtail Admin:

    • Acesse http://127.0.0.1:8009/admin/settings/pid_provider/pidprovidersetting/.
    • Alterne o checkbox "Gravar todos os eventos de auditoria" e salve.
  2. Testes de Envio via Shell (make django_shell):

    from django.contrib.auth import get_user_model
    from pid_provider.models import PidProviderXML
    from packtools.sps.pid_provider.xml_sps_lib import XMLWithPre
    
    user = get_user_model().objects.first()
    fixture_path = 'pid_provider/fixtures/1809-4457-esa-s1413-4152202020180029.xml'
    with open(fixture_path, 'r', encoding='utf-8') as f:
        xml_str_1 = f.read()
    
    # 1º Envio (Criação): Status 'created'
    xml_obj_1 = list(XMLWithPre.create(xml_content=xml_str_1))[0]
    res1 = PidProviderXML.register(xml_with_pre=xml_obj_1, filename="esa.xml", user=user)
    
    # 2º Envio (Idêntico): Status 'skipped' (sem nova versão)
    xml_obj_2 = list(XMLWithPre.create(xml_content=xml_str_1))[0]
    res2 = PidProviderXML.register(xml_with_pre=xml_obj_2, filename="esa.xml", user=user)
    
    # 3º Envio (Dado alterado): Status 'updated' (cria nova versão XMLVersion no disco)
    xml_str_3 = xml_str_1.replace('0000-0003-3365-4708', '0000-0000-0000-0000')
    xml_obj_3 = list(XMLWithPre.create(xml_content=xml_str_3))[0]
    res3 = PidProviderXML.register(xml_with_pre=xml_obj_3, filename="esa.xml", user=user)
    
    # 4º Envio (Sem metadados): Status 'bad_request' ou 'error'
    xml_bad_str = '<article><front><journal-meta></journal-meta><article-meta></article-meta></front></article>'
    xml_bad_obj = list(XMLWithPre.create(xml_content=xml_bad_str))[0]
    res4 = PidProviderXML.register(xml_with_pre=xml_bad_obj, filename="empty_meta.xml", user=user)
  3. Verificação no Admin:

    • Com a opção desativada: Apenas o 4º envio (erro) gerará registro em PidProviderXML Registrations (/admin/snippets/pid_provider/pidproviderxmlregistration/).
    • Com a opção ativada: Todos os 4 envios gerarão registros de auditoria.

Algum cenário de contexto que queira dar?

Esta branch substitui a proposta do PR #1449, rebaseando o trabalho sobre a main atualizada (que incorporou o PR #1460) e adicionando novas melhorias e correções identificadas durante os testes.

Por padrão, a auditoria em PidProviderXMLRegistration grava apenas erros e ambiguidades para otimizar o banco em produção. No entanto, adicionamos o modelo PidProviderSetting no Wagtail Admin para permitir ativar a auditoria completa dinamicamente via interface web sem necessitar de novas variáveis de ambiente ou reinicialização do servidor.


Screenshots

  • Configurações do PID Provider no Wagtail Admin:
pid_provider_flag

Quais são os tickets relevantes?


Referências

  • Documentação Wagtail Settings (wagtail.contrib.settings)

Segurança da informação (NSI.04)

Seção obrigatória. Marque as opções aplicáveis e justifique quando necessário. Referência: NSI.04 - Norma de Desenvolvimento Seguro.

Este PR manipula dados sensíveis ou pessoais (LGPD)?

  • Sim — descreva os controles de proteção aplicados (criptografia, mascaramento, anonimização, etc.):
  • Não

Este PR altera autenticação, autorização, controle de acesso ou gerenciamento de sessão?

  • Sim — descreva o que mudou e por quê:
  • Não

Este PR introduz, atualiza ou remove dependências de terceiros?

  • Sim — as novas dependências foram verificadas no SBOM/Trivy sem vulnerabilidades críticas/altas em aberto?
    • Verificado e aprovado (packtools atualizado para 4.16.11)
    • Pendente / vulnerabilidade aceita com justificativa:
  • Não

Este PR foi validado pelo pipeline de segurança (SonarQube / Trivy)?

  • Sim — link do job:
  • Não aplicável a este PR (justifique):

Este PR concatena, monta ou executa comandos SQL, HTML ou JavaScript a partir de entrada externa?

  • Sim — confirme que há sanitização/parametrização (prepared statements, escaping, etc.):
  • Não

Este PR expõe novos endpoints, telas ou serviços?

  • Sim — HTTPS obrigatório está garantido e o acesso segue o princípio de menor privilégio?
  • Não

Algum segredo, senha, chave ou token está sendo adicionado ao código-fonte?

  • Não, nenhum segredo foi commitado
  • Sim (bloquear merge e corrigir antes de prosseguir)

robertatakenaka and others added 30 commits August 6, 2026 16:15
Propósito: disponibilizar os novos métodos do packtools utilizados pelas
refatorações do pid_provider (get_article_data, get_complete_publication_date,
deprecated_sps_pkg_name_list, get_body_fragment).
Solução técnica: bump de versão fixado via git+https no requirements/base.txt.
Propósito: padronizar os valores possíveis do campo status do modelo XMLURL,
substituindo texto livre por opções controladas.
Solução técnica: cria XMLURL_STATUS_SUCCESS, XMLURL_STATUS_XML_FETCH_FAILED,
XMLURL_STATUS_PID_PROVIDER_XML_FAILED e a tupla XMLURL_STATUS.
Propósito: permitir que is_updated() sinalize, via exceção, que o registro
deve ser ignorado (equal ou já atualizado), em vez de retornar dados
silenciosamente.
Solução técnica: cria a classe SkipSavePidProviderXML(Exception).
…omparação por similaridade

Propósito: substituir o cálculo de score aditivo por campo por comparação
percentual baseada em similaridade textual, e simplificar o builder de
queries centralizando o acesso aos dados do adaptador.
Solução técnica: adiciona compare/compare_items/compare_lists usando
how_similar; QueryBuilderPidProviderXML passa a usar adapter_data,
compare_data e xml_with_pre_data como fonte única, com validate_input_data()
e article_location_params novos; remove as antigas cached_property
espelhando atributos do xml_adapter.
…e XML e cria auditoria por documento

Propósito: tornar o processo de identificação de documentos já registrados
mais preciso (comparação por similaridade em estágios) e garantir
rastreabilidade de toda tentativa de registro (sucesso, erro, conflito,
skip), substituindo o modelo de eventos XMLEvent.
Solução técnica:
- get_records/get_record/best_matches substituídos por select_records
  (generator em estágios: ids, journal-issue-article, journal-article),
  select_record e get_best_match, usando percentual_score.
- PidProviderXML.register() reescrito com try/except/finally, sempre
  gravando o evento via PidProviderXMLRegistration.record().
- is_updated() passa a levantar SkipSavePidProviderXML em vez de retornar
  registered.data.
- Novo PidProviderXMLManager aplicando select_related('current_version')
  por padrão.
- Novo campo readable_data em PidProviderXML.
- add_collections extraído de _save(), com fallback via FieldError entre
  scielojournal e journalproc (compatibilidade upload/core).
- Corrige bug em merge_records (other_pid.version, não
  other_pid.current_version) e em mark_items_as_invalid (persiste o status
  calculado via bulk_update).
- XMLURL ganha os campos detail e is_public e o classmethod record().
- Remove modelo XMLEvent e o método add_event().
…o de XMLEvent

Propósito: aplicar no banco de dados as mudanças de modelo introduzidas na
refatoração do pid_provider.
Solução técnica: cria o modelo PidProviderXMLRegistration com seus índices
(pid_provide_pkg_nam_2db0b2_idx, pid_provide_event_s_3c9ae7_idx,
pid_provide_created_94fb08_idx, pid_provide_pid_pro_c9fb0e_idx); remove os
campos creator, ppxml e updated_by de XMLEvent e em seguida exclui o modelo
XMLEvent; adiciona readable_data em PidProviderXML; adiciona detail e
is_public em XMLURL, altera o campo status (com choices) e cria o índice
pid_provide_is_public_idx.
…onViewSet no Wagtail admin

Propósito: permitir consulta, pela interface administrativa, das URLs com
falha de processamento (XMLURL) e dos eventos de auditoria de registro de
XML (PidProviderXMLRegistration).
Solução técnica: cria XMLURLViewSet e PidProviderXMLRegistrationViewSet
(list_display, list_filter, search_fields e select_related no
get_queryset) e os inclui em PidProviderViewSetGroup.
…erXML

Propósito: Reverter a remoção do model XMLEvent feita em refatoração
anterior — o rastreio de eventos por documento (registration attempts,
validation errors, etc.) via XMLEvent ainda é necessário e não deve ser
substituído pelo novo PidProviderXMLRegistration, que serve a um
propósito complementar (auditoria agregada de register()), não ao
histórico de eventos por instância de PidProviderXML.

Solução técnica: Reintroduzido o import de BaseEvent em
'from tracker.models import BaseEvent, UnexpectedEvent'. Restaurado o
método PidProviderXML.add_event(name, proc_status, detail=None,
errors=None, exceptions=None), que atualiza proc_status, salva a
instância e delega o registro do evento a XMLEvent.register(). Restaurado
o model XMLEvent(BaseEvent, CommonControlField), com o campo ppxml
(ParentalKey para PidProviderXML, related_name='events') e o classmethod
register(), que cria a instância, marca completed conforme presença de
errors/exceptions e delega a finalização a BaseEvent.finish().
Propósito: Consistência com a reversão feita em models.py — como o model
XMLEvent voltou a existir no código, a migration 0017 (que removia seus
campos creator/ppxml/updated_by e por fim o próprio model via
DeleteModel) deixou de refletir o estado real dos models e precisa ser
descartada.

Solução técnica: Excluído o arquivo
pid_provider/migrations/0017_pidproviderxmlregistration_remove_xmlevent_creator_and_more.py.
A criação de PidProviderXMLRegistration e os demais campos que essa
migration também introduzia (readable_data, XMLURL.detail/is_public,
choices de XMLURL.status, índices) precisam ser recriados em uma nova
migration, desta vez sem a remoção de XMLEvent — rodar
'python manage.py makemigrations pid_provider' para gerá-la a partir do
estado atual dos models.
…dência de artigos

Propósito:
A query anterior usava OR (|) entre z_surnames, z_collab, z_links e
z_partial_body, o que permitia que documentos totalmente diferentes
fossem retornados como correspondência só por coincidirem em
z_partial_body — campo que, no formato antigo, era o hash do primeiro
parágrafo e acabava coincidindo com títulos de seção repetidos entre
artigos distintos. Isso gerava falsos positivos no select_records.

Solução técnica:
- compare_items: usa 'input_data or ""' e 'registered or ""' antes de
  chamar how_similar, evitando passar None para a função de similaridade.
- article_data_query: removida a lógica OR entre os campos textuais;
  agora sempre retorna um Q com AND entre z_surnames, z_collab, z_links
  e z_partial_body, exigindo que todos os campos disponíveis coincidam
  simultaneamente, eliminando a ambiguidade do OR.
- Novo método get_article_data_query(issue), separando a combinação da
  query de dados do artigo conforme o escopo da busca:
  - issue=True: article_data_query & issue_params & article_location_params
    (correspondência dentro de um fascículo específico).
  - issue=False: article_data_query & filtro garantindo
    volume/number/suppl/elocation_id/fpage/lpage nulos (correspondência
    apenas por journal + dados do artigo, sem fascículo, evitando
    confundir com artigos de fascículos diferentes).
…t_records

Propósito:
Migrar o fingerprint principal de correspondência de artigos de
z_partial_body para body_fragment_fingerprint, disponibilizar os dados
legíveis do artigo com fallback ao XML, e centralizar a lógica de query
de seleção de registros no QueryBuilderPidProviderXML.

Solução técnica:
- Adicionado comentário documentando a migração de z_partial_body (hash
  do primeiro parágrafo, ambíguo) para body_fragment_fingerprint (hash de
  300 caracteres); registros antigos mantêm o valor legado e a query de
  match passa a cobrir ambos os formatos sem exigir backfill.
- Novo método get_readable_data(): retorna self.readable_data se já
  existir; caso contrário, calcula via self.xml_with_pre.get_article_data();
  retorna {} se não houver XML disponível.
- as_dict() passa a incluir os dados de get_readable_data() no dicionário
  retornado.
- data_to_compare agora usa get_readable_data() em vez de acessar
  readable_data diretamente, garantindo dados mesmo antes da persistência.
- select_records: substituídas as queries inline
  (Q(**qbuilder.issue_params) & qbuilder.article_data_query e
  qbuilder.article_data_query) pelas chamadas
  qbuilder.get_article_data_query(issue=True) e
  qbuilder.get_article_data_query(issue=False), centralizando a lógica de
  filtro no QueryBuilder.
- z_partial_body passa a ser preenchido a partir de
  xml_adapter.xml_with_pre.body_fragment_fingerprint, em vez de
  xml_adapter.z_partial_body.
…_query

Propósito:
Registros gravados antes desta correção têm z_partial_body como hash do
primeiro parágrafo não vazio do corpo (formato legado, sujeito a
colisão entre artigos diferentes que compartilham o mesmo texto de
seção, ex.: rótulos genéricos como "ARTIGO DE REVISÃO"). A partir de
agora, o campo passa a ser preenchido com o fingerprint do corpo INTEIRO
do artigo (xml_with_pre.body_fragment_fingerprint), mais robusto. É
preciso que a query de correspondência aceite ambos os formatos
simultaneamente, sem exigir migração/backfill dos registros antigos.

Solução técnica:
- __init__: adiciona self.z_body_fragment, obtido diretamente de
  xml_adapter.xml_with_pre.body_fragment_fingerprint, sem exigir
  mudanças no packtools nem no PidProviderXMLAdapter.
- Novo property partial_body_query:
  - Reúne em candidates os hashes não vazios entre
    adapter_data['z_partial_body'] (formato legado) e
    self.z_body_fragment (formato atual).
  - Se houver candidatos, usa Q(z_partial_body__in=candidates) para
    casar com registros gravados em qualquer um dos dois formatos.
  - Se não houver nenhum candidato (ambos None), usa
    Q(z_partial_body__isnull=True) explicitamente — evita usar
    z_partial_body__in=(None, None), que em SQL nunca retorna resultados
    porque IN é uma cadeia de igualdades e NULL = NULL é UNKNOWN, não
    True. Isso preserva o comportamento equivalente ao antigo
    Q(z_partial_body=None), que o Django traduz para IS NULL.
- article_data_query: remove o acesso direto a z_partial_body e a
  comparação Q(z_partial_body=z_partial_body); passa a compor o Q final
  com '& self.partial_body_query', delegando a lógica de correspondência
  do campo ao novo property.
Propósito:
Tornar o diretório de testes reconhecido como pacote Python, permitindo
que os módulos de teste (test_query_params, test_get_best_match,
test_select_record, test_select_records, test_register) sejam
descobertos e importados corretamente pelo test runner.

Solução técnica:
- Arquivo vazio, apenas com a função de marcar o diretório como pacote.
Propósito:
Cobrir com testes unitários a lógica de construção de queries em
QueryBuilderPidProviderXML, incluindo article_data_query,
partial_body_query e get_article_data_query, garantindo que as
correções recentes de ambiguidade (OR entre campos textuais, suporte a
dois formatos de hash em z_partial_body e tratamento de valores nulos)
se comportem conforme esperado.

Solução técnica:
- Casos de teste cobrindo cenários com e sem candidatos de hash
  disponíveis (z_partial_body legado, body_fragment_fingerprint atual,
  ambos ausentes).
- Verificação de que get_article_data_query(issue=True/False) monta
  corretamente a combinação com issue_params e article_location_params
  ou com o filtro de campos de fascículo nulos.
Propósito:
Cobrir com testes unitários a lógica de seleção do melhor candidato
dentre múltiplos registros retornados pela query de correspondência,
validando o cálculo de similaridade e o critério de desempate.

Solução técnica:
- Casos de teste com mocks simulando diferentes níveis de similaridade
  entre o XML de entrada e os candidatos registrados.
- Verificação do comportamento em cenários de match exato, parcial e
  ausência de candidatos.
Propósito:
Cobrir com testes unitários o fluxo de seleção de um único registro
correspondente ao XML de entrada, incluindo a integração com o
resultado de get_best_match.

Solução técnica:
- Casos de teste simulando diferentes conjuntos de resultados retornados
  pela query de seleção, verificando o registro escolhido em cada
  cenário.
Propósito:
Cobrir com testes unitários o pipeline de seleção de múltiplos
candidatos (por journal-issue-article e journal-article), validando a
integração com QueryBuilderPidProviderXML.get_article_data_query nos
dois escopos (issue=True/False).

Solução técnica:
- Casos de teste com mocks para os diferentes yields do gerador de
  seleção de registros, cobrindo cenários com e sem dados de fascículo.
Propósito:
Cobrir com testes unitários o fluxo completo de registro de um XML,
incluindo a seleção de registros existentes, atualização ou criação de
PidProviderXML e a gravação dos campos derivados (z_surnames, z_collab,
z_links, z_partial_body via body_fragment_fingerprint).

Solução técnica:
- Casos de teste simulando cenários de criação, atualização e
  registros já existentes, com mocks para as dependências externas
  (xml_adapter, xml_with_pre).
- Verificação de que os campos textuais e o novo fingerprint de corpo
  são persistidos corretamente conforme a lógica revisada em
  models.py e query_params.py.
Propósito: Atualizar a versão fixada do packtools no requirements/base.txt.

Solução técnica: Bump de packtools de 4.16.8 para 4.16.11 via egg
git+https://github.com/scieloorg/packtools.git@4.16.11#egg=packtools,
versão que corrige o bug de XMLWithPre.body_fragment_fingerprint
(que retornava incorretamente o fingerprint do corpo INTEIRO em vez
do fragmento), e cria XMLWithPre.body_fingerprint que retorna fingerprint do corpo INTEIRO, pré-requisito para a correção em query_params.py.
…l_body_query

Propósito: Corrigir falso-positivo de match em
QueryBuilderPidProviderXML.partial_body_query causado pelo bug do
XMLWithPre.body_fragment_fingerprint, que retornava o fingerprint do
corpo INTEIRO do artigo em vez do fragmento, permitindo colisão entre
artigos diferentes com rótulos de seção genéricos (ex.: 'ARTIGO DE
REVISÃO').

Solução técnica: Adiciona leitura de xml_with_pre.body_fingerprint
(novo atributo, fingerprint do corpo INTEIRO) em self.z_body, mantendo
self.z_body_fragment como fingerprint do FRAGMENTO (agora corrigido no
packtools 4.16.11). partial_body_query passa a compor candidates com
os três hashes disponíveis (z_partial_body legado, z_body_fragment,
z_body), preservando fallback para z_partial_body__isnull=True quando
nenhum estiver presente. Remove também variável morta other_pids em
identifier_queries.
…t em partial_body_query

Propósito: Validar a correção de partial_body_query após o fix do
bug em XMLWithPre.body_fragment_fingerprint, garantindo que o
fingerprint do corpo INTEIRO (body_fingerprint) e o do fragmento
(body_fragment_fingerprint) sejam tratados como candidatos distintos
e corretos, evitando regressão do falso-positivo original.

Solução técnica: Adiciona parâmetro body_fingerprint em
make_xml_adapter, setando explicitamente
adapter.xml_with_pre.body_fingerprint (default None) para evitar Mock
truthy espúrio nas asserções. Ajusta testes existentes para usar
'hash-fragmento-do-corpo' em vez de 'hash-corpo-inteiro' onde o valor
representa body_fragment_fingerprint, e para comparar
z_partial_body__in com set (não list), refletindo a implementação em
produção. Adiciona novos testes cobrindo os três hashes combinados
(test_combines_textual_fields_with_all_three_body_hashes) e a
regressão direta do incidente
(test_two_articles_with_same_legacy_hash_but_different_body_fingerprint_differ).
… nulo

Propósito: Prevenir exceções ao renderizar objetos XMLVersion sem relacionamento ativo no admin do Wagtail.
Solução técnica: Adiciona verificação defensiva de valor nulo no método __str__ do modelo XMLVersion.
…ions

Propósito: Adequar a interface do Wagtail Admin à estrutura atual do modelo PidProviderXML.
Solução técnica: Remove o campo collections dos painéis de edição panel_a e panel_b em pid_provider/models.py.
… skipped

Propósito: Alinhar os status leves de auditoria com a convenção de nomenclatura oficial do sistema.
Solução técnica: Atualiza o conjunto LIGHTWEIGHT_STATUSES para utilizar 'skipped' em vez de 'skip_update'.
…ara controle dinâmico de auditoria

Propósito: Permitir o controle em tempo de execução da gravação de auditoria em fluxos limpos via interface web sem necessidade de alterar variáveis de ambiente ou reiniciar a aplicação.
Solução técnica: Cria o modelo PidProviderSetting (BaseGenericSetting) com o campo record_all_registration_events, adiciona a migração 0018_pidprovidersetting.py e atualiza o método PidProviderXML.register para consultar a configuração dinamicamente.
Propósito: Corrigir o campo utilizado para pesquisa de versões de arquivos XML no Wagtail Admin.
Solução técnica: Altera a propriedade search_fields em XMLVersionViewSet no arquivo pid_provider/wagtail_hooks.py de 'file__path' para 'file'.
…ting no registro

Propósito: Garantir cobertura de testes automatizados para o comportamento da nova configuração dinâmica de auditoria.
Solução técnica: Atualiza a documentação do módulo de testes e adiciona a classe RecordAllEventsSettingTest realizando o mock de PidProviderSetting.load().
Propósito: Evitar falhas esporádicas nos testes provocadas por variações de ordenação de chaves em dicionários.
Solução técnica: Utiliza assertDictEqual sobre as representações em dicionário das estruturas de query em pid_provider/tests/test_query_params.py.
Propósito: Adequar os comandos e atalhos do Makefile às versões atuais e recomendadas do Docker CLI.
Solução técnica: Substitui os comandos hifenizados docker-compose por docker compose em todos os alvos do Makefile.
Propósito: Criar a tabela no banco de dados para armazenar as configurações dinâmicas do PID Provider no Wagtail Admin.
Solução técnica: Adiciona o arquivo de migração 0018_pidprovidersetting.py gerado pelo Django.
@pitangainnovare
pitangainnovare merged commit 2f3fd64 into scieloorg:main Aug 7, 2026
3 checks passed
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.

Unificar as mudanças no pid_provider do scms-upload e do core: auditoria de registro, aprimoramento de matching/persistência e otimizações de query

2 participants