Skip to content

Criar validações para o elemento <funding-group> #1085

@Rossi-Luciano

Description

@Rossi-Luciano

Objetivo

Implementar validações para o elemento <funding-group> conforme a especificação SPS 1.10, aumentando a conformidade de X% para 70% (7 de 10 regras).

Nota: Algumas validações para <funding-group> podem já estar parcialmente implementadas no repositório. Este Issue visa reavaliar, complementar e garantir cobertura completa das regras SPS 1.10.


Contexto

O elemento <funding-group> é usado para declarar informações estruturadas sobre financiamento e apoio à pesquisa. Essas informações devem estar sincronizadas com notas de documento (<fn fn-type="financial-disclosure"> ou <fn fn-type="supported-by">) ou agradecimentos (<ack>). Validações corretas garantem consistência entre as diferentes seções do documento e completude das informações de financiamento.

Conformidade atual: X de 10 regras implementadas (X%)
Meta após implementação: 7 de 10 regras (70%)


Documentação SPS

Referência oficial: https://docs.google.com/document/d/1GTv4Inc2LS_AXY-ToHT3HmO66UT0VAHWJNOIqzBNSgA/edit?tab=t.0#heading=h.fundinggroupfinanciapoio

Regras principais conforme SPS 1.10:

  1. Ocorrência:

    • <funding-group> deve aparecer no máximo uma vez em <article-meta>
  2. Estrutura obrigatória:

    • <funding-statement> é obrigatório em todos os casos
    • Quando há instituições declaradas: <funding-source> é obrigatório
    • Quando há número de contrato: <award-id> é obrigatório
  3. Organização:

    • Cada <award-group> agrupa <funding-source> com seu respectivo <award-id>
    • Múltiplas instituições com o mesmo número de contrato ficam no mesmo <award-group>
    • Instituições com números de contrato diferentes ficam em <award-group> separados
  4. Restrições de elementos filhos:

    • Não permitido: <label> ou <title> dentro de <funding-group>
  5. Sincronização com outras seções:

    • Texto em <funding-statement> deve replicar informações de:
      • <fn fn-type="financial-disclosure"> (financiamento com contrato)
      • <fn fn-type="supported-by"> (apoio sem contrato)
      • <ack> (agradecimentos com informações de financiamento)
  6. Declaração negativa de financiamento:

    • Quando não há financiamento, deve existir <funding-group> apenas com <funding-statement> declarando isso

Regras a Implementar

P0 – Críticas (implementar obrigatoriamente)

# Regra Nível Descrição
1 Validar unicidade de <funding-group> ERROR O elemento <funding-group> deve aparecer no máximo uma vez em <article-meta>
2 Validar presença de <funding-statement> CRITICAL O elemento <funding-statement> é obrigatório em <funding-group>
3 Validar presença de <funding-source> quando há instituições CRITICAL Quando <award-group> existe, deve conter pelo menos um <funding-source>
4 Validar presença de <award-id> quando há contrato ERROR Quando <funding-source> menciona número de contrato no texto, deve existir <award-id> correspondente

P1 – Importantes (implementar se possível)

# Regra Nível Descrição
5 Validar ausência de <label> em <funding-group> ERROR O elemento <label> não é permitido dentro de <funding-group> ou seus filhos
6 Validar ausência de <title> em <funding-group> ERROR O elemento <title> não é permitido dentro de <funding-group> ou seus filhos
7 Validar consistência de quantidade de <funding-source> e <award-id> WARNING Em cada <award-group>, a quantidade de <award-id> deve ser compatível: 0 (apoio sem contrato), 1 (um contrato), ou N (múltiplos contratos para múltiplas fontes)

P2 – Futuras (fora do escopo deste Issue)

# Regra Motivo de exclusão
8 Validar sincronização de texto entre <funding-statement> e <fn> ou <ack> Alta complexidade - requer análise semântica e comparação de texto livre
9 Validar que instituições em <funding-source> aparecem no texto de <funding-statement> Alta complexidade - requer análise de texto e matching fuzzy
10 Validar que números em <award-id> aparecem no texto de <funding-statement> Média complexidade - requer análise de texto e extração de padrões

