Files
compras/docs/validacao-tecnica.md
T

396 lines
26 KiB
Markdown

# Validação técnica do SGC — 28 de Outubro de 2026
## Incremento: qualificação documental validada
O responsável validou o primeiro âmbito documental de
`proposta-qualificacao-propostas.md`. Nas propostas existe o acesso
«Qualificação documental», em `/requisicoes/{requisition}/qualificacao`.
Compras define requisitos por processo com descrição, categoria e indicação
de obrigatoriedade segundo a regra desse processo. Não há certificados,
montantes mínimos ou requisitos predefinidos importados dos exemplos.
Ao guardar os requisitos fica preservada uma versão imutável e a base das
propostas. Uma alteração cria outra versão, conservando os dados anteriores.
Compras, Finanças e chefia autorizada analisam, desde que o analista seja
distinto do solicitante e cumpra o âmbito departamental e os conflitos
existentes. Administração consulta. Cada utilizador conserva o seu próprio
registo por proposta e versão dos requisitos; não substitui o de outro analista.
Cada registo contém uma resposta para todos os requisitos: por analisar,
cumprido, não cumprido ou não aplicável. Resultados preenchidos exigem
fundamento; cumprido/não cumprido exigem também referência de evidência.
Não aplicável exige justificação e não dispensa automaticamente um requisito
obrigatório. Uma correcção acrescenta uma versão da análise e exige o
identificador do último registo do próprio analista.
Bases alteradas ou requisitos ultrapassados não aceitam novas análises.
Os registos antigos continuam consultáveis com indicação histórica, sem
copiar respostas para outra base. Os requisitos e a base são conferidos
novamente dentro de uma transacção que bloqueia primeiro a empresa e
revalida o operador. Após adjudicação, ou fora do estado aprovado do pedido,
os registos anteriores permanecem em consulta, sem novas escritas.
O módulo não decide admissão/exclusão e não usa os resultados para alterar
elegibilidade, pontuações, ordenação ou emissão. O método de comparação
permanece intacto; continuam aplicáveis os conflitos existentes. Um teste
de integração regista «não cumprido» num requisito obrigatório e confirma
que a matriz é idêntica e que uma adjudicação antes elegível segue o circuito
normal até à emissão, sem criar uma regra automática adicional.
Consulta exige os mesmos perfis e visibilidade das propostas, respeitando
empresa e departamento. Solicitantes e Armazém não ganham acesso. Respostas
usam `private, no-store` e histórico Inertia cifrado. O histórico é paginado
e o último registo de cada analista/proposta é obtido separadamente, sem
confundir uma página histórica com a versão actual de trabalho. A visão única
inclui ligação e eventos conforme o perfil.
A migração aditiva 000018 foi aplicada no batch 19, após backup privado de
296378 bytes e restauro verificado de 55 tabelas. Dados anteriores, restrições
e `.env` foram preservados; as tabelas de requisitos e análises ficaram
vazias na base de negócio. Ver `qualificacao-migracao-000018.json`. Backup e
manifesto permanecem fora do Git.
Seis cenários PostgreSQL passaram com duas ligações e duas esperas simultâneas
de bloqueio: requisitos concorrentes, duas escritas do mesmo analista,
analistas distintos, base alterada, perfil revogado e requisitos novos em
disputa com uma análise da versão anterior. Não houve substituição de
analistas, mistura de bases ou duplicação de versões. A base exclusiva de
testes foi eliminada. Ver `qualificacao-concorrencia-postgresql.json`.
As alterações locais em `compatibilidade.md`, `desenvolvimento.md` e
`orientacoes-continuidade.md` foram preservadas e não fazem parte deste
incremento. A revisão visual permanece pendente: o navegador devolveu
`The browser access host is unavailable`. Admissão/exclusão formal, circuitos
de conferência/quórum, novos métodos de avaliação, certificação de evidências
e cancelamento de ordens emitidas continuam sem activação neste âmbito.
Resultado deste incremento: **454 testes aprovados, 2 ignorados e 3601
asserções**. São 11 testes novos: dez específicos do módulo e um de integração
com adjudicação/emissão. PHPStan, Pint, TypeScript, build e lint/formatação
dos ficheiros alterados passaram. A formatação global continua a assinalar
`compatibilidade.md`, já modificado fora desta entrega; não foi alterado nem
incluído no commit. Os dois testes ignorados continuam condicionados a MFA.
## Incremento: sessão de abertura e actas por versão
Nas propostas existe o acesso «Sessão de abertura e actas», em
`/requisicoes/{requisition}/abertura`. Compras pode registar uma sessão num
pedido aprovado, antes de existir adjudicação. O registo é opcional; não
introduz um concurso público obrigatório, um número mínimo de propostas,
um júri obrigatório ou um novo circuito financeiro em todas as empresas.
O operador declara referência, local, data/hora, fuso horário, intervenientes,
qualidade em que participam, observações e referências de anexos, selecciona
as propostas e confirma a conferência. As propostas seleccionadas são
copiadas no servidor com fornecedor, referência, valores e linhas; não se
aceitam valores de uma acta enviados pelo cliente. Uma impressão autenticada
usa a cópia preservada, incluindo nome da empresa e autor do registo.
Não contém pontuações ou uma recomendação de adjudicação.
As datas são interpretadas no fuso declarado, guardadas em UTC e apresentadas
nesse fuso. Este primeiro âmbito suporta Africa/Johannesburg, Africa/Maputo e
UTC; a interface começa pelo fuso do contexto local. Sessões futuras e prazo
de apresentação posterior à sessão são recusados. O prazo é declarado; não
se presume que a data de criação de uma cotação no SGC seja a sua data real
de entrega pelo concorrente.
Correcções criam versões novas, com fundamento e referência à versão anterior
na auditoria. As versões guardadas não são editadas ou eliminadas pela
aplicação. Uma base de propostas alterada desde a consulta ou uma versão
anterior desactualizada é recusada. A interface permite conferir a base
actualizada sem apagar os textos introduzidos. Propostas posteriormente
adicionadas ou alteradas não entram nas actas anteriores; uma divergência é
assinalada na consulta. Não se alterou a política de recepção de cotações.
Os nomes dos intervenientes são declarações, não assinaturas digitais
verificadas. A impressão disponibiliza espaço para assinaturas manuscritas.
As referências de anexos não representam carregamento ou validação de
ficheiros. Registar uma acta não avalia propostas, não certifica a realização
da sessão, não adjudica, não reserva orçamento e não autoriza compras.
Alterações documentais depois da adjudicação exigem um circuito futuro;
este incremento conserva as actas anteriores para consulta, sem as reescrever.
Administração, Compras, Finanças e chefias autorizadas consultam; apenas
Compras regista. Mantêm-se isolamento entre empresas, âmbito departamental,
verificação de conflitos e revalidação do operador dentro da transacção.
Solicitantes e Armazém não ganham acesso a preços ou actas. Consulta e
impressão usam `private, no-store`; o histórico Inertia é cifrado. Os registos
aparecem nos documentos e eventos da visão única conforme o perfil.
A migração aditiva 000017 foi aplicada no batch 18 após backup privado de
291397 bytes e restauro verificado de 54 tabelas. Dados anteriores,
restrições e `.env` foram preservados; não foram criadas actas fictícias na
base de negócio. Ver `abertura-migracao-000017.json`. Backup e manifesto
ficam fora do Git.
Resultado: **443 testes aprovados, 2 ignorados, 3431 asserções**, incluindo
11 testes novos de snapshots, versões, base desactualizada, impressão,
fuso horário, validação, segregação, empresas/departamentos, revogação de
perfil, rollback de auditoria, imutabilidade e escape de texto. Quatro
cenários PostgreSQL passaram, cada um com duas ligações e duas esperas de
bloqueio simultâneas: versões iniciais concorrentes, correcções concorrentes,
perfil revogado e base alterada durante a espera. A base temporária exclusiva
foi eliminada. Ver `abertura-concorrencia-postgresql.json`.
PHPStan, Pint, TypeScript e build passaram. A revisão visual da interface e
da impressão permanece pendente pela indisponibilidade do navegador. Não se
declara validação operacional de concursos, assinaturas, orçamentos ou regras
de cancelamento de ordens emitidas. Publicação de concursos, propostas
seladas, qualificação por etapas e novos métodos de avaliação continuam
pendentes; os exemplos locais não os tornam obrigações universais.
## Incremento: planeamento por empresa
O menu Compras inclui `/planeamento`. Administração e Compras registam itens
para bens, obras, serviços ou consultoria, seleccionam departamento e
responsável da própria empresa e definem marcos com nomes e datas próprios.
Estas naturezas são classificações de acompanhamento, não novas modalidades
de contratação. Não existem marcos obrigatórios ou valores financeiros
predefinidos, e o plano não cria reservas ou aprovações.
Uma compra pode ser planeada antes da requisição. Administração ou Compras
podem depois ligar uma requisição visível, do mesmo departamento, com
fundamento. A ligação é única e não substitui uma anterior. A visão única do
processo oferece um atalho para o item do plano quando o utilizador também
tem acesso a esse item; o filtro `?item=` conserva as mesmas permissões.
O responsável atribuído regista ou corrige datas realizadas e indica o
fundamento. Administração e Compras também podem rever datas previstas e
reatribuir responsáveis. Datas realizadas futuras são recusadas. Todas as
alterações guardam autor, valores anteriores, novos valores e fundamento,
com versão optimista e bloqueio da empresa para impedir sobrescrita silenciosa.
Uma data realizada é uma declaração de acompanhamento: não confirma entregas,
facturas, pagamentos ou execução integral da compra.
Administração, Compras e Finanças consultam o plano da empresa. Chefias
consultam o departamento ou itens de que são responsáveis; os restantes
perfis consultam apenas os itens atribuídos. Só Administração e Compras
definem o plano e consultam o histórico geral. Finanças não ganha permissão
de edição por ser leitor; um responsável pode registar datas realizadas no
seu item. Uma atribuição não dá acesso à requisição ou aos seus documentos
se as permissões normais não o permitirem. Dados de outras empresas, opções
de equipa e histórico geral não são expostos a utilizadores sem acesso.
A migração aditiva 000016 foi aplicada no batch 17 após backup privado de
281059 bytes e restauro verificado de 52 tabelas. Dados anteriores, restrições
e `.env` foram preservados. As duas tabelas novas ficaram vazias: não foram
criadas compras ou datas fictícias na base de negócio. Ver relatório
`planeamento-migracao-000016.json`; os ficheiros privados de recuperação
permanecem fora do Git.
Treze testes específicos verificam criação, marcos livres, datas realizadas,
reprogramação e versão, rejeição de datas futuras e ausência de fundamento,
perfis, empresas, departamentos, ligação única e posterior, reatribuição,
revogação de perfil, rollback de auditoria e acesso ao processo ligado.
Quatro cenários PostgreSQL com duas ligações e duas esperas simultâneas
passaram: datas concorrentes, responsáveis concorrentes, marcos duplicados e
perfil revogado enquanto os operadores aguardam o bloqueio. Cada escrita
aceite produz um único evento; a base temporária exclusiva foi eliminada.
Ver `planeamento-concorrencia-postgresql.json`.
O histórico apresenta os 50 eventos de planeamento mais recentes da empresa.
Título, natureza e departamento são definidos na criação; as revisões deste
âmbito abrangem responsável, ligação posterior e datas dos marcos. Não há
eliminação de itens ou marcos. Estimativas financeiras do plano, aprovações
do plano, importação dos exemplos, alertas automáticos, dependências entre
marcos, actas e novas modalidades continuam fora deste primeiro incremento.
A revisão visual continua pendente, devido à indisponibilidade do navegador.
Resultado deste incremento: **432 testes aprovados, 2 ignorados, 3336 asserções**;
**4 cenários concorrentes PostgreSQL aprovados**. PHPStan, Pint, TypeScript,
lint/formatação e build passaram. O navegador voltou a responder
`The browser access host is unavailable`. Não se declara revisão visual
concluída nem validação operacional de regras ou orçamentos das empresas.
## Incremento: visão única do processo de compra
O detalhe de uma requisição inclui o acesso «Ver processo completo», em
`/requisicoes/{requisition}/processo`. A página reúne as etapas já suportadas,
os responsáveis por função, decisões com autores e datas, atalhos para os
registos e o histórico permitido ao perfil. Inclui ligação entre processos
originais e revisões quando ambos são visíveis ao utilizador. O cabeçalho e
rodapé partilhados mantêm-se neste ecrã.
Esta é uma consulta dos registos existentes. Não cria etapas obrigatórias,
aprovações, documentos, reservas ou pagamentos. Planeamento, acta de abertura,
qualificação específica do concurso e relatório por etapas aparecem apenas
como funcionalidades futuras, sem se presumirem aplicáveis a todas as compras.
Os quatro exemplos locais continuam a ser referências, não regras impostas.
O estado da requisição é separado dos restantes estados. Existência de propostas
não significa elegibilidade; histórico técnico não garante validade da base
actual; existência de lançamentos não certifica o orçamento; recepções podem
ser parciais; registo de factura não equivale a validação; pagamentos externos
confirmados não comprovam liquidação integral nem executam transferências.
A rota exige autenticação, empresa configurada e visibilidade da requisição.
Solicitantes não obtêm detalhes de propostas, adjudicações, ordens ou finanças
por esta consulta. Chefias conservam o âmbito departamental; Finanças e
Administração consultam os resumos financeiros. O Armazém não obtém acesso a
requisições de terceiros por esta nova rota. Documentos e eventos são filtrados
no servidor, sem snapshots privados, anexos ou dados bancários. A resposta usa
`private, no-store` e histórico Inertia cifrado.
Cinco testes específicos cobrem registos e estados parciais, ocultação de
compras/finanças ao solicitante, propriedade e departamento, isolamento entre
empresas e convidados, actualização da validação de factura e leitura sem
novos eventos de auditoria. Não há migração nem alteração de dados de negócio.
TypeScript, lint/formatação, build, PHPStan e Pint passaram.
Bateria completa deste incremento: **419 testes aprovados, 2 ignorados,
3180 asserções**. Os testes ignorados continuam condicionados à activação de
MFA; não são apresentados como aprovados. Os seis cenários concorrentes do
incremento anterior não foram repetidos, pois esta entrega não altera as
operações transaccionais que verificam.
O navegador voltou a devolver `The browser access host is unavailable`.
A revisão visual pública, autenticada e de impressão continua pendente;
testes HTTP e compilação não a substituem. O cancelamento de ordens emitidas
continua sujeito à proposta de regras ainda não validada.
## Incremento: navegação partilhada e revisão sem ordem emitida
O cabeçalho e rodapé do SGC são partilhados pelo acesso autenticado e pela
consulta pública, incluindo a proposta `/proposta/principal`. Os dropdowns
agrupam Compras, Finanças, Armazém e Gestão; preservam os acessos anteriores,
o menu da conta e a localização do ecrã. As opções autenticadas respeitam o
perfil; a autorização continua a ser verificada no servidor. A referência
visual foi consultada apenas em leitura no InvesteMoz: preto `#090909`,
vermelho `#ed1c24`, menus brancos. O projecto InvesteMoz não foi alterado.
Em `/revisao-compras`, cada empresa pode propor uma política datada para
cancelar adjudicações sem ordem emitida. Não existe activação por defeito.
A implementação usa duas assinaturas administrativas distintas do proponente
para publicar a regra e uma decisão Financeira independente para cada
cancelamento pedido por Compras. Estas são opções deste circuito implementado;
não constituem valores financeiros predefinidos para as empresas.
Um cancelamento pendente bloqueia novas decisões finais e emissão. Aprovação
encerra a adjudicação e requisição originais, mantendo cotações e decisões;
liberta apenas reserva não comprometida. Repetições idênticas não duplicam
lançamentos. Rejeição mantém a compra original. Uma decisão é imutável e,
neste primeiro âmbito, existe no máximo um pedido de cancelamento por
adjudicação, incluindo pedidos rejeitados. Uma alteração da política bloqueia
a aprovação de pedidos antigos; a rejeição continua disponível para retomar
o processo. Ordens emitidas e compromissos financeiros impedem este circuito.
Só o solicitante original, ainda no mesmo departamento, pode preparar um
único novo rascunho ligado ao cancelamento aprovado, com nova data e
justificação. Copiam-se artigos e estimativas, sem decisões, cotações,
validações técnicas ou reserva automática. O novo pedido segue o circuito
normal, incluindo validação técnica quando aplicável. As restrições únicas
de adjudicação e ordem por requisição foram conservadas.
A migração aditiva 000015 foi aplicada no batch 16 após backup privado de
259925 bytes e restauro verificado de 48 tabelas numa base temporária.
Dados de negócio anteriores, restrições e `.env` foram preservados; não foram
criadas políticas ou operações fictícias na base real. Ver relatório
`revisao-migracao-000015.json`. O backup e o manifesto ficam fora do Git.
Sete cenários novos verificam política obrigatória, bloqueio pendente,
rejeição e retoma, histórico e rascunho único, recusa após emissão,
segregação após mudança de perfil, libertação única da reserva e rollback
conjunto quando falha a auditoria. A validação concorrente deste circuito
foi acrescentada numa base PostgreSQL temporária: **6 cenários aprovados**,
cada um com duas ligações independentes e duas esperas de bloqueio simultâneas.
Abrange decisão repetida, decisões opostas, revisão repetida, emissão com
cancelamento pendente, emissão repetida e emissão em disputa com um pedido
de cancelamento. Nos três cenários de emissão, a adjudicação é seleccionada
e aprovada pelos serviços reais da aplicação. O controlo positivo emite uma
única ordem e um único compromisso; na disputa, apenas uma operação avança.
Os quatro primeiros cenários verificam também reserva e revisão únicas.
O relatório é `revisao-concorrencia-postgresql.json`; a base exclusiva de
testes foi eliminada no fim. Não houve alterações à base de negócio.
Resultado do incremento: **414 testes aprovados, 2 ignorados, 3099 asserções**.
PHPStan e Pint passaram; TypeScript, lint/formatação e build passaram.
As quatro verificações HTTP da proposta, requisições públicas, reforços e
aparência responderam 200. Estes pedidos HTTP não constituem revisão visual.
A revisão visual pública, autenticada e de impressão continua pendente:
o acesso ao navegador permanece indisponível. Compilação e testes não a
substituem. Ordens emitidas, estornos, notas de crédito, devoluções e
validação operacional das regras de cada empresa continuam fora deste âmbito.
Esta revisão cobre os módulos implementados e as pendências documentadas no
repositório. Não equivale a validação operacional integral ou certificação de
todos os requisitos do sistema. Valores e políticas reais continuam a pertencer
a cada empresa; nenhum foi criado nesta revisão.
## Correcções verificadas
- Operações que verificavam o perfil antes de esperar pelo bloqueio da empresa
passam a recarregar e bloquear o utilizador dentro da transacção. Abrange
facturas, dados bancários, stock, recepções, requisições, adjudicação, emissão,
validação técnica e dotação inicial. Mudança de perfil ou de empresa durante
a espera não é autorizada pelo perfil antigo em memória.
- Requisição volta a verificar departamento e centro de custo ao guardar e o
departamento do solicitante ao submeter. Decisões departamentais usam o perfil
actual; revisão técnica e aprovadores finais são bloqueados durante as
verificações transaccionais.
- Dotação pendente mostra **zero disponível e zero aprovado**, preservando o
valor proposto e o histórico. O servidor já bloqueava a reserva; a interface
deixou de apresentar verba proposta como disponível.
- Teste da página de segurança com MFA desligado deixou de ser indevidamente
ignorado. Textos dessa página e confirmação de alteração de palavra-passe
traduzidos para português. Nenhuma palavra-passe real foi alterada.
- Configuração de fontes passou a declarar desactivada a optimização opcional
que já não era gerada por ausência de `fontaine`. Mantém Instrument Sans e
elimina o aviso de dependência opcional sem instalar pacotes novos.
## Resultados
**407 testes aprovados, 2 ignorados, 2.964 asserções** na suite completa SQLite
em memória. Os dois ignorados dependem de MFA activado, actualmente desligado;
não são apresentados como funcionalidades validadas. PHPStan, Pint, TypeScript,
compilação e formatação/lint frontend verificados no fecho.
**32 cenários concorrentes PostgreSQL aprovados**, todos em bases exclusivas
de teste, eliminadas no final:
| Área | Cenários | Evidência |
| ------------------------------ | -------: | ------------------------------------------------------ |
| Recepções | 4 | [Relatório](recepcao-concorrencia-postgresql.json) |
| Stock e peças | 7 | [Relatório](stock-concorrencia-postgresql.json) |
| Reservas e compromissos | 5 | [Relatório](orcamento-concorrencia-postgresql.json) |
| Facturas e consumo | 3 | [Relatório](facturas-concorrencia-postgresql.json) |
| Dados bancários | 3 | [Relatório](bancos-concorrencia-postgresql.json) |
| Pagamentos externos | 3 | [Relatório](pagamentos-concorrencia-postgresql.json) |
| Reforços | 3 | [Relatório](reforcos-concorrencia-postgresql.json) |
| Regras de investimento | 3 | [Relatório](investimento-concorrencia-postgresql.json) |
| Perfil revogado durante espera | 1 | [Relatório](autorizacao-concorrencia-postgresql.json) |
O último ensaio bloqueia a empresa, observa duas ligações simultaneamente à
espera e revoga os dois perfis de Armazém antes de libertar o bloqueio. Os dois
pedidos pelo kernel HTTP retornam **403**; não criam recepções nem movimentos.
Os restantes ensaios verificam saldos, duplicações e integridade conforme os
respectivos relatórios. Não são testes de carga ou uma validação de todos os
possíveis cruzamentos concorrentes do sistema.
Sem migrações, seeds, criação de contas, alteração de configuração de ambiente
ou escritas de negócio na base real nesta revisão. Acesso HTTP pode actualizar
sessões. Nenhuma autorização de compra ou transferência bancária foi emitida.
## O que permanece por tratar
| Pendência | Situação |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Revisão visual pública, autenticada e impressão | Bloqueada pelo acesso ao navegador; testes HTTP não a substituem. |
| MFA obrigatório e ciclo completo de acessos | Não implementados/activados; dois testes condicionais continuam ignorados. |
| Revisão/cancelamento de adjudicações e ordens | Cancelamento de adjudicações sem ordem implementado no incremento abaixo; cancelamento de ordens emitidas continua ausente. |
| Reversões, estornos, notas de crédito e devoluções | Funcionalidades ainda não implementadas; não se apagam lançamentos existentes. |
| Regras empresariais | Escalões provisórios, regras fiscais, validade/levantamento de conflitos e excepções exigem decisão da empresa. |
| Investimento agregado e fraccionamento | Apenas tecto por processo suportado; sem agregação/detecção automática. |
| Outras etapas do roteiro | Multimoeda, reposição, tolerâncias/investigação de inventários, manutenção/activos e requisitos de subscrição/hosting continuam no roteiro. |
| Controlos operacionais | Carga, permissões contra SQL administrativo, retenção e recuperação por empresa ainda exigem validação própria. |
Estas pendências não foram marcadas como concluídas por compilação ou testes
funcionais. O próximo incremento de revisão/cancelamento deve definir e guardar
uma política explícita por empresa, conservar o passado e exigir novas decisões
para processos revistos; não pode autorizar por omissão a alteração de ordens
emitidas ou a libertação de compromissos já consumidos.
Verificação HTTP local no fecho: **18 páginas públicas responderam 200** e
**13 rotas protegidas responderam 302 sem sessão**. O navegador voltou a devolver
`The browser access host is unavailable`; a revisão visual continua pendente.