-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Objetivo
Implementar validações para o elemento <response> conforme a especificação SPS 1.10, aumentando a conformidade de X% para 70% (7 de 10 regras).
Nota: Algumas validações para <response> 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 <response> identifica um conjunto de respostas referente a uma carta ou comentário, obrigatoriamente publicadas juntamente com a carta/comentário. É usado quando há múltiplas respostas no mesmo documento. Validações corretas garantem presença de atributos obrigatórios, unicidade de IDs, e estrutura mínima necessária.
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.response
Regras principais conforme SPS 1.10:
-
Ocorrência:
<response>pode aparecer zero ou mais vezes em<article>e<sub-article>
-
Contexto de uso:
- Tag para identificar conjunto de respostas referente a carta ou comentário
- Obrigatoriamente publicadas juntamente com carta ou comentário
- Se apenas uma resposta: usar
<sub-article article-type="reply"> - Se publicado com DOI separadamente: usar
<article article-type="reply">
-
Atributos obrigatórios:
@response-type="reply"(obrigatório)@xml:lang(obrigatório)@id(obrigatório)
-
Unicidade de IDs:
- Deve-se usar um
@iddiferente para cada<response>
- Deve-se usar um
-
Estrutura esperada:
<front-stub>- Metadados da resposta<body>- Conteúdo da resposta<back>- Seção final (opcional, pode conter<ref-list>)
Regras a Implementar
P0 – Críticas (implementar obrigatoriamente)
| # | Regra | Nível | Descrição |
|---|---|---|---|
| 1 | Validar presença de @response-type |
CRITICAL | O atributo @response-type é obrigatório em <response> |
| 2 | Validar valor de @response-type |
ERROR | O valor de @response-type deve ser "reply" |
| 3 | Validar presença de @xml:lang |
CRITICAL | O atributo @xml:lang é obrigatório em <response> |
| 4 | Validar presença de @id |
CRITICAL | O atributo @id é obrigatório em <response> |
| 5 | Validar unicidade de @id |
ERROR | Cada <response> deve ter um @id único (não pode repetir valores) |
P1 – Importantes (implementar se possível)
| # | Regra | Nível | Descrição |
|---|---|---|---|
| 6 | Validar presença de <front-stub> |
WARNING | Recomenda-se que <response> contenha <front-stub> com metadados da resposta |
| 7 | Validar presença de <body> |
WARNING | Recomenda-se que <response> contenha <body> com o conteúdo da resposta |
P2 – Futuras (fora do escopo deste Issue)
| # | Regra | Motivo de exclusão |
|---|---|---|
| 8 | Validar contexto de uso (carta/comentário) | Média complexidade - requer validação do article-type do documento pai |
| 9 | Validar uso de sub-article para resposta única | Alta complexidade - requer análise de quantidade e contexto |
| 10 | Validar formato de @id conforme sugestões SPS | Baixa prioridade - formato livre permitido |
Arquivos a Criar/Modificar
Avaliar existentes (podem ter validações parciais):
packtools/sps/models/response.pyou similar – Verificar se modelo existepacktools/sps/validation/response.py– Verificar validações existentespacktools/sps/validation/rules/response_rules.jsonou similar – Verificar configuração
Criar (se não existirem):
packtools/sps/models/response.py– Modelo de extração de dadospacktools/sps/validation/response.py– Validaçõespacktools/sps/validation/rules/response_rules.json– Configuração de níveis de errotests/sps/validation/test_response.py– Testes unitários
Referenciar (implementações similares):
packtools/sps/validation/sub_article.py– Validação de estrutura similarpacktools/sps/validation/utils.py– Funções auxiliares (build_response)
Exemplos de XML
XML Válido (deve passar sem erros):
<!-- Exemplo 1: Duas respostas em um documento -->
<article article-type="letter">
<front>
<!-- metadados da carta -->
</front>
<body>
<!-- conteúdo da carta -->
</body>
<response response-type="reply" xml:lang="en" id="S1">
<front-stub>
<contrib-group>
<contrib contrib-type="author">
<name>
<surname>Smith</surname>
<given-names>John</given-names>
</name>
</contrib>
</contrib-group>
</front-stub>
<body>
<p>First response content.</p>
</body>
<back>
<ref-list>
<!-- referências -->
</ref-list>
</back>
</response>
<response response-type="reply" xml:lang="en" id="S2">
<front-stub>
<contrib-group>
<contrib contrib-type="author">
<name>
<surname>Jones</surname>
<given-names>Mary</given-names>
</name>
</contrib>
</contrib-group>
</front-stub>
<body>
<p>Second response content.</p>
</body>
</response>
</article>
<!-- Exemplo 2: Resposta em português -->
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="pt" id="R01">
<front-stub>
<contrib-group>
<contrib contrib-type="author">
<name>
<surname>Silva</surname>
<given-names>João</given-names>
</name>
</contrib>
</contrib-group>
</front-stub>
<body>
<p>Conteúdo da resposta.</p>
</body>
</response>
</article>
<!-- Exemplo 3: Múltiplas respostas com IDs diferentes -->
<article article-type="commentary">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="en" id="resp1">
<front-stub>
<!-- metadados da resposta 1 -->
</front-stub>
<body>
<p>Response 1.</p>
</body>
</response>
<response response-type="reply" xml:lang="en" id="resp2">
<front-stub>
<!-- metadados da resposta 2 -->
</front-stub>
<body>
<p>Response 2.</p>
</body>
</response>
<response response-type="reply" xml:lang="en" id="resp3">
<front-stub>
<!-- metadados da resposta 3 -->
</front-stub>
<body>
<p>Response 3.</p>
</body>
</response>
</article>
<!-- Exemplo 4: Resposta mínima (sem back) -->
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="es" id="S1">
<front-stub>
<contrib-group>
<contrib contrib-type="author">
<name>
<surname>García</surname>
<given-names>Carlos</given-names>
</name>
</contrib>
</contrib-group>
</front-stub>
<body>
<p>Contenido de la respuesta.</p>
</body>
</response>
</article>
<!-- Exemplo 5: Resposta em sub-article -->
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<sub-article article-type="translation" xml:lang="pt">
<front-stub>
<!-- tradução -->
</front-stub>
<body>
<!-- conteúdo traduzido -->
</body>
<response response-type="reply" xml:lang="pt" id="S1-pt">
<front-stub>
<!-- metadados da resposta traduzida -->
</front-stub>
<body>
<p>Resposta em português.</p>
</body>
</response>
</sub-article>
</article>XML Inválido – Caso 1: Sem @response-type (CRITICAL)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response xml:lang="en" id="S1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response content.</p>
</body>
</response>
</article>Erro esperado: Atributo @response-type é obrigatório em <response>
XML Inválido – Caso 2: @response-type com valor incorreto (ERROR)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="answer" xml:lang="en" id="S1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response content.</p>
</body>
</response>
</article>Erro esperado: Valor de @response-type deve ser "reply". Valor encontrado: "answer"
XML Inválido – Caso 3: Sem @xml:lang (CRITICAL)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" id="S1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response content.</p>
</body>
</response>
</article>Erro esperado: Atributo @xml:lang é obrigatório em <response>
XML Inválido – Caso 4: Sem @id (CRITICAL)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="en">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response content.</p>
</body>
</response>
</article>Erro esperado: Atributo @id é obrigatório em <response>
XML Inválido – Caso 5: IDs duplicados (ERROR)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="en" id="S1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>First response.</p>
</body>
</response>
<response response-type="reply" xml:lang="en" id="S1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Second response.</p>
</body>
</response>
</article>Erro esperado: Valor de @id duplicado em <response>. Cada <response> deve ter um @id único. ID duplicado: "S1"
XML Inválido – Caso 6: Atributos vazios (CRITICAL)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="" xml:lang="" id="">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response content.</p>
</body>
</response>
</article>Erro esperado: Atributos obrigatórios não podem estar vazios
XML Inválido – Caso 7: @response-type apenas espaços (CRITICAL)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type=" " xml:lang="en" id="S1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response content.</p>
</body>
</response>
</article>Erro esperado: Atributo @response-type não pode conter apenas espaços
XML Inválido – Caso 8: @response-type com uppercase (ERROR)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="Reply" xml:lang="en" id="S1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response content.</p>
</body>
</response>
</article>Erro esperado: Valor de @response-type deve estar em minúsculas. Use reply ao invés de Reply
XML Inválido – Caso 9: Sem (WARNING)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="en" id="S1">
<body>
<p>Response content.</p>
</body>
</response>
</article>Erro esperado: (WARNING) Recomenda-se que <response> contenha <front-stub> com metadados da resposta
XML Inválido – Caso 10: Sem (WARNING)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="en" id="S1">
<front-stub>
<contrib-group>
<contrib contrib-type="author">
<name>
<surname>Smith</surname>
<given-names>John</given-names>
</name>
</contrib>
</contrib-group>
</front-stub>
</response>
</article>Erro esperado: (WARNING) Recomenda-se que <response> contenha <body> com o conteúdo da resposta
XML Inválido – Caso 11: vazio (CRITICAL + WARNING)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="en" id="S1">
</response>
</article>Erro esperado: (WARNING) <response> está vazio. Adicione <front-stub> e <body>
XML Inválido – Caso 12: Três IDs duplicados (ERROR)
<article article-type="letter">
<front>
<!-- metadados -->
</front>
<body>
<!-- conteúdo -->
</body>
<response response-type="reply" xml:lang="en" id="R1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response 1.</p>
</body>
</response>
<response response-type="reply" xml:lang="en" id="R1">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response 2.</p>
</body>
</response>
<response response-type="reply" xml:lang="en" id="R2">
<front-stub>
<!-- metadados -->
</front-stub>
<body>
<p>Response 3.</p>
</body>
</response>
</article>Erro esperado: Valor de @id duplicado em <response>: "R1" (aparece 2 vezes)
Padrão de Implementação
Diretrizes Gerais:
-
Seguir padrões existentes no repositório:
- Consultar implementações similares como
sub_article.py(estrutura similar) - Usar estrutura de classes já estabelecida no packtools
- IMPORTANTE: Verificar se já existem validações parciais para
<response>e integrá-las ou complementá-las
- Consultar implementações similares como
-
Internacionalização (i18n):
- OBRIGATÓRIO: Todas as mensagens devem suportar internacionalização
- Usar
advice_texteadvice_paramsembuild_response() - Consultar conversas anteriores sobre implementação de i18n no packtools
- Referência: validações em
article_contribs.pyque já implementam i18n completo
-
Validações condicionais:
- Validações que dependem de contexto devem retornar
Nonequando não aplicável - Exemplo: validação de
<front-stub>e<body>são WARNING, não CRITICAL - Usar
filter_results()nos testes para removerNone
- Validações que dependem de contexto devem retornar
-
Uso de
build_response():- Sempre usar
parent=self.data(dict completo, nunca string) - Campo
responsedeve conter:"OK","WARNING","ERROR","CRITICAL" - Sempre fornecer
advice_texteadvice_paramspara i18n
- Sempre usar
-
Modelo de dados:
- Criar propriedade que retorna lista de dicionários (um para cada
<response>) - Cada dict deve conter:
response_type,xml_lang,id,has_front_stub,has_body,has_back,parent,parent_id,parent_lang
- Criar propriedade que retorna lista de dicionários (um para cada
-
Validação de unicidade de IDs:
- Coletar todos os valores de
@idem<response> - Detectar duplicatas usando set ou Counter
- Reportar quais IDs estão duplicados
- Coletar todos os valores de
-
Validação de valor:
- Comparação case-sensitive:
@response-typedeve ser exatamente"reply"(minúsculas) - Trimmar espaços antes de validar
- Comparação case-sensitive:
-
Validação de elementos filhos:
- Verificar presença de
<front-stub>usando XPath ou.find() - Verificar presença de
<body>usando XPath ou.find() - Nível WARNING (recomendado, não obrigatório)
- Verificar presença de
Testes Esperados
Casos de teste obrigatórios:
Atributos obrigatórios:
-
<response>com todos os atributos obrigatórios (OK) - Sem
@response-type(CRITICAL) - Sem
@xml:lang(CRITICAL) - Sem
@id(CRITICAL) - Atributos vazios (CRITICAL)
- Atributos apenas com espaços (CRITICAL)
Valor de @response-type:
-
@response-type="reply"(OK) -
@response-type="answer"(ERROR) -
@response-type="response"(ERROR) -
@response-type="Reply"(ERROR - uppercase) -
@response-type="REPLY"(ERROR - uppercase)
Valores de @xml:lang:
-
@xml:lang="en"(OK) -
@xml:lang="pt"(OK) -
@xml:lang="es"(OK) -
@xml:langvazio (CRITICAL)
Unicidade de @id:
- Um
<response>com ID único (OK) - Dois
<response>com IDs diferentes (OK) - Três
<response>com IDs diferentes (OK) - Dois
<response>com mesmo ID (ERROR) - Três
<response>com dois IDs iguais (ERROR) - Múltiplos
<response>todos com mesmo ID (ERROR)
Presença de elementos filhos:
-
<response>com<front-stub>(OK) -
<response>sem<front-stub>(WARNING) -
<response>com<body>(OK) -
<response>sem<body>(WARNING) -
<response>com<front-stub>e<body>(OK) -
<response>sem<front-stub>nem<body>(WARNING) -
<response>com<back>(OK - opcional) -
<response>sem<back>(OK - opcional)
Múltiplos responses:
- Artigo sem
<response>(OK - zero ou mais vezes) - Artigo com um
<response>(OK) - Artigo com dois
<response>(OK) - Artigo com três ou mais
<response>(OK)
Contextos:
-
<response>em<article>(OK) -
<response>em<sub-article>(OK)
Casos de borda:
-
<response>vazio (WARNING - falta estrutura) - ID com caracteres especiais (OK)
- ID numérico (OK)
- ID alfanumérico (OK)
-
@xml:langcom código de 2 letras (OK) -
@xml:langcom código de 5 letras (OK - ex: pt-BR)
Total esperado: ~40 testes unitários
Estrutura de testes:
- Usar
filter_results()para removerNonedos resultados - Asserções devem usar campo
response(nãois_valid) - Testes devem ser autocontidos e descritivos
- Agrupar testes por categoria (atributos, valores, unicidade, elementos)
Critérios de Aceite
O PR será aceito quando:
- Verificação de validações existentes: Código existente para
<response>foi analisado e integrado ou substituído adequadamente - Todas as regras P0 implementadas (5 validações CRITICAL/ERROR)
- Todas as regras P1 implementadas (2 validações WARNING)
- Testes unitários passando com cobertura mínima de ~40 casos
- Nenhum teste existente quebrado
- Arquivo
response_rules.jsoncriado 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 todos os atributos
- Validação de unicidade de IDs funcionando (detecta duplicatas)
- Validação de valor case-sensitive (
replyminúsculo) - Validação de elementos filhos (front-stub, body) funcionando
- Suporte para múltiplos
<response>(zero ou mais vezes) - Documentação inline clara (docstrings)
Referências
Documentação SPS:
- SPS 1.10 –
<response>: Conjunto de Respostas - SPS 1.10 –
<article>: Artigo - SPS 1.10 –
<sub-article>+<front-stub>: Sub Artigo - SPS 1.10 – XML da Resposta para uma Carta
- SPS 1.10 – Sugestão de Atribuição de @id
Padrões JATS:
Referências internas packtools:
- Internacionalização: Consultar conversas anteriores sobre implementação de i18n
- Implementações similares:
sub_article.py(estrutura similar) - 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
<response>: X% (verificar validações existentes) - Atributos obrigatórios podem estar ausentes
- Valores incorretos de
@response-typepodem passar - IDs duplicados podem não ser detectados
- Estrutura mínima não verificada
Depois:
- Conformidade SPS 1.10 para
<response>: 70% (7 de 10 regras) - Validação CRITICAL de atributos obrigatórios
- Validação ERROR de valor correto (
reply) - Validação ERROR de unicidade de IDs
- Validação WARNING de elementos recomendados (front-stub, body)
- ~40 testes unitários garantindo qualidade
- Internacionalização completa (PT/EN/ES)
Benefícios:
- Melhora a qualidade dos XMLs SciELO
- Garante estrutura adequada para múltiplas respostas
- Detecta IDs duplicados antes da publicação
- Assegura presença de atributos obrigatórios
- Promove estrutura mínima recomendada (front-stub + body)
- Facilita processamento de respostas a cartas/comentários
- Melhora organização de debates científicos
- Garante conformidade com padrões SPS
- Facilita manutenção e depuração de XMLs