Arquivos a Criar/Modificar

Avaliar existentes (podem ter validações parciais):

  • packtools/sps/models/funding.py ou similar – Verificar se modelo existe
  • packtools/sps/validation/funding.py ou funding_group.py – Verificar validações existentes
  • packtools/sps/validation/rules/funding_rules.json ou similar – Verificar configuração

Criar (se não existirem):

  • packtools/sps/models/funding_group.py – Modelo de extração de dados
  • packtools/sps/validation/funding_group.py – Validações
  • packtools/sps/validation/rules/funding_group_rules.json – Configuração de níveis de erro
  • tests/sps/validation/test_funding_group.py – Testes unitários

Referenciar (implementações similares):

  • packtools/sps/validation/article_doi.py – Validação de unicidade
  • packtools/sps/validation/utils.py – Funções auxiliares (build_response)

Exemplos de XML

XML Válido (deve passar sem erros):

<!-- Exemplo 1: Financiamento com número de contrato -->
<article-meta>
    <funding-group>
        <award-group>
            <funding-source>Fundação de Amparo à Pesquisa do Estado de São Paulo (FAPESP)</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement>This study was supported by Fundação de Amparo à Pesquisa do Estado de São Paulo (FAPESP - Grant no. 04/08142-0; São Paulo, Brazil)</funding-statement>
    </funding-group>
</article-meta>

<!-- Exemplo 2: Duas instituições com o mesmo número de contrato -->
<article-meta>
    <funding-group>
        <award-group>
            <funding-source>FAPESP</funding-source>
            <funding-source>CAPES</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement>This study was supported by FAPESP and CAPES - Grant no. 04/08142-0; São Paulo, Brazil</funding-statement>
    </funding-group>
</article-meta>

<!-- Exemplo 3: Duas instituições com números de contrato diferentes -->
<article-meta>
    <funding-group>
        <award-group>
            <funding-source>FAPESP</funding-source>
            <award-id>05/07183-0</award-id>
        </award-group>
        <award-group>
            <funding-source>CAPES</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement>This study was supported by FAPESP - Grant no. 05/07183-0 and CAPES - Grant no. 04/08142-0; São Paulo, Brazil</funding-statement>
    </funding-group>
</article-meta>

<!-- Exemplo 4: Apoio sem número de contrato -->
<article-meta>
    <funding-group>
        <award-group>
            <funding-source>Fundação de Amparo à Pesquisa do Estado de São Paulo (FAPESP)</funding-source>
        </award-group>
        <funding-statement>This study was supported by Fundação de Amparo à Pesquisa do Estado de São Paulo (FAPESP) - São Paulo, Brazil</funding-statement>
    </funding-group>
</article-meta>

<!-- Exemplo 5: Múltiplas instituições de apoio sem contrato -->
<article-meta>
    <funding-group>
        <award-group>
            <funding-source>Coordenação de Aperfeiçoamento de Pessoal de Nível Superior (Capes)</funding-source>
        </award-group>
        <award-group>
            <funding-source>Fundação de Amparo à Pesquisa do Estado de São Paulo (FAPESP)</funding-source>
        </award-group>
        <funding-statement>This study was supported in part by Coordenação de Aperfeiçoamento de Pessoal de Nível Superior (Capes - Brasília, Brazil), Fundação de Amparo à Pesquisa do Estado de São Paulo (FAPESP)</funding-statement>
    </funding-group>
</article-meta>

<!-- Exemplo 6: Declaração negativa de financiamento -->
<article-meta>
    <funding-group>
        <funding-statement>Não houve financiamento para esta publicação</funding-statement>
    </funding-group>
</article-meta>

<!-- Exemplo 7: Apoio + Financiamento combinados -->
<article-meta>
    <funding-group>
        <award-group>
            <funding-source>Coordenação de Aperfeiçoamento de Pessoal de Nível Superior (Capes)</funding-source>
        </award-group>
        <award-group>
            <funding-source>Fundação de Amparo à Pesquisa do Estado de São Paulo (FAPESP)</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement>The authors would like to thank the support of the Brazilian National Research Council. This study was supported in part by Coordenação de Aperfeiçoamento de Pessoal de Nível Superior (Capes - Brasília, Brazil), Fundação de Amparo à Pesquisa do Estado de São Paulo (FAPESP - Grant no. 04/08142-0; São Paulo, Brazil)</funding-statement>
    </funding-group>
</article-meta>

XML Inválido – Caso 1: Múltiplos (ERROR)

<article-meta>
    <funding-group>
        <award-group>
            <funding-source>FAPESP</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement>Supported by FAPESP - Grant no. 04/08142-0</funding-statement>
    </funding-group>
    <funding-group>
        <award-group>
            <funding-source>CAPES</funding-source>
        </award-group>
        <funding-statement>Supported by CAPES</funding-statement>
    </funding-group>
</article-meta>

Erro esperado: Elemento <funding-group> deve aparecer no máximo uma vez em <article-meta>

XML Inválido – Caso 2: Sem (CRITICAL)

<article-meta>
    <funding-group>
        <award-group>
            <funding-source>FAPESP</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
    </funding-group>
</article-meta>

Erro esperado: Elemento <funding-statement> é obrigatório em <funding-group>

XML Inválido – Caso 3: sem (CRITICAL)

<article-meta>
    <funding-group>
        <award-group>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement>Supported by grant no. 04/08142-0</funding-statement>
    </funding-group>
</article-meta>

Erro esperado: Quando <award-group> existe, deve conter pelo menos um <funding-source>

XML Inválido – Caso 4: dentro de (ERROR)

<article-meta>
    <funding-group>
        <label>Financiamento</label>
        <award-group>
            <funding-source>FAPESP</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement>Supported by FAPESP - Grant no. 04/08142-0</funding-statement>
    </funding-group>
</article-meta>

Erro esperado: Elemento <label> não é permitido dentro de <funding-group>

XML Inválido – Caso 5: <title> dentro de (ERROR)

<article-meta>
    <funding-group>
        <title>Funding Information</title>
        <award-group>
            <funding-source>FAPESP</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement>Supported by FAPESP - Grant no. 04/08142-0</funding-statement>
    </funding-group>
</article-meta>

Erro esperado: Elemento <title> não é permitido dentro de <funding-group>

XML Inválido – Caso 6: Múltiplos sem correspondentes (WARNING)

<article-meta>
    <funding-group>
        <award-group>
            <funding-source>FAPESP</funding-source>
            <award-id>04/08142-0</award-id>
            <award-id>05/07183-0</award-id>
        </award-group>
        <funding-statement>Supported by FAPESP - Grant no. 04/08142-0 and 05/07183-0</funding-statement>
    </funding-group>
</article-meta>

Erro esperado: WARNING - <award-group> tem 1 <funding-source> mas 2 <award-id>. Considere usar award-groups separados ou adicionar funding-sources para cada award-id.

XML Inválido – Caso 7: vazio (CRITICAL)

<article-meta>
    <funding-group>
        <award-group>
            <funding-source>FAPESP</funding-source>
            <award-id>04/08142-0</award-id>
        </award-group>
        <funding-statement></funding-statement>
    </funding-group>
</article-meta>

Erro esperado: <funding-statement> não pode estar vazio

XML Inválido – Caso 8: apenas com espaços (CRITICAL)

<article-meta>
    <funding-group>
        <award-group>
            <funding-source>FAPESP</funding-source>
        </award-group>
        <funding-statement>   </funding-statement>
    </funding-group>
</article-meta>

Erro esperado: <funding-statement> não pode conter apenas espaços em branco


Padrão de Implementação

