Repository navigation
Conversation
33d6a62 to
2498b9d
Compare
POST /api/sessao/sessaoplenaria/{id}/lote/ grava numa única requisição
presenças da sessão, presenças da ordem do dia, votações (registro e votos
nominais) e atualizações de matérias da ordem do dia e do expediente.
Cada item é gravado em sua própria transação e devolve um status
(criado, atualizado, removido, inalterado ou erro). O reenvio do mesmo
lote é idempotente. Validações e permissões são as mesmas dos endpoints
individuais, que seguem sem alteração.
GET /api/sessao/sessaoplenaria/{id}/painel/ devolve numa única requisição
sessão, mesa, parlamentares, presenças, expediente, ordem do dia, matérias,
autorias, votações, votos, leituras e oradores, no mesmo formato dos
endpoints de listagem.
Segue as permissões de leitura de cada model e a visibilidade pública das
sessões. O número de consultas ao banco não cresce com o tamanho da sessão.
2498b9d to
a80cd3d
Compare
|
Fiz rebase do branch sobre a Primeiro rebase (sobre #3849, #3855 e #3865): havia conflito em Também conferi a compatibilidade com as novas constraints de unicidade:
Segundo rebase (sobre #3846, sanitização de TextField): aplicou sem conflitos. A sanitização é feita em um receiver Quem tiver o branch localmente precisa atualizá-lo com |
|
@edwardoliveira @joaohortsenado tenho ticket no interlegis sobre isso de número 124060 e muitas camaras que desenvolvem integrações seriam beneficiadas por isso. Podemos conversar? |
Descrição
Adiciona dois endpoints na sessão plenária para que painéis e integrações montem e sincronizem uma sessão com uma requisição no início e uma no fim. Hoje são centenas.
Requisições por sessão
Exemplo: Casa com 21 vereadores, sessão com 20 matérias votadas nominalmente e 10 matérias lidas no expediente.
expande filtros__inGET .../painel/POST .../lote/As 522 requisições da sincronização:
PATCHna ordem do dia, por matériaPATCHno expediente, por matériaDe modo geral, são
2 × P + M × (P + 2) + 2 × Lrequisições (P parlamentares, M matérias votadas nominalmente, L matérias lidas). Com este PR, a sincronização passa a ser 1 requisição ao final da sessão, apenas para sincronização.GET /api/sessao/sessaoplenaria/{id}/painel/Devolve tudo o que o painel precisa: sessão, tipo, casa, parlamentares, mandatos, filiações e partidos, mesa diretora, presenças da sessão e da ordem do dia, expedientes, matérias do expediente e da ordem do dia, matérias, autorias e autores, registros de votação, votos, leituras e oradores (expediente, ordem do dia e explicações pessoais).
/api/<app>/<model>/.403com os models que faltam.restringe_sessoes_visiveis. Sessões futuras ainda ocultas ao público respondem404para anônimos.__str__, campos many-to-many emetadatasão carregados uma vez por bloco. Com ~620 registros, a resposta faz menos de 100 consultas (antes do ajuste eram 2.681). Para isso,SaplSerializerMixin.get_metadatapassou a aceitar metadata pré-carregado no contexto do serializer. Sem esse contexto, o comportamento é o mesmo de antes.Documentação:
docs/api-sessao-painel.md.POST /api/sessao/sessaoplenaria/{id}/lote/Grava numa única requisição:
presencas_sessaoPOST/DELETE /api/sessao/sessaoplenariapresenca/presencas_ordem_diaPOST/DELETE /api/sessao/presencaordemdia/votacoesPOST /api/sessao/registrovotacao/+ umPOST /api/sessao/votoparlamentar/por votoleiturasPOST/PATCH/DELETE /api/sessao/registroleitura/ordens_diaPATCH /api/sessao/ordemdia/{id}/expedientes_materiaPATCH /api/sessao/expedientemateria/{id}/criado,atualizado,removido,inalteradoouerro(comerros), além de umresumo. Assim o cliente reenvia só o que falhou.inalteradoe não duplica presenças, registros, votos nem leituras.drfautoapide cada model, e cada item exige as mesmas permissõessessao.add_*/change_*/delete_*do endpoint individual. A action usaIsAuthenticatedporque oSaplModelPermissionspadrão exigiriaadd_sessaoplenariapara um POST nesse viewset.votos(Sim,Não,Abstenção,Não Votou), e a lista substitui os votos da matéria, como ao finalizar a votação nominal na tela. Simbólica/secreta: informenumero_votos_sim,numero_votos_naoenumero_abstencoes.lida: truecria ou atualiza a leitura;lida: falseremove, como "retirar leitura" na tela.Documentação:
docs/api-sessao-lote.md.Os endpoints individuais seguem sem alteração.
Issue Relacionada
Resolve #3843 (dados completos da sessão via API pública para painel). Inclui também o caminho de escrita dessas integrações.
Motivação e Contexto
Na Câmara Municipal de Parnamirim/RN mantemos um painel e outras integrações que consomem o SAPL via API autenticada. Com as regras de firewall adotadas por causa do volume de requisições de IA, essas integrações passaram a sofrer throttle e negação de serviço, mesmo enfileirando cerca de uma requisição por minuto. Cada requisição passou a levar de 2 a 3 segundos.
O problema de fundo é que a API só aceita um registro por requisição, tanto para ler quanto para gravar uma sessão. Com estes endpoints, a integração baixa a sessão uma vez, trabalha localmente e envia tudo de uma vez ao final. Se algo falhar, reenvia apenas os itens com
erro.Como Isso Foi Testado?
sapl/sessao/tests/test_sessao_painel_api.py(6 testes): acesso público, conteúdo completo de uma sessão com 21 parlamentares e 20 votações nominais (420 votos), mesmo formato da listagem, isolamento entre sessões, número de consultas limitado, sessão futura oculta ao público e sessão inexistente.sapl/sessao/tests/test_sessao_lote.py(16 testes): autenticação, sessão inexistente, payload inválido, idempotência de presenças, remoção de presença, falha de um item sem afetar os demais, votação nominal (criação, reenvio e atualização), votação inválida sem gravação parcial, votação simbólica de expediente, alvo de outra sessão ou ambíguo, leituras (criação, reenvio, atualização, retirada e duplicadas), atualização e idempotência da ordem do dia, bloqueio de troca de sessão e permissões por bloco com usuário comum.pytest sapl/sessao sapl/api sapl/painel sapl/materia sapl/base: os 22 testes novos passam. As falhas restantes (TestResumoView,test_numero_duplicado_sessao_plenaria_forme testes de formulário emsapl/base) são as mesmas da3.1.xsem este PR.manage.py spectacular: o schema é gerado com as novas rotas.Tipos de Mudanças
Checklist: