Repository navigation
feat(almoxarifado): implementar distribuição interna rastreável #417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
devmnsoft
merged 1 commit into
main
from
codex/evoluir-design-de-telas-e-corrigir-erros
Sep 15, 2026
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
database/postgres/migrations/20260915160000_distribuicao_interna_materiais.sql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| -- Distribuição interna: reserva, expedição, recebimento e divergência rastreáveis. | ||
| create table if not exists sigov.almoxarifado_entrega( | ||
| id bigint generated always as identity primary key, tenant_id bigint not null, entidade_id bigint not null, | ||
| requisicao_id bigint not null references sigov.almoxarifado_requisicao(id), almoxarifado_id bigint not null references sigov.almoxarifado_local(id), | ||
| status varchar(24) not null default 'SEPARADA', idempotency_key varchar(100) not null, observacao text, | ||
| created_at timestamptz not null default now(), created_by bigint not null, expedida_em timestamptz, expedida_por bigint, recebida_em timestamptz, recebida_por bigint, | ||
| constraint ck_almox_entrega_status check(status in('SEPARADA','EXPEDIDA','RECEBIDA_PARCIAL','RECEBIDA','DIVERGENCIA','CANCELADA')), | ||
| constraint ux_almox_entrega_idempotencia unique(tenant_id,entidade_id,idempotency_key)); | ||
| create table if not exists sigov.almoxarifado_entrega_item( | ||
| id bigint generated always as identity primary key, tenant_id bigint not null, entidade_id bigint not null, | ||
| entrega_id bigint not null references sigov.almoxarifado_entrega(id), requisicao_item_id bigint not null references sigov.almoxarifado_requisicao_item(id), | ||
| quantidade_separada numeric(18,4) not null, quantidade_recebida numeric(18,4) not null default 0, quantidade_recusada numeric(18,4) not null default 0, lote varchar(100), divergencia text, | ||
| constraint ck_almox_entrega_item_qtd check(quantidade_separada>0 and quantidade_recebida>=0 and quantidade_recusada>=0 and quantidade_recebida+quantidade_recusada<=quantidade_separada), | ||
| constraint ux_almox_entrega_item unique(entrega_id,requisicao_item_id,lote)); | ||
| create table if not exists sigov.almoxarifado_entrega_evento( | ||
| id bigint generated always as identity primary key, tenant_id bigint not null, entidade_id bigint not null, entrega_id bigint not null references sigov.almoxarifado_entrega(id), | ||
| tipo varchar(30) not null, dados jsonb, usuario_id bigint not null, correlation_id varchar(100) not null, ocorrido_em timestamptz not null default now()); | ||
| create index if not exists ix_almox_entrega_fila on sigov.almoxarifado_entrega(tenant_id,entidade_id,status,created_at,id); | ||
| create index if not exists ix_almox_entrega_req on sigov.almoxarifado_entrega(tenant_id,entidade_id,requisicao_id,id); | ||
| insert into sigov.permissao(modulo,chave,recurso,acao,descricao,ativo,is_deleted) | ||
| select 'almoxarifado','almoxarifado.recebimento.confirmar','almoxarifado.recebimento','confirmar','Confirmar recebimento e divergências',true,false | ||
| where not exists(select 1 from sigov.permissao where chave='almoxarifado.recebimento.confirmar'); | ||
| insert into sigov.perfil_permissao(perfil_acesso_id,permissao_id,efeito,ativo,is_deleted) | ||
| select pa.id,p.id,'PERMITIR',true,false from sigov.perfil_acesso pa join sigov.permissao p on p.chave='almoxarifado.recebimento.confirmar' | ||
| where pa.codigo_externo='SUPERADMIN' and pa.sistemico and pa.ativo and not pa.is_deleted | ||
| on conflict(perfil_acesso_id,permissao_id) do update set efeito='PERMITIR',ativo=true,is_deleted=false; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # RC51.02 — distribuição interna de materiais | ||
|
|
||
| Data: 2026-09-15. Estado: **implementada sem validação runtime / BLOCKED**. | ||
|
|
||
| ## Estado inicial e classificação | ||
|
|
||
| Branch `work`, HEAD inicial `0ab62eb5edc323271b774d825109d3d89b47497b`, árvore limpa, sem remoto e sem upstream. SDK normativo `10.0.100`, C# 14, ASP.NET Core MVC/Razor/API, PostgreSQL 16+ e Dapper. Somente Git, Node 20, npm 11 e Python estavam disponíveis; `dotnet`, `psql`, PostgreSQL, Docker, PowerShell e navegador estavam ausentes. | ||
|
|
||
| | Jornada | Estado inicial | Resultado desta fatia | | ||
| |---|---|---| | ||
| | Catálogo, locais, saldo e movimento | parcial | preservado como estoque canônico | | ||
| | Solicitação interna | parcial | fluxo existente rascunho → envio → autorização preservado; detalhe ganhou pendências e entregas | | ||
| | Autorização | parcial | política persistida existente preservada; nenhuma autoaprovação | | ||
| | Separação/reserva | ausente | persistida por entrega e item, com disponibilidade descontando outras separações | | ||
| | Expedição | atendimento monolítico parcial | saída, saldo, movimento e quantidade atendida passam pela mesma transação | | ||
| | Recebimento e divergência | ausente | conferência parcial/idempotente e divergência sem ajuste automático | | ||
| | Transferência, devolução e estorno | parcial em outros modelos / ausente nesta jornada | não foram tratados como distribuição nem implementados por falta de política canônica confirmada | | ||
| | Relatórios completos | parcial | consultas existentes preservadas; novos relatórios continuam pendentes | | ||
| | Formulários | implementados sem validação | Razor real, antiforgery, erros operacionais e impressão; browser indisponível | | ||
|
|
||
| ## Contrato operacional aplicado | ||
|
|
||
| - **Solicitação:** solicitante autenticado e contexto vêm da sessão; itens positivos e materiais/locais do mesmo tenant e entidade são validados no banco. Rascunho não movimenta nem reserva. | ||
| - **Autorização:** `ENVIADA → APROVADA` exige a permissão canônica. A separação recusa qualquer outro estado. | ||
| - **Separação:** cria `SEPARADA`; a reserva é a soma persistida de itens em entregas separadas. Disponibilidade é saldo físico menos reservas concorrentes. A requisição e seus itens são bloqueados durante a decisão; chave idempotente evita duplicação. | ||
| - **Expedição:** somente `SEPARADA`; bloqueia entrega e saldo, baixa fisicamente a origem, cria movimento ligado à requisição e incrementa atendimento. Repetição após `EXPEDIDA` não duplica saída. Se restar quantidade, a solicitação continua `APROVADA`; caso contrário fica `ATENDIDA`. Não foi criado estoque em trânsito. | ||
| - **Recebimento:** somente entrega expedida ou parcialmente conferida; recebido + recusado nunca excede expedido. Confirmações são serializadas e idempotentes. Recebimento de unidade consumidora não cria saldo. Divergência/recusa é registrada e não gera ajuste, descarte ou devolução automática. | ||
| - **Devolução e estorno:** permanecem pendentes de política e permissão específicas; movimento não é apagado e divergência não é devolvida silenciosamente ao disponível. | ||
|
|
||
| ## Persistência e concorrência | ||
|
|
||
| A migration forward-only cria entrega, itens e eventos com PK `bigint identity`, isolamento por tenant/entidade, constraints quantitativas, índices de fila e idempotência. A saída reutiliza `almoxarifado_estoque` e `almoxarifado_movimentacao`; não existe segundo saldo. Todas as escritas operacionais usam SQL parametrizado e transação Dapper. | ||
|
|
||
| ## Validação e bloqueios | ||
|
|
||
| Passaram JSON do manifesto, verificação estática de whitespace/diff e busca por conflitos. Restore locked, build Release, Razor, testes, Swagger, rotas Web, PostgreSQL vazio/upgrade/reexecução, dois tenants, concorrência real, screenshots e acessibilidade nas larguras solicitadas ficaram **BLOCKED** pela ausência de SDK, banco e navegador. Não há declaração de homologação. | ||
|
|
||
| ## Pendências e próximo backlog | ||
|
|
||
| A unidade solicitante ainda não possui catálogo seletor autorizado no formulário legado; relatórios paginados/exportações de pendências e divergências, cancelamento de separação, devolução e estorno requerem política persistida. Próximo item exato: implementar cancelamento concorrente de entrega `SEPARADA` que libere exclusivamente sua reserva, seguido de política persistida de devolução/estorno e prova PostgreSQL 16. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new persisted delivery entity records only tenant and entity IDs, omitting the mandatory
esfera_governo,tipo_entidade, administrative hierarchy, managing/executing units, and territorial scope. Deliveries therefore cannot retain or query the required municipal, state, or federal context independently, contrary to the repository's schema invariant for every entity; add the prescribed context columns and constraints to this new schema.AGENTS.md reference: AGENTS.md:L34-L37
Useful? React with 👍 / 👎.