Diretrizes Gerais:

  1. Seguir padrões existentes no repositório:

    • Consultar implementações similares como article_doi.py (validação de unicidade)
    • Usar estrutura de classes já estabelecida no packtools
    • IMPORTANTE: Verificar se já existem validações parciais para <funding-group> e integrá-las ou complementá-las
  2. Internacionalização (i18n):

    • OBRIGATÓRIO: Todas as mensagens devem suportar internacionalização
    • Usar advice_text e advice_params em build_response()
    • Consultar conversas anteriores sobre implementação de i18n no packtools
    • Referência: validações em article_contribs.py que já implementam i18n completo
  3. Validações condicionais:

    • Validações que dependem de contexto devem retornar None quando não aplicável
    • Exemplo: validação de <award-id> só deve ser executada se existir <award-group>
    • Exemplo: validação de <funding-source> só se aplica quando há <award-group>
    • Usar filter_results() nos testes para remover None
  4. Uso de build_response():

    • Sempre usar parent=self.data (dict completo, nunca string)
    • Campo response deve conter: "OK", "WARNING", "ERROR", "CRITICAL"
    • Sempre fornecer advice_text e advice_params para i18n
  5. Modelo de dados:

    • Criar propriedade que retorna dicionário com dados completos de <funding-group>
    • Dict deve conter: award_groups (lista), funding_statement, has_label, has_title, parent, parent_id, parent_lang
    • Cada award_group deve conter: funding_sources (lista), award_ids (lista)
  6. Validação de unicidade:

    • Contar ocorrências de <funding-group> em <article-meta>
    • Usar XPath para buscar especificamente em <article-meta>, não em todo o documento
  7. Validação de elementos proibidos:

    • Verificar presença de <label> e <title> em qualquer nível dentro de <funding-group>
    • Usar descendant axis no XPath para buscar em profundidade
  8. Validação de texto vazio:

    • Usar .strip() para verificar se <funding-statement> tem conteúdo real
    • Strings com apenas espaços devem ser consideradas inválidas

Testes Esperados

Casos de teste obrigatórios:

Unicidade:

  • Um único <funding-group> em <article-meta> (OK)
  • Dois ou mais <funding-group> em <article-meta> (ERROR)
  • Nenhum <funding-group> em <article-meta> (OK - opcional)

Presença de :

  • <funding-group> com <funding-statement> (OK)
  • <funding-group> sem <funding-statement> (CRITICAL)
  • <funding-statement> vazio (CRITICAL)
  • <funding-statement> apenas com espaços (CRITICAL)
  • <funding-statement> com conteúdo válido (OK)

Presença de :

  • <award-group> com <funding-source> (OK)
  • <award-group> sem <funding-source> (CRITICAL)
  • <award-group> com múltiplos <funding-source> (OK)
  • <funding-group> sem <award-group> (OK - declaração negativa)

Presença de :

  • <award-group> com <funding-source> e <award-id> (OK)
  • <award-group> com <funding-source> sem <award-id> (OK - apoio sem contrato)
  • Múltiplos <funding-source> com um <award-id> (OK - mesmo contrato)
  • Múltiplos <funding-source> com múltiplos <award-id> em grupos separados (OK)

Elementos proibidos:

  • <funding-group> sem <label> (OK)
  • <funding-group> com <label> direto (ERROR)
  • <funding-group> com <label> em descendente (ERROR)
  • <funding-group> sem <title> (OK)
  • <funding-group> com <title> direto (ERROR)
  • <funding-group> com <title> em descendente (ERROR)

Consistência de quantidade:

  • 1 <funding-source> + 1 <award-id> (OK)
  • 2 <funding-source> + 1 <award-id> (OK - mesmo contrato)
  • 1 <funding-source> + 2 <award-id> (WARNING - inconsistência)
  • 2 <funding-source> + 2 <award-id> no mesmo grupo (WARNING - ambíguo)
  • N <funding-source> + 0 <award-id> (OK - apoio sem contrato)

Estruturas válidas:

  • Financiamento com número de contrato (OK)
  • Apoio sem número de contrato (OK)
  • Declaração negativa de financiamento (OK)
  • Múltiplas instituições com mesmo contrato (OK)
  • Múltiplas instituições com contratos diferentes (OK)
  • Combinação de apoio + financiamento (OK)

Casos de borda:

  • <funding-group> vazio (CRITICAL - falta funding-statement)
  • <award-group> vazio (CRITICAL - falta funding-source)
  • Múltiplos <funding-statement> (validar se é permitido pelo schema)
  • <funding-source> vazio ou só espaços (WARNING)
  • <award-id> vazio ou só espaços (WARNING)

Total esperado: ~35 testes unitários

Estrutura de testes:

  • Usar filter_results() para remover None dos resultados
  • Asserções devem usar campo response (não is_valid)
  • Testes devem ser autocontidos e descritivos
  • Agrupar testes por categoria (unicidade, elementos obrigatórios, elementos proibidos, etc.)

Critérios de Aceite

O PR será aceito quando:

  • Verificação de validações existentes: Código existente para <funding-group> foi analisado e integrado ou substituído adequadamente
  • Todas as regras P0 implementadas (4 validações CRITICAL/ERROR)
  • Todas as regras P1 implementadas (3 validações ERROR/WARNING)
  • Testes unitários passando com cobertura mínima de ~35 casos
  • Nenhum teste existente quebrado
  • Arquivo funding_group_rules.json criado com todos os níveis de erro
  • Internacionalização completa em todas as mensagens (i18n obrigatório)
  • Código seguindo padrões do packtools (build_response, filter_results, validações condicionais)
  • Modelo de dados criado com extração adequada de estrutura hierárquica
  • Validação de unicidade funcionando em <article-meta>
  • Validação de elementos proibidos usando busca em profundidade
  • Validação de texto vazio usando .strip()
  • Documentação inline clara (docstrings)

Referências

Documentação SPS:

Padrões JATS:

Referências internas packtools:

  • Internacionalização: Consultar conversas anteriores sobre implementação de i18n
  • Implementações similares: article_doi.py (unicidade)
  • Funções auxiliares: utils.py (build_response)

Labels Sugeridas

enhancement validation SPS-1.10 good-first-issue


Impacto Esperado

Antes:

  • Conformidade SPS 1.10 para <funding-group>: X% (verificar validações existentes)
  • Possível falta de validação de elementos obrigatórios (<funding-statement>, <funding-source>)
  • Múltiplas ocorrências de <funding-group> podem passar sem detecção
  • Elementos proibidos (<label>, <title>) podem não ser detectados
  • Estruturas incompletas podem passar sem validação

Depois:

  • Conformidade SPS 1.10 para <funding-group>: 70% (7 de 10 regras)
  • Validação CRITICAL de elementos obrigatórios (<funding-statement>, <funding-source>)
  • Validação ERROR de unicidade e elementos proibidos
  • Validação WARNING de consistência estrutural
  • ~35 testes unitários garantindo qualidade
  • Internacionalização completa (PT/EN/ES)

Benefícios:

  • Melhora a qualidade dos XMLs SciELO
  • Garante completude de informações de financiamento
  • Detecta inconsistências estruturais antes da publicação
  • Previne uso de elementos não permitidos pelo SPS
  • Facilita sincronização entre <funding-group> e notas/agradecimentos
  • Promove conformidade com padrões internacionais de transparência em financiamento
  • Facilita manutenção e depuração de XMLs

Observações importantes:

  • Implementar internacionalização ajustando as respostas das validações ao formato da função build_response em packtools/sps/validation/utils.py;
  • Verificar e adicionar as validações no orquestrador: packtools/sps/validation/xml_validations.py e packtools/sps/validation/xml_validator.py
  • Verificar a corretude dos testes exsitentes para a validação e complementar caso necessário;
  • Realizar ajustes, caso necessário, nos modelos que são utilizados pelas validações, garantindo que o ajuste não interfira em possíveis usos atuais desses modelos.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions