From 2134aa084be2d7be0a3bcaba74cc5eae604e6663 Mon Sep 17 00:00:00 2001 From: nala Date: Fri, 30 Oct 2026 20:14:24 +0200 Subject: [PATCH] =?UTF-8?q?Permitir=20consulta=20p=C3=BAblica=20dos=20ecr?= =?UTF-8?q?=C3=A3s=20reais=20com=20dados=20privados=20protegidos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Middleware/EnterLocalEvaluation.php | 4 + .../PublicDevelopmentNavigation.php | 32 + app/Services/PublicNavigation.php | 58 + bootstrap/app.php | 4 + config/public_navigation.php | 3 + docs/compatibilidade.md | 32 +- docs/desenvolvimento.md | 79 +- docs/indicadores-sgc.md | 36 +- docs/menus-benchmark-20261029.md | 40 +- docs/obrigacoes-activacao-local.json | 6 +- docs/orientacoes-continuidade.md | 2 - docs/plano-ia.md | 20 +- docs/proofs/ai-plan-pg.json | 14 +- docs/proofs/ai-plan.json | 138 +- docs/proofs/ai-rehearsal-authorization.json | 32 +- docs/proofs/ai-rehearsal-live.json | 124 +- docs/proofs/ai-rehearsal.json | 70 +- docs/proofs/candidate-portal-http.json | 12 +- docs/proofs/candidate-portal.json | 122 +- docs/proofs/candidate-submissions-http.json | 16 +- docs/proofs/candidate-submissions-pg.json | 26 +- docs/proofs/candidate-submissions.json | 144 +- docs/proofs/candidate-triage-http.json | 12 +- docs/proofs/candidate-triage-pg.json | 26 +- docs/proofs/candidate-triage.json | 130 +- docs/proofs/comparison-policy.json | 92 +- docs/proofs/economic-comparison.json | 100 +- docs/proofs/evaluation-access.json | 94 +- docs/proofs/evidence-brief.json | 132 +- docs/proofs/intelligence-policy-pg.json | 14 +- docs/proofs/intelligence-policy.json | 152 +- docs/proofs/invoice-payable-link.json | 18 +- docs/proofs/menu-code-contract.json | 2018 ++++++++--------- docs/proofs/menu-links.json | 338 +-- docs/proofs/organization-access-http.json | 46 +- docs/proofs/organization-configuration.json | 122 +- docs/proofs/payable-history-pg.json | 49 +- docs/proofs/payable-payment-decisions-pg.json | 34 +- docs/proofs/people-access-pg.json | 4 +- docs/proofs/people-access.json | 106 +- docs/proofs/people-clarifications-pg.json | 4 +- docs/proofs/people-clarifications.json | 116 +- docs/proofs/people-hiring-pg.json | 4 +- docs/proofs/people-hiring.json | 114 +- docs/proofs/people-intelligence.json | 86 +- docs/proofs/people-registry-pg.json | 5 +- docs/proofs/people-registry.json | 150 +- docs/proofs/people-workdesk-pg.json | 4 +- docs/proofs/people-workdesk.json | 100 +- docs/proofs/procurement-intelligence.json | 108 +- docs/proofs/procurement-reports.json | 96 +- docs/proofs/requisition-catalogue-pg.json | 5 +- docs/proofs/requisition-catalogue.json | 100 +- docs/proofs/sgc-brand.json | 54 +- docs/proofs/submission-forms-http.json | 14 +- docs/proofs/submission-forms-pg.json | 26 +- docs/proofs/submission-forms.json | 118 +- docs/proofs/supplier-evaluations-http.json | 26 +- .../supplier-improvement-report-http.json | 36 +- docs/proofs/supplier-improvement-report.json | 54 +- docs/proofs/supplier-improvements-http.json | 34 +- docs/proofs/supplier-responses-http.json | 36 +- docs/proofs/supplier-responses.json | 52 +- docs/reutilizacao-dados.md | 18 +- resources/js/components/app-sidebar.tsx | 15 +- .../js/components/sgc-workspace-shell.tsx | 11 + resources/js/lib/procurement-navigation.ts | 26 +- resources/js/pages/budgets/index.tsx | 4 +- .../js/pages/company/submission-forms.tsx | 7 +- resources/js/pages/dashboard.tsx | 6 +- resources/js/pages/investment/index.tsx | 4 +- resources/js/pages/invoices/index.tsx | 19 +- resources/js/pages/payments/index.tsx | 2 +- .../js/pages/suppliers/evaluation-proposal.ts | 2 +- scripts/evaluation-access-check.mjs | 191 +- scripts/invoice-payable-link-check.mjs | 108 +- scripts/menu-code-check.mjs | 54 +- scripts/menu-links-check.mjs | 280 ++- scripts/payable-history-proof.mjs | 157 +- tests/Feature/PublicNavigationTest.php | 82 + tests/Fixtures/ai-synthetic-result.json | 23 +- tests/frontend/public-navigation.test.tsx | 54 + tests/frontend/requisition-catalogue.test.tsx | 115 +- 83 files changed, 3894 insertions(+), 3127 deletions(-) create mode 100644 app/Http/Middleware/PublicDevelopmentNavigation.php create mode 100644 app/Services/PublicNavigation.php create mode 100644 config/public_navigation.php create mode 100644 tests/Feature/PublicNavigationTest.php create mode 100644 tests/frontend/public-navigation.test.tsx diff --git a/app/Http/Middleware/EnterLocalEvaluation.php b/app/Http/Middleware/EnterLocalEvaluation.php index 5120cce..82a47ab 100644 --- a/app/Http/Middleware/EnterLocalEvaluation.php +++ b/app/Http/Middleware/EnterLocalEvaluation.php @@ -3,6 +3,7 @@ namespace App\Http\Middleware; use App\Services\EvaluationAccess; +use App\Services\PublicNavigation; use App\Services\RequisitionWorkflow; use Closure; use Illuminate\Http\Request; @@ -14,6 +15,9 @@ class EnterLocalEvaluation public function handle(Request $request, Closure $next): Response { $access = app(EvaluationAccess::class); + if (app(PublicNavigation::class)->enabled()) { + return $next($request); + } if (! $access->dashboardEntry($request)) { return $next($request); } diff --git a/app/Http/Middleware/PublicDevelopmentNavigation.php b/app/Http/Middleware/PublicDevelopmentNavigation.php new file mode 100644 index 0000000..0fedb6a --- /dev/null +++ b/app/Http/Middleware/PublicDevelopmentNavigation.php @@ -0,0 +1,32 @@ +enabled() || $request->user('web') !== null || ! in_array($request->method(), ['GET', 'HEAD'], true)) { + return $next($request); + } + $path = '/'.$request->path(); + if ($request->path() === '/') { + return redirect('/dashboard'); + } + if (! isset(PublicNavigation::PAGES[$path])) { + return $next($request); + } + $response = Inertia::render(PublicNavigation::PAGES[$path], $navigation->props($request))->toResponse($request); + $response->headers->set('Cache-Control', 'private, no-store, max-age=0'); + $response->headers->set('X-Robots-Tag', 'noindex, nofollow'); + + return $response; + } +} diff --git a/app/Services/PublicNavigation.php b/app/Services/PublicNavigation.php new file mode 100644 index 0000000..ae4f0c8 --- /dev/null +++ b/app/Services/PublicNavigation.php @@ -0,0 +1,58 @@ + 'dashboard', '/requisicoes' => 'requisitions/index', '/requisicoes/criar' => 'requisitions/form', + '/fornecedores' => 'suppliers/index', '/cotacoes' => 'quotations/index', '/ordens' => 'purchases/index', '/recepcoes' => 'receipts/index', + '/stock' => 'stock/index', '/stock/catalogo' => 'stock/catalogue', '/stock/operacoes' => 'stock/operations', '/equipamentos' => 'equipment/index', + '/planeamento' => 'planning/index', '/pessoas' => 'people/index', '/orcamentos' => 'budgets/index', '/facturas' => 'invoices/index', '/pagamentos' => 'payments/index', + '/regras-investimento' => 'investment/index', '/politica-admissao' => 'purchases/admission-policy', '/politica-recomendacao' => 'purchases/recommendation-policy', + '/revisao-compras' => 'purchase-controls/index', '/settings/appearance' => 'settings/appearance', + ]; + + /** Public navigation deliberately has no tenant, actor or business data provider. */ + public function enabled(): bool + { + return (bool) config('public_navigation.enabled'); + } + + /** @return array */ + public function props(Request $request): array + { + $filter = $request->validate(['search' => 'nullable|string|max:100', 'status' => 'nullable|string|max:40', 'view' => ['nullable', Rule::in(['all', 'mine', 'approvals', 'decided'])], + 'page' => 'nullable|integer|min:1|max:10000', 'receipts_page' => 'nullable|integer|min:1|max:10000', 'kind' => 'nullable|in:staff,service', 'from' => 'nullable|date_format:Y-m-d', 'to' => 'nullable|date_format:Y-m-d', 'warehouse_id' => 'nullable|integer|min:1']); + $page = fn (string $name = 'page') => (new LengthAwarePaginator([], 0, 15, (int) ($filter[$name] ?? 1), ['path' => $request->url(), 'pageName' => $name]))->appends($filter); + $common = ['publicNavigation' => ['paths' => array_keys(self::PAGES), 'dataScope' => 'none'], 'auth' => ['user' => null], 'organizationAccess' => null, 'canRequest' => false, 'payablesAvailable' => false]; + $props = match ('/'.$request->path()) { + '/dashboard' => ['company' => null, 'stats' => ['total' => 0, 'pending' => 0, 'approved' => 0, 'approvedMinor' => 0, 'awaitingMe' => 0], 'recent' => [], 'approvals' => []], + '/requisicoes' => ['requisitions' => $page(), 'filters' => $filter], + '/requisicoes/criar' => ['costCenters' => [], 'requisition' => null, 'catalogue' => ['ready' => false, 'items' => [], 'search' => '', 'more' => false]], + '/fornecedores' => ['suppliers' => $page(), 'filters' => $filter, 'canCreate' => false, 'canReview' => false], + '/cotacoes' => ['requisitions' => $page()], + '/ordens' => ['orders' => $page(), 'awards' => $page()], + '/recepcoes' => ['orders' => $page(), 'receipts' => $page('receipts_page')], + '/stock' => ['items' => [], 'warehouses' => [], 'balances' => [], 'movements' => $page(), 'filters' => $filter, 'canManage' => false], + '/stock/catalogo' => ['records' => $page(), 'filters' => $filter, 'ready' => true, 'canManage' => false], + '/stock/operacoes' => ['items' => [], 'warehouses' => [], 'balances' => [], 'users' => [], 'operations' => $page(), 'counts' => [], 'equipment' => [], 'canOperate' => false], + '/equipamentos' => ['equipment' => [], 'parts' => [], 'links' => [], 'levels' => [], 'items' => [], 'departments' => [], 'history' => $page(), 'canManage' => false, 'canConfigure' => false], + '/planeamento' => ['items' => $page(), 'milestones' => [], 'history' => [], 'canManage' => false, 'today' => today()->toDateString(), 'departments' => [], 'users' => [], 'requisitions' => []], + '/pessoas' => ['ready' => true, 'kinds' => ['staff', 'service'], 'availableKinds' => ['staff', 'service'], 'filters' => $filter, 'workdesk' => null, 'insights' => null, 'company' => null, 'canPrepare' => [], 'formFields' => ['staff' => PeopleForms::STAFF, 'service' => PeopleForms::SERVICE], 'administration' => [], 'processes' => $page()], + '/orcamentos' => ['centers' => [], 'budgets' => [], 'reinforcements' => $page(), 'canManage' => false], + '/facturas' => ['invoices' => $page(), 'orders' => [], 'canManage' => false], + '/pagamentos' => ['invoices' => [], 'payments' => $page(), 'canManage' => false], + '/regras-investimento' => ['policies' => [], 'reviews' => [], 'currentPolicyId' => null, 'canManage' => false], + '/politica-admissao', '/politica-recomendacao' => ['policies' => $page(), 'latest' => null], + '/revisao-compras' => ['role' => '', 'permissions' => [], 'actorId' => null, 'policies' => [], 'reviews' => [], 'awards' => [], 'cancellations' => [], 'sources' => []], + default => [], + }; + + return [...$common, ...$props]; + } +} diff --git a/bootstrap/app.php b/bootstrap/app.php index 8c8b101..2f366ee 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -3,6 +3,7 @@ use App\Http\Middleware\EnterLocalEvaluation; use App\Http\Middleware\HandleAppearance; use App\Http\Middleware\HandleInertiaRequests; +use App\Http\Middleware\PublicDevelopmentNavigation; use App\Services\EvaluationNavigation; use Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests; use Illuminate\Foundation\Application; @@ -21,8 +22,11 @@ return Application::configure(basePath: dirname(__DIR__)) $middleware->redirectGuestsTo(fn (Request $request) => EvaluationNavigation::local($request) ? '/avaliar' : route('login')); $middleware->encryptCookies(except: ['appearance', 'sidebar_state']); $middleware->prependToPriorityList(AuthenticatesRequests::class, EnterLocalEvaluation::class); + $middleware->prependToPriorityList(EnterLocalEvaluation::class, PublicDevelopmentNavigation::class); + $middleware->prependToPriorityList(PublicDevelopmentNavigation::class, HandleInertiaRequests::class); $middleware->web(append: [ + PublicDevelopmentNavigation::class, EnterLocalEvaluation::class, HandleAppearance::class, HandleInertiaRequests::class, diff --git a/config/public_navigation.php b/config/public_navigation.php new file mode 100644 index 0000000..878f9c2 --- /dev/null +++ b/config/public_navigation.php @@ -0,0 +1,3 @@ + (bool) env('SGC_PUBLIC_NAVIGATION', false)]; diff --git a/docs/compatibilidade.md b/docs/compatibilidade.md index 0456fe6..fc017b0 100644 --- a/docs/compatibilidade.md +++ b/docs/compatibilidade.md @@ -8,22 +8,22 @@ Estado actualizado em 28 de Outubro de 2026. Projecto activo: C:\laragon\www\compras, Laravel + React + PostgreSQL, http://127.0.0.1:8015. Preservar conta, dados, configuração, cookie e porta. SGF Tempo e Investmoz são independentes. A implementação Python separada fica apenas como referência; não importar contas, sessões ou bases experimentais. -| Área | Implementado no Laravel | Pendente | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -| Acesso e organização | Fortify, conta, empresa, equipa, departamentos e centros de custo | MFA obrigatório e ciclo completo de acessos | -| Requisições e aprovações | Rascunhos, cálculos exactos, etapas, segregação e snapshots | Validação empresarial das regras provisórias | -| Fornecedores | Cadastro, anexos privados e versões bancárias com duas validações | Múltiplas contas e verificação bancária externa | -| Cotações | Propostas, avaliações e matriz comparativa | Multimoeda e revisão das propostas | -| RF-AF-01 | Declarações pessoais, histórico e ConflictGuard no servidor | Política de periodicidade, validade e levantamento | -| Adjudicação | Escolha, aprovação final e cancelamento sem ordem sob política publicada; rascunho revisto ligado | Cancelamento de ordens emitidas, compromissos, estornos e devoluções fora deste circuito | -| Ordens | Emissão única, snapshots, compromisso orçamental, consulta e impressão | Cancelamento de ordens emitidas e validação operacional integral | -| Recepção | Parcial/total, qualidade, divergências, pendentes, segregação do emitente e auditoria | Substituições e anexos; rejeições não autorizam receber acima do total | -| Stock | Artigos, armazéns, entradas, saídas fundamentadas, transferências atómicas, contagens e ajustes auditados por empresa | Revisão visual, reposição e conversões | -| Equipamentos e peças | Cadastro, compatibilidade, mínimos, validação técnica e investimento condicionado | Configuração empresarial, agregação por projecto e fraccionamento | -| Orçamento | Dotação, reforços aprovados, reservas e compromissos por empresa/centro/exercício | Revisão visual, reduções/transferências e validação operacional integral | -| Facturas e pagamentos | Facturas, consumo e registo/conferência de pagamentos externos | Estornos, notas de crédito e anexos | -| Início e navegação | Página inicial própria, menus por área/perfil e consulta pública por módulo | Revisão visual | -| Auditoria | Histórico das operações implementadas | Exportações, retenção e protecção contra SQL administrativo | +| Área | Implementado no Laravel | Pendente | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| Acesso e organização | Fortify, conta, empresa, equipa, departamentos e centros de custo | MFA obrigatório e ciclo completo de acessos | +| Requisições e aprovações | Rascunhos, cálculos exactos, etapas, segregação e snapshots | Validação empresarial das regras provisórias | +| Fornecedores | Cadastro, anexos privados e versões bancárias com duas validações | Múltiplas contas e verificação bancária externa | +| Cotações | Propostas, avaliações e matriz comparativa | Multimoeda e revisão das propostas | +| RF-AF-01 | Declarações pessoais, histórico e ConflictGuard no servidor | Política de periodicidade, validade e levantamento | +| Adjudicação | Escolha, aprovação final e cancelamento sem ordem sob política publicada; rascunho revisto ligado | Cancelamento de ordens emitidas, compromissos, estornos e devoluções fora deste circuito | +| Ordens | Emissão única, snapshots, compromisso orçamental, consulta e impressão | Cancelamento de ordens emitidas e validação operacional integral | +| Recepção | Parcial/total, qualidade, divergências, pendentes, segregação do emitente e auditoria | Substituições e anexos; rejeições não autorizam receber acima do total | +| Stock | Artigos, armazéns, entradas, saídas fundamentadas, transferências atómicas, contagens e ajustes auditados por empresa | Revisão visual, reposição e conversões | +| Equipamentos e peças | Cadastro, compatibilidade, mínimos, validação técnica e investimento condicionado | Configuração empresarial, agregação por projecto e fraccionamento | +| Orçamento | Dotação, reforços aprovados, reservas e compromissos por empresa/centro/exercício | Revisão visual, reduções/transferências e validação operacional integral | +| Facturas e pagamentos | Facturas, consumo e registo/conferência de pagamentos externos | Estornos, notas de crédito e anexos | +| Início e navegação | Página inicial própria, menus por área/perfil e consulta pública por módulo | Revisão visual | +| Auditoria | Histórico das operações implementadas | Exportações, retenção e protecção contra SQL administrativo | | Revisão de compras | Política por empresa com duas aprovações administrativas; decisão independente de Finanças; reserva não comprometida libertada uma vez | Sem activação automática; máximo de um pedido por adjudicação, mesmo rejeitado | | Visão do processo | Etapas, responsáveis, documentos, decisões e ligações às revisões, filtrados por perfil | Consulta não certifica execução integral | diff --git a/docs/desenvolvimento.md b/docs/desenvolvimento.md index 0a003ed..85e3259 100644 --- a/docs/desenvolvimento.md +++ b/docs/desenvolvimento.md @@ -54,7 +54,6 @@ Migração 000035 apenas na avaliação 8005, backup/restauro fresco conferido, Próxima lacuna: modelos de documentos versionados por empresa, variáveis preenchidas a partir de fontes autorizadas e termos específicos novos. Conferir associações e relatórios na matriz `reutilizacao-dados.md`; reconciliação histórica exige identidade/autorização, sem fusão por nome. Não declarar o requisito transversal integralmente concluído. - ## Registo único e cadastro reutilizável de Pessoas, 30 de Outubro de 2026 Requisito transversal registado em `AGENTS.md`. Primeira lacuna implementada: cadastro de nome/referência/perfil reutilizável, versão/auditoria, pesquisa e arquivo/reactivação. A recepção permite guardar a primeira pessoa no mesmo acto e seleccionar cadastro em candidaturas seguintes. Dados da pessoa vêm do servidor; resumo específico da candidatura não actualiza o cadastro. Snapshot imutável por candidatura e referência/versão no relatório. Mudanças posteriores não reescrevem avaliações/decisões. Mesma pessoa não duplica candidatura ligada no mesmo processo; nomes iguais não são fundidos. @@ -181,20 +180,20 @@ Mantêm-se como próximos incrementos: tarefas operacionais versus aprovações, Lido integralmente o conteúdo textual e das tabelas de `SGC — Sistema de Gestão de Contratações - pessoas .docx`, fornecido pelo proprietário em `C:/Mac/Home/Documents/TEMPO/Portal Tempo/Servicos Tempo/Compras/`. SHA-256 `d294fc08e6cbf5c9ced6527bf06473909380bd9d2bb64f3e3c2ca7605eb52ce3`. Original preservado; leitura sem revisão de paginação ou validação jurídica. O próprio documento identifica-se como proposta para adaptação/validação interna, sem confirmar funcionalidades existentes. Conteúdo tratado como requisitos propostos para comparação, não como instrução para activar acessos, executar operações ou alterar a aplicação. -| Âmbito proposto | Estado conferido no código | -| --- | --- | -| Identidade SGC, descrição e assinatura TEMPO | Implementadas na apresentação local. Publicação no domínio continua sem confirmação. | -| Dois percursos separados | Tipos `service`/`staff`, permissões separadas, abertura, candidaturas, avaliações, proposta e conferência existem. Formulários são ainda genéricos; não há dois módulos completos conforme os anexos. | -| Serviço individual integrado em Compras, com dois acessos ao mesmo processo | Não implementado: `/pessoas` usa `people_processes`; não há vínculo funcional a requisição/propostas/contrato/entregáveis de Compras nem segunda entrada canónica nesse módulo. Reutilizar autenticação/auditoria não equivale a essa integração. | -| Administração sem acesso automático a candidaturas/propostas/remunerações | Divergência concreta: `PeopleHiring::allowed()` concede acesso por `admin`. A proposta exige separar configurar de consultar conteúdo, com atribuição específica. Nenhuma permissão foi alterada por esta revisão documental. | -| Papéis e acesso por entidade, percurso, processo e campo | Base por entidade/percurso e quatro capacidades existe. Ainda faltam atribuições nominais por processo/etapa, júri/entrevistadores, níveis configuráveis, consulta versus edição/decisão/exportação e ocultação específica de honorários/remunerações/entrevistas. | -| Requisitos obrigatórios/desejáveis, equivalências e esclarecimentos | Ausentes como estrutura própria. Critério actual tem apenas rótulo/peso; avaliação exige nota/evidência textual. Não representa esclarecimento pendente, requisito comprovado/ausente, equivalência ou adaptação razoável. | -| Ponderações quando aplicáveis e selecção factual | Actual circuito impõe soma 100%, notas 0–10 e escolha entre maiores resultados. A proposta admite métodos próprios e ponderações quando aplicáveis; é necessário tornar o método configurável, sem tratar ausência de comprovativo como reprovação nem requisitos desejáveis como eliminatórios. | -| Anexo A, Guião, Anexo B e Anexo C | Não implementados como formulários/modelos versionados. Faltam campos próprios de vaga e necessidade de serviço, perguntas/exercícios, evidência relatada/observada/comprovada e seguimento dos esclarecimentos. Texto livre actual não equivale aos anexos. | -| Regras anteriores à abertura e alterações versionadas | Critérios/âmbito actuais preservados, com abertura independente, versão de operação e auditoria. Ainda não há circuito de revisão/substituição de regras/documentos, correcção/reabertura e aprovação dessas alterações. | -| Tarefas, Aprovações e ecrã inicial | Ausentes como filas atribuídas e contagens separadas. A página actual lista processos autorizados e criação, sem painel de trabalho, pesquisa/filtros por percurso/estado/período, alertas ou selector autorizado de entidade. | -| Contrato, acompanhamento, relatório final e encerramento | Apenas minuta interna e consulta imprimível. Faltam formalização contratual, entregáveis/marcos/aceitação, integração/formação factual, pendências, relatório final e encerramento. Salários não implementados; classificação individual de desempenho pós-admissão não integra esta proposta. | -| Contas externas e dados pessoais | Não há criação automática de contas de candidatos/prestadores. Faltam recepção externa configurável, biblioteca/anexos, retenção, acesso por documento/campo, comunicações e exportação própria autorizada. Não afirmar conformidade jurídica com base nesta leitura. | +| Âmbito proposto | Estado conferido no código | +| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Identidade SGC, descrição e assinatura TEMPO | Implementadas na apresentação local. Publicação no domínio continua sem confirmação. | +| Dois percursos separados | Tipos `service`/`staff`, permissões separadas, abertura, candidaturas, avaliações, proposta e conferência existem. Formulários são ainda genéricos; não há dois módulos completos conforme os anexos. | +| Serviço individual integrado em Compras, com dois acessos ao mesmo processo | Não implementado: `/pessoas` usa `people_processes`; não há vínculo funcional a requisição/propostas/contrato/entregáveis de Compras nem segunda entrada canónica nesse módulo. Reutilizar autenticação/auditoria não equivale a essa integração. | +| Administração sem acesso automático a candidaturas/propostas/remunerações | Divergência concreta: `PeopleHiring::allowed()` concede acesso por `admin`. A proposta exige separar configurar de consultar conteúdo, com atribuição específica. Nenhuma permissão foi alterada por esta revisão documental. | +| Papéis e acesso por entidade, percurso, processo e campo | Base por entidade/percurso e quatro capacidades existe. Ainda faltam atribuições nominais por processo/etapa, júri/entrevistadores, níveis configuráveis, consulta versus edição/decisão/exportação e ocultação específica de honorários/remunerações/entrevistas. | +| Requisitos obrigatórios/desejáveis, equivalências e esclarecimentos | Ausentes como estrutura própria. Critério actual tem apenas rótulo/peso; avaliação exige nota/evidência textual. Não representa esclarecimento pendente, requisito comprovado/ausente, equivalência ou adaptação razoável. | +| Ponderações quando aplicáveis e selecção factual | Actual circuito impõe soma 100%, notas 0–10 e escolha entre maiores resultados. A proposta admite métodos próprios e ponderações quando aplicáveis; é necessário tornar o método configurável, sem tratar ausência de comprovativo como reprovação nem requisitos desejáveis como eliminatórios. | +| Anexo A, Guião, Anexo B e Anexo C | Não implementados como formulários/modelos versionados. Faltam campos próprios de vaga e necessidade de serviço, perguntas/exercícios, evidência relatada/observada/comprovada e seguimento dos esclarecimentos. Texto livre actual não equivale aos anexos. | +| Regras anteriores à abertura e alterações versionadas | Critérios/âmbito actuais preservados, com abertura independente, versão de operação e auditoria. Ainda não há circuito de revisão/substituição de regras/documentos, correcção/reabertura e aprovação dessas alterações. | +| Tarefas, Aprovações e ecrã inicial | Ausentes como filas atribuídas e contagens separadas. A página actual lista processos autorizados e criação, sem painel de trabalho, pesquisa/filtros por percurso/estado/período, alertas ou selector autorizado de entidade. | +| Contrato, acompanhamento, relatório final e encerramento | Apenas minuta interna e consulta imprimível. Faltam formalização contratual, entregáveis/marcos/aceitação, integração/formação factual, pendências, relatório final e encerramento. Salários não implementados; classificação individual de desempenho pós-admissão não integra esta proposta. | +| Contas externas e dados pessoais | Não há criação automática de contas de candidatos/prestadores. Faltam recepção externa configurável, biblioteca/anexos, retenção, acesso por documento/campo, comunicações e exportação própria autorizada. Não afirmar conformidade jurídica com base nesta leitura. | Observação editorial: a introdução afirma que os critérios do dashboard ainda não foram disponibilizados, mas o documento contém uma proposta detalhada de ecrã inicial e critérios de aceitação. Convém distinguir os requisitos operacionais já descritos dos indicadores de negócio/metas ainda por definir. @@ -296,19 +295,19 @@ Lido o ficheiro do proprietário `recepcao de propostas.docx`, SHA-256 `77e8df9c O documento é coerente ao separar recepção, abertura, admissibilidade, avaliação e adjudicação. O registo de entrega não deve decidir admissibilidade; o comprovativo identifica a mesma entrega e preserva essa ressalva; substituições têm referências relacionadas sem reutilizar a identidade da entrega anterior. A descrição externa de volumes/ficheiros, a confidencialidade e a preservação de ocorrências também são adequadas como requisitos funcionais. Para o contexto privado, a constituição de júri/comissão/equipa e a sua competência devem resultar da política, do risco e das delegações da empresa, com nomes, composição, impedimentos, substituições e permissões parametrizáveis. Não adoptar automaticamente o júri como requisito fixo de qualquer compra. -| Elemento do documento | Cobertura no código local | -| --- | --- | -| Necessidades de compras | Requisições justificadas, linhas, estimativas, planeamento e orçamento existentes; não equivalem automaticamente a um relatório de necessidades consolidado/aprovado com todas as evidências do modelo | -| Condições de entrega e divulgação | Parcial: a acta pode registar prazo/fuso, mas falta a configuração publicada e versionada de canais, formatos, prazos e esclarecimentos antes da recepção | -| Registo protocolar por entrega | Não encontrado: falta entidade própria com referência única, recepção exacta, canal/local, entregante, identificação externa dos volumes/ficheiros, ocorrências e guarda | -| Comprovativo de entrega | Não encontrado: falta emissão ligada à entrega, número próprio quando aplicável, disponibilização ao fornecedor e preservação da cópia original/metadados | -| Recepção electrónica confidencial | Não encontrada como envelope protegido: as cotações já contêm valores/linhas consultáveis antes da acta; não existe mecanismo de recepção selada e abertura autorizada sobre os originais | -| Fora de prazo, substituição, retirada e falha técnica | Falta ciclo próprio de ocorrências e decisões, ligado às entregas anteriores e à versão das condições de recepção | -| Nomeação e poderes do júri/equipa | Parcial: a acta regista nome/capacidade e grupo `jury`/`participant`; esses campos não são uma nomeação, associação a contas com vigência/quórum ou autorização efectiva de acesso às propostas | -| Abertura | Acta versionada, data/fuso, participantes, referências de anexos, selecção de propostas, fingerprint e impressão existentes; não substitui o protocolo/comprovativo nem implementa por si a guarda selada anterior | -| Admissibilidade e avaliação | Qualificação, decisões de admissão fundamentadas/revistas, comparação e recomendação existentes nos seus âmbitos; faltam as ligações à entrega protocolada e às ocorrências, e a prova de divulgação prévia/comum de critérios/esclarecimentos | -| Classificação e adjudicação | Comparação/classificação, recomendação, aprovações e ordem existentes; comunicação aos concorrentes e tratamento completo de reclamações do procedimento não encontrados. Contraditório da avaliação de desempenho é outro âmbito | -| Arquivo | Histórico, referências e versões preservadas em vários módulos; não foi encontrado ciclo próprio de custódia, auditoria de todos os acessos ao conteúdo de propostas, retenção, bloqueio de eliminação e eliminação autorizada dos respectivos originais | +| Elemento do documento | Cobertura no código local | +| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Necessidades de compras | Requisições justificadas, linhas, estimativas, planeamento e orçamento existentes; não equivalem automaticamente a um relatório de necessidades consolidado/aprovado com todas as evidências do modelo | +| Condições de entrega e divulgação | Parcial: a acta pode registar prazo/fuso, mas falta a configuração publicada e versionada de canais, formatos, prazos e esclarecimentos antes da recepção | +| Registo protocolar por entrega | Não encontrado: falta entidade própria com referência única, recepção exacta, canal/local, entregante, identificação externa dos volumes/ficheiros, ocorrências e guarda | +| Comprovativo de entrega | Não encontrado: falta emissão ligada à entrega, número próprio quando aplicável, disponibilização ao fornecedor e preservação da cópia original/metadados | +| Recepção electrónica confidencial | Não encontrada como envelope protegido: as cotações já contêm valores/linhas consultáveis antes da acta; não existe mecanismo de recepção selada e abertura autorizada sobre os originais | +| Fora de prazo, substituição, retirada e falha técnica | Falta ciclo próprio de ocorrências e decisões, ligado às entregas anteriores e à versão das condições de recepção | +| Nomeação e poderes do júri/equipa | Parcial: a acta regista nome/capacidade e grupo `jury`/`participant`; esses campos não são uma nomeação, associação a contas com vigência/quórum ou autorização efectiva de acesso às propostas | +| Abertura | Acta versionada, data/fuso, participantes, referências de anexos, selecção de propostas, fingerprint e impressão existentes; não substitui o protocolo/comprovativo nem implementa por si a guarda selada anterior | +| Admissibilidade e avaliação | Qualificação, decisões de admissão fundamentadas/revistas, comparação e recomendação existentes nos seus âmbitos; faltam as ligações à entrega protocolada e às ocorrências, e a prova de divulgação prévia/comum de critérios/esclarecimentos | +| Classificação e adjudicação | Comparação/classificação, recomendação, aprovações e ordem existentes; comunicação aos concorrentes e tratamento completo de reclamações do procedimento não encontrados. Contraditório da avaliação de desempenho é outro âmbito | +| Arquivo | Histórico, referências e versões preservadas em vários módulos; não foi encontrado ciclo próprio de custódia, auditoria de todos os acessos ao conteúdo de propostas, retenção, bloqueio de eliminação e eliminação autorizada dos respectivos originais | Ponto técnico crítico: `QuotationController::show` disponibiliza a comparação/conteúdo a utilizadores autorizados pelo âmbito/função, sem condição de abertura prévia. `ProposalOpeningWorkflow::proposals` também obtém os preços/linhas para preparar a acta. O `basis_hash` detecta mudanças na representação dos dados, mas não é um selo de ficheiros recebidos nem uma barreira de confidencialidade antes da abertura. Assim, não se deve apresentar o mecanismo actual como cumprimento do requisito de propostas seladas. O módulo de recepções de bens/serviços (`GoodsReceipt`) não é recepção de propostas. @@ -322,18 +321,18 @@ Pedido do proprietário: verificar se o fluxo do ficheiro `fluxo sector público Conclusão: o percurso-base da compra já existe, mas a proposta privada não está integralmente implementada. A disponibilidade abaixo refere-se ao código local e aos âmbitos documentados, sem nova aceitação visual, activação da configuração da empresa ou confirmação de instalação no domínio. -| Etapa da proposta privada | Implementação existente | Lacuna para cobertura integral | -| --- | --- | --- | -| 1 Requisição e justificação | Rascunhos, linhas/quantidades, prazo, justificação, departamento/centro, planeamento e consulta de stock | Verificação prévia obrigatória de existências e alternativas, com evidência associada ao pedido | -| 2 Orçamento e autorização | Reserva/compromisso/consumo orçamental, aprovações e limites monetários configuráveis | Cobertura obrigatória em todos os processos: o núcleo ainda retorna `null` quando não existe dotação; prevenção de fraccionamento e matriz de poderes por risco não implementadas | -| 3 Estratégia de compra | Consulta e registo de cotações, comparação e adjudicação | Política configurável para consulta, concurso privado, negociação e fornecedor único, número de propostas variável, excepções/urgências aprovadas e revisão posterior | -| 4 Verificação do fornecedor | Cadastro, beneficiários em texto, diligência, documentos, revisão/impedimento, conflitos e versões bancárias com revisão independente | Diligência estruturada e proporcional ao risco, partes relacionadas e beneficiários efectivos estruturados, sanções/restrições e antecedentes com verificações documentadas; confirmação por canal independente não tem fluxo específico | -| 5 Solicitação e recepção de propostas | Propostas por linhas comparáveis, ponderações, qualificação/admissão e abertura opcionais | Ciclo completo de convites aos fornecedores, esclarecimentos e negociação, com controlo próprio de informação concorrencial | -| 6 Avaliação e selecção | Comparação de preço, qualidade, prazo, histórico e condições de pagamento; análises técnicas e recomendação com revisão | Custo total estruturado, risco transversal, assistência e revisão independente accionada pela classificação de risco, com pareceres configuráveis | -| 7 Aprovação e formalização | Aprovação da adjudicação e emissão de ordem de compra, preservando regras e evidências | Gestão de contratos/acordos, clausulado, subcontratação, versões/alterações e excepções de execução antecipada aprovadas | -| 8 Execução e recepção | Recepções parciais, quantidade/qualidade, reservas/rejeições, aceitação de serviços e stock quando físico | Gestão da execução contratual, marcos de serviços, alterações contratuais e respectivos aprovadores | -| 9 Validação e pagamento | Conferência ordem–recepção aceite–factura; quantidades/preços/imposto, duplicados, conferência independente e registo de pagamentos externos | Adiantamentos e marcos contratuais, excepções/tolerâncias aprovadas e conclusão do percurso comercial comum de pagamentos, actualmente restrito ao ensaio | -| 10 Encerramento e monitorização | Histórico/auditoria, relatórios, avaliações qualitativas, medidas de melhoria e contraditório do fornecedor | Encerramento formal do processo/contrato e indicadores consolidados de concentração, excepções, compras sem ordem, alterações contratuais e diligências pendentes | +| Etapa da proposta privada | Implementação existente | Lacuna para cobertura integral | +| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 Requisição e justificação | Rascunhos, linhas/quantidades, prazo, justificação, departamento/centro, planeamento e consulta de stock | Verificação prévia obrigatória de existências e alternativas, com evidência associada ao pedido | +| 2 Orçamento e autorização | Reserva/compromisso/consumo orçamental, aprovações e limites monetários configuráveis | Cobertura obrigatória em todos os processos: o núcleo ainda retorna `null` quando não existe dotação; prevenção de fraccionamento e matriz de poderes por risco não implementadas | +| 3 Estratégia de compra | Consulta e registo de cotações, comparação e adjudicação | Política configurável para consulta, concurso privado, negociação e fornecedor único, número de propostas variável, excepções/urgências aprovadas e revisão posterior | +| 4 Verificação do fornecedor | Cadastro, beneficiários em texto, diligência, documentos, revisão/impedimento, conflitos e versões bancárias com revisão independente | Diligência estruturada e proporcional ao risco, partes relacionadas e beneficiários efectivos estruturados, sanções/restrições e antecedentes com verificações documentadas; confirmação por canal independente não tem fluxo específico | +| 5 Solicitação e recepção de propostas | Propostas por linhas comparáveis, ponderações, qualificação/admissão e abertura opcionais | Ciclo completo de convites aos fornecedores, esclarecimentos e negociação, com controlo próprio de informação concorrencial | +| 6 Avaliação e selecção | Comparação de preço, qualidade, prazo, histórico e condições de pagamento; análises técnicas e recomendação com revisão | Custo total estruturado, risco transversal, assistência e revisão independente accionada pela classificação de risco, com pareceres configuráveis | +| 7 Aprovação e formalização | Aprovação da adjudicação e emissão de ordem de compra, preservando regras e evidências | Gestão de contratos/acordos, clausulado, subcontratação, versões/alterações e excepções de execução antecipada aprovadas | +| 8 Execução e recepção | Recepções parciais, quantidade/qualidade, reservas/rejeições, aceitação de serviços e stock quando físico | Gestão da execução contratual, marcos de serviços, alterações contratuais e respectivos aprovadores | +| 9 Validação e pagamento | Conferência ordem–recepção aceite–factura; quantidades/preços/imposto, duplicados, conferência independente e registo de pagamentos externos | Adiantamentos e marcos contratuais, excepções/tolerâncias aprovadas e conclusão do percurso comercial comum de pagamentos, actualmente restrito ao ensaio | +| 10 Encerramento e monitorização | Histórico/auditoria, relatórios, avaliações qualitativas, medidas de melhoria e contraditório do fornecedor | Encerramento formal do processo/contrato e indicadores consolidados de concentração, excepções, compras sem ordem, alterações contratuais e diligências pendentes | Divergências concretas: `ProposalComparison::inspect` exige pelo menos três propostas elegíveis de fornecedores distintos e duas avaliações elegíveis por proposta; `PurchaseWorkflow::currentBasis` bloqueia excepções sem política. Esses números permanecem fixos e não correspondem à quantidade definida por cada empresa/valor/risco na proposta. `RequisitionWorkflow::submit` determina as etapas por limites monetários e equipamento; ainda não resolve uma matriz geral de risco inicial/residual. `BudgetControl::record` permite continuar sem dotação configurada, retornando `null`. A existência do módulo orçamental, portanto, não prova cobertura obrigatória universal. `SettlementHttp::guard` restringe o percurso comum de pagamentos ao ambiente/base de ensaio; ordens/recepções e pagamentos externos conservam marcadores de desenvolvimento nas snapshots. A remoção de tais marcadores não substitui a conclusão funcional da entrega comercial. diff --git a/docs/indicadores-sgc.md b/docs/indicadores-sgc.md index 4610f12..f8e8989 100644 --- a/docs/indicadores-sgc.md +++ b/docs/indicadores-sgc.md @@ -6,15 +6,15 @@ Versão de definição 1, 30/10/2026. Indicadores factuais, sem modelo de machin Método `procurement_facts_v1`, mesmo snapshot de leitura do relatório. O período filtra a criação da requisição, não a data de submissão ou a execução. Contagens incluem todas as páginas. Origem: requisições autorizadas por empresa/departamento, propostas registadas e ordem visível. Actualização ao consultar/aplicar filtros; não há actualização automática em segundo plano. -| Indicador | Definição e base | Limite de interpretação | -| --- | --- | --- | -| Requisições no âmbito | Todos os pedidos visíveis que satisfazem os filtros | Não representa necessariamente toda a empresa | -| Em aprovação | Estado actual `pending` | Não é uma fila pessoal nem autorização para decidir | -| Antiguidade de submissão | Dias de calendário entre submissão e instante de leitura, no fuso configurado da aplicação; até cinco pendentes mais antigos, desempate por ID | Não mede a duração da etapa actual; não estima prazo de conclusão | -| Antiguidade desconhecida | Pendentes sem submissão registada ou com data de submissão num dia futuro | Não substitui a data de submissão pela criação nem inventa duração | -| Data de necessidade ultrapassada | `draft`/`pending` com `needed_by` anterior ao dia da leitura | Data de necessidade do requisitante não é prazo contratual de entrega; hoje não conta como ultrapassado | -| Aprovadas sem propostas registadas | Aprovadas com contagem de propostas igual a zero, denominador: aprovadas do filtro | Uma proposta registada não é necessariamente válida ou comparável | -| Aprovadas sem ordem visível | Aprovadas sem ordem encontrada pela mesma projecção autorizada do relatório | Não prova incumprimento ou inexistência absoluta; pode sobrepor-se à ausência de propostas | +| Indicador | Definição e base | Limite de interpretação | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | +| Requisições no âmbito | Todos os pedidos visíveis que satisfazem os filtros | Não representa necessariamente toda a empresa | +| Em aprovação | Estado actual `pending` | Não é uma fila pessoal nem autorização para decidir | +| Antiguidade de submissão | Dias de calendário entre submissão e instante de leitura, no fuso configurado da aplicação; até cinco pendentes mais antigos, desempate por ID | Não mede a duração da etapa actual; não estima prazo de conclusão | +| Antiguidade desconhecida | Pendentes sem submissão registada ou com data de submissão num dia futuro | Não substitui a data de submissão pela criação nem inventa duração | +| Data de necessidade ultrapassada | `draft`/`pending` com `needed_by` anterior ao dia da leitura | Data de necessidade do requisitante não é prazo contratual de entrega; hoje não conta como ultrapassado | +| Aprovadas sem propostas registadas | Aprovadas com contagem de propostas igual a zero, denominador: aprovadas do filtro | Uma proposta registada não é necessariamente válida ou comparável | +| Aprovadas sem ordem visível | Aprovadas sem ordem encontrada pela mesma projecção autorizada do relatório | Não prova incumprimento ou inexistência absoluta; pode sobrepor-se à ausência de propostas | As ligações das submissões antigas abrem o processo original e reaplicam a sua autorização. Relatório e exportação CSV anteriores conservam a sua estrutura; os novos indicadores são apresentados no painel, não acrescentados silenciosamente ao contrato do CSV. @@ -22,15 +22,15 @@ As ligações das submissões antigas abrem o processo original e reaplicam a su Método `operational_facts_v1`, mesmo instante e snapshot da fila pessoal autorizada. Filtros por percurso, estado, título/referência e criação. Origem: processos visíveis, tarefas possíveis para o interveniente, aprovações independentes e esclarecimentos pendentes. Actualizar ou voltar a consultar para reflectir intervenções posteriores. -| Indicador | Definição e base | Limite de interpretação | -| --- | --- | --- | -| Processos no âmbito | Processos visíveis nos filtros, todas as páginas | Não equivale ao universo da organização | -| Prazos vencidos | Ocorrências de recepção ou esclarecimento ainda pendentes com prazo anterior à data de leitura | Várias ocorrências podem pertencer ao mesmo processo | -| Processos com vencimentos | IDs distintos nas ocorrências vencidas | Distingue carga de ocorrências de quantidade de processos | -| Maior atraso | Maior diferença em dias de calendário nas ocorrências; nulo quando não existem | Não determina resultado de candidatura; dias corridos, sem calendário laboral | -| Tarefas por acção | Contagem das acções disponíveis à pessoa na sua fila | Não classifica desempenho de trabalhadores ou candidatos | -| Tarefas sem prazo próprio | Tarefas cuja data da fila é nula | Ausência de prazo não indica incumprimento | -| Aprovações | Intervenções formais pendentes para as quais o actor é elegível e independente | Separadas de tarefas operacionais e de conferência de esclarecimentos | +| Indicador | Definição e base | Limite de interpretação | +| ------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | +| Processos no âmbito | Processos visíveis nos filtros, todas as páginas | Não equivale ao universo da organização | +| Prazos vencidos | Ocorrências de recepção ou esclarecimento ainda pendentes com prazo anterior à data de leitura | Várias ocorrências podem pertencer ao mesmo processo | +| Processos com vencimentos | IDs distintos nas ocorrências vencidas | Distingue carga de ocorrências de quantidade de processos | +| Maior atraso | Maior diferença em dias de calendário nas ocorrências; nulo quando não existem | Não determina resultado de candidatura; dias corridos, sem calendário laboral | +| Tarefas por acção | Contagem das acções disponíveis à pessoa na sua fila | Não classifica desempenho de trabalhadores ou candidatos | +| Tarefas sem prazo próprio | Tarefas cuja data da fila é nula | Ausência de prazo não indica incumprimento | +| Aprovações | Intervenções formais pendentes para as quais o actor é elegível e independente | Separadas de tarefas operacionais e de conferência de esclarecimentos | ## Evolução e qualidade diff --git a/docs/menus-benchmark-20261029.md b/docs/menus-benchmark-20261029.md index 48b0779..8a7a829 100644 --- a/docs/menus-benchmark-20261029.md +++ b/docs/menus-benchmark-20261029.md @@ -14,16 +14,16 @@ Inventário do código actual, preservando as entregas anteriores. `scripts/menu-code-check.mjs` confere a definição real do menu contra as rotas Laravel GET e o destaque activo: **102 entradas somadas nos seis perfis**, com obrigações ligadas/desligadas. Prova em `proofs/menu-code-contract.json`. É prova de ligação/capacidade do menu, não declaração de funcionamento integral de cada módulo. -| Grupo do menu | Código e percurso existentes | Ligação ao relatório / saldo identificado | -| --- | --- | --- | -| Requisições | RequisitionController: criar, editar, submeter, decidir, vistas pessoais/rascunhos; PurchasePlanningController: itens, responsáveis e marcos | O processo reúne as etapas; a central nova localiza pedidos por número, data, estado e departamento. | -| Aprovações | Elegibilidade e decisões em RequisitionController/RequisitionWorkflow | Conservadas as decisões efectivas; relatórios não executam nem substituem aprovações. | -| Consultas e adjudicações | QuotationController, abertura, qualificação, admissão, recomendação e PurchaseController; revisão/cancelamento existente | Relatório de conferência recupera bases, versões e decisões; não inventa validade de documentos antigos. | -| Fornecedores | Cadastro/manutenção/documentos em SupplierController e SupplierDocumentController | **Avaliação de fornecedores continua como proposta de interface**: não existem ainda gravação/revisão/histórico operacional desse módulo. Desenvolver esse fluxo até ao seu relatório é a próxima lacuna funcional concreta. | -| Recepções e armazém | GoodsReceiptController, StockController, StockOperationController e EquipmentController | O relatório individual passa a incluir recepções associadas e a ligação às respectivas fichas; não presume entrega integral nem adiciona movimentos. | -| Finanças | Facturas, pagamentos externos, orçamento/reforços e políticas existentes; núcleo comum sob configuração própria | Relatório individual inclui facturas/registos de pagamentos apenas para Finanças/Administração. Montantes preservados, sem cálculo de saldo ou inferência de liquidação. Pagamentos/afectações sintéticos e relatórios agregados financeiros ainda requerem os incrementos próprios. | -| Administração e controlo | Empresa/equipa/centros, políticas de admissão/recomendação e conflitos | Mantidas regras e autorizações existentes; não há criação de contas ou novos direitos por abrir relatórios. | -| Relatórios | **Nova central `/relatorios` e exportação `/relatorios/compras.csv`**, ligadas ao backend | Menu → filtros → requisição/processo → relatório de conferência → impressão existente. CSV usa todos os resultados autorizados dos filtros, não só a página visível. | +| Grupo do menu | Código e percurso existentes | Ligação ao relatório / saldo identificado | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Requisições | RequisitionController: criar, editar, submeter, decidir, vistas pessoais/rascunhos; PurchasePlanningController: itens, responsáveis e marcos | O processo reúne as etapas; a central nova localiza pedidos por número, data, estado e departamento. | +| Aprovações | Elegibilidade e decisões em RequisitionController/RequisitionWorkflow | Conservadas as decisões efectivas; relatórios não executam nem substituem aprovações. | +| Consultas e adjudicações | QuotationController, abertura, qualificação, admissão, recomendação e PurchaseController; revisão/cancelamento existente | Relatório de conferência recupera bases, versões e decisões; não inventa validade de documentos antigos. | +| Fornecedores | Cadastro/manutenção/documentos em SupplierController e SupplierDocumentController | **Avaliação de fornecedores continua como proposta de interface**: não existem ainda gravação/revisão/histórico operacional desse módulo. Desenvolver esse fluxo até ao seu relatório é a próxima lacuna funcional concreta. | +| Recepções e armazém | GoodsReceiptController, StockController, StockOperationController e EquipmentController | O relatório individual passa a incluir recepções associadas e a ligação às respectivas fichas; não presume entrega integral nem adiciona movimentos. | +| Finanças | Facturas, pagamentos externos, orçamento/reforços e políticas existentes; núcleo comum sob configuração própria | Relatório individual inclui facturas/registos de pagamentos apenas para Finanças/Administração. Montantes preservados, sem cálculo de saldo ou inferência de liquidação. Pagamentos/afectações sintéticos e relatórios agregados financeiros ainda requerem os incrementos próprios. | +| Administração e controlo | Empresa/equipa/centros, políticas de admissão/recomendação e conflitos | Mantidas regras e autorizações existentes; não há criação de contas ou novos direitos por abrir relatórios. | +| Relatórios | **Nova central `/relatorios` e exportação `/relatorios/compras.csv`**, ligadas ao backend | Menu → filtros → requisição/processo → relatório de conferência → impressão existente. CSV usa todos os resultados autorizados dos filtros, não só a página visível. | O novo recorte não encerra contratos, multimoeda, relatórios financeiros agregados, avaliação de fornecedores ou o percurso comercial dos pagamentos ainda sintéticos. A prioridade seguinte é substituir a proposta de avaliação por um ciclo persistente, com critérios/configuração e evidências explícitos, revisão, histórico e relatório; não activar pesos/políticas provisórias silenciosamente. @@ -37,16 +37,16 @@ Verificações deste recorte: 14 testes Feature/223 asserções, incluindo 207 r A aplicação autenticada usa agora um menu lateral por tarefas e uma barra superior com pesquisa do menu, atalho de nova requisição e conta. As secções podem ser expandidas, a área actual abre automaticamente e a ligação corrente fica destacada. Pesquisa sem distinção de acentos/maiúsculas, limpeza e mensagem de ausência de resultados. Não é uma pesquisa global de documentos. -| Secção | Percursos existentes reunidos | -| --- | --- | -| Painel inicial | Visão geral e indicadores existentes | -| Requisições | Nova, minhas, meus rascunhos, todas as autorizadas e planeamento | -| Aprovações | Próxima decisão elegível para o utilizador e histórico das suas decisões de requisições | -| Consultas e adjudicações | Cotações/comparação, adjudicações/ordens e revisão/cancelamento existente | -| Fornecedores | Cadastro e documentos | -| Recepções e armazém | Recepções/divergências, artigos/stock, saídas/inventários, equipamentos/peças | -| Finanças | Facturas, obrigações autorizadas, pagamentos externos, orçamentos/reforços e investimento | -| Administração e controlo | Empresa/equipa/centros, políticas de admissão/recomendação e conflitos | +| Secção | Percursos existentes reunidos | +| ------------------------ | ----------------------------------------------------------------------------------------- | +| Painel inicial | Visão geral e indicadores existentes | +| Requisições | Nova, minhas, meus rascunhos, todas as autorizadas e planeamento | +| Aprovações | Próxima decisão elegível para o utilizador e histórico das suas decisões de requisições | +| Consultas e adjudicações | Cotações/comparação, adjudicações/ordens e revisão/cancelamento existente | +| Fornecedores | Cadastro e documentos | +| Recepções e armazém | Recepções/divergências, artigos/stock, saídas/inventários, equipamentos/peças | +| Finanças | Facturas, obrigações autorizadas, pagamentos externos, orçamentos/reforços e investimento | +| Administração e controlo | Empresa/equipa/centros, políticas de admissão/recomendação e conflitos | O layout real é `SgcShell`, usado por `AppLayout`; o componente antigo `AppSidebar` não é a navegação activa. A renovação foi feita no layout efectivamente utilizado. As consultas públicas mantêm o seu layout próprio e as ligações anteriores. O núcleo comum de obrigações continua com o seu ecrã próprio e regresso às facturas; a sua ligação usa carregamento completo para não receber uma página HTML como modal Inertia. diff --git a/docs/obrigacoes-activacao-local.json b/docs/obrigacoes-activacao-local.json index f9024be..7d5ccbe 100644 --- a/docs/obrigacoes-activacao-local.json +++ b/docs/obrigacoes-activacao-local.json @@ -3,11 +3,7 @@ "database": "compras_dev", "user_id": 1, "tenant_id": 1, - "actions": [ - "view", - "prepare", - "validate" - ], + "actions": ["view", "prepare", "validate"], "enabled": true, "source_instance": "compras-local-aa0dbeec75b98ca65246756541f75363", "backup_restore_verified": true, diff --git a/docs/orientacoes-continuidade.md b/docs/orientacoes-continuidade.md index 5006a11..6c4e69f 100644 --- a/docs/orientacoes-continuidade.md +++ b/docs/orientacoes-continuidade.md @@ -16,7 +16,6 @@ Migração 000035 apenas na avaliação 8005, backup/restauro fresco conferido, Próxima lacuna: modelos de documentos versionados por empresa, variáveis preenchidas a partir de fontes autorizadas e termos específicos novos. Conferir associações e relatórios na matriz `reutilizacao-dados.md`; reconciliação histórica exige identidade/autorização, sem fusão por nome. Não declarar o requisito transversal integralmente concluído. - **Registar uma vez/reutilizar — Pessoas, 30/10/2026:** implementado cadastro próprio/partilhado por permissões, nome/referência/perfil, versão/auditoria/arquivo. Primeira candidatura pode guardar perfil no mesmo acto; seguintes seleccionam fonte autorizada. Nome e snapshot vêm do servidor; dados específicos da candidatura não reescrevem cadastro. Snapshot e referência/versão preservados por processo, actualizações/arquivo não alteram histórico; sem duplicar pessoa ligada no mesmo processo ou fundir nomes. Preparador consulta próprios, capacidades `people_registry_read/manage` dão âmbito partilhado; administrador não recebe leitura alheia automática, cadastro não dá acesso aos processos. Migração 000034 apenas em 8005: backup/restauro e 93 tabelas antigas preservados, nova tabela vazia, duas colunas nulas em candidaturas antigas, sem pessoas/grants/importação. Provas `people-registry.json`, `people-registry-install.json`, `people-registry-pg.json`. PHP integral 698/696 aprovados/dois ignorados, 6 739 asserções; módulo/PG 43/1124; React 44; menu seis grupos/111 acessos. Visual/domínio pendentes. Matriz `reutilizacao-dados.md`: requisito global ainda não concluído; próximos catálogo genérico de artigos, modelos documentais e reconciliação assistida de históricos. Não depende de IA; nenhuma chamada paga repetida. **Garantia comercial sem IA, 30/10/2026:** proprietário confirmou que as funcionalidades prometidas têm de permanecer disponíveis. Requisito permanente em `AGENTS.md`: SGC base independente do adicional de IA; sem chave/crédito/subscrição/fornecedor não bloqueiam os percursos normais ou relatórios. Indicadores/alertas/sínteses locais fazem parte do núcleo. Preservar documentos, decisões e resultados incorporados após cancelar IA; não mover funções aprovadas do núcleo para o adicional. Aplicar nas futuras integrações, reservas, limites e cobrança, mantendo permissões e auditoria. Conferidos controlos/testes existentes e reutilizada prova `ai-plan.json`; alteração documental, sem novas chamadas/dados/código. Pendências funcionais continuam pendentes, sem alegar conclusão integral. @@ -97,7 +96,6 @@ Próxima lacuna: modelos de documentos versionados por empresa, variáveis preen **Pagamentos e afectações sintéticos, 29/10/2026:** percurso comum disponível apenas nas demonstrações isoladas 8005/8006, com preparação, confirmação independente e afectação explícita. Prova nas duas composições e preservação por hashes aprovadas; revisão visual/manual pendente. Sem migração habitual, utilização real ou novos pagamentos sobre importações históricas. Ver [relatório do núcleo comum](../../sgf-tempo/docs/SUPPLIER_SETTLEMENT_DELIVERY.md). - **Conferência posterior dos pendentes implementada, 29/10/2026:** confirmação/rejeição ligada ao núcleo comum com decisão imutável, saldo único e escrita original atómica. Provas SQLite e PostgreSQL descartável, incluindo dois pedidos simultâneos e reversão de falha, aprovadas. Ver [entrega](conferencia-pendentes-importados.md). Migração 000023 e opção de conferência preparadas, ainda não aplicadas/activadas em `compras_dev` ou 8005; importação local anterior preservada. Substitui a pendência de desenvolver esta conferência, sem novos pagamentos/transferências. **Aplicação/activação histórica local concluída, 29/10/2026:** após «continue», 000022 aplicada em `compras_dev`, lote 23, e flag histórica activada, após backup/restauro das 72 tabelas. Registos/restrições preservados, duas tabelas novas vazias e dois triggers verificados. Activação auditada sem novas contas/concessões ou alteração de identidade; zero facturas/pagamentos/obrigações e nenhuma incorporação automática. Ver `historico-migracao-000022.json`, `historico-activacao-local.json` e [relatório](passagem-historico-pagamentos.md). Demo 8005 permanece sem esta migração/activação, confirmada em leitura; restantes demos e público preservados. Substitui apenas as indicações históricas de aplicação/activação pendentes abaixo. Novos pagamentos e decisão de pendentes depois da passagem continuam incremento próprio. diff --git a/docs/plano-ia.md b/docs/plano-ia.md index 3b6d9f4..9248fe7 100644 --- a/docs/plano-ia.md +++ b/docs/plano-ia.md @@ -14,16 +14,16 @@ O plano usa o JSON de política já existente na empresa; não há nova migraç Nos relatórios individuais de Compras e Pessoas, um plano com fornecedor escolhido torna disponível «Pré-visualização de IA — plano da empresa». A entrada deriva apenas da síntese factual autorizada/redigida do servidor, respeitando o percurso e as categorias escolhidas. Não consulta anexos, CV, notas de entrevista ou dados bancários. Desactivar a apresentação da síntese local não apaga o plano: o relatório continua disponível e a preparação segue as suas próprias escolhas de âmbito. -| Categoria | Factos de Compras | Factos de Pessoas | -| --- | --- | --- | -| Estado e regras | Estado da requisição | Número de critérios e mínimo de avaliações | -| Comparação | Contagem de propostas e estado de preparação da matriz | — | -| Actualidade documental | Versão/actualidade da qualificação e acta | — | -| Ordem/minuta/recepção | Presença de ordem e contagem de recepções | Presença de minuta interna, apenas se autorizada | -| Selecção | — | Proposta pendente/devolvida/selecção aprovada | -| Candidaturas | — | Contagem na matriz actual ou base preservada | -| Esclarecimentos | — | Contagem em acompanhamento | -| Finanças | Contagens de facturas/pagamentos, apenas quando o actor já tem acesso | — | +| Categoria | Factos de Compras | Factos de Pessoas | +| ---------------------- | --------------------------------------------------------------------- | ------------------------------------------------ | +| Estado e regras | Estado da requisição | Número de critérios e mínimo de avaliações | +| Comparação | Contagem de propostas e estado de preparação da matriz | — | +| Actualidade documental | Versão/actualidade da qualificação e acta | — | +| Ordem/minuta/recepção | Presença de ordem e contagem de recepções | Presença de minuta interna, apenas se autorizada | +| Selecção | — | Proposta pendente/devolvida/selecção aprovada | +| Candidaturas | — | Contagem na matriz actual ou base preservada | +| Esclarecimentos | — | Contagem em acompanhamento | +| Finanças | Contagens de facturas/pagamentos, apenas quando o actor já tem acesso | — | As categorias nunca concedem permissões de documento ou acesso retroactivo. O administrador que configura o plano não ganha acesso automático às candidaturas. Nomes, justificações livres, referências de pessoas, pontuações individuais, respostas de entrevista e hashes de fontes não integram os factos pré-visualizados. Os relatórios originais conservam a sua projecção autorizada. diff --git a/docs/proofs/ai-plan-pg.json b/docs/proofs/ai-plan-pg.json index 8bb9aa1..0b36ba0 100644 --- a/docs/proofs/ai-plan-pg.json +++ b/docs/proofs/ai-plan-pg.json @@ -1,9 +1,9 @@ { - "checked_at": "2026-10-30T15:45:53+00:00", - "database": "disposable PostgreSQL", - "application_role_reused_without_privilege_change": true, - "result": "passed", - "scenario": "draft tenant AI plan configuration and permission-scoped previews for procurement and people, no external requests", - "original_evaluation_untouched": true, - "database_removed": true + "checked_at": "2026-10-30T15:45:53+00:00", + "database": "disposable PostgreSQL", + "application_role_reused_without_privilege_change": true, + "result": "passed", + "scenario": "draft tenant AI plan configuration and permission-scoped previews for procurement and people, no external requests", + "original_evaluation_untouched": true, + "database_removed": true } diff --git a/docs/proofs/ai-plan.json b/docs/proofs/ai-plan.json index 6a3532f..7ef17f0 100644 --- a/docs/proofs/ai-plan.json +++ b/docs/proofs/ai-plan.json @@ -1,71 +1,71 @@ { - "checked_at": "2026-10-30T15:48:55.811028+00:00", - "environment": "local evaluation 8005", - "scope": [ - "tenant scoped draft provider model domain and fact-category plan", - "planned monthly budget request count and per-request payload/output limits", - "optimistic version reason and atomic audit", - "preserve local brief settings and AI plan during reciprocal changes", - "previews use authorised redacted facts with no people identities free notes bank data or source hashes", - "excluded domain empty scope financial privacy and oversized input handling" - ], - "module_tests": { - "tool": "pest", - "result": "passed", - "tests": 90, - "passed": 90, - "assertions": 1469, - "duration_ms": 10623 - }, - "react_inertia_tests": 40, - "postgresql_integration": { - "tool": "phpunit", - "result": "passed", - "tests": 1, - "passed": 1, - "assertions": 147, - "duration_ms": 3367 - }, - "postgresql_proof": "ai-plan-pg.json", - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "http_proof": "menu-links.json", - "runtime_sha256_files": 18, - "accepted_full_suite_reused": "people-clarifications.json", - "migrations_applied": false, - "schema_changed": false, - "business_records_changed": false, - "tenant_plan_choices_automatically_created": false, - "accounts_or_grants_changed": false, - "external_AI_calls_this_increment": 0, - "live_execution_enabled": false, - "consumption_ledger_or_budget_reservation_implemented": false, - "model_compatibility_verified_by_saving_plan": false, - "prior_authorised_synthetic_generation_repeated": false, - "visual_review": false, - "domain_installed": false, - "source_sha256": { - "app/Services/AiPreparationPlan.php": "3c6345376b3444f561207f1c8c781da214e87609f97d20255cdd79c419a406a9", - "app/Services/IntelligencePolicy.php": "07956aa32f585d00a1c9c4414c2baec9e037e243ff23e305aa4b70cf1ace7d95", - "app/Services/OrganizationConfiguration.php": "bbeae0c4bafad412830cd902842b4bf56158d9d004f8203825436954185cd793", - "app/Models/Tenant.php": "c503893033342a32f02dd89175b785af08a1061da2d5b9cb2d7bb45a1ff30f66", - "app/Http/Controllers/OrganizationConfigurationController.php": "3ce1931f6b793626a2faaa84a1f9be5f589c8cdd5e6dc2fa5730e72c095b3103", - "app/Http/Controllers/ProcurementReviewReportController.php": "a78ed469ed5e914d47a4afa2fcbd64afce9177aff80d59418b90c7bfc41f89ad", - "app/Http/Controllers/PeopleHiringController.php": "ef449c2f1e67454615ff8454d188590b6acac7966f61b6b697887b8d44b112f4", - "resources/js/components/ai-plan-settings.tsx": "d06682971acb274376e0986bf00bfd63fde2a7a72f75e90aca4fd2fedbee7621", - "resources/js/components/ai-preparation-preview.tsx": "0ba01e2f641a52baf8fbb9b52a1342c86289e6eb9946a3b7b4a71c970ff256be", - "resources/js/pages/company/parameters.tsx": "aa9f1f475961dc176f378f5851efbdaf43a0007f0cd233adaffdfb8d40906fdb", - "resources/js/pages/purchases/review-report.tsx": "2b1066bb2be52c945f58c143f48417754d4ad8772f04579a23c9fdef150a28ad", - "resources/js/pages/people/show.tsx": "10c59a01033094543458b00771faff70249994dc539fdeacd1eb786e561526f7", - "tests/Feature/OrganizationConfigurationTest.php": "4bfe5bfe83042c3285ebf5c0e2aa731e9cd02eaf73b1b8774bd2684d80ef71da", - "tests/Feature/AiPreparationTest.php": "cf84282b2e879a6d0eb9605d052de070ddf8b45ede07a969bd03d3155d796254", - "tests/Feature/PeopleHiringTest.php": "35f444dddaad5e2702c055ef8b02afbc757de2d6a58eb997b06d413f5bf82691", - "tests/Support/AiPlanFixture.php": "af62e4b7f46d5ceab5cfbfaadcc85a53d42db1c4e71da7b30427f02fd6deea74", - "tests/frontend/ai-plan.test.tsx": "14e6dac9e49ca7b6434f177e5456533275268a8f9f745b2c000b22376a9e1573", - "routes/web.php": "38fdd89d976f9b82369aef440cf64ef384a584bdaeb519c0ec24741a296f6868", - "docs/plano-ia.md": "aa1ce1186b2b6077b52d7ed7b749250bb7f013a059e4b9f652b0d989c67ee7f3" - } + "checked_at": "2026-10-30T15:48:55.811028+00:00", + "environment": "local evaluation 8005", + "scope": [ + "tenant scoped draft provider model domain and fact-category plan", + "planned monthly budget request count and per-request payload/output limits", + "optimistic version reason and atomic audit", + "preserve local brief settings and AI plan during reciprocal changes", + "previews use authorised redacted facts with no people identities free notes bank data or source hashes", + "excluded domain empty scope financial privacy and oversized input handling" + ], + "module_tests": { + "tool": "pest", + "result": "passed", + "tests": 90, + "passed": 90, + "assertions": 1469, + "duration_ms": 10623 + }, + "react_inertia_tests": 40, + "postgresql_integration": { + "tool": "phpunit", + "result": "passed", + "tests": 1, + "passed": 1, + "assertions": 147, + "duration_ms": 3367 + }, + "postgresql_proof": "ai-plan-pg.json", + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "http_proof": "menu-links.json", + "runtime_sha256_files": 18, + "accepted_full_suite_reused": "people-clarifications.json", + "migrations_applied": false, + "schema_changed": false, + "business_records_changed": false, + "tenant_plan_choices_automatically_created": false, + "accounts_or_grants_changed": false, + "external_AI_calls_this_increment": 0, + "live_execution_enabled": false, + "consumption_ledger_or_budget_reservation_implemented": false, + "model_compatibility_verified_by_saving_plan": false, + "prior_authorised_synthetic_generation_repeated": false, + "visual_review": false, + "domain_installed": false, + "source_sha256": { + "app/Services/AiPreparationPlan.php": "3c6345376b3444f561207f1c8c781da214e87609f97d20255cdd79c419a406a9", + "app/Services/IntelligencePolicy.php": "07956aa32f585d00a1c9c4414c2baec9e037e243ff23e305aa4b70cf1ace7d95", + "app/Services/OrganizationConfiguration.php": "bbeae0c4bafad412830cd902842b4bf56158d9d004f8203825436954185cd793", + "app/Models/Tenant.php": "c503893033342a32f02dd89175b785af08a1061da2d5b9cb2d7bb45a1ff30f66", + "app/Http/Controllers/OrganizationConfigurationController.php": "3ce1931f6b793626a2faaa84a1f9be5f589c8cdd5e6dc2fa5730e72c095b3103", + "app/Http/Controllers/ProcurementReviewReportController.php": "a78ed469ed5e914d47a4afa2fcbd64afce9177aff80d59418b90c7bfc41f89ad", + "app/Http/Controllers/PeopleHiringController.php": "ef449c2f1e67454615ff8454d188590b6acac7966f61b6b697887b8d44b112f4", + "resources/js/components/ai-plan-settings.tsx": "d06682971acb274376e0986bf00bfd63fde2a7a72f75e90aca4fd2fedbee7621", + "resources/js/components/ai-preparation-preview.tsx": "0ba01e2f641a52baf8fbb9b52a1342c86289e6eb9946a3b7b4a71c970ff256be", + "resources/js/pages/company/parameters.tsx": "aa9f1f475961dc176f378f5851efbdaf43a0007f0cd233adaffdfb8d40906fdb", + "resources/js/pages/purchases/review-report.tsx": "2b1066bb2be52c945f58c143f48417754d4ad8772f04579a23c9fdef150a28ad", + "resources/js/pages/people/show.tsx": "10c59a01033094543458b00771faff70249994dc539fdeacd1eb786e561526f7", + "tests/Feature/OrganizationConfigurationTest.php": "4bfe5bfe83042c3285ebf5c0e2aa731e9cd02eaf73b1b8774bd2684d80ef71da", + "tests/Feature/AiPreparationTest.php": "cf84282b2e879a6d0eb9605d052de070ddf8b45ede07a969bd03d3155d796254", + "tests/Feature/PeopleHiringTest.php": "35f444dddaad5e2702c055ef8b02afbc757de2d6a58eb997b06d413f5bf82691", + "tests/Support/AiPlanFixture.php": "af62e4b7f46d5ceab5cfbfaadcc85a53d42db1c4e71da7b30427f02fd6deea74", + "tests/frontend/ai-plan.test.tsx": "14e6dac9e49ca7b6434f177e5456533275268a8f9f745b2c000b22376a9e1573", + "routes/web.php": "38fdd89d976f9b82369aef440cf64ef384a584bdaeb519c0ec24741a296f6868", + "docs/plano-ia.md": "aa1ce1186b2b6077b52d7ed7b749250bb7f013a059e4b9f652b0d989c67ee7f3" + } } diff --git a/docs/proofs/ai-rehearsal-authorization.json b/docs/proofs/ai-rehearsal-authorization.json index d3adb99..0cd8f14 100644 --- a/docs/proofs/ai-rehearsal-authorization.json +++ b/docs/proofs/ai-rehearsal-authorization.json @@ -1,18 +1,18 @@ { - "checked_at": "2026-10-30T15:08:33.102627+00:00", - "authorisation": "granted by owner after cost estimate", - "authorised_live_calls": 1, - "live_calls_executed": 1, - "destination": "https://api.openai.com/v1/responses", - "model": "gpt-5.6-terra", - "data_scope": "three built-in synthetic facts only", - "max_output_tokens": 1000, - "credential_presence_checked_without_value_output": true, - "dedicated_credential_configured": false, - "standard_openai_credential_available": false, - "rehearsal_enabled": false, - "execution_status": "completed: one successful synthetic generation, see ai-rehearsal-live.json", - "new_authorisation_required_for_same_call": false, - "successful_generations": 1, - "live_call_count_definition": "successful generation; transport and authentication failures separately recorded in ai-rehearsal-live.json" + "checked_at": "2026-10-30T15:08:33.102627+00:00", + "authorisation": "granted by owner after cost estimate", + "authorised_live_calls": 1, + "live_calls_executed": 1, + "destination": "https://api.openai.com/v1/responses", + "model": "gpt-5.6-terra", + "data_scope": "three built-in synthetic facts only", + "max_output_tokens": 1000, + "credential_presence_checked_without_value_output": true, + "dedicated_credential_configured": false, + "standard_openai_credential_available": false, + "rehearsal_enabled": false, + "execution_status": "completed: one successful synthetic generation, see ai-rehearsal-live.json", + "new_authorisation_required_for_same_call": false, + "successful_generations": 1, + "live_call_count_definition": "successful generation; transport and authentication failures separately recorded in ai-rehearsal-live.json" } diff --git a/docs/proofs/ai-rehearsal-live.json b/docs/proofs/ai-rehearsal-live.json index 90a522e..2527816 100644 --- a/docs/proofs/ai-rehearsal-live.json +++ b/docs/proofs/ai-rehearsal-live.json @@ -1,64 +1,64 @@ { - "checked_at": "2026-10-30T15:37:00+00:00", - "authorisation": "owner authorised one synthetic paid call", - "attempts": 3, - "destination": "https://api.openai.com/v1/responses", - "model": "gpt-5.6-terra", - "max_output_tokens": 1000, - "real_business_data_sent": false, - "status": "completed", - "automatic_retry": false, - "prior_transport_failure": { - "php_curl_errno": 60, - "diagnosis": "local issuer certificate unavailable before HTTPS establishment" - }, - "tls_verification_disabled": false, - "trust_source": "Windows trusted root certificate stores; process-only CA configuration", - "prior_rejected_request": { - "http_status": 401, - "code": "invalid_api_key", - "local_cause": "duplicated setting and embedded assignment normalised without exposing key" - }, - "http_status": 200, - "usage": { - "input_tokens": 204, - "output_tokens": 81, - "total_tokens": 285 - }, - "result_sha256": "d3412a0c4f7e34bfef51be924903c21e8724813e8cb7500a923a55fb0a96ebce", - "assessment": { - "method": "synthetic_ai_assessment_v1", - "facts": 3, - "claims": 3, - "cited_facts": 3, - "uncited_fact_ids": [], - "citation_coverage_complete": true, - "exact_source_text_matches": 1, - "requires_human_review": true, - "semantic_accuracy": "not_automatically_verified" - }, - "reviewed_at": "2026-10-30T15:37:34.123863+00:00", - "human_content_review": { - "three_source_facts_preserved": true, - "invented_approval": false, - "invented_order": false, - "invented_delivery_or_payment": false, - "synthetic_scenario_accepted": true, - "general_model_quality_certified": false - }, - "attempt_outcomes": [ - "TLS trust failure before HTTPS establishment", - "HTTP 401 for malformed local credential setting", - "HTTP 200 completed after local corrections" - ], - "successful_generations": 1, - "estimated_text_cost_usd": "0.001380", - "cost_basis": { - "input_tokens": 204, - "output_tokens": 81, - "input_usd_per_million": "2.00", - "output_usd_per_million": "12.00", - "billing_balance_or_credit_deduction_verified": false - }, - "real_document_processing_enabled": false + "checked_at": "2026-10-30T15:37:00+00:00", + "authorisation": "owner authorised one synthetic paid call", + "attempts": 3, + "destination": "https://api.openai.com/v1/responses", + "model": "gpt-5.6-terra", + "max_output_tokens": 1000, + "real_business_data_sent": false, + "status": "completed", + "automatic_retry": false, + "prior_transport_failure": { + "php_curl_errno": 60, + "diagnosis": "local issuer certificate unavailable before HTTPS establishment" + }, + "tls_verification_disabled": false, + "trust_source": "Windows trusted root certificate stores; process-only CA configuration", + "prior_rejected_request": { + "http_status": 401, + "code": "invalid_api_key", + "local_cause": "duplicated setting and embedded assignment normalised without exposing key" + }, + "http_status": 200, + "usage": { + "input_tokens": 204, + "output_tokens": 81, + "total_tokens": 285 + }, + "result_sha256": "d3412a0c4f7e34bfef51be924903c21e8724813e8cb7500a923a55fb0a96ebce", + "assessment": { + "method": "synthetic_ai_assessment_v1", + "facts": 3, + "claims": 3, + "cited_facts": 3, + "uncited_fact_ids": [], + "citation_coverage_complete": true, + "exact_source_text_matches": 1, + "requires_human_review": true, + "semantic_accuracy": "not_automatically_verified" + }, + "reviewed_at": "2026-10-30T15:37:34.123863+00:00", + "human_content_review": { + "three_source_facts_preserved": true, + "invented_approval": false, + "invented_order": false, + "invented_delivery_or_payment": false, + "synthetic_scenario_accepted": true, + "general_model_quality_certified": false + }, + "attempt_outcomes": [ + "TLS trust failure before HTTPS establishment", + "HTTP 401 for malformed local credential setting", + "HTTP 200 completed after local corrections" + ], + "successful_generations": 1, + "estimated_text_cost_usd": "0.001380", + "cost_basis": { + "input_tokens": 204, + "output_tokens": 81, + "input_usd_per_million": "2.00", + "output_usd_per_million": "12.00", + "billing_balance_or_credit_deduction_verified": false + }, + "real_document_processing_enabled": false } diff --git a/docs/proofs/ai-rehearsal.json b/docs/proofs/ai-rehearsal.json index 6d1cc17..97866a4 100644 --- a/docs/proofs/ai-rehearsal.json +++ b/docs/proofs/ai-rehearsal.json @@ -1,37 +1,37 @@ { - "checked_at": "2026-10-30T14:55:29.383515+00:00", - "scope": "synthetic-only OpenAI Responses rehearsal, no web or business integration", - "tests": { - "tool": "pest", - "result": "passed", - "tests": 15, - "passed": 15, - "assertions": 41, - "duration_ms": 1041 - }, - "phpstan_errors": 0, - "pint": "passed", - "preview_executed": true, - "live_external_calls": 0, - "model": "gpt-5.6-terra", - "maximum_request_bytes": 4500, - "maximum_output_tokens": 1000, - "automatic_retries": 0, - "HTTP_redirects": false, - "server_credentials_changed": false, - "real_data_allowed": false, - "factual_accuracy_automatically_verified": false, - "live_authorisation": "pending", - "review_document": "../ensaio-ia.md", - "official_docs": [ - "https://developers.openai.com/api/docs/guides/structured-outputs", - "https://developers.openai.com/api/docs/models/gpt-5.6-terra" - ], - "source_sha256": { - "app/Services/SyntheticAiRehearsal.php": "96dee8e663b7b211f8b3be0b9c98ded1745a1019457dced413de62d265c35d41", - "app/Console/Commands/SgcAiRehearsal.php": "3003a8bcdd1cea5bc53dc4071ea22c970f59e802fe0deeb42abed7d963f5d1e7", - "config/sgc_intelligence.php": "ac385a06fd4c5a7421fa7ebc45185e81db790b17a5ef45cce469e769787587da", - "tests/Feature/SyntheticAiRehearsalTest.php": "ae03beda519ae06b175b0ad0a63848af831689153387aef5f1adc9d5105874f2", - "docs/ensaio-ia.md": "a1bef675b436f63b2f8ff434c73daeea53efc5a01b1374a53b8f0512e0a97b50" - } + "checked_at": "2026-10-30T14:55:29.383515+00:00", + "scope": "synthetic-only OpenAI Responses rehearsal, no web or business integration", + "tests": { + "tool": "pest", + "result": "passed", + "tests": 15, + "passed": 15, + "assertions": 41, + "duration_ms": 1041 + }, + "phpstan_errors": 0, + "pint": "passed", + "preview_executed": true, + "live_external_calls": 0, + "model": "gpt-5.6-terra", + "maximum_request_bytes": 4500, + "maximum_output_tokens": 1000, + "automatic_retries": 0, + "HTTP_redirects": false, + "server_credentials_changed": false, + "real_data_allowed": false, + "factual_accuracy_automatically_verified": false, + "live_authorisation": "pending", + "review_document": "../ensaio-ia.md", + "official_docs": [ + "https://developers.openai.com/api/docs/guides/structured-outputs", + "https://developers.openai.com/api/docs/models/gpt-5.6-terra" + ], + "source_sha256": { + "app/Services/SyntheticAiRehearsal.php": "96dee8e663b7b211f8b3be0b9c98ded1745a1019457dced413de62d265c35d41", + "app/Console/Commands/SgcAiRehearsal.php": "3003a8bcdd1cea5bc53dc4071ea22c970f59e802fe0deeb42abed7d963f5d1e7", + "config/sgc_intelligence.php": "ac385a06fd4c5a7421fa7ebc45185e81db790b17a5ef45cce469e769787587da", + "tests/Feature/SyntheticAiRehearsalTest.php": "ae03beda519ae06b175b0ad0a63848af831689153387aef5f1adc9d5105874f2", + "docs/ensaio-ia.md": "a1bef675b436f63b2f8ff434c73daeea53efc5a01b1374a53b8f0512e0a97b50" + } } diff --git a/docs/proofs/candidate-portal-http.json b/docs/proofs/candidate-portal-http.json index 16e5c29..05d36d0 100644 --- a/docs/proofs/candidate-portal-http.json +++ b/docs/proofs/candidate-portal-http.json @@ -1,8 +1,8 @@ { - "checked_at": "2026-10-30T17:04:03.991Z", - "administration": 200, - "unconfigured_public_portal": 404, - "staff_session_does_not_authenticate_candidate": true, - "registration_open": false, - "accounts_created": 0 + "checked_at": "2026-10-30T17:04:03.991Z", + "administration": 200, + "unconfigured_public_portal": 404, + "staff_session_does_not_authenticate_candidate": true, + "registration_open": false, + "accounts_created": 0 } diff --git a/docs/proofs/candidate-portal.json b/docs/proofs/candidate-portal.json index 4bde47d..f5f09ec 100644 --- a/docs/proofs/candidate-portal.json +++ b/docs/proofs/candidate-portal.json @@ -1,63 +1,63 @@ { - "checked_at": "2026-10-30T17:04:58.049470+00:00", - "scope": [ - "separate candidate authentication scoped by company", - "explicit portal registration policy and versioned notice acknowledgment", - "immutable own profile revisions including province district locality", - "no staff or cross-account access", - "atomic profile and audit rollback", - "login and logout history clearing" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 715, - "passed": 713, - "assertions": 6985, - "duration_ms": 149158, - "skipped": 2 - }, - "candidate_tests": 5, - "candidate_assertions": 81, - "disposable_postgresql_tests": 47, - "disposable_postgresql_assertions": 1163, - "react_inertia_tests": 52, - "phpstan_errors": 0, - "typescript": "passed", - "pint": "passed", - "targeted_lint": "passed", - "build_exit": 0, - "menu_entries_across_six_roles": 111, - "runtime_sha256_files": 18, - "postgresql_proof": "candidate-portal-pg.json", - "installation_proof": "candidate-portal-install.json", - "http_proof": "candidate-portal-http.json", - "visual_review": false, - "domain_installed": false, - "registration_open_in_evaluation": false, - "candidate_accounts_created_in_evaluation": 0, - "external_AI_calls": 0, - "emails_sent": 0, - "outstanding": [ - "email/identity verification", - "password recovery", - "submission to opportunities and frozen profile documents", - "attachment security verification", - "triage complements revisions", - "retention deletion and privacy policy configuration before public use" - ], - "source_sha256": { - "database/migrations/2026_10_30_000037_create_candidate_profiles.php": "159648252836af068226978666d8eb11148ed6890cba2082b0d5c8b415365e97", - "app/Models/CandidateAccount.php": "ab30a14616554bbe7d5ec0dec2347582754f846c0a4ade5455cfa095d73e4bec", - "app/Services/CandidateProfiles.php": "54e1e95e10c9004fef69fbdd14b54f85d617f3296cc27a7aba2f1f51552f2cad", - "app/Http/Controllers/CandidatePortalController.php": "9ff56978b43c4a2401c02ca3f7f2a95c7f3a550009b3385c682dafcecd6f2615", - "config/auth.php": "e3fd9d4244bc9dd92b6e8d76dc2e5163834ef21b4b9df7dd04f1015d82d32ba6", - "app/Http/Middleware/HandleInertiaRequests.php": "8db70b1500d683f1df3b7a26ce019c72b5c917ab51b020fdec59700100d588ed", - "resources/js/app.tsx": "5669117aa4b607b1d6c3b1f51af8b18650c80c75a5eb697ff7f89a3146c851a9", - "resources/js/pages/candidate/entry.tsx": "90b178c84d4a20ff4a1a8624f317d36eeb02ef017647fe524da03aee28a86e79", - "resources/js/pages/candidate/profile.tsx": "6a51689bc0bbe63255467c5c454593707c08bfd0e3867e59b50259eb20d1a306", - "resources/js/pages/company/candidate-portal.tsx": "07882a3695897d7cc184c1b09c7c616b76c362556e75f8e82d292925a5da9c09", - "tests/Feature/CandidatePortalTest.php": "b603113232db600105462577022da5018b76b8e852a50128e0bceb65e3e3e5b1", - "tests/frontend/candidate-portal.test.tsx": "81f3199e33bb46f16c8f73f2b641c1d9778579c12cd1f4f2d33e727f11d241af" - } + "checked_at": "2026-10-30T17:04:58.049470+00:00", + "scope": [ + "separate candidate authentication scoped by company", + "explicit portal registration policy and versioned notice acknowledgment", + "immutable own profile revisions including province district locality", + "no staff or cross-account access", + "atomic profile and audit rollback", + "login and logout history clearing" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 715, + "passed": 713, + "assertions": 6985, + "duration_ms": 149158, + "skipped": 2 + }, + "candidate_tests": 5, + "candidate_assertions": 81, + "disposable_postgresql_tests": 47, + "disposable_postgresql_assertions": 1163, + "react_inertia_tests": 52, + "phpstan_errors": 0, + "typescript": "passed", + "pint": "passed", + "targeted_lint": "passed", + "build_exit": 0, + "menu_entries_across_six_roles": 111, + "runtime_sha256_files": 18, + "postgresql_proof": "candidate-portal-pg.json", + "installation_proof": "candidate-portal-install.json", + "http_proof": "candidate-portal-http.json", + "visual_review": false, + "domain_installed": false, + "registration_open_in_evaluation": false, + "candidate_accounts_created_in_evaluation": 0, + "external_AI_calls": 0, + "emails_sent": 0, + "outstanding": [ + "email/identity verification", + "password recovery", + "submission to opportunities and frozen profile documents", + "attachment security verification", + "triage complements revisions", + "retention deletion and privacy policy configuration before public use" + ], + "source_sha256": { + "database/migrations/2026_10_30_000037_create_candidate_profiles.php": "159648252836af068226978666d8eb11148ed6890cba2082b0d5c8b415365e97", + "app/Models/CandidateAccount.php": "ab30a14616554bbe7d5ec0dec2347582754f846c0a4ade5455cfa095d73e4bec", + "app/Services/CandidateProfiles.php": "54e1e95e10c9004fef69fbdd14b54f85d617f3296cc27a7aba2f1f51552f2cad", + "app/Http/Controllers/CandidatePortalController.php": "9ff56978b43c4a2401c02ca3f7f2a95c7f3a550009b3385c682dafcecd6f2615", + "config/auth.php": "e3fd9d4244bc9dd92b6e8d76dc2e5163834ef21b4b9df7dd04f1015d82d32ba6", + "app/Http/Middleware/HandleInertiaRequests.php": "8db70b1500d683f1df3b7a26ce019c72b5c917ab51b020fdec59700100d588ed", + "resources/js/app.tsx": "5669117aa4b607b1d6c3b1f51af8b18650c80c75a5eb697ff7f89a3146c851a9", + "resources/js/pages/candidate/entry.tsx": "90b178c84d4a20ff4a1a8624f317d36eeb02ef017647fe524da03aee28a86e79", + "resources/js/pages/candidate/profile.tsx": "6a51689bc0bbe63255467c5c454593707c08bfd0e3867e59b50259eb20d1a306", + "resources/js/pages/company/candidate-portal.tsx": "07882a3695897d7cc184c1b09c7c616b76c362556e75f8e82d292925a5da9c09", + "tests/Feature/CandidatePortalTest.php": "b603113232db600105462577022da5018b76b8e852a50128e0bceb65e3e3e5b1", + "tests/frontend/candidate-portal.test.tsx": "81f3199e33bb46f16c8f73f2b641c1d9778579c12cd1f4f2d33e727f11d241af" + } } diff --git a/docs/proofs/candidate-submissions-http.json b/docs/proofs/candidate-submissions-http.json index c34014e..9b84c0e 100644 --- a/docs/proofs/candidate-submissions-http.json +++ b/docs/proofs/candidate-submissions-http.json @@ -1,10 +1,10 @@ { - "checked_at": "2026-10-30T17:15:17.008Z", - "administration": 200, - "unconfigured_recovery": 404, - "unauthenticated_opportunity": 401, - "unauthenticated_receipt": 401, - "registration_open": false, - "candidates_created": 0, - "email_transport_available": false + "checked_at": "2026-10-30T17:15:17.008Z", + "administration": 200, + "unconfigured_recovery": 404, + "unauthenticated_opportunity": 401, + "unauthenticated_receipt": 401, + "registration_open": false, + "candidates_created": 0, + "email_transport_available": false } diff --git a/docs/proofs/candidate-submissions-pg.json b/docs/proofs/candidate-submissions-pg.json index 200d137..3db24f2 100644 --- a/docs/proofs/candidate-submissions-pg.json +++ b/docs/proofs/candidate-submissions-pg.json @@ -1,15 +1,15 @@ { - "checked_at": "2026-10-30T17:19:13+00:00", - "database": "disposable PostgreSQL", - "application_role_reused_without_privilege_change": true, - "result": "passed", - "test_files": [ - "CandidateAccessTest", - "CandidatePortalTest", - "CandidateSubmissionsTest" - ], - "original_evaluation_untouched": true, - "database_removed": true, - "tests": 14, - "assertions": 161 + "checked_at": "2026-10-30T17:19:13+00:00", + "database": "disposable PostgreSQL", + "application_role_reused_without_privilege_change": true, + "result": "passed", + "test_files": [ + "CandidateAccessTest", + "CandidatePortalTest", + "CandidateSubmissionsTest" + ], + "original_evaluation_untouched": true, + "database_removed": true, + "tests": 14, + "assertions": 161 } diff --git a/docs/proofs/candidate-submissions.json b/docs/proofs/candidate-submissions.json index 50f2f18..74a1634 100644 --- a/docs/proofs/candidate-submissions.json +++ b/docs/proofs/candidate-submissions.json @@ -1,74 +1,74 @@ { - "checked_at": "2026-10-30T17:19:44.183589+00:00", - "scope": [ - "single-use hashed email verification and recovery tokens", - "no secret links in mail log transports or request query strings", - "candidate session revocation on password reset", - "explicit publication by assigned process preparer", - "verified own-account data-only submission with frozen profile form and answers", - "idempotent receipt and own account access", - "internal received inbox separated from assessment", - "mandatory-file opportunities rejected until attachment intake exists" - ], - "module_tests": 14, - "module_assertions": 161, - "postgresql_tests": 14, - "postgresql_assertions": 161, - "react_inertia_tests": 56, - "typescript": "passed", - "phpstan_errors": 0, - "pint": "passed", - "targeted_lint": "passed", - "build_exit": 0, - "mail_template_render_without_delivery": "passed", - "menu_entries_across_six_roles": 111, - "runtime_sha256_files": 18, - "installation_proof": "candidate-submissions-install.json", - "postgresql_proof": "candidate-submissions-pg.json", - "http_proof": "candidate-submissions-http.json", - "visual_review": false, - "domain_installed": false, - "emails_sent": 0, - "external_AI_calls": 0, - "candidate_accounts_created_in_evaluation": 0, - "portals_or_opportunities_activated": 0, - "outstanding": [ - "secure attachment intake storage and verification", - "triage and controlled reuse into internal assessment", - "complements corrections and revisions", - "spontaneous submissions and supplier intake", - "configured mail transport and real delivery rehearsal", - "privacy retention deletion policies and public visual acceptance" - ], - "source_sha256": { - "database/migrations/2026_10_30_000038_create_candidate_access_tokens.php": "a461cd157d23c00f0c54dccd8b739e0efe6803d3d3495253a86477972c25b0cb", - "database/migrations/2026_10_30_000039_create_candidate_submissions.php": "7901cf6b7dd31e4753ff92ca791f436ee13732eec7faa197b1ef829ba5cc4b7a", - "app/Services/CandidateAccess.php": "d63452a1148911fa4bf8e5cb0e2d5c0d68e4d6d4b7c2f9371a4a4ecf85d59a86", - "app/Services/CandidateSubmissions.php": "33114852f9c4444675206876662ad28b3846a72b8ded1d03c6f0e074118b8fa2", - "app/Services/CandidateProfiles.php": "0bfaa3602261e897b940a63e302bf4c2655c6dd2d8aa8bdd02bd350e3d39081f", - "app/Http/Controllers/CandidatePortalController.php": "13477331e1f0a270300143f1465e6493a9e52e20944fb542a0241d66e81ae588", - "app/Models/CandidateAccount.php": "8fc2fc485ad1bb2ccc27a971dbd9417bec7263bf5c51d170f45629bfec8e5d86", - "app/Mail/CandidateAccessLink.php": "67a9c556646114af96857537e2a60836d4eaa3b5243dbb8493071562fc1cfcbd", - "resources/views/mail/candidate-access.blade.php": "81eefd72fb05d2272a05fe9c9479a0652140c06d91dbc6e1694770109046abff", - "bootstrap/app.php": "a57fa8ea590c68d1007e1457611c95cf8b52576bfd8e5cdd7af2389ed18384f6", - "routes/web.php": "3d9b9755e1387eae89285b3ba3f4ad78730b69df9756853f063aa4e98fe20c7f", - "resources/js/pages/candidate/access.tsx": "4a0b92b6903d659a429db7dafaf25acccfee3c48a151a588e352d2b34eb18142", - "resources/js/pages/candidate/opportunity.tsx": "4da4db3e1f02138a73e4399aaf50eca969e53b02a004818165891cb24457239b", - "resources/js/pages/candidate/receipt.tsx": "59dd13beed2df74481740afabc4e78637ab8f6c244d3873eaafdd9b661c57392", - "resources/js/pages/candidate/profile.tsx": "39ae2da3182bf9fac69bdf88b69a376de3aa0750e659d9a05721070e2e207798", - "resources/js/pages/people/submissions.tsx": "9f79cbcda18154b685429f10c9bc31b49765ef0c1c93b1a19e4b001a7074eb43", - "tests/Feature/CandidateAccessTest.php": "7c953d2a633e3cc71d5d8ad0a97432a4056a01c2985ead0cc5743f368166b490", - "tests/Feature/CandidateSubmissionsTest.php": "7862130e921864e74469a364a19aa631635595598324133491fbcbffa419e0e7", - "tests/frontend/candidate-submissions.test.tsx": "4857543a847754fed542cb7ec32a961e94cb7fd287a5c67627d0cb17b7520ace" - }, - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 724, - "passed": 722, - "assertions": 7063, - "duration_ms": 146678, - "skipped": 2 - }, - "full_suite_reused_with_latest_permission_regression_retested_in_module": true + "checked_at": "2026-10-30T17:19:44.183589+00:00", + "scope": [ + "single-use hashed email verification and recovery tokens", + "no secret links in mail log transports or request query strings", + "candidate session revocation on password reset", + "explicit publication by assigned process preparer", + "verified own-account data-only submission with frozen profile form and answers", + "idempotent receipt and own account access", + "internal received inbox separated from assessment", + "mandatory-file opportunities rejected until attachment intake exists" + ], + "module_tests": 14, + "module_assertions": 161, + "postgresql_tests": 14, + "postgresql_assertions": 161, + "react_inertia_tests": 56, + "typescript": "passed", + "phpstan_errors": 0, + "pint": "passed", + "targeted_lint": "passed", + "build_exit": 0, + "mail_template_render_without_delivery": "passed", + "menu_entries_across_six_roles": 111, + "runtime_sha256_files": 18, + "installation_proof": "candidate-submissions-install.json", + "postgresql_proof": "candidate-submissions-pg.json", + "http_proof": "candidate-submissions-http.json", + "visual_review": false, + "domain_installed": false, + "emails_sent": 0, + "external_AI_calls": 0, + "candidate_accounts_created_in_evaluation": 0, + "portals_or_opportunities_activated": 0, + "outstanding": [ + "secure attachment intake storage and verification", + "triage and controlled reuse into internal assessment", + "complements corrections and revisions", + "spontaneous submissions and supplier intake", + "configured mail transport and real delivery rehearsal", + "privacy retention deletion policies and public visual acceptance" + ], + "source_sha256": { + "database/migrations/2026_10_30_000038_create_candidate_access_tokens.php": "a461cd157d23c00f0c54dccd8b739e0efe6803d3d3495253a86477972c25b0cb", + "database/migrations/2026_10_30_000039_create_candidate_submissions.php": "7901cf6b7dd31e4753ff92ca791f436ee13732eec7faa197b1ef829ba5cc4b7a", + "app/Services/CandidateAccess.php": "d63452a1148911fa4bf8e5cb0e2d5c0d68e4d6d4b7c2f9371a4a4ecf85d59a86", + "app/Services/CandidateSubmissions.php": "33114852f9c4444675206876662ad28b3846a72b8ded1d03c6f0e074118b8fa2", + "app/Services/CandidateProfiles.php": "0bfaa3602261e897b940a63e302bf4c2655c6dd2d8aa8bdd02bd350e3d39081f", + "app/Http/Controllers/CandidatePortalController.php": "13477331e1f0a270300143f1465e6493a9e52e20944fb542a0241d66e81ae588", + "app/Models/CandidateAccount.php": "8fc2fc485ad1bb2ccc27a971dbd9417bec7263bf5c51d170f45629bfec8e5d86", + "app/Mail/CandidateAccessLink.php": "67a9c556646114af96857537e2a60836d4eaa3b5243dbb8493071562fc1cfcbd", + "resources/views/mail/candidate-access.blade.php": "81eefd72fb05d2272a05fe9c9479a0652140c06d91dbc6e1694770109046abff", + "bootstrap/app.php": "a57fa8ea590c68d1007e1457611c95cf8b52576bfd8e5cdd7af2389ed18384f6", + "routes/web.php": "3d9b9755e1387eae89285b3ba3f4ad78730b69df9756853f063aa4e98fe20c7f", + "resources/js/pages/candidate/access.tsx": "4a0b92b6903d659a429db7dafaf25acccfee3c48a151a588e352d2b34eb18142", + "resources/js/pages/candidate/opportunity.tsx": "4da4db3e1f02138a73e4399aaf50eca969e53b02a004818165891cb24457239b", + "resources/js/pages/candidate/receipt.tsx": "59dd13beed2df74481740afabc4e78637ab8f6c244d3873eaafdd9b661c57392", + "resources/js/pages/candidate/profile.tsx": "39ae2da3182bf9fac69bdf88b69a376de3aa0750e659d9a05721070e2e207798", + "resources/js/pages/people/submissions.tsx": "9f79cbcda18154b685429f10c9bc31b49765ef0c1c93b1a19e4b001a7074eb43", + "tests/Feature/CandidateAccessTest.php": "7c953d2a633e3cc71d5d8ad0a97432a4056a01c2985ead0cc5743f368166b490", + "tests/Feature/CandidateSubmissionsTest.php": "7862130e921864e74469a364a19aa631635595598324133491fbcbffa419e0e7", + "tests/frontend/candidate-submissions.test.tsx": "4857543a847754fed542cb7ec32a961e94cb7fd287a5c67627d0cb17b7520ace" + }, + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 724, + "passed": 722, + "assertions": 7063, + "duration_ms": 146678, + "skipped": 2 + }, + "full_suite_reused_with_latest_permission_regression_retested_in_module": true } diff --git a/docs/proofs/candidate-triage-http.json b/docs/proofs/candidate-triage-http.json index 4ac25f2..f393b9c 100644 --- a/docs/proofs/candidate-triage-http.json +++ b/docs/proofs/candidate-triage-http.json @@ -1,8 +1,8 @@ { - "checked_at": "2026-10-30T17:32:58.543Z", - "people_workspace": 200, - "portal_settings": 200, - "unauthenticated_receipt": 401, - "portal_opened": false, - "candidates_created": 0 + "checked_at": "2026-10-30T17:32:58.543Z", + "people_workspace": 200, + "portal_settings": 200, + "unauthenticated_receipt": 401, + "portal_opened": false, + "candidates_created": 0 } diff --git a/docs/proofs/candidate-triage-pg.json b/docs/proofs/candidate-triage-pg.json index 6734b22..34665f6 100644 --- a/docs/proofs/candidate-triage-pg.json +++ b/docs/proofs/candidate-triage-pg.json @@ -1,15 +1,15 @@ { - "checked_at": "2026-10-30T17:30:39+00:00", - "database": "disposable PostgreSQL", - "application_role_reused_without_privilege_change": true, - "result": "passed", - "test_files": [ - "CandidateSubmissionsTest", - "PeopleHiringTest", - "CandidatePortalTest" - ], - "original_evaluation_untouched": true, - "database_removed": true, - "tests": 53, - "assertions": 1234 + "checked_at": "2026-10-30T17:30:39+00:00", + "database": "disposable PostgreSQL", + "application_role_reused_without_privilege_change": true, + "result": "passed", + "test_files": [ + "CandidateSubmissionsTest", + "PeopleHiringTest", + "CandidatePortalTest" + ], + "original_evaluation_untouched": true, + "database_removed": true, + "tests": 53, + "assertions": 1234 } diff --git a/docs/proofs/candidate-triage.json b/docs/proofs/candidate-triage.json index 6f68612..426ea91 100644 --- a/docs/proofs/candidate-triage.json +++ b/docs/proofs/candidate-triage.json @@ -1,67 +1,67 @@ { - "checked_at": "2026-10-30T17:35:03.695737+00:00", - "scope": [ - "explicit accepted-for-analysis or not-accepted triage", - "separate confidential reason and public communication", - "immutable idempotent decision and atomic application linkage", - "frozen submitted profile reused without re-entry or name-based merging", - "triager registered as application author preserving independent assessment", - "source reading restricted to preparers or reviewers with evidence scope", - "pending triage routed in workdesk and checked before close evaluation selection", - "admission blocked after reviews start", - "cross-company/process composite foreign keys" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 730, - "passed": 728, - "assertions": 7141, - "duration_ms": 150333, - "skipped": 2 - }, - "module_sqlite_tests": 48, - "module_sqlite_assertions": 1153, - "postgresql_tests": 53, - "postgresql_assertions": 1234, - "react_inertia_tests": 59, - "typescript": "passed", - "phpstan_errors": 0, - "pint": "passed", - "targeted_lint": "passed", - "build_exit": 0, - "menu_entries_across_six_roles": 111, - "runtime_sha256_files": 18, - "installation_proof": "candidate-triage-install.json", - "postgresql_proof": "candidate-triage-pg.json", - "http_proof": "candidate-triage-http.json", - "visual_review": false, - "domain_installed": false, - "emails_sent": 0, - "external_AI_calls": 0, - "candidate_accounts_created_in_evaluation": 0, - "automatic_transfers_in_evaluation": 0, - "outstanding": [ - "secure attachment intake", - "triage revision and reopening", - "candidate complements and corrected submissions", - "spontaneous and supplier electronic intake", - "real mail transport delivery rehearsal", - "visual validation and deployment" - ], - "source_sha256": { - "database/migrations/2026_10_30_000040_create_candidate_triage.php": "4a054bceb7abaa7d3ff1796f0529bb777061156927d91fab1f5ab324b2af8195", - "app/Services/CandidateTriage.php": "3566f527c99f8fea076d9babe68431c7d9e8f539be685e69d9c43a1cde8d5527", - "app/Services/PeopleHiring.php": "6fff082fede593e5a29d02d291d82d1d07492fdd941483a4301c4e99365cacbd", - "app/Services/PeopleWorkdesk.php": "f3b8096209897f0b9199804bd5f230a42627b6210f66a881ee755bc9a5c77767", - "app/Http/Controllers/CandidatePortalController.php": "e776651fa41ae071f7bfe8da301cc9c9e0b19df0f34c63dd58175de3b231b217", - "app/Http/Controllers/PeopleHiringController.php": "365e6cd116ed0d4e253e45b7e1768e586aaf6c6987a5c753809c52204c70469d", - "routes/web.php": "5d61be0bfaa196d8b81f1a124f863e475c0e428f282bfa3926d64395d2651a24", - "resources/js/pages/people/submissions.tsx": "57a4b57962b22797c560de928b0155d166a43212442641ca860016ce0554390e", - "resources/js/pages/people/show.tsx": "de1b290772a7e3f0b2083511dab0fcee9cf5fc7ca71e5014f87a892cdd32c06d", - "resources/js/pages/candidate/receipt.tsx": "5667ac51c6fd654fc96bff7bece924617561bac16b552dfce371aafdcb2e8830", - "resources/js/components/people-operational-insights.tsx": "55ce0f42e7d574e7c8832ec869aceaecd41d70a2ba8117b9397ce30528aab82f", - "tests/Feature/CandidateSubmissionsTest.php": "73808825233b55169f185c1fad555c53aa13bf6933c39fe2d84777638a9bf39d", - "tests/frontend/candidate-triage.test.tsx": "9d0455f569112f4869627bd22f1aaa6862cd34fc6f8912ab61b621c67ea1d880" - } + "checked_at": "2026-10-30T17:35:03.695737+00:00", + "scope": [ + "explicit accepted-for-analysis or not-accepted triage", + "separate confidential reason and public communication", + "immutable idempotent decision and atomic application linkage", + "frozen submitted profile reused without re-entry or name-based merging", + "triager registered as application author preserving independent assessment", + "source reading restricted to preparers or reviewers with evidence scope", + "pending triage routed in workdesk and checked before close evaluation selection", + "admission blocked after reviews start", + "cross-company/process composite foreign keys" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 730, + "passed": 728, + "assertions": 7141, + "duration_ms": 150333, + "skipped": 2 + }, + "module_sqlite_tests": 48, + "module_sqlite_assertions": 1153, + "postgresql_tests": 53, + "postgresql_assertions": 1234, + "react_inertia_tests": 59, + "typescript": "passed", + "phpstan_errors": 0, + "pint": "passed", + "targeted_lint": "passed", + "build_exit": 0, + "menu_entries_across_six_roles": 111, + "runtime_sha256_files": 18, + "installation_proof": "candidate-triage-install.json", + "postgresql_proof": "candidate-triage-pg.json", + "http_proof": "candidate-triage-http.json", + "visual_review": false, + "domain_installed": false, + "emails_sent": 0, + "external_AI_calls": 0, + "candidate_accounts_created_in_evaluation": 0, + "automatic_transfers_in_evaluation": 0, + "outstanding": [ + "secure attachment intake", + "triage revision and reopening", + "candidate complements and corrected submissions", + "spontaneous and supplier electronic intake", + "real mail transport delivery rehearsal", + "visual validation and deployment" + ], + "source_sha256": { + "database/migrations/2026_10_30_000040_create_candidate_triage.php": "4a054bceb7abaa7d3ff1796f0529bb777061156927d91fab1f5ab324b2af8195", + "app/Services/CandidateTriage.php": "3566f527c99f8fea076d9babe68431c7d9e8f539be685e69d9c43a1cde8d5527", + "app/Services/PeopleHiring.php": "6fff082fede593e5a29d02d291d82d1d07492fdd941483a4301c4e99365cacbd", + "app/Services/PeopleWorkdesk.php": "f3b8096209897f0b9199804bd5f230a42627b6210f66a881ee755bc9a5c77767", + "app/Http/Controllers/CandidatePortalController.php": "e776651fa41ae071f7bfe8da301cc9c9e0b19df0f34c63dd58175de3b231b217", + "app/Http/Controllers/PeopleHiringController.php": "365e6cd116ed0d4e253e45b7e1768e586aaf6c6987a5c753809c52204c70469d", + "routes/web.php": "5d61be0bfaa196d8b81f1a124f863e475c0e428f282bfa3926d64395d2651a24", + "resources/js/pages/people/submissions.tsx": "57a4b57962b22797c560de928b0155d166a43212442641ca860016ce0554390e", + "resources/js/pages/people/show.tsx": "de1b290772a7e3f0b2083511dab0fcee9cf5fc7ca71e5014f87a892cdd32c06d", + "resources/js/pages/candidate/receipt.tsx": "5667ac51c6fd654fc96bff7bece924617561bac16b552dfce371aafdcb2e8830", + "resources/js/components/people-operational-insights.tsx": "55ce0f42e7d574e7c8832ec869aceaecd41d70a2ba8117b9397ce30528aab82f", + "tests/Feature/CandidateSubmissionsTest.php": "73808825233b55169f185c1fad555c53aa13bf6933c39fe2d84777638a9bf39d", + "tests/frontend/candidate-triage.test.tsx": "9d0455f569112f4869627bd22f1aaa6862cd34fc6f8912ab61b621c67ea1d880" + } } diff --git a/docs/proofs/comparison-policy.json b/docs/proofs/comparison-policy.json index b97eb95..65f914a 100644 --- a/docs/proofs/comparison-policy.json +++ b/docs/proofs/comparison-policy.json @@ -1,48 +1,48 @@ { - "checked_at": "2026-10-30T11:11:26.981246+00:00", - "environment": "local evaluation 8005", - "scope": [ - "company-configured minimum eligible suppliers and independent evaluators", - "company-configured criterion weights totalling 100 percent", - "policy frozen when a request is created and retained on draft edits", - "old processes retain compatibility rules", - "quotation weights validated against process policy", - "policy included in new comparison hashes and order snapshots", - "policy visible in request comparison award reports and order print" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 622, - "passed": 620, - "assertions": 5306, - "duration_ms": 113835, - "skipped": 2 - }, - "postgresql": { - "tests": 45, - "assertions": 367, - "disposable_database_removed": true - }, - "phpstan_errors": 0, - "typescript": "passed", - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "installation_proof": "comparison-policy-install.json", - "company_policy_automatically_activated": false, - "domain_installed": false, - "visual_review": false, - "source_sha256": { - "app/Services/ComparisonPolicy.php": "bdcd5739b1d52fc57759ff59a2257a059ce7772b21552a09ef6aa83966f0145e", - "app/Services/ProposalComparison.php": "d091f73065064dd132196cb79033835f38f7bd55ec6a98a54a76bbcdfd4e6df0", - "app/Services/RequisitionWorkflow.php": "e06c11e0208f0cf2cff80e44b5de3c55de05e8cce079d4f1a77f1d9f37f08323", - "app/Services/PurchaseWorkflow.php": "30c622685cb80766addaaba9987281ea40b5890b51c907f1a50743e3ba7540c5", - "app/Services/OrganizationConfiguration.php": "478c5605ec6933e868d38f904c9e87727f884b2d1663ba6c0f58cc5872d90e95", - "app/Http/Controllers/QuotationController.php": "0ca2ec13459d2daefacc62ac30fa437217cdb648ab35c90083a958261ccd9f84", - "app/Http/Controllers/OrganizationConfigurationController.php": "c1d017a550619705ea3521f5ea794e4b5585be3fbbe3bc9557c1dc625502b9bf", - "resources/js/components/comparison-policy-summary.tsx": "c086bafc0e08e900938bd49a6b802880f4be7ba11ba29c9272ed85b42143bfe9", - "resources/js/pages/company/parameters.tsx": "e7ca03fc6600ec6db7395d0db289f5f277b2ba6a05053b1b136202600e195b3d", - "database/migrations/2026_10_30_000029_add_comparison_policy_snapshots.php": "92eacb2835908fe26938111098163e167d1afa6a42ad682c9ef63711c92274cc" - } + "checked_at": "2026-10-30T11:11:26.981246+00:00", + "environment": "local evaluation 8005", + "scope": [ + "company-configured minimum eligible suppliers and independent evaluators", + "company-configured criterion weights totalling 100 percent", + "policy frozen when a request is created and retained on draft edits", + "old processes retain compatibility rules", + "quotation weights validated against process policy", + "policy included in new comparison hashes and order snapshots", + "policy visible in request comparison award reports and order print" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 622, + "passed": 620, + "assertions": 5306, + "duration_ms": 113835, + "skipped": 2 + }, + "postgresql": { + "tests": 45, + "assertions": 367, + "disposable_database_removed": true + }, + "phpstan_errors": 0, + "typescript": "passed", + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "installation_proof": "comparison-policy-install.json", + "company_policy_automatically_activated": false, + "domain_installed": false, + "visual_review": false, + "source_sha256": { + "app/Services/ComparisonPolicy.php": "bdcd5739b1d52fc57759ff59a2257a059ce7772b21552a09ef6aa83966f0145e", + "app/Services/ProposalComparison.php": "d091f73065064dd132196cb79033835f38f7bd55ec6a98a54a76bbcdfd4e6df0", + "app/Services/RequisitionWorkflow.php": "e06c11e0208f0cf2cff80e44b5de3c55de05e8cce079d4f1a77f1d9f37f08323", + "app/Services/PurchaseWorkflow.php": "30c622685cb80766addaaba9987281ea40b5890b51c907f1a50743e3ba7540c5", + "app/Services/OrganizationConfiguration.php": "478c5605ec6933e868d38f904c9e87727f884b2d1663ba6c0f58cc5872d90e95", + "app/Http/Controllers/QuotationController.php": "0ca2ec13459d2daefacc62ac30fa437217cdb648ab35c90083a958261ccd9f84", + "app/Http/Controllers/OrganizationConfigurationController.php": "c1d017a550619705ea3521f5ea794e4b5585be3fbbe3bc9557c1dc625502b9bf", + "resources/js/components/comparison-policy-summary.tsx": "c086bafc0e08e900938bd49a6b802880f4be7ba11ba29c9272ed85b42143bfe9", + "resources/js/pages/company/parameters.tsx": "e7ca03fc6600ec6db7395d0db289f5f277b2ba6a05053b1b136202600e195b3d", + "database/migrations/2026_10_30_000029_add_comparison_policy_snapshots.php": "92eacb2835908fe26938111098163e167d1afa6a42ad682c9ef63711c92274cc" + } } diff --git a/docs/proofs/economic-comparison.json b/docs/proofs/economic-comparison.json index 0453ccb..acb1759 100644 --- a/docs/proofs/economic-comparison.json +++ b/docs/proofs/economic-comparison.json @@ -1,52 +1,52 @@ { - "checked_at": "2026-10-30T10:54:53.071479+00:00", - "environment": "local evaluation 8005", - "scope": [ - "company default VAT for new lines only", - "explicit unit discounts before VAT", - "tie warning without automatic winner", - "invalid and missing prices excluded", - "discount evidence in comparison award order and reports", - "six functional navigation groups with unchanged permissions" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 618, - "passed": 616, - "assertions": 5245, - "duration_ms": 181394, - "skipped": 2 - }, - "postgresql": { - "tests": 42, - "assertions": 327, - "disposable_database_removed": true - }, - "order_workflow_tests": 71, - "phpstan_errors": 0, - "typescript": "passed", - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "runtime_sha256_files": 18, - "menu_contract_entries_by_role": 107, - "menu_role_count": 6, - "fresh_backup_and_restore": "economic-install.json", - "http_proof": "menu-links.json", - "spreadsheet_original_modified": false, - "spreadsheet_example_values_imported": false, - "visual_review": false, - "domain_installed": false, - "source_sha256": { - "app/Services/QuotationPricing.php": "4b4ef22c0be338742b4ebf17a8018bf35dd0996d4b9d0fc460d4c02c2c0b8fa6", - "app/Services/ProposalComparison.php": "a106e659a855ddaf8a1279e3918ed7f631ff0ed6c374488d06d4dfe95b9a8872", - "app/Services/ProposalOpeningWorkflow.php": "ef7bc41fd696cd51bfa4113c9aa1ab42c91a86a6b36f1926b51a8b1fcd01284c", - "app/Services/OrganizationConfiguration.php": "89e452c699ccab4a388e0643e777bf77305e7ea6cde2357801d3d3b16406912a", - "app/Http/Controllers/QuotationController.php": "cf2a2064004d73c49d61e1aa21d8fa100300dfb5baa8fc737e1da72b4b57242d", - "resources/js/lib/procurement-navigation.ts": "488efff63a6ff1505abaab41f4e248ff740a8da456d9a627cc9143dfd6b26bbf", - "resources/js/components/sgc-workspace-shell.tsx": "892de779373aaf7689c95c4b3112734e0683fd60197916464a965ba1eabd1466", - "resources/js/pages/quotations/show.tsx": "e756b347e0da3b06e5e5f2d67ccb8d3370360db219b134227b611e91d1af7958", - "database/migrations/2026_10_30_000028_add_economic_comparison_terms.php": "dba2a5f8bfd3e76fee5fed032e11e71b2800dead3dfc9d66d040502e53c7e2c5" - } + "checked_at": "2026-10-30T10:54:53.071479+00:00", + "environment": "local evaluation 8005", + "scope": [ + "company default VAT for new lines only", + "explicit unit discounts before VAT", + "tie warning without automatic winner", + "invalid and missing prices excluded", + "discount evidence in comparison award order and reports", + "six functional navigation groups with unchanged permissions" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 618, + "passed": 616, + "assertions": 5245, + "duration_ms": 181394, + "skipped": 2 + }, + "postgresql": { + "tests": 42, + "assertions": 327, + "disposable_database_removed": true + }, + "order_workflow_tests": 71, + "phpstan_errors": 0, + "typescript": "passed", + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "runtime_sha256_files": 18, + "menu_contract_entries_by_role": 107, + "menu_role_count": 6, + "fresh_backup_and_restore": "economic-install.json", + "http_proof": "menu-links.json", + "spreadsheet_original_modified": false, + "spreadsheet_example_values_imported": false, + "visual_review": false, + "domain_installed": false, + "source_sha256": { + "app/Services/QuotationPricing.php": "4b4ef22c0be338742b4ebf17a8018bf35dd0996d4b9d0fc460d4c02c2c0b8fa6", + "app/Services/ProposalComparison.php": "a106e659a855ddaf8a1279e3918ed7f631ff0ed6c374488d06d4dfe95b9a8872", + "app/Services/ProposalOpeningWorkflow.php": "ef7bc41fd696cd51bfa4113c9aa1ab42c91a86a6b36f1926b51a8b1fcd01284c", + "app/Services/OrganizationConfiguration.php": "89e452c699ccab4a388e0643e777bf77305e7ea6cde2357801d3d3b16406912a", + "app/Http/Controllers/QuotationController.php": "cf2a2064004d73c49d61e1aa21d8fa100300dfb5baa8fc737e1da72b4b57242d", + "resources/js/lib/procurement-navigation.ts": "488efff63a6ff1505abaab41f4e248ff740a8da456d9a627cc9143dfd6b26bbf", + "resources/js/components/sgc-workspace-shell.tsx": "892de779373aaf7689c95c4b3112734e0683fd60197916464a965ba1eabd1466", + "resources/js/pages/quotations/show.tsx": "e756b347e0da3b06e5e5f2d67ccb8d3370360db219b134227b611e91d1af7958", + "database/migrations/2026_10_30_000028_add_economic_comparison_terms.php": "dba2a5f8bfd3e76fee5fed032e11e71b2800dead3dfc9d66d040502e53c7e2c5" + } } diff --git a/docs/proofs/evaluation-access.json b/docs/proofs/evaluation-access.json index 4d10c79..12f5023 100644 --- a/docs/proofs/evaluation-access.json +++ b/docs/proofs/evaluation-access.json @@ -1,49 +1,49 @@ { - "checked_at": "2026-10-30T10:29:54.976Z", - "base": "http://127.0.0.1:8005", - "owner_modules": [ - "/dashboard", - "/empresa", - "/requisicoes", - "/planeamento", - "/fornecedores", - "/cotacoes", - "/ordens", - "/recepcoes", - "/stock", - "/stock/operacoes", - "/equipamentos", - "/orcamentos", - "/regras-investimento", - "/facturas", - "/pagamentos", - "/obrigacoes-fornecedores", - "/conflitos", - "/revisao-compras", - "/politica-admissao", - "/politica-recomendacao", - "/relatorios", - "/relatorios/medidas-fornecedores", - "/administracao/parametrizacao" - ], - "roles": [ - "requester", - "department_head", - "procurement", - "finance", - "warehouse", - "admin" - ], - "csrf_enforced": true, - "arbitrary_role_refused": true, - "arbitrary_user_refused": true, - "logout": true, - "business_commands": 0, - "real_accounts_changed": false, - "operational_entry_status": "not running", - "visual_review": false, - "dashboard_auto_entry": true, - "other_routes_require_session": true, - "guest_report_redirect": true, - "intended_report_and_filters_preserved": true + "checked_at": "2026-10-30T10:29:54.976Z", + "base": "http://127.0.0.1:8005", + "owner_modules": [ + "/dashboard", + "/empresa", + "/requisicoes", + "/planeamento", + "/fornecedores", + "/cotacoes", + "/ordens", + "/recepcoes", + "/stock", + "/stock/operacoes", + "/equipamentos", + "/orcamentos", + "/regras-investimento", + "/facturas", + "/pagamentos", + "/obrigacoes-fornecedores", + "/conflitos", + "/revisao-compras", + "/politica-admissao", + "/politica-recomendacao", + "/relatorios", + "/relatorios/medidas-fornecedores", + "/administracao/parametrizacao" + ], + "roles": [ + "requester", + "department_head", + "procurement", + "finance", + "warehouse", + "admin" + ], + "csrf_enforced": true, + "arbitrary_role_refused": true, + "arbitrary_user_refused": true, + "logout": true, + "business_commands": 0, + "real_accounts_changed": false, + "operational_entry_status": "not running", + "visual_review": false, + "dashboard_auto_entry": true, + "other_routes_require_session": true, + "guest_report_redirect": true, + "intended_report_and_filters_preserved": true } diff --git a/docs/proofs/evidence-brief.json b/docs/proofs/evidence-brief.json index 4270a92..b10194c 100644 --- a/docs/proofs/evidence-brief.json +++ b/docs/proofs/evidence-brief.json @@ -1,68 +1,68 @@ { - "checked_at": "2026-10-30T14:55:29.383515+00:00", - "environment": "local evaluation 8005", - "scope": [ - "separate procurement and people evidence briefs", - "source paths and section anchors", - "redacted authorised report projections only", - "SHA256 basis without private financial content", - "current frozen returned approved and unsigned draft distinctions", - "PostgreSQL read snapshot on people detail" - ], - "procurement_tests": { - "tool": "pest", - "result": "passed", - "tests": 18, - "passed": 18, - "assertions": 317, - "duration_ms": 4718 - }, - "people_tests": { - "tool": "pest", - "result": "passed", - "tests": 35, - "passed": 35, - "assertions": 972, - "duration_ms": 11099 - }, - "postgresql_integration": { - "tool": "phpunit", - "result": "passed", - "tests": 1, - "passed": 1, - "assertions": 64, - "duration_ms": 2543 - }, - "react_inertia_tests": 31, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "http_proof": "menu-links.json", - "postgresql_proof": "evidence-brief-pg.json", - "prior_full_suite_reused": "people-clarifications.json", - "migrations_applied": false, - "business_records_changed": false, - "domain_installed": false, - "visual_review": false, - "visual_attempt_errors": [ - "Computer Use native pipe is unavailable (os error 2)", - "The browser access host is unavailable" - ], - "AI_provider_used_for_reports": false, - "source_sha256": { - "app/Services/ProcurementEvidenceBrief.php": "9a610e1d80f1040fa7a46117a5e251bebc4a6ca6d02383aa2c9d62f0ba3aef08", - "app/Services/PeopleEvidenceBrief.php": "76f5a6bdd36fb8878eac5aa80cbb34db5784979ad654166778775c5c28f5f80a", - "app/Http/Controllers/ProcurementReviewReportController.php": "ba96649bb5585ace55249f706dfb740cc12918676bc2ff3b4dac620ad602fb57", - "app/Http/Controllers/PeopleHiringController.php": "bc6656d73a033bffa540d2b555d15d9c52a38c84446d892710d7d8ded35200ec", - "resources/js/components/evidence-brief.tsx": "3b4630e44fdc02191d1e8ecebcd451c20b9e5a35b49ded9f5d78044bd1e24932", - "resources/js/components/procurement.tsx": "846599386826eece0c9d5f48f4a30d3d52815fce3fde4d781073ff9347bf97c6", - "resources/js/pages/purchases/review-report.tsx": "e29457affd4d2005b4393f4d21ee8ae1fbd9e4ccdc4ffbc253122d4628c1ba89", - "resources/js/pages/people/show.tsx": "247e4e80d4ffca649b46fe00ee665de7e4c5476f2ce3cc1e5590e7cced049e47", - "tests/Feature/ProcurementReviewReportTest.php": "46b95f3fc21b557021dd013357016a312078b99d20911a29e4e5ca3d09a5ed20", - "tests/Feature/PeopleHiringTest.php": "fbd93d8134298d6b666634659223487646dbcb8074bd05889d660e378c40be5a", - "tests/frontend/evidence-brief.test.tsx": "385b617074ac8c718f97e52981acce2a7b3dda9b965432e7e2be04c1ca7ef279", - "tests/frontend/people-hiring.test.tsx": "24c51db9886358dfb1bd43d6b82c2a45ac731abdab76bc4e9dea3b85cbcb8bb4" - } + "checked_at": "2026-10-30T14:55:29.383515+00:00", + "environment": "local evaluation 8005", + "scope": [ + "separate procurement and people evidence briefs", + "source paths and section anchors", + "redacted authorised report projections only", + "SHA256 basis without private financial content", + "current frozen returned approved and unsigned draft distinctions", + "PostgreSQL read snapshot on people detail" + ], + "procurement_tests": { + "tool": "pest", + "result": "passed", + "tests": 18, + "passed": 18, + "assertions": 317, + "duration_ms": 4718 + }, + "people_tests": { + "tool": "pest", + "result": "passed", + "tests": 35, + "passed": 35, + "assertions": 972, + "duration_ms": 11099 + }, + "postgresql_integration": { + "tool": "phpunit", + "result": "passed", + "tests": 1, + "passed": 1, + "assertions": 64, + "duration_ms": 2543 + }, + "react_inertia_tests": 31, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "http_proof": "menu-links.json", + "postgresql_proof": "evidence-brief-pg.json", + "prior_full_suite_reused": "people-clarifications.json", + "migrations_applied": false, + "business_records_changed": false, + "domain_installed": false, + "visual_review": false, + "visual_attempt_errors": [ + "Computer Use native pipe is unavailable (os error 2)", + "The browser access host is unavailable" + ], + "AI_provider_used_for_reports": false, + "source_sha256": { + "app/Services/ProcurementEvidenceBrief.php": "9a610e1d80f1040fa7a46117a5e251bebc4a6ca6d02383aa2c9d62f0ba3aef08", + "app/Services/PeopleEvidenceBrief.php": "76f5a6bdd36fb8878eac5aa80cbb34db5784979ad654166778775c5c28f5f80a", + "app/Http/Controllers/ProcurementReviewReportController.php": "ba96649bb5585ace55249f706dfb740cc12918676bc2ff3b4dac620ad602fb57", + "app/Http/Controllers/PeopleHiringController.php": "bc6656d73a033bffa540d2b555d15d9c52a38c84446d892710d7d8ded35200ec", + "resources/js/components/evidence-brief.tsx": "3b4630e44fdc02191d1e8ecebcd451c20b9e5a35b49ded9f5d78044bd1e24932", + "resources/js/components/procurement.tsx": "846599386826eece0c9d5f48f4a30d3d52815fce3fde4d781073ff9347bf97c6", + "resources/js/pages/purchases/review-report.tsx": "e29457affd4d2005b4393f4d21ee8ae1fbd9e4ccdc4ffbc253122d4628c1ba89", + "resources/js/pages/people/show.tsx": "247e4e80d4ffca649b46fe00ee665de7e4c5476f2ce3cc1e5590e7cced049e47", + "tests/Feature/ProcurementReviewReportTest.php": "46b95f3fc21b557021dd013357016a312078b99d20911a29e4e5ca3d09a5ed20", + "tests/Feature/PeopleHiringTest.php": "fbd93d8134298d6b666634659223487646dbcb8074bd05889d660e378c40be5a", + "tests/frontend/evidence-brief.test.tsx": "385b617074ac8c718f97e52981acce2a7b3dda9b965432e7e2be04c1ca7ef279", + "tests/frontend/people-hiring.test.tsx": "24c51db9886358dfb1bd43d6b82c2a45ac731abdab76bc4e9dea3b85cbcb8bb4" + } } diff --git a/docs/proofs/intelligence-policy-pg.json b/docs/proofs/intelligence-policy-pg.json index 75dd1af..b762b25 100644 --- a/docs/proofs/intelligence-policy-pg.json +++ b/docs/proofs/intelligence-policy-pg.json @@ -1,9 +1,9 @@ { - "checked_at": "2026-10-30T15:13:30+00:00", - "database": "disposable PostgreSQL", - "application_role_reused_without_privilege_change": true, - "result": "passed", - "scenario": "real report snapshots, tenant policy toggles, stale version rejection and authorisation", - "original_evaluation_untouched": true, - "database_removed": true + "checked_at": "2026-10-30T15:13:30+00:00", + "database": "disposable PostgreSQL", + "application_role_reused_without_privilege_change": true, + "result": "passed", + "scenario": "real report snapshots, tenant policy toggles, stale version rejection and authorisation", + "original_evaluation_untouched": true, + "database_removed": true } diff --git a/docs/proofs/intelligence-policy.json b/docs/proofs/intelligence-policy.json index 20af58e..842aa83 100644 --- a/docs/proofs/intelligence-policy.json +++ b/docs/proofs/intelligence-policy.json @@ -1,78 +1,78 @@ { - "checked_at": "2026-10-30T15:16:21.466309+00:00", - "environment": "local evaluation 8005", - "scope": [ - "independent tenant settings for procurement and people local briefs", - "optimistic version reason and transactional audit", - "preserve full reports process decisions and access rules", - "offline synthetic AI assessment of citation coverage and literal matches", - "no automatic semantic certification" - ], - "module_tests": { - "tool": "pest", - "result": "passed", - "tests": 82, - "passed": 82, - "assertions": 1337, - "duration_ms": 12897 - }, - "react_inertia_tests": 33, - "postgresql_integration": { - "tool": "phpunit", - "result": "passed", - "tests": 1, - "passed": 1, - "assertions": 110, - "duration_ms": 2935 - }, - "postgresql_proof": "intelligence-policy-pg.json", - "installation_proof": "intelligence-policy-install.json", - "manual_fixture_assessment": { - "method": "synthetic_ai_assessment_v1", - "facts": 3, - "claims": 3, - "cited_facts": 3, - "uncited_fact_ids": [], - "citation_coverage_complete": true, - "exact_source_text_matches": 3, - "requires_human_review": true, - "semantic_accuracy": "not_automatically_verified" - }, - "fixture_is_model_output": false, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "http_proof": "menu-links.json", - "prior_full_suite_reused": "people-clarifications.json", - "accounts_or_grants_changed": false, - "tenant_policy_choices_automatically_created": false, - "live_external_calls": 0, - "live_authorisation": "previously granted for one synthetic call; pending credential setup by owner", - "real_document_AI_enabled": false, - "visual_review": false, - "domain_installed": false, - "source_sha256": { - "app/Services/IntelligencePolicy.php": "c25d9c97e3902327486dc128274662d77b3da041b18d675510b0d29a76c7465b", - "app/Services/OrganizationConfiguration.php": "6a3a95f03491f47e0d80f12568d7e04a9a202a463d980d82daa794bbba17328e", - "app/Services/SyntheticAiAssessment.php": "a664903a3b0e4889e931d085697891588df7aced7e868e8e80c438d798365963", - "app/Services/SyntheticAiRehearsal.php": "76d0f2fa2ef07e670dc74b67e098d0d49df3755354342dc8592fbcb8f96796c6", - "app/Console/Commands/SgcAiAssess.php": "e47320fa2aeb0787e1d43b3c6fe2acb73c5732b63aa57d2f1ec6ae7109b1213d", - "app/Models/Tenant.php": "e7446af40d11ef77747caac54e623efb7c560d60bf05161557dac3086ea72d96", - "app/Http/Controllers/OrganizationConfigurationController.php": "88916867ddc3bcaccae9145bf9ca0c8598b3f6c8206c9222cbaed91c1490427b", - "app/Http/Controllers/PeopleHiringController.php": "6da8c0728838050b32db5bbde09420e164265cd78b185d500b040f03cb46e35f", - "app/Http/Controllers/ProcurementReviewReportController.php": "9ff40d3ee01cc0e5e97b900d2d0d6be8909c93c42df949deb14a33e21de7e828", - "database/migrations/2026_10_30_000033_add_intelligence_policy.php": "37b109a2bcad6572498e6350363e75e9f981da5f0ba921c50e861805a34a0ada", - "resources/js/components/intelligence-settings.tsx": "f63b9f7795bdfd9a263a9339d752618d13b87d05d3985272062aa5a5cfacfb79", - "resources/js/pages/company/parameters.tsx": "380ccc3933131004950d281108100b568c8b90a69a2286788fb8798500fc6ff2", - "resources/js/pages/people/show.tsx": "ad2f1ec8aeb350ade2da2ebd242ef448e068ca2974912aae3afdedf0530ecdb0", - "resources/js/pages/purchases/review-report.tsx": "7f572d0f27b2e1b35cddb4518846534940dbf99c13e76e3270eb572c0fef83ee", - "tests/Feature/OrganizationConfigurationTest.php": "1072451618d1104e61cec0b879597de3e3f3a7060f53c91f3196a181ad912bb3", - "tests/Feature/PeopleHiringTest.php": "9db07af59529ea6e9bc559531498813c5983bfc7d64c5f5729ad23d30aedfa1f", - "tests/Feature/SyntheticAiAssessmentTest.php": "6913b68906d41806312b244f9909385892ed8ce88129fad6e711c0d9fe6ead36", - "tests/Fixtures/ai-synthetic-result.json": "d488c086b2199a70b98f2238634d595d89fd086e3c52dc3aa85c80da1ebd959f", - "tests/frontend/intelligence-settings.test.tsx": "80feabb237675ecda8a4a516a58a4cc74cfd633e5900964625d1b0431f3c8670", - "routes/web.php": "279f3d92fabd359e8da154a288f6ff45a46c287897b424081d4a19d54636eeb5" - } + "checked_at": "2026-10-30T15:16:21.466309+00:00", + "environment": "local evaluation 8005", + "scope": [ + "independent tenant settings for procurement and people local briefs", + "optimistic version reason and transactional audit", + "preserve full reports process decisions and access rules", + "offline synthetic AI assessment of citation coverage and literal matches", + "no automatic semantic certification" + ], + "module_tests": { + "tool": "pest", + "result": "passed", + "tests": 82, + "passed": 82, + "assertions": 1337, + "duration_ms": 12897 + }, + "react_inertia_tests": 33, + "postgresql_integration": { + "tool": "phpunit", + "result": "passed", + "tests": 1, + "passed": 1, + "assertions": 110, + "duration_ms": 2935 + }, + "postgresql_proof": "intelligence-policy-pg.json", + "installation_proof": "intelligence-policy-install.json", + "manual_fixture_assessment": { + "method": "synthetic_ai_assessment_v1", + "facts": 3, + "claims": 3, + "cited_facts": 3, + "uncited_fact_ids": [], + "citation_coverage_complete": true, + "exact_source_text_matches": 3, + "requires_human_review": true, + "semantic_accuracy": "not_automatically_verified" + }, + "fixture_is_model_output": false, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "http_proof": "menu-links.json", + "prior_full_suite_reused": "people-clarifications.json", + "accounts_or_grants_changed": false, + "tenant_policy_choices_automatically_created": false, + "live_external_calls": 0, + "live_authorisation": "previously granted for one synthetic call; pending credential setup by owner", + "real_document_AI_enabled": false, + "visual_review": false, + "domain_installed": false, + "source_sha256": { + "app/Services/IntelligencePolicy.php": "c25d9c97e3902327486dc128274662d77b3da041b18d675510b0d29a76c7465b", + "app/Services/OrganizationConfiguration.php": "6a3a95f03491f47e0d80f12568d7e04a9a202a463d980d82daa794bbba17328e", + "app/Services/SyntheticAiAssessment.php": "a664903a3b0e4889e931d085697891588df7aced7e868e8e80c438d798365963", + "app/Services/SyntheticAiRehearsal.php": "76d0f2fa2ef07e670dc74b67e098d0d49df3755354342dc8592fbcb8f96796c6", + "app/Console/Commands/SgcAiAssess.php": "e47320fa2aeb0787e1d43b3c6fe2acb73c5732b63aa57d2f1ec6ae7109b1213d", + "app/Models/Tenant.php": "e7446af40d11ef77747caac54e623efb7c560d60bf05161557dac3086ea72d96", + "app/Http/Controllers/OrganizationConfigurationController.php": "88916867ddc3bcaccae9145bf9ca0c8598b3f6c8206c9222cbaed91c1490427b", + "app/Http/Controllers/PeopleHiringController.php": "6da8c0728838050b32db5bbde09420e164265cd78b185d500b040f03cb46e35f", + "app/Http/Controllers/ProcurementReviewReportController.php": "9ff40d3ee01cc0e5e97b900d2d0d6be8909c93c42df949deb14a33e21de7e828", + "database/migrations/2026_10_30_000033_add_intelligence_policy.php": "37b109a2bcad6572498e6350363e75e9f981da5f0ba921c50e861805a34a0ada", + "resources/js/components/intelligence-settings.tsx": "f63b9f7795bdfd9a263a9339d752618d13b87d05d3985272062aa5a5cfacfb79", + "resources/js/pages/company/parameters.tsx": "380ccc3933131004950d281108100b568c8b90a69a2286788fb8798500fc6ff2", + "resources/js/pages/people/show.tsx": "ad2f1ec8aeb350ade2da2ebd242ef448e068ca2974912aae3afdedf0530ecdb0", + "resources/js/pages/purchases/review-report.tsx": "7f572d0f27b2e1b35cddb4518846534940dbf99c13e76e3270eb572c0fef83ee", + "tests/Feature/OrganizationConfigurationTest.php": "1072451618d1104e61cec0b879597de3e3f3a7060f53c91f3196a181ad912bb3", + "tests/Feature/PeopleHiringTest.php": "9db07af59529ea6e9bc559531498813c5983bfc7d64c5f5729ad23d30aedfa1f", + "tests/Feature/SyntheticAiAssessmentTest.php": "6913b68906d41806312b244f9909385892ed8ce88129fad6e711c0d9fe6ead36", + "tests/Fixtures/ai-synthetic-result.json": "d488c086b2199a70b98f2238634d595d89fd086e3c52dc3aa85c80da1ebd959f", + "tests/frontend/intelligence-settings.test.tsx": "80feabb237675ecda8a4a516a58a4cc74cfd633e5900964625d1b0431f3c8670", + "routes/web.php": "279f3d92fabd359e8da154a288f6ff45a46c287897b424081d4a19d54636eeb5" + } } diff --git a/docs/proofs/invoice-payable-link.json b/docs/proofs/invoice-payable-link.json index ab5c1ac..63a2e1f 100644 --- a/docs/proofs/invoice-payable-link.json +++ b/docs/proofs/invoice-payable-link.json @@ -1,11 +1,11 @@ { - "checked_at": "2026-10-29T18:41:52.592Z", - "documents_checked": 1, - "per_invoice_entry": true, - "return_to_invoices": true, - "invalid_identifiers_refused": true, - "unknown_invoice_refused": true, - "full_listing_unchanged": true, - "business_commands": 0, - "visual_review": false + "checked_at": "2026-10-29T18:41:52.592Z", + "documents_checked": 1, + "per_invoice_entry": true, + "return_to_invoices": true, + "invalid_identifiers_refused": true, + "unknown_invoice_refused": true, + "full_listing_unchanged": true, + "business_commands": 0, + "visual_review": false } diff --git a/docs/proofs/menu-code-contract.json b/docs/proofs/menu-code-contract.json index e81deaa..7bc6ebf 100644 --- a/docs/proofs/menu-code-contract.json +++ b/docs/proofs/menu-code-contract.json @@ -1,1011 +1,1011 @@ { - "checked_at": "2026-10-30T17:30:57.094Z", - "result": "passed", - "entries": 111, - "roles": 6, - "configurable_permissions_and_multiple_profiles": true, - "maximum_functional_groups": 6, - "source": "procurementNavigation compared with actual Laravel GET routes", - "scope": "Menu routing, active entry and visibility contract; not a substitute for functional or visual workflow acceptance", - "rows": [ - { - "role": "admin", - "group": "Compras", - "id": "new_request", - "label": "Nova requisição", - "path": "/requisicoes/criar", - "action": "App\\Http\\Controllers\\RequisitionController@create", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "my_requests", - "label": "Minhas requisições", - "path": "/requisicoes?view=mine", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "my_drafts", - "label": "Os meus rascunhos", - "path": "/requisicoes?view=mine&status=draft", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "all_requests", - "label": "Todas as autorizadas", - "path": "/requisicoes?view=all", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "planning", - "label": "Planeamento", - "path": "/planeamento", - "action": "App\\Http\\Controllers\\PurchasePlanningController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "pending_approvals", - "label": "Pendentes para mim", - "path": "/requisicoes?view=approvals", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "decisions", - "label": "Minhas decisões", - "path": "/requisicoes?view=decided", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "quotations", - "label": "Cotações e comparação", - "path": "/cotacoes", - "action": "App\\Http\\Controllers\\QuotationController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "orders", - "label": "Adjudicações e ordens", - "path": "/ordens", - "action": "App\\Http\\Controllers\\PurchaseController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "purchase_review", - "label": "Revisão e cancelamento", - "path": "/revisao-compras", - "action": "App\\Http\\Controllers\\PurchaseControlController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "suppliers", - "label": "Cadastro e documentos", - "path": "/fornecedores", - "action": "App\\Http\\Controllers\\SupplierController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Compras", - "id": "supplier_evaluations", - "label": "Avaliação de fornecedores", - "path": "/fornecedores/avaliacoes", - "action": "App\\Http\\Controllers\\SupplierEvaluationController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Pessoas e contratações", - "id": "people_registry", - "label": "Cadastro reutilizável de pessoas", - "path": "/pessoas/cadastro", - "action": "App\\Http\\Controllers\\PeopleRegistryController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Pessoas e contratações", - "id": "people_hiring", - "label": "Processos e equipas", - "path": "/pessoas", - "action": "App\\Http\\Controllers\\PeopleHiringController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Pessoas e contratações", - "id": "people_services", - "label": "Serviços individuais", - "path": "/pessoas?kind=service", - "action": "App\\Http\\Controllers\\PeopleHiringController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Pessoas e contratações", - "id": "people_staff", - "label": "Recrutamento e selecção", - "path": "/pessoas?kind=staff", - "action": "App\\Http\\Controllers\\PeopleHiringController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Armazém e activos", - "id": "receipts", - "label": "Recepções e divergências", - "path": "/recepcoes", - "action": "App\\Http\\Controllers\\GoodsReceiptController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Armazém e activos", - "id": "stock", - "label": "Artigos e stock", - "path": "/stock", - "action": "App\\Http\\Controllers\\StockController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Armazém e activos", - "id": "stock_operations", - "label": "Saídas e inventários", - "path": "/stock/operacoes", - "action": "App\\Http\\Controllers\\StockOperationController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Armazém e activos", - "id": "equipment", - "label": "Equipamentos e peças", - "path": "/equipamentos", - "action": "App\\Http\\Controllers\\EquipmentController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Finanças", - "id": "invoices", - "label": "Facturas e conferência", - "path": "/facturas", - "action": "App\\Http\\Controllers\\InvoiceController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Finanças", - "id": "payments", - "label": "Pagamentos externos", - "path": "/pagamentos", - "action": "App\\Http\\Controllers\\ExternalPaymentController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Finanças", - "id": "budgets", - "label": "Orçamentos e reforços", - "path": "/orcamentos", - "action": "App\\Http\\Controllers\\BudgetController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Finanças", - "id": "investment", - "label": "Regras de investimento", - "path": "/regras-investimento", - "action": "App\\Http\\Controllers\\InvestmentPolicyController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Administração", - "id": "company", - "label": "Empresa, equipa e centros", - "path": "/empresa", - "action": "App\\Http\\Controllers\\CompanyController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Administração", - "id": "organization_parameters", - "label": "Parametrização da aplicação", - "path": "/administracao/parametrizacao", - "action": "App\\Http\\Controllers\\OrganizationConfigurationController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Administração", - "id": "admission_policy", - "label": "Política de admissão", - "path": "/politica-admissao", - "action": "App\\Http\\Controllers\\FormalAdmissionController@policy", - "full_page": false - }, - { - "role": "admin", - "group": "Administração", - "id": "recommendation_policy", - "label": "Política de recomendação", - "path": "/politica-recomendacao", - "action": "App\\Http\\Controllers\\FormalRecommendationController@policy", - "full_page": false - }, - { - "role": "admin", - "group": "Administração", - "id": "conflicts", - "label": "Conflitos de interesses", - "path": "/conflitos", - "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Relatórios", - "id": "procurement_reports", - "label": "Relatórios de compras", - "path": "/relatorios", - "action": "App\\Http\\Controllers\\ProcurementReportController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Relatórios", - "id": "supplier_improvement_reports", - "label": "Medidas de melhoria", - "path": "/relatorios/medidas-fornecedores", - "action": "App\\Http\\Controllers\\SupplierImprovementReportController@index", - "full_page": false - }, - { - "role": "admin", - "group": "Finanças", - "id": "payables", - "label": "Obrigações a fornecedores", - "path": "/obrigacoes-fornecedores", - "action": "App\\Http\\Controllers\\SupplierPayablesController@page", - "full_page": true - }, - { - "role": "procurement", - "group": "Compras", - "id": "new_request", - "label": "Nova requisição", - "path": "/requisicoes/criar", - "action": "App\\Http\\Controllers\\RequisitionController@create", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "my_requests", - "label": "Minhas requisições", - "path": "/requisicoes?view=mine", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "my_drafts", - "label": "Os meus rascunhos", - "path": "/requisicoes?view=mine&status=draft", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "all_requests", - "label": "Todas as autorizadas", - "path": "/requisicoes?view=all", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "planning", - "label": "Planeamento", - "path": "/planeamento", - "action": "App\\Http\\Controllers\\PurchasePlanningController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "pending_approvals", - "label": "Pendentes para mim", - "path": "/requisicoes?view=approvals", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "decisions", - "label": "Minhas decisões", - "path": "/requisicoes?view=decided", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "quotations", - "label": "Cotações e comparação", - "path": "/cotacoes", - "action": "App\\Http\\Controllers\\QuotationController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "orders", - "label": "Adjudicações e ordens", - "path": "/ordens", - "action": "App\\Http\\Controllers\\PurchaseController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "purchase_review", - "label": "Revisão e cancelamento", - "path": "/revisao-compras", - "action": "App\\Http\\Controllers\\PurchaseControlController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "suppliers", - "label": "Cadastro e documentos", - "path": "/fornecedores", - "action": "App\\Http\\Controllers\\SupplierController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Compras", - "id": "supplier_evaluations", - "label": "Avaliação de fornecedores", - "path": "/fornecedores/avaliacoes", - "action": "App\\Http\\Controllers\\SupplierEvaluationController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Armazém e activos", - "id": "receipts", - "label": "Recepções e divergências", - "path": "/recepcoes", - "action": "App\\Http\\Controllers\\GoodsReceiptController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Armazém e activos", - "id": "stock", - "label": "Artigos e stock", - "path": "/stock", - "action": "App\\Http\\Controllers\\StockController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Armazém e activos", - "id": "stock_operations", - "label": "Saídas e inventários", - "path": "/stock/operacoes", - "action": "App\\Http\\Controllers\\StockOperationController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Armazém e activos", - "id": "equipment", - "label": "Equipamentos e peças", - "path": "/equipamentos", - "action": "App\\Http\\Controllers\\EquipmentController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Finanças", - "id": "investment", - "label": "Regras de investimento", - "path": "/regras-investimento", - "action": "App\\Http\\Controllers\\InvestmentPolicyController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Administração", - "id": "conflicts", - "label": "Conflitos de interesses", - "path": "/conflitos", - "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Relatórios", - "id": "procurement_reports", - "label": "Relatórios de compras", - "path": "/relatorios", - "action": "App\\Http\\Controllers\\ProcurementReportController@index", - "full_page": false - }, - { - "role": "procurement", - "group": "Relatórios", - "id": "supplier_improvement_reports", - "label": "Medidas de melhoria", - "path": "/relatorios/medidas-fornecedores", - "action": "App\\Http\\Controllers\\SupplierImprovementReportController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "new_request", - "label": "Nova requisição", - "path": "/requisicoes/criar", - "action": "App\\Http\\Controllers\\RequisitionController@create", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "my_requests", - "label": "Minhas requisições", - "path": "/requisicoes?view=mine", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "my_drafts", - "label": "Os meus rascunhos", - "path": "/requisicoes?view=mine&status=draft", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "all_requests", - "label": "Todas as autorizadas", - "path": "/requisicoes?view=all", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "planning", - "label": "Planeamento", - "path": "/planeamento", - "action": "App\\Http\\Controllers\\PurchasePlanningController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "pending_approvals", - "label": "Pendentes para mim", - "path": "/requisicoes?view=approvals", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "decisions", - "label": "Minhas decisões", - "path": "/requisicoes?view=decided", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "quotations", - "label": "Cotações e comparação", - "path": "/cotacoes", - "action": "App\\Http\\Controllers\\QuotationController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "orders", - "label": "Adjudicações e ordens", - "path": "/ordens", - "action": "App\\Http\\Controllers\\PurchaseController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "purchase_review", - "label": "Revisão e cancelamento", - "path": "/revisao-compras", - "action": "App\\Http\\Controllers\\PurchaseControlController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "suppliers", - "label": "Cadastro e documentos", - "path": "/fornecedores", - "action": "App\\Http\\Controllers\\SupplierController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Compras", - "id": "supplier_evaluations", - "label": "Avaliação de fornecedores", - "path": "/fornecedores/avaliacoes", - "action": "App\\Http\\Controllers\\SupplierEvaluationController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Armazém e activos", - "id": "receipts", - "label": "Recepções e divergências", - "path": "/recepcoes", - "action": "App\\Http\\Controllers\\GoodsReceiptController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Armazém e activos", - "id": "stock", - "label": "Artigos e stock", - "path": "/stock", - "action": "App\\Http\\Controllers\\StockController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Armazém e activos", - "id": "stock_operations", - "label": "Saídas e inventários", - "path": "/stock/operacoes", - "action": "App\\Http\\Controllers\\StockOperationController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Armazém e activos", - "id": "equipment", - "label": "Equipamentos e peças", - "path": "/equipamentos", - "action": "App\\Http\\Controllers\\EquipmentController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Finanças", - "id": "invoices", - "label": "Facturas e conferência", - "path": "/facturas", - "action": "App\\Http\\Controllers\\InvoiceController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Finanças", - "id": "payments", - "label": "Pagamentos externos", - "path": "/pagamentos", - "action": "App\\Http\\Controllers\\ExternalPaymentController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Finanças", - "id": "budgets", - "label": "Orçamentos e reforços", - "path": "/orcamentos", - "action": "App\\Http\\Controllers\\BudgetController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Finanças", - "id": "investment", - "label": "Regras de investimento", - "path": "/regras-investimento", - "action": "App\\Http\\Controllers\\InvestmentPolicyController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Administração", - "id": "conflicts", - "label": "Conflitos de interesses", - "path": "/conflitos", - "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Relatórios", - "id": "procurement_reports", - "label": "Relatórios de compras", - "path": "/relatorios", - "action": "App\\Http\\Controllers\\ProcurementReportController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Relatórios", - "id": "supplier_improvement_reports", - "label": "Medidas de melhoria", - "path": "/relatorios/medidas-fornecedores", - "action": "App\\Http\\Controllers\\SupplierImprovementReportController@index", - "full_page": false - }, - { - "role": "finance", - "group": "Finanças", - "id": "payables", - "label": "Obrigações a fornecedores", - "path": "/obrigacoes-fornecedores", - "action": "App\\Http\\Controllers\\SupplierPayablesController@page", - "full_page": true - }, - { - "role": "department_head", - "group": "Compras", - "id": "new_request", - "label": "Nova requisição", - "path": "/requisicoes/criar", - "action": "App\\Http\\Controllers\\RequisitionController@create", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "my_requests", - "label": "Minhas requisições", - "path": "/requisicoes?view=mine", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "my_drafts", - "label": "Os meus rascunhos", - "path": "/requisicoes?view=mine&status=draft", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "all_requests", - "label": "Todas as autorizadas", - "path": "/requisicoes?view=all", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "planning", - "label": "Planeamento", - "path": "/planeamento", - "action": "App\\Http\\Controllers\\PurchasePlanningController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "pending_approvals", - "label": "Pendentes para mim", - "path": "/requisicoes?view=approvals", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "decisions", - "label": "Minhas decisões", - "path": "/requisicoes?view=decided", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "quotations", - "label": "Cotações e comparação", - "path": "/cotacoes", - "action": "App\\Http\\Controllers\\QuotationController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "orders", - "label": "Adjudicações e ordens", - "path": "/ordens", - "action": "App\\Http\\Controllers\\PurchaseController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "purchase_review", - "label": "Revisão e cancelamento", - "path": "/revisao-compras", - "action": "App\\Http\\Controllers\\PurchaseControlController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "suppliers", - "label": "Cadastro e documentos", - "path": "/fornecedores", - "action": "App\\Http\\Controllers\\SupplierController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Compras", - "id": "supplier_evaluations", - "label": "Avaliação de fornecedores", - "path": "/fornecedores/avaliacoes", - "action": "App\\Http\\Controllers\\SupplierEvaluationController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Armazém e activos", - "id": "receipts", - "label": "Recepções e divergências", - "path": "/recepcoes", - "action": "App\\Http\\Controllers\\GoodsReceiptController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Armazém e activos", - "id": "equipment", - "label": "Equipamentos e peças", - "path": "/equipamentos", - "action": "App\\Http\\Controllers\\EquipmentController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Administração", - "id": "conflicts", - "label": "Conflitos de interesses", - "path": "/conflitos", - "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Relatórios", - "id": "procurement_reports", - "label": "Relatórios de compras", - "path": "/relatorios", - "action": "App\\Http\\Controllers\\ProcurementReportController@index", - "full_page": false - }, - { - "role": "department_head", - "group": "Relatórios", - "id": "supplier_improvement_reports", - "label": "Medidas de melhoria", - "path": "/relatorios/medidas-fornecedores", - "action": "App\\Http\\Controllers\\SupplierImprovementReportController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Compras", - "id": "new_request", - "label": "Nova requisição", - "path": "/requisicoes/criar", - "action": "App\\Http\\Controllers\\RequisitionController@create", - "full_page": false - }, - { - "role": "warehouse", - "group": "Compras", - "id": "my_requests", - "label": "Minhas requisições", - "path": "/requisicoes?view=mine", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Compras", - "id": "my_drafts", - "label": "Os meus rascunhos", - "path": "/requisicoes?view=mine&status=draft", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Compras", - "id": "all_requests", - "label": "Todas as autorizadas", - "path": "/requisicoes?view=all", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Compras", - "id": "planning", - "label": "Planeamento", - "path": "/planeamento", - "action": "App\\Http\\Controllers\\PurchasePlanningController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Compras", - "id": "purchase_review", - "label": "Revisão e cancelamento", - "path": "/revisao-compras", - "action": "App\\Http\\Controllers\\PurchaseControlController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Armazém e activos", - "id": "receipts", - "label": "Recepções e divergências", - "path": "/recepcoes", - "action": "App\\Http\\Controllers\\GoodsReceiptController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Armazém e activos", - "id": "stock", - "label": "Artigos e stock", - "path": "/stock", - "action": "App\\Http\\Controllers\\StockController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Armazém e activos", - "id": "stock_operations", - "label": "Saídas e inventários", - "path": "/stock/operacoes", - "action": "App\\Http\\Controllers\\StockOperationController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Armazém e activos", - "id": "equipment", - "label": "Equipamentos e peças", - "path": "/equipamentos", - "action": "App\\Http\\Controllers\\EquipmentController@index", - "full_page": false - }, - { - "role": "warehouse", - "group": "Administração", - "id": "conflicts", - "label": "Conflitos de interesses", - "path": "/conflitos", - "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", - "full_page": false - }, - { - "role": "requester", - "group": "Compras", - "id": "new_request", - "label": "Nova requisição", - "path": "/requisicoes/criar", - "action": "App\\Http\\Controllers\\RequisitionController@create", - "full_page": false - }, - { - "role": "requester", - "group": "Compras", - "id": "my_requests", - "label": "Minhas requisições", - "path": "/requisicoes?view=mine", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "requester", - "group": "Compras", - "id": "my_drafts", - "label": "Os meus rascunhos", - "path": "/requisicoes?view=mine&status=draft", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "requester", - "group": "Compras", - "id": "all_requests", - "label": "Todas as autorizadas", - "path": "/requisicoes?view=all", - "action": "App\\Http\\Controllers\\RequisitionController@index", - "full_page": false - }, - { - "role": "requester", - "group": "Compras", - "id": "planning", - "label": "Planeamento", - "path": "/planeamento", - "action": "App\\Http\\Controllers\\PurchasePlanningController@index", - "full_page": false - }, - { - "role": "requester", - "group": "Compras", - "id": "purchase_review", - "label": "Revisão e cancelamento", - "path": "/revisao-compras", - "action": "App\\Http\\Controllers\\PurchaseControlController@index", - "full_page": false - }, - { - "role": "requester", - "group": "Administração", - "id": "conflicts", - "label": "Conflitos de interesses", - "path": "/conflitos", - "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", - "full_page": false - } - ] + "checked_at": "2026-10-30T17:30:57.094Z", + "result": "passed", + "entries": 111, + "roles": 6, + "configurable_permissions_and_multiple_profiles": true, + "maximum_functional_groups": 6, + "source": "procurementNavigation compared with actual Laravel GET routes", + "scope": "Menu routing, active entry and visibility contract; not a substitute for functional or visual workflow acceptance", + "rows": [ + { + "role": "admin", + "group": "Compras", + "id": "new_request", + "label": "Nova requisição", + "path": "/requisicoes/criar", + "action": "App\\Http\\Controllers\\RequisitionController@create", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "my_requests", + "label": "Minhas requisições", + "path": "/requisicoes?view=mine", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "my_drafts", + "label": "Os meus rascunhos", + "path": "/requisicoes?view=mine&status=draft", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "all_requests", + "label": "Todas as autorizadas", + "path": "/requisicoes?view=all", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "planning", + "label": "Planeamento", + "path": "/planeamento", + "action": "App\\Http\\Controllers\\PurchasePlanningController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "pending_approvals", + "label": "Pendentes para mim", + "path": "/requisicoes?view=approvals", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "decisions", + "label": "Minhas decisões", + "path": "/requisicoes?view=decided", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "quotations", + "label": "Cotações e comparação", + "path": "/cotacoes", + "action": "App\\Http\\Controllers\\QuotationController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "orders", + "label": "Adjudicações e ordens", + "path": "/ordens", + "action": "App\\Http\\Controllers\\PurchaseController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "purchase_review", + "label": "Revisão e cancelamento", + "path": "/revisao-compras", + "action": "App\\Http\\Controllers\\PurchaseControlController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "suppliers", + "label": "Cadastro e documentos", + "path": "/fornecedores", + "action": "App\\Http\\Controllers\\SupplierController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Compras", + "id": "supplier_evaluations", + "label": "Avaliação de fornecedores", + "path": "/fornecedores/avaliacoes", + "action": "App\\Http\\Controllers\\SupplierEvaluationController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Pessoas e contratações", + "id": "people_registry", + "label": "Cadastro reutilizável de pessoas", + "path": "/pessoas/cadastro", + "action": "App\\Http\\Controllers\\PeopleRegistryController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Pessoas e contratações", + "id": "people_hiring", + "label": "Processos e equipas", + "path": "/pessoas", + "action": "App\\Http\\Controllers\\PeopleHiringController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Pessoas e contratações", + "id": "people_services", + "label": "Serviços individuais", + "path": "/pessoas?kind=service", + "action": "App\\Http\\Controllers\\PeopleHiringController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Pessoas e contratações", + "id": "people_staff", + "label": "Recrutamento e selecção", + "path": "/pessoas?kind=staff", + "action": "App\\Http\\Controllers\\PeopleHiringController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Armazém e activos", + "id": "receipts", + "label": "Recepções e divergências", + "path": "/recepcoes", + "action": "App\\Http\\Controllers\\GoodsReceiptController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Armazém e activos", + "id": "stock", + "label": "Artigos e stock", + "path": "/stock", + "action": "App\\Http\\Controllers\\StockController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Armazém e activos", + "id": "stock_operations", + "label": "Saídas e inventários", + "path": "/stock/operacoes", + "action": "App\\Http\\Controllers\\StockOperationController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Armazém e activos", + "id": "equipment", + "label": "Equipamentos e peças", + "path": "/equipamentos", + "action": "App\\Http\\Controllers\\EquipmentController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Finanças", + "id": "invoices", + "label": "Facturas e conferência", + "path": "/facturas", + "action": "App\\Http\\Controllers\\InvoiceController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Finanças", + "id": "payments", + "label": "Pagamentos externos", + "path": "/pagamentos", + "action": "App\\Http\\Controllers\\ExternalPaymentController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Finanças", + "id": "budgets", + "label": "Orçamentos e reforços", + "path": "/orcamentos", + "action": "App\\Http\\Controllers\\BudgetController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Finanças", + "id": "investment", + "label": "Regras de investimento", + "path": "/regras-investimento", + "action": "App\\Http\\Controllers\\InvestmentPolicyController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Administração", + "id": "company", + "label": "Empresa, equipa e centros", + "path": "/empresa", + "action": "App\\Http\\Controllers\\CompanyController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Administração", + "id": "organization_parameters", + "label": "Parametrização da aplicação", + "path": "/administracao/parametrizacao", + "action": "App\\Http\\Controllers\\OrganizationConfigurationController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Administração", + "id": "admission_policy", + "label": "Política de admissão", + "path": "/politica-admissao", + "action": "App\\Http\\Controllers\\FormalAdmissionController@policy", + "full_page": false + }, + { + "role": "admin", + "group": "Administração", + "id": "recommendation_policy", + "label": "Política de recomendação", + "path": "/politica-recomendacao", + "action": "App\\Http\\Controllers\\FormalRecommendationController@policy", + "full_page": false + }, + { + "role": "admin", + "group": "Administração", + "id": "conflicts", + "label": "Conflitos de interesses", + "path": "/conflitos", + "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Relatórios", + "id": "procurement_reports", + "label": "Relatórios de compras", + "path": "/relatorios", + "action": "App\\Http\\Controllers\\ProcurementReportController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Relatórios", + "id": "supplier_improvement_reports", + "label": "Medidas de melhoria", + "path": "/relatorios/medidas-fornecedores", + "action": "App\\Http\\Controllers\\SupplierImprovementReportController@index", + "full_page": false + }, + { + "role": "admin", + "group": "Finanças", + "id": "payables", + "label": "Obrigações a fornecedores", + "path": "/obrigacoes-fornecedores", + "action": "App\\Http\\Controllers\\SupplierPayablesController@page", + "full_page": true + }, + { + "role": "procurement", + "group": "Compras", + "id": "new_request", + "label": "Nova requisição", + "path": "/requisicoes/criar", + "action": "App\\Http\\Controllers\\RequisitionController@create", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "my_requests", + "label": "Minhas requisições", + "path": "/requisicoes?view=mine", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "my_drafts", + "label": "Os meus rascunhos", + "path": "/requisicoes?view=mine&status=draft", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "all_requests", + "label": "Todas as autorizadas", + "path": "/requisicoes?view=all", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "planning", + "label": "Planeamento", + "path": "/planeamento", + "action": "App\\Http\\Controllers\\PurchasePlanningController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "pending_approvals", + "label": "Pendentes para mim", + "path": "/requisicoes?view=approvals", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "decisions", + "label": "Minhas decisões", + "path": "/requisicoes?view=decided", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "quotations", + "label": "Cotações e comparação", + "path": "/cotacoes", + "action": "App\\Http\\Controllers\\QuotationController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "orders", + "label": "Adjudicações e ordens", + "path": "/ordens", + "action": "App\\Http\\Controllers\\PurchaseController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "purchase_review", + "label": "Revisão e cancelamento", + "path": "/revisao-compras", + "action": "App\\Http\\Controllers\\PurchaseControlController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "suppliers", + "label": "Cadastro e documentos", + "path": "/fornecedores", + "action": "App\\Http\\Controllers\\SupplierController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Compras", + "id": "supplier_evaluations", + "label": "Avaliação de fornecedores", + "path": "/fornecedores/avaliacoes", + "action": "App\\Http\\Controllers\\SupplierEvaluationController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Armazém e activos", + "id": "receipts", + "label": "Recepções e divergências", + "path": "/recepcoes", + "action": "App\\Http\\Controllers\\GoodsReceiptController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Armazém e activos", + "id": "stock", + "label": "Artigos e stock", + "path": "/stock", + "action": "App\\Http\\Controllers\\StockController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Armazém e activos", + "id": "stock_operations", + "label": "Saídas e inventários", + "path": "/stock/operacoes", + "action": "App\\Http\\Controllers\\StockOperationController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Armazém e activos", + "id": "equipment", + "label": "Equipamentos e peças", + "path": "/equipamentos", + "action": "App\\Http\\Controllers\\EquipmentController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Finanças", + "id": "investment", + "label": "Regras de investimento", + "path": "/regras-investimento", + "action": "App\\Http\\Controllers\\InvestmentPolicyController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Administração", + "id": "conflicts", + "label": "Conflitos de interesses", + "path": "/conflitos", + "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Relatórios", + "id": "procurement_reports", + "label": "Relatórios de compras", + "path": "/relatorios", + "action": "App\\Http\\Controllers\\ProcurementReportController@index", + "full_page": false + }, + { + "role": "procurement", + "group": "Relatórios", + "id": "supplier_improvement_reports", + "label": "Medidas de melhoria", + "path": "/relatorios/medidas-fornecedores", + "action": "App\\Http\\Controllers\\SupplierImprovementReportController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "new_request", + "label": "Nova requisição", + "path": "/requisicoes/criar", + "action": "App\\Http\\Controllers\\RequisitionController@create", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "my_requests", + "label": "Minhas requisições", + "path": "/requisicoes?view=mine", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "my_drafts", + "label": "Os meus rascunhos", + "path": "/requisicoes?view=mine&status=draft", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "all_requests", + "label": "Todas as autorizadas", + "path": "/requisicoes?view=all", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "planning", + "label": "Planeamento", + "path": "/planeamento", + "action": "App\\Http\\Controllers\\PurchasePlanningController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "pending_approvals", + "label": "Pendentes para mim", + "path": "/requisicoes?view=approvals", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "decisions", + "label": "Minhas decisões", + "path": "/requisicoes?view=decided", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "quotations", + "label": "Cotações e comparação", + "path": "/cotacoes", + "action": "App\\Http\\Controllers\\QuotationController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "orders", + "label": "Adjudicações e ordens", + "path": "/ordens", + "action": "App\\Http\\Controllers\\PurchaseController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "purchase_review", + "label": "Revisão e cancelamento", + "path": "/revisao-compras", + "action": "App\\Http\\Controllers\\PurchaseControlController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "suppliers", + "label": "Cadastro e documentos", + "path": "/fornecedores", + "action": "App\\Http\\Controllers\\SupplierController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Compras", + "id": "supplier_evaluations", + "label": "Avaliação de fornecedores", + "path": "/fornecedores/avaliacoes", + "action": "App\\Http\\Controllers\\SupplierEvaluationController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Armazém e activos", + "id": "receipts", + "label": "Recepções e divergências", + "path": "/recepcoes", + "action": "App\\Http\\Controllers\\GoodsReceiptController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Armazém e activos", + "id": "stock", + "label": "Artigos e stock", + "path": "/stock", + "action": "App\\Http\\Controllers\\StockController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Armazém e activos", + "id": "stock_operations", + "label": "Saídas e inventários", + "path": "/stock/operacoes", + "action": "App\\Http\\Controllers\\StockOperationController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Armazém e activos", + "id": "equipment", + "label": "Equipamentos e peças", + "path": "/equipamentos", + "action": "App\\Http\\Controllers\\EquipmentController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Finanças", + "id": "invoices", + "label": "Facturas e conferência", + "path": "/facturas", + "action": "App\\Http\\Controllers\\InvoiceController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Finanças", + "id": "payments", + "label": "Pagamentos externos", + "path": "/pagamentos", + "action": "App\\Http\\Controllers\\ExternalPaymentController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Finanças", + "id": "budgets", + "label": "Orçamentos e reforços", + "path": "/orcamentos", + "action": "App\\Http\\Controllers\\BudgetController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Finanças", + "id": "investment", + "label": "Regras de investimento", + "path": "/regras-investimento", + "action": "App\\Http\\Controllers\\InvestmentPolicyController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Administração", + "id": "conflicts", + "label": "Conflitos de interesses", + "path": "/conflitos", + "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Relatórios", + "id": "procurement_reports", + "label": "Relatórios de compras", + "path": "/relatorios", + "action": "App\\Http\\Controllers\\ProcurementReportController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Relatórios", + "id": "supplier_improvement_reports", + "label": "Medidas de melhoria", + "path": "/relatorios/medidas-fornecedores", + "action": "App\\Http\\Controllers\\SupplierImprovementReportController@index", + "full_page": false + }, + { + "role": "finance", + "group": "Finanças", + "id": "payables", + "label": "Obrigações a fornecedores", + "path": "/obrigacoes-fornecedores", + "action": "App\\Http\\Controllers\\SupplierPayablesController@page", + "full_page": true + }, + { + "role": "department_head", + "group": "Compras", + "id": "new_request", + "label": "Nova requisição", + "path": "/requisicoes/criar", + "action": "App\\Http\\Controllers\\RequisitionController@create", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "my_requests", + "label": "Minhas requisições", + "path": "/requisicoes?view=mine", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "my_drafts", + "label": "Os meus rascunhos", + "path": "/requisicoes?view=mine&status=draft", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "all_requests", + "label": "Todas as autorizadas", + "path": "/requisicoes?view=all", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "planning", + "label": "Planeamento", + "path": "/planeamento", + "action": "App\\Http\\Controllers\\PurchasePlanningController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "pending_approvals", + "label": "Pendentes para mim", + "path": "/requisicoes?view=approvals", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "decisions", + "label": "Minhas decisões", + "path": "/requisicoes?view=decided", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "quotations", + "label": "Cotações e comparação", + "path": "/cotacoes", + "action": "App\\Http\\Controllers\\QuotationController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "orders", + "label": "Adjudicações e ordens", + "path": "/ordens", + "action": "App\\Http\\Controllers\\PurchaseController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "purchase_review", + "label": "Revisão e cancelamento", + "path": "/revisao-compras", + "action": "App\\Http\\Controllers\\PurchaseControlController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "suppliers", + "label": "Cadastro e documentos", + "path": "/fornecedores", + "action": "App\\Http\\Controllers\\SupplierController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Compras", + "id": "supplier_evaluations", + "label": "Avaliação de fornecedores", + "path": "/fornecedores/avaliacoes", + "action": "App\\Http\\Controllers\\SupplierEvaluationController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Armazém e activos", + "id": "receipts", + "label": "Recepções e divergências", + "path": "/recepcoes", + "action": "App\\Http\\Controllers\\GoodsReceiptController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Armazém e activos", + "id": "equipment", + "label": "Equipamentos e peças", + "path": "/equipamentos", + "action": "App\\Http\\Controllers\\EquipmentController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Administração", + "id": "conflicts", + "label": "Conflitos de interesses", + "path": "/conflitos", + "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Relatórios", + "id": "procurement_reports", + "label": "Relatórios de compras", + "path": "/relatorios", + "action": "App\\Http\\Controllers\\ProcurementReportController@index", + "full_page": false + }, + { + "role": "department_head", + "group": "Relatórios", + "id": "supplier_improvement_reports", + "label": "Medidas de melhoria", + "path": "/relatorios/medidas-fornecedores", + "action": "App\\Http\\Controllers\\SupplierImprovementReportController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Compras", + "id": "new_request", + "label": "Nova requisição", + "path": "/requisicoes/criar", + "action": "App\\Http\\Controllers\\RequisitionController@create", + "full_page": false + }, + { + "role": "warehouse", + "group": "Compras", + "id": "my_requests", + "label": "Minhas requisições", + "path": "/requisicoes?view=mine", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Compras", + "id": "my_drafts", + "label": "Os meus rascunhos", + "path": "/requisicoes?view=mine&status=draft", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Compras", + "id": "all_requests", + "label": "Todas as autorizadas", + "path": "/requisicoes?view=all", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Compras", + "id": "planning", + "label": "Planeamento", + "path": "/planeamento", + "action": "App\\Http\\Controllers\\PurchasePlanningController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Compras", + "id": "purchase_review", + "label": "Revisão e cancelamento", + "path": "/revisao-compras", + "action": "App\\Http\\Controllers\\PurchaseControlController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Armazém e activos", + "id": "receipts", + "label": "Recepções e divergências", + "path": "/recepcoes", + "action": "App\\Http\\Controllers\\GoodsReceiptController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Armazém e activos", + "id": "stock", + "label": "Artigos e stock", + "path": "/stock", + "action": "App\\Http\\Controllers\\StockController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Armazém e activos", + "id": "stock_operations", + "label": "Saídas e inventários", + "path": "/stock/operacoes", + "action": "App\\Http\\Controllers\\StockOperationController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Armazém e activos", + "id": "equipment", + "label": "Equipamentos e peças", + "path": "/equipamentos", + "action": "App\\Http\\Controllers\\EquipmentController@index", + "full_page": false + }, + { + "role": "warehouse", + "group": "Administração", + "id": "conflicts", + "label": "Conflitos de interesses", + "path": "/conflitos", + "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", + "full_page": false + }, + { + "role": "requester", + "group": "Compras", + "id": "new_request", + "label": "Nova requisição", + "path": "/requisicoes/criar", + "action": "App\\Http\\Controllers\\RequisitionController@create", + "full_page": false + }, + { + "role": "requester", + "group": "Compras", + "id": "my_requests", + "label": "Minhas requisições", + "path": "/requisicoes?view=mine", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "requester", + "group": "Compras", + "id": "my_drafts", + "label": "Os meus rascunhos", + "path": "/requisicoes?view=mine&status=draft", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "requester", + "group": "Compras", + "id": "all_requests", + "label": "Todas as autorizadas", + "path": "/requisicoes?view=all", + "action": "App\\Http\\Controllers\\RequisitionController@index", + "full_page": false + }, + { + "role": "requester", + "group": "Compras", + "id": "planning", + "label": "Planeamento", + "path": "/planeamento", + "action": "App\\Http\\Controllers\\PurchasePlanningController@index", + "full_page": false + }, + { + "role": "requester", + "group": "Compras", + "id": "purchase_review", + "label": "Revisão e cancelamento", + "path": "/revisao-compras", + "action": "App\\Http\\Controllers\\PurchaseControlController@index", + "full_page": false + }, + { + "role": "requester", + "group": "Administração", + "id": "conflicts", + "label": "Conflitos de interesses", + "path": "/conflitos", + "action": "App\\Http\\Controllers\\ConflictDeclarationController@index", + "full_page": false + } + ] } diff --git a/docs/proofs/menu-links.json b/docs/proofs/menu-links.json index 999d664..044f6d2 100644 --- a/docs/proofs/menu-links.json +++ b/docs/proofs/menu-links.json @@ -1,174 +1,174 @@ { - "checked_at": "2026-10-30T17:33:21.203Z", - "results": [ - { - "role": "admin", - "checked_entries": 32, - "paths": [ - "/requisicoes/criar", - "/requisicoes?view=mine", - "/requisicoes?view=mine&status=draft", - "/requisicoes?view=all", - "/planeamento", - "/requisicoes?view=approvals", - "/requisicoes?view=decided", - "/cotacoes", - "/ordens", - "/revisao-compras", - "/fornecedores", - "/fornecedores/avaliacoes", - "/pessoas/cadastro", - "/pessoas", - "/pessoas?kind=service", - "/pessoas?kind=staff", - "/recepcoes", - "/stock", - "/stock/operacoes", - "/equipamentos", - "/facturas", - "/obrigacoes-fornecedores", - "/pagamentos", + "checked_at": "2026-10-30T17:33:21.203Z", + "results": [ + { + "role": "admin", + "checked_entries": 32, + "paths": [ + "/requisicoes/criar", + "/requisicoes?view=mine", + "/requisicoes?view=mine&status=draft", + "/requisicoes?view=all", + "/planeamento", + "/requisicoes?view=approvals", + "/requisicoes?view=decided", + "/cotacoes", + "/ordens", + "/revisao-compras", + "/fornecedores", + "/fornecedores/avaliacoes", + "/pessoas/cadastro", + "/pessoas", + "/pessoas?kind=service", + "/pessoas?kind=staff", + "/recepcoes", + "/stock", + "/stock/operacoes", + "/equipamentos", + "/facturas", + "/obrigacoes-fornecedores", + "/pagamentos", + "/orcamentos", + "/regras-investimento", + "/empresa", + "/administracao/parametrizacao", + "/politica-admissao", + "/politica-recomendacao", + "/conflitos", + "/relatorios", + "/relatorios/medidas-fornecedores" + ] + }, + { + "role": "procurement", + "checked_entries": 20, + "paths": [ + "/requisicoes/criar", + "/requisicoes?view=mine", + "/requisicoes?view=mine&status=draft", + "/requisicoes?view=all", + "/planeamento", + "/requisicoes?view=approvals", + "/requisicoes?view=decided", + "/cotacoes", + "/ordens", + "/revisao-compras", + "/fornecedores", + "/fornecedores/avaliacoes", + "/recepcoes", + "/stock", + "/stock/operacoes", + "/equipamentos", + "/regras-investimento", + "/conflitos", + "/relatorios", + "/relatorios/medidas-fornecedores" + ] + }, + { + "role": "finance", + "checked_entries": 24, + "paths": [ + "/requisicoes/criar", + "/requisicoes?view=mine", + "/requisicoes?view=mine&status=draft", + "/requisicoes?view=all", + "/planeamento", + "/requisicoes?view=approvals", + "/requisicoes?view=decided", + "/cotacoes", + "/ordens", + "/revisao-compras", + "/fornecedores", + "/fornecedores/avaliacoes", + "/recepcoes", + "/stock", + "/stock/operacoes", + "/equipamentos", + "/facturas", + "/obrigacoes-fornecedores", + "/pagamentos", + "/orcamentos", + "/regras-investimento", + "/conflitos", + "/relatorios", + "/relatorios/medidas-fornecedores" + ] + }, + { + "role": "department_head", + "checked_entries": 17, + "paths": [ + "/requisicoes/criar", + "/requisicoes?view=mine", + "/requisicoes?view=mine&status=draft", + "/requisicoes?view=all", + "/planeamento", + "/requisicoes?view=approvals", + "/requisicoes?view=decided", + "/cotacoes", + "/ordens", + "/revisao-compras", + "/fornecedores", + "/fornecedores/avaliacoes", + "/recepcoes", + "/equipamentos", + "/conflitos", + "/relatorios", + "/relatorios/medidas-fornecedores" + ] + }, + { + "role": "warehouse", + "checked_entries": 11, + "paths": [ + "/requisicoes/criar", + "/requisicoes?view=mine", + "/requisicoes?view=mine&status=draft", + "/requisicoes?view=all", + "/planeamento", + "/revisao-compras", + "/recepcoes", + "/stock", + "/stock/operacoes", + "/equipamentos", + "/conflitos" + ] + }, + { + "role": "requester", + "checked_entries": 7, + "paths": [ + "/requisicoes/criar", + "/requisicoes?view=mine", + "/requisicoes?view=mine&status=draft", + "/requisicoes?view=all", + "/planeamento", + "/revisao-compras", + "/conflitos" + ] + } + ], + "request_detail_checked": true, + "invoice_count": 1, + "process_links_checked": [ + "/requisicoes/1", "/orcamentos", - "/regras-investimento", - "/empresa", - "/administracao/parametrizacao", - "/politica-admissao", - "/politica-recomendacao", - "/conflitos", - "/relatorios", - "/relatorios/medidas-fornecedores" - ] - }, - { - "role": "procurement", - "checked_entries": 20, - "paths": [ - "/requisicoes/criar", - "/requisicoes?view=mine", - "/requisicoes?view=mine&status=draft", - "/requisicoes?view=all", - "/planeamento", - "/requisicoes?view=approvals", - "/requisicoes?view=decided", - "/cotacoes", - "/ordens", - "/revisao-compras", - "/fornecedores", - "/fornecedores/avaliacoes", - "/recepcoes", - "/stock", - "/stock/operacoes", - "/equipamentos", - "/regras-investimento", - "/conflitos", - "/relatorios", - "/relatorios/medidas-fornecedores" - ] - }, - { - "role": "finance", - "checked_entries": 24, - "paths": [ - "/requisicoes/criar", - "/requisicoes?view=mine", - "/requisicoes?view=mine&status=draft", - "/requisicoes?view=all", - "/planeamento", - "/requisicoes?view=approvals", - "/requisicoes?view=decided", - "/cotacoes", - "/ordens", - "/revisao-compras", - "/fornecedores", - "/fornecedores/avaliacoes", - "/recepcoes", - "/stock", - "/stock/operacoes", - "/equipamentos", + "/requisicoes/1/cotacoes", + "/requisicoes/1/adjudicacao", + "/ordens/1", + "/ordens/1/recepcoes", "/facturas", - "/obrigacoes-fornecedores", "/pagamentos", - "/orcamentos", - "/regras-investimento", - "/conflitos", - "/relatorios", - "/relatorios/medidas-fornecedores" - ] - }, - { - "role": "department_head", - "checked_entries": 17, - "paths": [ - "/requisicoes/criar", - "/requisicoes?view=mine", - "/requisicoes?view=mine&status=draft", - "/requisicoes?view=all", - "/planeamento", - "/requisicoes?view=approvals", - "/requisicoes?view=decided", - "/cotacoes", - "/ordens", - "/revisao-compras", - "/fornecedores", - "/fornecedores/avaliacoes", - "/recepcoes", - "/equipamentos", - "/conflitos", - "/relatorios", - "/relatorios/medidas-fornecedores" - ] - }, - { - "role": "warehouse", - "checked_entries": 11, - "paths": [ - "/requisicoes/criar", - "/requisicoes?view=mine", - "/requisicoes?view=mine&status=draft", - "/requisicoes?view=all", - "/planeamento", - "/revisao-compras", - "/recepcoes", - "/stock", - "/stock/operacoes", - "/equipamentos", - "/conflitos" - ] - }, - { - "role": "requester", - "checked_entries": 7, - "paths": [ - "/requisicoes/criar", - "/requisicoes?view=mine", - "/requisicoes?view=mine&status=draft", - "/requisicoes?view=all", - "/planeamento", - "/revisao-compras", - "/conflitos" - ] - } - ], - "request_detail_checked": true, - "invoice_count": 1, - "process_links_checked": [ - "/requisicoes/1", - "/orcamentos", - "/requisicoes/1/cotacoes", - "/requisicoes/1/adjudicacao", - "/ordens/1", - "/ordens/1/recepcoes", - "/facturas", - "/pagamentos", - "/requisicoes/1/relatorio", - "/requisicoes/1/admissao", - "/requisicoes/1/recomendacao", - "/recepcoes/1" - ], - "canonical_query_order": true, - "active_subroutes": true, - "vat_setting_and_default_checked": true, - "comparison_ties_and_reasons_checked": true, - "business_history_unchanged": true, - "business_commands": 0 + "/requisicoes/1/relatorio", + "/requisicoes/1/admissao", + "/requisicoes/1/recomendacao", + "/recepcoes/1" + ], + "canonical_query_order": true, + "active_subroutes": true, + "vat_setting_and_default_checked": true, + "comparison_ties_and_reasons_checked": true, + "business_history_unchanged": true, + "business_commands": 0 } diff --git a/docs/proofs/organization-access-http.json b/docs/proofs/organization-access-http.json index 3c47e0f..fbbabe2 100644 --- a/docs/proofs/organization-access-http.json +++ b/docs/proofs/organization-access-http.json @@ -1,25 +1,25 @@ { - "checked_at": "2026-10-30T08:46:09.751Z", - "base": "http://127.0.0.1:8005", - "path": "/administracao/parametrizacao", - "roles": [ - "admin", - "requester", - "department_head", - "procurement", - "finance", - "warehouse" - ], - "owner_access": true, - "other_legacy_profiles_refused": true, - "passwords_not_returned": true, - "configuration_state": { - "active": false, - "version": 1, - "profiles": 0 - }, - "business_commands": 0, - "accounts_created": 0, - "permissions_changed": false, - "visual_review": false + "checked_at": "2026-10-30T08:46:09.751Z", + "base": "http://127.0.0.1:8005", + "path": "/administracao/parametrizacao", + "roles": [ + "admin", + "requester", + "department_head", + "procurement", + "finance", + "warehouse" + ], + "owner_access": true, + "other_legacy_profiles_refused": true, + "passwords_not_returned": true, + "configuration_state": { + "active": false, + "version": 1, + "profiles": 0 + }, + "business_commands": 0, + "accounts_created": 0, + "permissions_changed": false, + "visual_review": false } diff --git a/docs/proofs/organization-configuration.json b/docs/proofs/organization-configuration.json index 7d39e0c..d210930 100644 --- a/docs/proofs/organization-configuration.json +++ b/docs/proofs/organization-configuration.json @@ -1,63 +1,63 @@ { - "checked_at": "2026-10-30T08:47:37.236992+00:00", - "full_suite": { - "total": 603, - "passed": 601, - "skipped": 2, - "assertions": 5157, - "log": "storage/logs/organization-delivery-tests.log" - }, - "postgresql_configuration": { - "tests": 13, - "passed": 13, - "assertions": 96, - "disposable_database_removed": true, - "log": "storage/logs/organization-pg-tests.log" - }, - "phpstan_errors": 0, - "typescript": "passed", - "lint_format_targeted": "passed", - "pint": "passed", - "build": "passed", - "build_log": "storage/logs/organization-build.log", - "runtime_files_verified": 18, - "menu_entries": 107, - "evaluation_catalog_pages": 23, - "installed_only_in_evaluation": true, - "configuration_activated_in_evaluation": false, - "accounts_or_permissions_changed_in_evaluation": false, - "maintenance": { - "named_account": true, - "normal_authentication": true, - "expiry_required": true, - "revocable": true, - "audited": true, - "read_only": true, - "universal_password": false, - "hidden_entry": false - }, - "domain_installed": false, - "visual_review": false, - "remaining": [ - "permission granularity by operation", - "universal workflow stage/condition editor", - "specific common financial identity and entitlement associations", - "visual and print review" - ], - "sources": { - "app/Services/OrganizationAccess.php": "872f06e50d561714ab50d88dc113c0fa054dea9f170a09bb37f8d39d07b78a09", - "app/Services/OrganizationConfiguration.php": "e2d6e725a78dc4f10d931017969d0fcdacaed4dd6b37a4a08a96cb44b09fd1b5", - "app/Http/Controllers/OrganizationConfigurationController.php": "9765cee7b1770f48fde4affcefc518a36576190bbaeac8bce079655353377c72", - "app/Http/Controllers/CompanyController.php": "5a8112e0f1535f90aeb8cf9785259da8d713d1bfcd3ad908aa3eabd161dba8a3", - "app/Http/Middleware/EnsureOrganizationAccess.php": "6782164f18f982fedb91dfb4fb2365895c757d776d7bf1728a91682fa95b8b02", - "app/Models/User.php": "835c119c097e7927136e8c7775ebb5ed677f964e766a213ec3c04e0b7388e740", - "app/Enums/PurchasingRole.php": "91da2d40bf11988fd6324aba8e5068e6be7c92222be31baf83844c134affe1c4", - "database/migrations/2026_10_30_000027_create_organization_access.php": "130d92ba8a093a8f77678e1ce4c1a90125bb996e88ed81633359d224fe77a853", - "database/seeders/DatabaseSeeder.php": "2aaea71ca2eba604abd5723e95cd1a99521c61b6f00b70dfedba246f3dcfae48", - "resources/js/pages/company/parameters.tsx": "c0760c50d100c8b2dfb3d3ad3b2a05fae14eed7900e95461c766a885d07677d1", - "resources/js/pages/company/setup.tsx": "614000ad22692ea3e707a00103227953d95f32fd7d9a7fc031bdbba7a1ccdb48", - "resources/js/lib/procurement-navigation.ts": "d7a42ec76e0166e4783bb496834325ad583b903ebf8c999c2ba5a2307431d56d", - "tests/Feature/OrganizationConfigurationTest.php": "eef7e82a6efc8ebad46cea8752861c01bec53c552874d72120a6e982f0114d73", - "scripts/organization-access-check.mjs": "1ca7cd2bdafa5f62afb26fa0b074d879273cda27c8350b968de54c8f53328bb0" - } + "checked_at": "2026-10-30T08:47:37.236992+00:00", + "full_suite": { + "total": 603, + "passed": 601, + "skipped": 2, + "assertions": 5157, + "log": "storage/logs/organization-delivery-tests.log" + }, + "postgresql_configuration": { + "tests": 13, + "passed": 13, + "assertions": 96, + "disposable_database_removed": true, + "log": "storage/logs/organization-pg-tests.log" + }, + "phpstan_errors": 0, + "typescript": "passed", + "lint_format_targeted": "passed", + "pint": "passed", + "build": "passed", + "build_log": "storage/logs/organization-build.log", + "runtime_files_verified": 18, + "menu_entries": 107, + "evaluation_catalog_pages": 23, + "installed_only_in_evaluation": true, + "configuration_activated_in_evaluation": false, + "accounts_or_permissions_changed_in_evaluation": false, + "maintenance": { + "named_account": true, + "normal_authentication": true, + "expiry_required": true, + "revocable": true, + "audited": true, + "read_only": true, + "universal_password": false, + "hidden_entry": false + }, + "domain_installed": false, + "visual_review": false, + "remaining": [ + "permission granularity by operation", + "universal workflow stage/condition editor", + "specific common financial identity and entitlement associations", + "visual and print review" + ], + "sources": { + "app/Services/OrganizationAccess.php": "872f06e50d561714ab50d88dc113c0fa054dea9f170a09bb37f8d39d07b78a09", + "app/Services/OrganizationConfiguration.php": "e2d6e725a78dc4f10d931017969d0fcdacaed4dd6b37a4a08a96cb44b09fd1b5", + "app/Http/Controllers/OrganizationConfigurationController.php": "9765cee7b1770f48fde4affcefc518a36576190bbaeac8bce079655353377c72", + "app/Http/Controllers/CompanyController.php": "5a8112e0f1535f90aeb8cf9785259da8d713d1bfcd3ad908aa3eabd161dba8a3", + "app/Http/Middleware/EnsureOrganizationAccess.php": "6782164f18f982fedb91dfb4fb2365895c757d776d7bf1728a91682fa95b8b02", + "app/Models/User.php": "835c119c097e7927136e8c7775ebb5ed677f964e766a213ec3c04e0b7388e740", + "app/Enums/PurchasingRole.php": "91da2d40bf11988fd6324aba8e5068e6be7c92222be31baf83844c134affe1c4", + "database/migrations/2026_10_30_000027_create_organization_access.php": "130d92ba8a093a8f77678e1ce4c1a90125bb996e88ed81633359d224fe77a853", + "database/seeders/DatabaseSeeder.php": "2aaea71ca2eba604abd5723e95cd1a99521c61b6f00b70dfedba246f3dcfae48", + "resources/js/pages/company/parameters.tsx": "c0760c50d100c8b2dfb3d3ad3b2a05fae14eed7900e95461c766a885d07677d1", + "resources/js/pages/company/setup.tsx": "614000ad22692ea3e707a00103227953d95f32fd7d9a7fc031bdbba7a1ccdb48", + "resources/js/lib/procurement-navigation.ts": "d7a42ec76e0166e4783bb496834325ad583b903ebf8c999c2ba5a2307431d56d", + "tests/Feature/OrganizationConfigurationTest.php": "eef7e82a6efc8ebad46cea8752861c01bec53c552874d72120a6e982f0114d73", + "scripts/organization-access-check.mjs": "1ca7cd2bdafa5f62afb26fa0b074d879273cda27c8350b968de54c8f53328bb0" + } } diff --git a/docs/proofs/payable-history-pg.json b/docs/proofs/payable-history-pg.json index 464f3f6..a6a837a 100644 --- a/docs/proofs/payable-history-pg.json +++ b/docs/proofs/payable-history-pg.json @@ -1,28 +1,25 @@ { - "checked_at": "2026-10-29T19:41:38.688Z", - "passed": true, - "fault_recovery": true, - "concurrent_recognition": true, - "original_business_history_unchanged": true, - "new_transfers_executed": false, - "scenario": { - "principal_minor": 1160000, - "balance_minor": 860000, - "confirmed_minor": 300000, - "pending_minor": 100000, - "rejected_minor": 50000, - "obligations": 1, - "imports": 1, - "payment_links": 3, - "business_fingerprint": "fb66326abf7968aa818b0c6a214c2a1f59966fa11d3692e748fa0fa1aaa3cf1f", - "ui_balance_correct": true, - "due_on": null, - "days_overdue": null, - "append_only_tables": [ - "pa_history_imports", - "pa_imported_payments" - ], - "changed_history_refused": true - }, - "visual_review": false + "checked_at": "2026-10-29T19:41:38.688Z", + "passed": true, + "fault_recovery": true, + "concurrent_recognition": true, + "original_business_history_unchanged": true, + "new_transfers_executed": false, + "scenario": { + "principal_minor": 1160000, + "balance_minor": 860000, + "confirmed_minor": 300000, + "pending_minor": 100000, + "rejected_minor": 50000, + "obligations": 1, + "imports": 1, + "payment_links": 3, + "business_fingerprint": "fb66326abf7968aa818b0c6a214c2a1f59966fa11d3692e748fa0fa1aaa3cf1f", + "ui_balance_correct": true, + "due_on": null, + "days_overdue": null, + "append_only_tables": ["pa_history_imports", "pa_imported_payments"], + "changed_history_refused": true + }, + "visual_review": false } diff --git a/docs/proofs/payable-payment-decisions-pg.json b/docs/proofs/payable-payment-decisions-pg.json index f3a1cac..35504a3 100644 --- a/docs/proofs/payable-payment-decisions-pg.json +++ b/docs/proofs/payable-payment-decisions-pg.json @@ -1,19 +1,19 @@ { - "checked_at": "2026-10-29T19:41:38.669Z", - "passed": true, - "atomic_rollback": true, - "concurrent_decision_once": true, - "original_import_preserved": true, - "new_transfers_executed": false, - "scenario": { - "balance_minor": 760000, - "confirmed_minor": 400000, - "pending_minor": 0, - "decisions": 1, - "events": 1, - "original_status": "confirmed", - "append_only": true, - "frozen": "4b5aa40f964c0709661449b4ab5bfd7cd8295eac9c4d186822d0a1e10aa63534" - }, - "visual_review": false + "checked_at": "2026-10-29T19:41:38.669Z", + "passed": true, + "atomic_rollback": true, + "concurrent_decision_once": true, + "original_import_preserved": true, + "new_transfers_executed": false, + "scenario": { + "balance_minor": 760000, + "confirmed_minor": 400000, + "pending_minor": 0, + "decisions": 1, + "events": 1, + "original_status": "confirmed", + "append_only": true, + "frozen": "4b5aa40f964c0709661449b4ab5bfd7cd8295eac9c4d186822d0a1e10aa63534" + }, + "visual_review": false } diff --git a/docs/proofs/people-access-pg.json b/docs/proofs/people-access-pg.json index 4a1d11a..a541500 100644 --- a/docs/proofs/people-access-pg.json +++ b/docs/proofs/people-access-pg.json @@ -3,9 +3,7 @@ "database": "disposable PostgreSQL", "application_role_reused_without_privilege_change": true, "result": "passed", - "test_files": [ - "PeopleHiringTest" - ], + "test_files": ["PeopleHiringTest"], "original_evaluation_untouched": true, "database_removed": true } diff --git a/docs/proofs/people-access.json b/docs/proofs/people-access.json index c3b0ce8..a291fe6 100644 --- a/docs/proofs/people-access.json +++ b/docs/proofs/people-access.json @@ -1,55 +1,55 @@ { - "checked_at": "2026-10-30T12:12:17.828306+00:00", - "environment": "local evaluation 8005", - "scope": [ - "separate purchasing and people navigation and workflows", - "per-process named access with expiry revocation version and audit", - "administrative team setup without automatic candidate access", - "server-side financial interview and contract projections including selection copies", - "separate service and staff annex fields and classified requirements", - "typed reported observed and verified interview evidence", - "old records and rules preserved" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 638, - "passed": 636, - "assertions": 5556, - "duration_ms": 135871, - "skipped": 2 - }, - "latest_module_tests": { - "sqlite": 16, - "postgresql": 16, - "assertions": 286, - "disposable_database_removed": true - }, - "react_inertia_tests": 22, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "runtime_sha256_files": 18, - "menu_entries_by_role": 110, - "menu_groups_maximum": 6, - "http_proof": "menu-links.json", - "installation_proof": "people-access-install.json", - "business_accounts_or_grants_created_in_evaluation": false, - "domain_installed": false, - "visual_review": false, - "source_sha256": { - "app/Services/PeopleHiring.php": "ec0365c2ef2b1035468f16e8d4923b458889fc8438bbc6532de95791dda17548", - "app/Services/PeopleAccess.php": "5ed3feac3f48a4516bd611638e9720ae1096ee86ef6bc00ee6c48fbc67ccf4ea", - "app/Services/PeopleForms.php": "9ae5c1da667566cf08c4cc250cdc04a8ecba8a9c9af19b07a4138b1501aa4da8", - "app/Http/Controllers/PeopleHiringController.php": "7b4dd572ec3d67c112e02243d6db69d71fe5f17a8e64712738b553b114a4e275", - "database/migrations/2026_10_30_000031_create_people_process_access.php": "e899d6adc07122ec6d4ec7606a4714ae69ddc6db30479d4ad66f92767d8d2560", - "resources/js/pages/people/access.tsx": "399beb8193906491528954680eb8900d4aa5b5a7a8dd3af6557e6e0fd579780d", - "resources/js/pages/people/index.tsx": "a822ee13c1dc158e76396959e944d30e01b7385879050cd0d977c8972e98d6a8", - "resources/js/pages/people/show.tsx": "84a3910c9840f88c8c42465d2209834b5d82a94df860dfec31705b1a95623663", - "resources/js/lib/procurement-navigation.ts": "bcad7f21492355f8f66687d5dfb74fa105a2b575cf210dc1618f90ddea8e9251", - "tests/Feature/PeopleHiringTest.php": "611db1c7e744dae085b966c1c01583336a59ef8daa4087f8904ba14c5b9dcd61", - "tests/frontend/people-hiring.test.tsx": "67b9fe5af8f9b076b2b8ee8abc6b441b3a36bd8d4dd5bf04978eb5aa0f02a3a3" - } + "checked_at": "2026-10-30T12:12:17.828306+00:00", + "environment": "local evaluation 8005", + "scope": [ + "separate purchasing and people navigation and workflows", + "per-process named access with expiry revocation version and audit", + "administrative team setup without automatic candidate access", + "server-side financial interview and contract projections including selection copies", + "separate service and staff annex fields and classified requirements", + "typed reported observed and verified interview evidence", + "old records and rules preserved" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 638, + "passed": 636, + "assertions": 5556, + "duration_ms": 135871, + "skipped": 2 + }, + "latest_module_tests": { + "sqlite": 16, + "postgresql": 16, + "assertions": 286, + "disposable_database_removed": true + }, + "react_inertia_tests": 22, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "runtime_sha256_files": 18, + "menu_entries_by_role": 110, + "menu_groups_maximum": 6, + "http_proof": "menu-links.json", + "installation_proof": "people-access-install.json", + "business_accounts_or_grants_created_in_evaluation": false, + "domain_installed": false, + "visual_review": false, + "source_sha256": { + "app/Services/PeopleHiring.php": "ec0365c2ef2b1035468f16e8d4923b458889fc8438bbc6532de95791dda17548", + "app/Services/PeopleAccess.php": "5ed3feac3f48a4516bd611638e9720ae1096ee86ef6bc00ee6c48fbc67ccf4ea", + "app/Services/PeopleForms.php": "9ae5c1da667566cf08c4cc250cdc04a8ecba8a9c9af19b07a4138b1501aa4da8", + "app/Http/Controllers/PeopleHiringController.php": "7b4dd572ec3d67c112e02243d6db69d71fe5f17a8e64712738b553b114a4e275", + "database/migrations/2026_10_30_000031_create_people_process_access.php": "e899d6adc07122ec6d4ec7606a4714ae69ddc6db30479d4ad66f92767d8d2560", + "resources/js/pages/people/access.tsx": "399beb8193906491528954680eb8900d4aa5b5a7a8dd3af6557e6e0fd579780d", + "resources/js/pages/people/index.tsx": "a822ee13c1dc158e76396959e944d30e01b7385879050cd0d977c8972e98d6a8", + "resources/js/pages/people/show.tsx": "84a3910c9840f88c8c42465d2209834b5d82a94df860dfec31705b1a95623663", + "resources/js/lib/procurement-navigation.ts": "bcad7f21492355f8f66687d5dfb74fa105a2b575cf210dc1618f90ddea8e9251", + "tests/Feature/PeopleHiringTest.php": "611db1c7e744dae085b966c1c01583336a59ef8daa4087f8904ba14c5b9dcd61", + "tests/frontend/people-hiring.test.tsx": "67b9fe5af8f9b076b2b8ee8abc6b441b3a36bd8d4dd5bf04978eb5aa0f02a3a3" + } } diff --git a/docs/proofs/people-clarifications-pg.json b/docs/proofs/people-clarifications-pg.json index 7d9a551..ec0cb34 100644 --- a/docs/proofs/people-clarifications-pg.json +++ b/docs/proofs/people-clarifications-pg.json @@ -3,9 +3,7 @@ "database": "disposable PostgreSQL", "application_role_reused_without_privilege_change": true, "result": "passed", - "test_files": [ - "PeopleHiringTest" - ], + "test_files": ["PeopleHiringTest"], "original_evaluation_untouched": true, "database_removed": true } diff --git a/docs/proofs/people-clarifications.json b/docs/proofs/people-clarifications.json index fe45e9f..f6e3c56 100644 --- a/docs/proofs/people-clarifications.json +++ b/docs/proofs/people-clarifications.json @@ -1,60 +1,60 @@ { - "checked_at": "2026-10-30T12:56:09.626883+00:00", - "environment": "local evaluation 8005", - "scope": [ - "assigned clarification follow-up from immutable review", - "late responses and reassignment", - "independent review return or justified waiver", - "privacy limited to assigned question", - "personal operational tasks overdue alerts and printable report", - "deadline-only change preserves pending selection basis", - "substantive changes checked before pending approval", - "approved selection and original scores preserved" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 652, - "passed": 650, - "assertions": 6142, - "duration_ms": 103765, - "skipped": 2 - }, - "disposable_postgresql": { - "tool": "pest", - "result": "passed", - "tests": 30, - "passed": 30, - "assertions": 836, - "duration_ms": 21163 - }, - "react_inertia_tests": 25, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build": "passed", - "runtime_sha256_files": 18, - "http_proof": "menu-links.json", - "installation_proof": "people-clarifications-install.json", - "postgresql_proof": "people-clarifications-pg.json", - "new_accounts": 0, - "new_local_assignments": 0, - "outbound_messages": 0, - "domain_installed": false, - "visual_review": false, - "production_consulta_hotfix_published": false, - "source_sha256": { - "app/Services/PeopleClarifications.php": "f52dfd2a29eb7a8180a0449d7c4d9a4ffd15da1569d492f22c58c2c704d245b3", - "app/Services/PeopleHiring.php": "ba43edecf4eb09ec0fd34b0639faa3053e985ba65fd10d737a4ee7cc5cc105f2", - "app/Services/PeopleWorkdesk.php": "db901201362434d89743641306cfb1cee0b7bb70059ab87593fd6e00fef9bc21", - "app/Http/Controllers/PeopleHiringController.php": "11b01291e8378e7e330bcba9e28a68d0fbb707bd0200881a8b126c866c3793ff", - "database/migrations/2026_10_30_000032_create_people_clarifications.php": "a8cd29710192f1cb1f9046d4643a10e1aa4df1a463a2939e880082fe4b76da6d", - "resources/js/components/people-clarifications.tsx": "a378159cf383d8cfa78c2ffaaf151d311a3e2c6f58ae3d72f21ebe9f9852e95b", - "resources/js/pages/people/show.tsx": "e51622810a0c70436cc00eefadf51a9f37cf350098fa2d049f652988916d0d3c", - "resources/js/pages/people/index.tsx": "84a956018fd12a4cb8de9df875742a4d119d8975c70f1a88ca2b0b6275f034c5", - "tests/Feature/PeopleHiringTest.php": "47e15747b5fbf5a618289ae4d25efc9749166e889078c404f166ab366e615b5b", - "tests/frontend/people-hiring.test.tsx": "7709432faf232497ff3c057afd1d5b6516b7cb5a6d8d52d83a1a4cc0afb70561", - "routes/web.php": "c7255ae11660d009f9b25d263681500dedb0f1a700d19c2994312612d599286f" - } + "checked_at": "2026-10-30T12:56:09.626883+00:00", + "environment": "local evaluation 8005", + "scope": [ + "assigned clarification follow-up from immutable review", + "late responses and reassignment", + "independent review return or justified waiver", + "privacy limited to assigned question", + "personal operational tasks overdue alerts and printable report", + "deadline-only change preserves pending selection basis", + "substantive changes checked before pending approval", + "approved selection and original scores preserved" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 652, + "passed": 650, + "assertions": 6142, + "duration_ms": 103765, + "skipped": 2 + }, + "disposable_postgresql": { + "tool": "pest", + "result": "passed", + "tests": 30, + "passed": 30, + "assertions": 836, + "duration_ms": 21163 + }, + "react_inertia_tests": 25, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build": "passed", + "runtime_sha256_files": 18, + "http_proof": "menu-links.json", + "installation_proof": "people-clarifications-install.json", + "postgresql_proof": "people-clarifications-pg.json", + "new_accounts": 0, + "new_local_assignments": 0, + "outbound_messages": 0, + "domain_installed": false, + "visual_review": false, + "production_consulta_hotfix_published": false, + "source_sha256": { + "app/Services/PeopleClarifications.php": "f52dfd2a29eb7a8180a0449d7c4d9a4ffd15da1569d492f22c58c2c704d245b3", + "app/Services/PeopleHiring.php": "ba43edecf4eb09ec0fd34b0639faa3053e985ba65fd10d737a4ee7cc5cc105f2", + "app/Services/PeopleWorkdesk.php": "db901201362434d89743641306cfb1cee0b7bb70059ab87593fd6e00fef9bc21", + "app/Http/Controllers/PeopleHiringController.php": "11b01291e8378e7e330bcba9e28a68d0fbb707bd0200881a8b126c866c3793ff", + "database/migrations/2026_10_30_000032_create_people_clarifications.php": "a8cd29710192f1cb1f9046d4643a10e1aa4df1a463a2939e880082fe4b76da6d", + "resources/js/components/people-clarifications.tsx": "a378159cf383d8cfa78c2ffaaf151d311a3e2c6f58ae3d72f21ebe9f9852e95b", + "resources/js/pages/people/show.tsx": "e51622810a0c70436cc00eefadf51a9f37cf350098fa2d049f652988916d0d3c", + "resources/js/pages/people/index.tsx": "84a956018fd12a4cb8de9df875742a4d119d8975c70f1a88ca2b0b6275f034c5", + "tests/Feature/PeopleHiringTest.php": "47e15747b5fbf5a618289ae4d25efc9749166e889078c404f166ab366e615b5b", + "tests/frontend/people-hiring.test.tsx": "7709432faf232497ff3c057afd1d5b6516b7cb5a6d8d52d83a1a4cc0afb70561", + "routes/web.php": "c7255ae11660d009f9b25d263681500dedb0f1a700d19c2994312612d599286f" + } } diff --git a/docs/proofs/people-hiring-pg.json b/docs/proofs/people-hiring-pg.json index 95bfb89..c5013df 100644 --- a/docs/proofs/people-hiring-pg.json +++ b/docs/proofs/people-hiring-pg.json @@ -3,9 +3,7 @@ "database": "disposable PostgreSQL", "application_role_reused_without_privilege_change": true, "result": "passed", - "test_files": [ - "PeopleHiringTest" - ], + "test_files": ["PeopleHiringTest"], "original_evaluation_untouched": true, "database_removed": true } diff --git a/docs/proofs/people-hiring.json b/docs/proofs/people-hiring.json index c98d56f..a41067b 100644 --- a/docs/proofs/people-hiring.json +++ b/docs/proofs/people-hiring.json @@ -1,59 +1,59 @@ { - "checked_at": "2026-10-30T11:46:07.311681+00:00", - "environment": "local evaluation 8005", - "scope": [ - "individual service provider hiring", - "staff recruitment", - "process-specific criteria weights and minimum independent reviews", - "independent opening evaluation and final decision", - "candidate records and evidence", - "reasoned selection including ties and returns", - "unsigned internal contract draft and printable process report", - "separate configurable preparation and review permissions per kind" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 633, - "passed": 631, - "assertions": 5438, - "duration_ms": 178754, - "skipped": 2 - }, - "latest_module_tests": { - "tests": 11, - "assertions": 133, - "sqlite": "passed", - "disposable_postgresql": "passed", - "database_removed": true - }, - "react_inertia_tests": 21, - "phpstan_errors": 0, - "typescript": "passed", - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "runtime_sha256_files": 18, - "installation_proof": "people-hiring-install.json", - "menu_proof": "menu-links.json", - "menu_contract_entries_by_role": 108, - "company_accounts_or_grants_created": false, - "evaluation_tables_initially_empty": true, - "external_messages_sent": false, - "signed_contracts_created": false, - "domain_installed": false, - "visual_review": false, - "source_sha256": { - "app/Services/PeopleHiring.php": "a7e50e55034ce4085d35184f04d8549741c7fb29e4585dc334dd3bf9525a3d09", - "app/Http/Controllers/PeopleHiringController.php": "4e07d58c9f474eec85f5854e9e442978f198888994c27be376f100a0d4e2263c", - "app/Models/PeopleProcess.php": "10b1ed29426ab6988d01f1ed43b77f49b689520197c7a9023b41338fe60e7e4b", - "app/Services/OrganizationAccess.php": "84f3cddc43b1446f12390d9d3ffcf504f4a1f8909d88612ee30a9fdcb1bd7137", - "database/migrations/2026_10_30_000030_create_people_hiring.php": "c1f69354ec82ec5b3aabd0eff85c88c4a8a9eb3cb77c16e9a942d47eb1149c1b", - "resources/js/pages/people/index.tsx": "8d65c71d2c5862d640f14a37e7aea997bdfa6aacd7d128568532cbf5821295fd", - "resources/js/pages/people/show.tsx": "ffa77f0bb5e72877f7aab6fb30ae129cd7dd7c72911c0ef156a958f821451dc0", - "resources/js/lib/people-hiring.ts": "65efd515d39541c7e875127c91731bfc1a379f8db58fcd34e0f39e1a8d75f807", - "resources/js/lib/procurement-navigation.ts": "9578b8ac69b8b8a8e6cb0f7134e3cac55e19c1e973ecb21015b592fc8b804318", - "tests/Feature/PeopleHiringTest.php": "f1cceadb0ddf7faaf901dd2283953812dad5fb9ebc4f1f3c4f57e546f4591abc", - "tests/frontend/people-hiring.test.tsx": "5548b79b353bc36451b42888f7f7727f2524d46df677e106a60968c8e6039dc9" - } + "checked_at": "2026-10-30T11:46:07.311681+00:00", + "environment": "local evaluation 8005", + "scope": [ + "individual service provider hiring", + "staff recruitment", + "process-specific criteria weights and minimum independent reviews", + "independent opening evaluation and final decision", + "candidate records and evidence", + "reasoned selection including ties and returns", + "unsigned internal contract draft and printable process report", + "separate configurable preparation and review permissions per kind" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 633, + "passed": 631, + "assertions": 5438, + "duration_ms": 178754, + "skipped": 2 + }, + "latest_module_tests": { + "tests": 11, + "assertions": 133, + "sqlite": "passed", + "disposable_postgresql": "passed", + "database_removed": true + }, + "react_inertia_tests": 21, + "phpstan_errors": 0, + "typescript": "passed", + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "runtime_sha256_files": 18, + "installation_proof": "people-hiring-install.json", + "menu_proof": "menu-links.json", + "menu_contract_entries_by_role": 108, + "company_accounts_or_grants_created": false, + "evaluation_tables_initially_empty": true, + "external_messages_sent": false, + "signed_contracts_created": false, + "domain_installed": false, + "visual_review": false, + "source_sha256": { + "app/Services/PeopleHiring.php": "a7e50e55034ce4085d35184f04d8549741c7fb29e4585dc334dd3bf9525a3d09", + "app/Http/Controllers/PeopleHiringController.php": "4e07d58c9f474eec85f5854e9e442978f198888994c27be376f100a0d4e2263c", + "app/Models/PeopleProcess.php": "10b1ed29426ab6988d01f1ed43b77f49b689520197c7a9023b41338fe60e7e4b", + "app/Services/OrganizationAccess.php": "84f3cddc43b1446f12390d9d3ffcf504f4a1f8909d88612ee30a9fdcb1bd7137", + "database/migrations/2026_10_30_000030_create_people_hiring.php": "c1f69354ec82ec5b3aabd0eff85c88c4a8a9eb3cb77c16e9a942d47eb1149c1b", + "resources/js/pages/people/index.tsx": "8d65c71d2c5862d640f14a37e7aea997bdfa6aacd7d128568532cbf5821295fd", + "resources/js/pages/people/show.tsx": "ffa77f0bb5e72877f7aab6fb30ae129cd7dd7c72911c0ef156a958f821451dc0", + "resources/js/lib/people-hiring.ts": "65efd515d39541c7e875127c91731bfc1a379f8db58fcd34e0f39e1a8d75f807", + "resources/js/lib/procurement-navigation.ts": "9578b8ac69b8b8a8e6cb0f7134e3cac55e19c1e973ecb21015b592fc8b804318", + "tests/Feature/PeopleHiringTest.php": "f1cceadb0ddf7faaf901dd2283953812dad5fb9ebc4f1f3c4f57e546f4591abc", + "tests/frontend/people-hiring.test.tsx": "5548b79b353bc36451b42888f7f7727f2524d46df677e106a60968c8e6039dc9" + } } diff --git a/docs/proofs/people-intelligence.json b/docs/proofs/people-intelligence.json index 916ff06..ee3915d 100644 --- a/docs/proofs/people-intelligence.json +++ b/docs/proofs/people-intelligence.json @@ -1,45 +1,45 @@ { - "checked_at": "2026-10-30T13:01:28.499029+00:00", - "environment": "local evaluation 8005", - "scope": [ - "authorised filtered operational reading", - "calendar delays and oldest five source links", - "separate overdue occurrence and process counts", - "personal task distribution and independent approval counts", - "explicit missing deadlines and deterministic method", - "documented AI ML product roadmap" - ], - "method": "operational_facts_v1", - "module_tests": { - "tool": "pest", - "result": "passed", - "tests": 32, - "passed": 32, - "assertions": 856, - "duration_ms": 10518 - }, - "react_inertia_tests": 26, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "accepted_full_suite_reused": "people-clarifications.json", - "http_proof": "menu-links.json", - "new_migrations": 0, - "new_data_writes": 0, - "external_AI_calls": 0, - "trained_ml_model": false, - "AI_provider_configured": false, - "domain_installed": false, - "visual_review": false, - "source_sha256": { - "app/Services/PeopleOperationalInsights.php": "fab92b0b0c58fe608a7e030cbfaa2e36842cf391a609fd05bb6f4b443be1ede6", - "app/Http/Controllers/PeopleHiringController.php": "5cf48435c3ba22505544dbaecd368d7abf27bb97edf55158308507db4c36f767", - "resources/js/components/people-operational-insights.tsx": "fce6a71ecc15979749437945639aed6b4ed3bcbfedcee82d50d95a9469ca4300", - "resources/js/pages/people/index.tsx": "bf0753393b9d5cc851be7dccadc27fb3421c0bc1a5215b6af779e1a114034bb9", - "tests/Feature/PeopleHiringTest.php": "01dacd9895e10391732f65372a7a8872576527e4d13b8a4ae8f612c2485fc958", - "tests/frontend/people-hiring.test.tsx": "b1fce7ede76258ee62a686e487e2bcce666b43b9595619d4da1a73d6c9d42d71", - "docs/inteligencia-sgc.md": "51e5ecf9fa8d54a54272fa263b4202f69873145572a9ea7892a5603c37c334cd" - } + "checked_at": "2026-10-30T13:01:28.499029+00:00", + "environment": "local evaluation 8005", + "scope": [ + "authorised filtered operational reading", + "calendar delays and oldest five source links", + "separate overdue occurrence and process counts", + "personal task distribution and independent approval counts", + "explicit missing deadlines and deterministic method", + "documented AI ML product roadmap" + ], + "method": "operational_facts_v1", + "module_tests": { + "tool": "pest", + "result": "passed", + "tests": 32, + "passed": 32, + "assertions": 856, + "duration_ms": 10518 + }, + "react_inertia_tests": 26, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "accepted_full_suite_reused": "people-clarifications.json", + "http_proof": "menu-links.json", + "new_migrations": 0, + "new_data_writes": 0, + "external_AI_calls": 0, + "trained_ml_model": false, + "AI_provider_configured": false, + "domain_installed": false, + "visual_review": false, + "source_sha256": { + "app/Services/PeopleOperationalInsights.php": "fab92b0b0c58fe608a7e030cbfaa2e36842cf391a609fd05bb6f4b443be1ede6", + "app/Http/Controllers/PeopleHiringController.php": "5cf48435c3ba22505544dbaecd368d7abf27bb97edf55158308507db4c36f767", + "resources/js/components/people-operational-insights.tsx": "fce6a71ecc15979749437945639aed6b4ed3bcbfedcee82d50d95a9469ca4300", + "resources/js/pages/people/index.tsx": "bf0753393b9d5cc851be7dccadc27fb3421c0bc1a5215b6af779e1a114034bb9", + "tests/Feature/PeopleHiringTest.php": "01dacd9895e10391732f65372a7a8872576527e4d13b8a4ae8f612c2485fc958", + "tests/frontend/people-hiring.test.tsx": "b1fce7ede76258ee62a686e487e2bcce666b43b9595619d4da1a73d6c9d42d71", + "docs/inteligencia-sgc.md": "51e5ecf9fa8d54a54272fa263b4202f69873145572a9ea7892a5603c37c334cd" + } } diff --git a/docs/proofs/people-registry-pg.json b/docs/proofs/people-registry-pg.json index 9da512d..d472ebf 100644 --- a/docs/proofs/people-registry-pg.json +++ b/docs/proofs/people-registry-pg.json @@ -3,10 +3,7 @@ "database": "disposable PostgreSQL", "application_role_reused_without_privilege_change": true, "result": "passed", - "test_files": [ - "PeopleHiringTest", - "PeopleRegistryTest" - ], + "test_files": ["PeopleHiringTest", "PeopleRegistryTest"], "original_evaluation_untouched": true, "database_removed": true } diff --git a/docs/proofs/people-registry.json b/docs/proofs/people-registry.json index d738b69..9475db7 100644 --- a/docs/proofs/people-registry.json +++ b/docs/proofs/people-registry.json @@ -1,77 +1,77 @@ { - "checked_at": "2026-10-30T16:08:01.496023+00:00", - "environment": "local evaluation 8005", - "scope": [ - "reusable person identity and profile registry", - "private creator scope and explicit shared read/manage permissions", - "save first profile during reception or select authorised existing record", - "immutable source snapshot per candidature and historical source version display", - "stale or archived registry selection rejected", - "same person unique within process and names never merged automatically", - "atomic registry candidature process and audit rollback", - "cross-company application/registry composite foreign key", - "legacy applications preserved unlinked" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 698, - "passed": 696, - "assertions": 6739, - "duration_ms": 103510, - "skipped": 2 - }, - "module_tests": { - "tool": "pest", - "result": "passed", - "tests": 43, - "passed": 43, - "assertions": 1124, - "duration_ms": 7925 - }, - "disposable_postgresql": { - "tool": "pest", - "result": "passed", - "tests": 43, - "passed": 43, - "assertions": 1124, - "duration_ms": 24156 - }, - "postgresql_proof": "people-registry-pg.json", - "installation_proof": "people-registry-install.json", - "react_inertia_tests": 44, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "menu_code_proof": "menu-code-contract.json", - "menu_entries_across_six_roles": 111, - "http_proof": "menu-links.json", - "runtime_sha256_files": 18, - "legacy_records_auto_linked": false, - "people_created_in_evaluation": 0, - "accounts_or_grants_changed": false, - "external_AI_calls": 0, - "global_enter_once_requirement_complete": false, - "remaining_coverage_matrix": "../reutilizacao-dados.md", - "visual_review": false, - "domain_installed": false, - "source_sha256": { - "database/migrations/2026_10_30_000034_create_people_registry.php": "f5869f09cad06b2ded831bce66da4b1f923c001acd56ac8dbfda53d3d79bcc8c", - "app/Services/PeopleRegistry.php": "cbef69cbc127b61731bf44f246201a77f1c78b2447e1d11601635260e066d89c", - "app/Services/PeopleHiring.php": "6b6cf58a022fe1fe9da2f40177557735d0e4112c946fde7e0c9b5eae32b78514", - "app/Services/OrganizationAccess.php": "76809e2f24003a2a1343cae317f47b972544adb231882ed56c6c8484dbaa4ea1", - "app/Http/Controllers/PeopleRegistryController.php": "e702275161464a9835c02f817ebf5215a1c6b3f4c875a77d717fda7c490b0db0", - "app/Http/Controllers/PeopleHiringController.php": "f0d82d3d8bff9fe46abc93bfb4faacb6e6a8d49079c6ca8499fbe479db68aa18", - "resources/js/pages/people/registry.tsx": "3b1249c3425ac1173f50031db99dc979ea875d5ea33b886dc84d003ba1011e92", - "resources/js/components/people-registry-choice.tsx": "9a2a61518b54cbbc30e45126f8fbae76663f0ac5d4c1b7fc010c3c141df00102", - "resources/js/pages/people/show.tsx": "9aaf142675ae73b2a9857a56d91121073bb1180bf7b01fec8fe657f0fbc205e1", - "resources/js/lib/procurement-navigation.ts": "242ebdea74d4d26eca32b716f88f7c9608bca590abefee56ab282010820afe2e", - "routes/web.php": "7097d8299c17ad3912e3fe3d35370d63f38365410325319eb4c571ebf5cc6fb3", - "tests/Feature/PeopleRegistryTest.php": "7b3cefce0fcf25aa910d6ffd138af00ee506d693dbb673e334a70298054a480b", - "tests/frontend/people-registry.test.tsx": "02e6915167cfdd66121ef3768fd55dd95b46bf169fda791e6e68eaf7f974ef21", - "scripts/menu-code-check.mjs": "40063716dee602fd57edd82fed90cc4c69cd315174065f067cfb377877669d9f", - "docs/reutilizacao-dados.md": "937620871fa9504b889e81b727468156a5f2cdeb17408e76389478bd10db9405" - } + "checked_at": "2026-10-30T16:08:01.496023+00:00", + "environment": "local evaluation 8005", + "scope": [ + "reusable person identity and profile registry", + "private creator scope and explicit shared read/manage permissions", + "save first profile during reception or select authorised existing record", + "immutable source snapshot per candidature and historical source version display", + "stale or archived registry selection rejected", + "same person unique within process and names never merged automatically", + "atomic registry candidature process and audit rollback", + "cross-company application/registry composite foreign key", + "legacy applications preserved unlinked" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 698, + "passed": 696, + "assertions": 6739, + "duration_ms": 103510, + "skipped": 2 + }, + "module_tests": { + "tool": "pest", + "result": "passed", + "tests": 43, + "passed": 43, + "assertions": 1124, + "duration_ms": 7925 + }, + "disposable_postgresql": { + "tool": "pest", + "result": "passed", + "tests": 43, + "passed": 43, + "assertions": 1124, + "duration_ms": 24156 + }, + "postgresql_proof": "people-registry-pg.json", + "installation_proof": "people-registry-install.json", + "react_inertia_tests": 44, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "menu_code_proof": "menu-code-contract.json", + "menu_entries_across_six_roles": 111, + "http_proof": "menu-links.json", + "runtime_sha256_files": 18, + "legacy_records_auto_linked": false, + "people_created_in_evaluation": 0, + "accounts_or_grants_changed": false, + "external_AI_calls": 0, + "global_enter_once_requirement_complete": false, + "remaining_coverage_matrix": "../reutilizacao-dados.md", + "visual_review": false, + "domain_installed": false, + "source_sha256": { + "database/migrations/2026_10_30_000034_create_people_registry.php": "f5869f09cad06b2ded831bce66da4b1f923c001acd56ac8dbfda53d3d79bcc8c", + "app/Services/PeopleRegistry.php": "cbef69cbc127b61731bf44f246201a77f1c78b2447e1d11601635260e066d89c", + "app/Services/PeopleHiring.php": "6b6cf58a022fe1fe9da2f40177557735d0e4112c946fde7e0c9b5eae32b78514", + "app/Services/OrganizationAccess.php": "76809e2f24003a2a1343cae317f47b972544adb231882ed56c6c8484dbaa4ea1", + "app/Http/Controllers/PeopleRegistryController.php": "e702275161464a9835c02f817ebf5215a1c6b3f4c875a77d717fda7c490b0db0", + "app/Http/Controllers/PeopleHiringController.php": "f0d82d3d8bff9fe46abc93bfb4faacb6e6a8d49079c6ca8499fbe479db68aa18", + "resources/js/pages/people/registry.tsx": "3b1249c3425ac1173f50031db99dc979ea875d5ea33b886dc84d003ba1011e92", + "resources/js/components/people-registry-choice.tsx": "9a2a61518b54cbbc30e45126f8fbae76663f0ac5d4c1b7fc010c3c141df00102", + "resources/js/pages/people/show.tsx": "9aaf142675ae73b2a9857a56d91121073bb1180bf7b01fec8fe657f0fbc205e1", + "resources/js/lib/procurement-navigation.ts": "242ebdea74d4d26eca32b716f88f7c9608bca590abefee56ab282010820afe2e", + "routes/web.php": "7097d8299c17ad3912e3fe3d35370d63f38365410325319eb4c571ebf5cc6fb3", + "tests/Feature/PeopleRegistryTest.php": "7b3cefce0fcf25aa910d6ffd138af00ee506d693dbb673e334a70298054a480b", + "tests/frontend/people-registry.test.tsx": "02e6915167cfdd66121ef3768fd55dd95b46bf169fda791e6e68eaf7f974ef21", + "scripts/menu-code-check.mjs": "40063716dee602fd57edd82fed90cc4c69cd315174065f067cfb377877669d9f", + "docs/reutilizacao-dados.md": "937620871fa9504b889e81b727468156a5f2cdeb17408e76389478bd10db9405" + } } diff --git a/docs/proofs/people-workdesk-pg.json b/docs/proofs/people-workdesk-pg.json index f0f0527..a4f560e 100644 --- a/docs/proofs/people-workdesk-pg.json +++ b/docs/proofs/people-workdesk-pg.json @@ -3,9 +3,7 @@ "database": "disposable PostgreSQL", "application_role_reused_without_privilege_change": true, "result": "passed", - "test_files": [ - "PeopleHiringTest" - ], + "test_files": ["PeopleHiringTest"], "original_evaluation_untouched": true, "database_removed": true } diff --git a/docs/proofs/people-workdesk.json b/docs/proofs/people-workdesk.json index 91ab32e..b1b318d 100644 --- a/docs/proofs/people-workdesk.json +++ b/docs/proofs/people-workdesk.json @@ -1,52 +1,52 @@ { - "checked_at": "2026-10-30T12:28:22.580872+00:00", - "environment": "local evaluation 8005", - "scope": [ - "personal operational task queue", - "separate independent formal approval queue", - "original process links and candidate selection hint", - "permission scoped counts filters and reception deadline alerts", - "complete filtered totals beyond pagination", - "minimal list projection excluding rules financial data interviews selection and contract", - "PostgreSQL repeatable read read-only normal index request" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 643, - "passed": 641, - "assertions": 5859, - "duration_ms": 135280, - "skipped": 2 - }, - "latest_module_tests": { - "tests": 21, - "assertions": 562, - "sqlite": "passed", - "disposable_postgresql": "passed", - "database_removed": true - }, - "react_inertia_tests": 23, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "runtime_sha256_files": 18, - "http_proof": "menu-links.json", - "new_tables": 0, - "migrations_applied": false, - "new_assignments_created": false, - "background_decisions_created": false, - "domain_installed": false, - "visual_review": false, - "source_sha256": { - "app/Services/PeopleWorkdesk.php": "b840eb70a94cbfc3c02869602097a15cfd9fed0333d4d871dd5240ed446b5a8c", - "app/Services/PeopleHiring.php": "c13a0c029496f9e0ab988265501bacfbf5562d70a7176afac2836ad28d4aecd8", - "app/Http/Controllers/PeopleHiringController.php": "a207f268ed65c6da6c75d325142f0df81316b2e1242c3e9745c0ab4b116cf43e", - "resources/js/pages/people/index.tsx": "ed95ed6a64cf8532ed101cc597423c240e699b243083acc22892c65a2875cac2", - "resources/js/pages/people/show.tsx": "67e8d2f3bcd9e85ba52a6f29e285f5572764e65c591a7167f1d4f7f29629a5ab", - "tests/Feature/PeopleHiringTest.php": "82a3a2b2351b233a4a40c5f8fb2babb247d80fa6454974fe61bc6749ad444567", - "tests/frontend/people-hiring.test.tsx": "5f7bfbfa873a66bc6681c746e196bc89a769e929d67293ab8f5465ee21f6dde4" - } + "checked_at": "2026-10-30T12:28:22.580872+00:00", + "environment": "local evaluation 8005", + "scope": [ + "personal operational task queue", + "separate independent formal approval queue", + "original process links and candidate selection hint", + "permission scoped counts filters and reception deadline alerts", + "complete filtered totals beyond pagination", + "minimal list projection excluding rules financial data interviews selection and contract", + "PostgreSQL repeatable read read-only normal index request" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 643, + "passed": 641, + "assertions": 5859, + "duration_ms": 135280, + "skipped": 2 + }, + "latest_module_tests": { + "tests": 21, + "assertions": 562, + "sqlite": "passed", + "disposable_postgresql": "passed", + "database_removed": true + }, + "react_inertia_tests": 23, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "runtime_sha256_files": 18, + "http_proof": "menu-links.json", + "new_tables": 0, + "migrations_applied": false, + "new_assignments_created": false, + "background_decisions_created": false, + "domain_installed": false, + "visual_review": false, + "source_sha256": { + "app/Services/PeopleWorkdesk.php": "b840eb70a94cbfc3c02869602097a15cfd9fed0333d4d871dd5240ed446b5a8c", + "app/Services/PeopleHiring.php": "c13a0c029496f9e0ab988265501bacfbf5562d70a7176afac2836ad28d4aecd8", + "app/Http/Controllers/PeopleHiringController.php": "a207f268ed65c6da6c75d325142f0df81316b2e1242c3e9745c0ab4b116cf43e", + "resources/js/pages/people/index.tsx": "ed95ed6a64cf8532ed101cc597423c240e699b243083acc22892c65a2875cac2", + "resources/js/pages/people/show.tsx": "67e8d2f3bcd9e85ba52a6f29e285f5572764e65c591a7167f1d4f7f29629a5ab", + "tests/Feature/PeopleHiringTest.php": "82a3a2b2351b233a4a40c5f8fb2babb247d80fa6454974fe61bc6749ad444567", + "tests/frontend/people-hiring.test.tsx": "5f7bfbfa873a66bc6681c746e196bc89a769e929d67293ab8f5465ee21f6dde4" + } } diff --git a/docs/proofs/procurement-intelligence.json b/docs/proofs/procurement-intelligence.json index 2f4a209..aed0167 100644 --- a/docs/proofs/procurement-intelligence.json +++ b/docs/proofs/procurement-intelligence.json @@ -1,56 +1,56 @@ { - "checked_at": "2026-10-30T14:40:19.164501+00:00", - "environment": "local evaluation 8005", - "method": "procurement_facts_v1", - "scope": [ - "authorised filtered report across all pages", - "pending submission calendar age and unknown age", - "need date distinguished from supplier delivery deadline", - "approved requests without registered quotations or visible orders", - "source links and shared indicator definitions" - ], - "module_tests": { - "tool": "pest", - "result": "passed", - "tests": 9, - "passed": 9, - "assertions": 197, - "duration_ms": 5247 - }, - "postgresql_integration": { - "tool": "phpunit", - "result": "passed", - "tests": 1, - "passed": 1, - "assertions": 36, - "duration_ms": 2364 - }, - "postgresql_note": "Standalone PHPUnit scenario without RefreshDatabase outer transaction; report transaction guard preserved. Disposable database removed.", - "postgresql_proof": "procurement-intelligence-pg.json", - "react_inertia_tests": 28, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "http_proof": "menu-links.json", - "prior_full_suite_reused": "people-clarifications.json", - "migrations_installed": false, - "business_data_changed": false, - "csv_contract_changed": false, - "domain_installed": false, - "visual_review": false, - "ml_model_active": false, - "external_AI_calls": 0, - "source_sha256": { - "app/Services/ProcurementOperationalInsights.php": "ddd1eab9214fd8bd029b6a3de2a6999af703d32eeed639419b93527cd9a92930", - "app/Http/Controllers/ProcurementReportController.php": "96c33da41d00de5a6263ce1cb474e8ded64a28a1bdc9688659dbd82f6f37f992", - "app/Models/Requisition.php": "e915153723afa5dc3e7c0642502800cd3b7d9df3e3109809adcd43c122e803d6", - "resources/js/components/procurement-operational-insights.tsx": "beed70921e0287830aa3ae9126a5ef6b7f4a634c986a5e4a5f5be8a09b3e96fa", - "resources/js/pages/reports/procurement.tsx": "11af82a74fc516bf5e1c47741b7c081d0b63c2196c6ac148e45df2da29f03f7a", - "tests/Feature/ProcurementReportsTest.php": "e51ad3f19533c0b0e974ccd2e8138755eeadf0d65f81ba7c2a3eb434c1f9fb9d", - "tests/frontend/procurement-insights.test.tsx": "182639a220ea4b8bb09195a9623b03f17cc32a588a4c8619648595bc592a89f4", - "docs/indicadores-sgc.md": "83a3c486e77622da635574065d5f4147f60a6558b009fb1ab1ad43944c433c11", - "docs/inteligencia-sgc.md": "360e21b342c26d31e543ca8ce5dbbe0d7e155f57e0be8d4b214599d4c9f4ddac" - } + "checked_at": "2026-10-30T14:40:19.164501+00:00", + "environment": "local evaluation 8005", + "method": "procurement_facts_v1", + "scope": [ + "authorised filtered report across all pages", + "pending submission calendar age and unknown age", + "need date distinguished from supplier delivery deadline", + "approved requests without registered quotations or visible orders", + "source links and shared indicator definitions" + ], + "module_tests": { + "tool": "pest", + "result": "passed", + "tests": 9, + "passed": 9, + "assertions": 197, + "duration_ms": 5247 + }, + "postgresql_integration": { + "tool": "phpunit", + "result": "passed", + "tests": 1, + "passed": 1, + "assertions": 36, + "duration_ms": 2364 + }, + "postgresql_note": "Standalone PHPUnit scenario without RefreshDatabase outer transaction; report transaction guard preserved. Disposable database removed.", + "postgresql_proof": "procurement-intelligence-pg.json", + "react_inertia_tests": 28, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "http_proof": "menu-links.json", + "prior_full_suite_reused": "people-clarifications.json", + "migrations_installed": false, + "business_data_changed": false, + "csv_contract_changed": false, + "domain_installed": false, + "visual_review": false, + "ml_model_active": false, + "external_AI_calls": 0, + "source_sha256": { + "app/Services/ProcurementOperationalInsights.php": "ddd1eab9214fd8bd029b6a3de2a6999af703d32eeed639419b93527cd9a92930", + "app/Http/Controllers/ProcurementReportController.php": "96c33da41d00de5a6263ce1cb474e8ded64a28a1bdc9688659dbd82f6f37f992", + "app/Models/Requisition.php": "e915153723afa5dc3e7c0642502800cd3b7d9df3e3109809adcd43c122e803d6", + "resources/js/components/procurement-operational-insights.tsx": "beed70921e0287830aa3ae9126a5ef6b7f4a634c986a5e4a5f5be8a09b3e96fa", + "resources/js/pages/reports/procurement.tsx": "11af82a74fc516bf5e1c47741b7c081d0b63c2196c6ac148e45df2da29f03f7a", + "tests/Feature/ProcurementReportsTest.php": "e51ad3f19533c0b0e974ccd2e8138755eeadf0d65f81ba7c2a3eb434c1f9fb9d", + "tests/frontend/procurement-insights.test.tsx": "182639a220ea4b8bb09195a9623b03f17cc32a588a4c8619648595bc592a89f4", + "docs/indicadores-sgc.md": "83a3c486e77622da635574065d5f4147f60a6558b009fb1ab1ad43944c433c11", + "docs/inteligencia-sgc.md": "360e21b342c26d31e543ca8ce5dbbe0d7e155f57e0be8d4b214599d4c9f4ddac" + } } diff --git a/docs/proofs/procurement-reports.json b/docs/proofs/procurement-reports.json index 4472b3b..48ad109 100644 --- a/docs/proofs/procurement-reports.json +++ b/docs/proofs/procurement-reports.json @@ -1,50 +1,50 @@ { - "date": "2026-10-30", - "base_commit": "0235c7609ed52345e91ae1a6b268e45e1eb991af", - "scope": "Menu routing inventory, central filtered procurement reports/CSV and existing individual report extended to receipt/invoice/external-payment records.", - "checks": { - "feature_passed": 14, - "assertions": 223, - "new_cases": 8, - "existing_report_regressions": 6, - "export_fixture_records": 207, - "menu_entries_across_roles": 102, - "roles": 6, - "types": "passed", - "lint": "passed", - "format": "passed", - "pint": "passed", - "phpstan": "passed after correcting the documented date cast type", - "build": "passed", - "new_module_http": 200, - "evaluation_entry_http": 200, - "runtime_manifest_files": 18 - }, - "source_sha256": { - "app/Http/Controllers/ProcurementReportController.php": "5161063f8f9684595c83300f22e6516e03700917e3b578651dee7254ee5f6a55", - "app/Services/ProcurementReviewReport.php": "1d5a41b59c471ad1db5e7f39eb15ac4b080239968341ccdf9a78ce17a301144c", - "app/Models/GoodsReceipt.php": "ec9b86ca625a8d4d8972ba1d91636bf37475f680f2212faa1e31c44709660a5a", - "routes/web.php": "1014ea42f0544428df49304c16cc55fb0632188ac0ad1940ba6a637b9f228be0", - "resources/js/lib/procurement-navigation.ts": "f250199564cd56e73ff5d5851a19dcbbe41df6da7b5c2cb9024c0965b8e087dc", - "resources/js/pages/reports/procurement.tsx": "a4ec4c51a8b7b8012852f1ad1d36ac931fec25c41a383c10a9449fddc3bd23d5", - "resources/js/pages/purchases/review-report.tsx": "8a5a02d99b5dd5d6f50a41e6e76711b15e578fd09dc039e2b6defc64d20abe04", - "tests/Feature/ProcurementReportsTest.php": "fc88ceef66d419ef72e9231e8273da20f2e1f400ad9610ad5ff85cadeb2259b2", - "scripts/menu-code-check.mjs": "8480ec5b1f3fd26aa7ff7cbc52c304a632b11e0eaa5a4cacadab0e119ceac236" - }, - "menu_proof": "docs/proofs/menu-code-contract.json", - "build_log_local": "storage/logs/development-reports-build.log", - "build_log_sha256": "2709a9c383c3110469d6aa08a1efc8b821e24c3b7b8f9a5d3552e403ea9f5ad6", - "preservation": { - "migrations": 0, - "active_business_writes": 0, - "new_accounts_or_grants": 0, - "balance_or_tax_recalculation": false, - "remote_deployment": false - }, - "limits": [ - "Visual and manual printing not executed.", - "PostgreSQL snapshot clause implemented using the existing report pattern; new tests used isolated SQLite, not a PostgreSQL concurrency proof.", - "Supplier evaluations remain an interface proposal pending its operational implementation.", - "Not a consolidated debt/bank/accounting report; common settlements keep their own history." - ] + "date": "2026-10-30", + "base_commit": "0235c7609ed52345e91ae1a6b268e45e1eb991af", + "scope": "Menu routing inventory, central filtered procurement reports/CSV and existing individual report extended to receipt/invoice/external-payment records.", + "checks": { + "feature_passed": 14, + "assertions": 223, + "new_cases": 8, + "existing_report_regressions": 6, + "export_fixture_records": 207, + "menu_entries_across_roles": 102, + "roles": 6, + "types": "passed", + "lint": "passed", + "format": "passed", + "pint": "passed", + "phpstan": "passed after correcting the documented date cast type", + "build": "passed", + "new_module_http": 200, + "evaluation_entry_http": 200, + "runtime_manifest_files": 18 + }, + "source_sha256": { + "app/Http/Controllers/ProcurementReportController.php": "5161063f8f9684595c83300f22e6516e03700917e3b578651dee7254ee5f6a55", + "app/Services/ProcurementReviewReport.php": "1d5a41b59c471ad1db5e7f39eb15ac4b080239968341ccdf9a78ce17a301144c", + "app/Models/GoodsReceipt.php": "ec9b86ca625a8d4d8972ba1d91636bf37475f680f2212faa1e31c44709660a5a", + "routes/web.php": "1014ea42f0544428df49304c16cc55fb0632188ac0ad1940ba6a637b9f228be0", + "resources/js/lib/procurement-navigation.ts": "f250199564cd56e73ff5d5851a19dcbbe41df6da7b5c2cb9024c0965b8e087dc", + "resources/js/pages/reports/procurement.tsx": "a4ec4c51a8b7b8012852f1ad1d36ac931fec25c41a383c10a9449fddc3bd23d5", + "resources/js/pages/purchases/review-report.tsx": "8a5a02d99b5dd5d6f50a41e6e76711b15e578fd09dc039e2b6defc64d20abe04", + "tests/Feature/ProcurementReportsTest.php": "fc88ceef66d419ef72e9231e8273da20f2e1f400ad9610ad5ff85cadeb2259b2", + "scripts/menu-code-check.mjs": "8480ec5b1f3fd26aa7ff7cbc52c304a632b11e0eaa5a4cacadab0e119ceac236" + }, + "menu_proof": "docs/proofs/menu-code-contract.json", + "build_log_local": "storage/logs/development-reports-build.log", + "build_log_sha256": "2709a9c383c3110469d6aa08a1efc8b821e24c3b7b8f9a5d3552e403ea9f5ad6", + "preservation": { + "migrations": 0, + "active_business_writes": 0, + "new_accounts_or_grants": 0, + "balance_or_tax_recalculation": false, + "remote_deployment": false + }, + "limits": [ + "Visual and manual printing not executed.", + "PostgreSQL snapshot clause implemented using the existing report pattern; new tests used isolated SQLite, not a PostgreSQL concurrency proof.", + "Supplier evaluations remain an interface proposal pending its operational implementation.", + "Not a consolidated debt/bank/accounting report; common settlements keep their own history." + ] } diff --git a/docs/proofs/requisition-catalogue-pg.json b/docs/proofs/requisition-catalogue-pg.json index 35bd478..8a4e277 100644 --- a/docs/proofs/requisition-catalogue-pg.json +++ b/docs/proofs/requisition-catalogue-pg.json @@ -3,10 +3,7 @@ "database": "disposable PostgreSQL", "application_role_reused_without_privilege_change": true, "result": "passed", - "test_files": [ - "RequisitionCatalogueTest", - "ReceiptStockTest" - ], + "test_files": ["RequisitionCatalogueTest", "ReceiptStockTest"], "original_evaluation_untouched": true, "database_removed": true } diff --git a/docs/proofs/requisition-catalogue.json b/docs/proofs/requisition-catalogue.json index 70b1718..d07dee3 100644 --- a/docs/proofs/requisition-catalogue.json +++ b/docs/proofs/requisition-catalogue.json @@ -1,52 +1,52 @@ { - "checked_at": "2026-10-30T16:26:29.650769+00:00", - "scope": [ - "published company article selection in requisition", - "server-authoritative descriptors", - "frozen source and version through order", - "receipt stock identification and rejection of other stock", - "legacy rows preserved without automatic linking" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 703, - "passed": 701, - "assertions": 6828, - "duration_ms": 163777, - "skipped": 2 - }, - "postgresql_tests": 35, - "postgresql_assertions": 252, - "react_inertia_tests": 47, - "typescript": "passed", - "phpstan_errors": 0, - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "menu_entries_across_six_roles": 111, - "http_proof": "menu-links.json", - "runtime_sha256_files": 18, - "installation_proof": "requisition-catalogue-install.json", - "postgresql_proof": "requisition-catalogue-pg.json", - "visual_review": false, - "domain_installed": false, - "external_AI_calls": 0, - "global_enter_once_requirement_complete": false, - "remaining_coverage_matrix": "../reutilizacao-dados.md", - "source_sha256": { - "database/migrations/2026_10_30_000035_create_requisition_catalogue.php": "8899a8f118a3fed3ef2302f82cb75008445ebfdd5bf08f7ef3b3f167bdd9fdb6", - "app/Services/RequisitionCatalogue.php": "ddf8079125a0c6ce2a898780ac82c8eb8f0f335e46f499c10f8c04b6a74b879e", - "app/Services/RequisitionWorkflow.php": "8d35c229c22bee4ccb2bbde1b204c35b2e61231ae05ce850f1dec3f6c874dd56", - "app/Services/PurchaseWorkflow.php": "09cfdb70966b5067b3cfab0a7b8e87d83307ef89e566bf700a38048647b0ac11", - "app/Services/ReceiptWorkflow.php": "736c13dce0812e5c4b0b949cbdd38a6988de6a0651566876935379f8f4b673d6", - "app/Http/Controllers/RequisitionCatalogueController.php": "86540cba2c4f5219e56a254fa5278ff4421126f8b6c78cc3e92b69800603e422", - "app/Http/Requests/StoreRequisitionRequest.php": "83685bf281027d36cc78734078bb567a3808b7c313efe775df205a78e521851e", - "resources/js/pages/requisitions/form.tsx": "a8df407caa3aa859f34dfd18820a25b9c7e36ddf15342ff3e13ff409bfd4b070", - "resources/js/pages/stock/catalogue.tsx": "560f529f1c61dd1dd731c00f05e0d5a0f4f5147abc63916cafdacd406b4b7776", - "resources/js/pages/receipts/order.tsx": "635c8759254bd559b7a0f84bf26a9eeade9062aeb0c847488bd1b9949617ad72", - "tests/Feature/RequisitionCatalogueTest.php": "8bc598ff89e4c15bedb763f67891ee493e7a248ce387ff96b9355e9f6385fbf2", - "tests/Feature/PurchaseAwardOrderTest.php": "914a8459cb98a049fb38c6e6e745953b3068499829162568f7f7accce71bb068", - "tests/frontend/requisition-catalogue.test.tsx": "2dc95238e5b50a93ad4879f0ac5df161c9ced3227afe15a15e501e32e0314c13" - } + "checked_at": "2026-10-30T16:26:29.650769+00:00", + "scope": [ + "published company article selection in requisition", + "server-authoritative descriptors", + "frozen source and version through order", + "receipt stock identification and rejection of other stock", + "legacy rows preserved without automatic linking" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 703, + "passed": 701, + "assertions": 6828, + "duration_ms": 163777, + "skipped": 2 + }, + "postgresql_tests": 35, + "postgresql_assertions": 252, + "react_inertia_tests": 47, + "typescript": "passed", + "phpstan_errors": 0, + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "menu_entries_across_six_roles": 111, + "http_proof": "menu-links.json", + "runtime_sha256_files": 18, + "installation_proof": "requisition-catalogue-install.json", + "postgresql_proof": "requisition-catalogue-pg.json", + "visual_review": false, + "domain_installed": false, + "external_AI_calls": 0, + "global_enter_once_requirement_complete": false, + "remaining_coverage_matrix": "../reutilizacao-dados.md", + "source_sha256": { + "database/migrations/2026_10_30_000035_create_requisition_catalogue.php": "8899a8f118a3fed3ef2302f82cb75008445ebfdd5bf08f7ef3b3f167bdd9fdb6", + "app/Services/RequisitionCatalogue.php": "ddf8079125a0c6ce2a898780ac82c8eb8f0f335e46f499c10f8c04b6a74b879e", + "app/Services/RequisitionWorkflow.php": "8d35c229c22bee4ccb2bbde1b204c35b2e61231ae05ce850f1dec3f6c874dd56", + "app/Services/PurchaseWorkflow.php": "09cfdb70966b5067b3cfab0a7b8e87d83307ef89e566bf700a38048647b0ac11", + "app/Services/ReceiptWorkflow.php": "736c13dce0812e5c4b0b949cbdd38a6988de6a0651566876935379f8f4b673d6", + "app/Http/Controllers/RequisitionCatalogueController.php": "86540cba2c4f5219e56a254fa5278ff4421126f8b6c78cc3e92b69800603e422", + "app/Http/Requests/StoreRequisitionRequest.php": "83685bf281027d36cc78734078bb567a3808b7c313efe775df205a78e521851e", + "resources/js/pages/requisitions/form.tsx": "a8df407caa3aa859f34dfd18820a25b9c7e36ddf15342ff3e13ff409bfd4b070", + "resources/js/pages/stock/catalogue.tsx": "560f529f1c61dd1dd731c00f05e0d5a0f4f5147abc63916cafdacd406b4b7776", + "resources/js/pages/receipts/order.tsx": "635c8759254bd559b7a0f84bf26a9eeade9062aeb0c847488bd1b9949617ad72", + "tests/Feature/RequisitionCatalogueTest.php": "8bc598ff89e4c15bedb763f67891ee493e7a248ce387ff96b9355e9f6385fbf2", + "tests/Feature/PurchaseAwardOrderTest.php": "914a8459cb98a049fb38c6e6e745953b3068499829162568f7f7accce71bb068", + "tests/frontend/requisition-catalogue.test.tsx": "2dc95238e5b50a93ad4879f0ac5df161c9ced3227afe15a15e501e32e0314c13" + } } diff --git a/docs/proofs/sgc-brand.json b/docs/proofs/sgc-brand.json index d40391e..876387a 100644 --- a/docs/proofs/sgc-brand.json +++ b/docs/proofs/sgc-brand.json @@ -1,29 +1,29 @@ { - "checked_at": "2026-10-30T11:53:42.906027+00:00", - "name": "SGC - Sistema de Gestão de Contratações", - "tagline": "Aquisições, serviços e pessoas", - "signature": "Uma solução TEMPO", - "acronym": "SGC", - "php_tests": 35, - "assertions": 228, - "react_inertia_tests": 21, - "typescript": "passed", - "targeted_lint": "passed", - "pint": "passed", - "build_exit": 0, - "local_entry_http": "passed", - "migrations_applied": false, - "business_data_changed": false, - "domain_installed": false, - "visual_review": false, - "source_sha256": { - "resources/js/components/sgc-workspace-shell.tsx": "4c6857d4e66bd5732af61c7ff52659fd38db7ea7805173f58398acb7a4a0f287", - "resources/js/components/sgc-shell.tsx": "76e8059c5b5a9ae1e4351ee8efaa0e376394dc7133bc7524b5ee653009836687", - "resources/js/pages/home.tsx": "719c1feb0ed0070545a98b00e012b09ef2a8dbd2877c94a0fbb0f0ba25548d87", - "resources/js/pages/auth/login.tsx": "13256348dc44f9f19105c320782ba7f54ddea9e92bd95f2dabc38dc86958ffa6", - "resources/js/layouts/auth/auth-simple-layout.tsx": "a08bee2476691273897ff1218f93c9da2e26a7d0e9b98558c3aa78a49f76edc4", - "resources/views/app.blade.php": "d16385dff24a46c10efe39ee201ad5de9441eaa7dd88407540330c00894fac13", - "resources/views/purchases/opening.blade.php": "7a630cf84e8189c65d3e24b477b5685a5411d9f1ca06da238c91c46a1a2d9592", - "resources/views/purchases/recommendation-print.blade.php": "6854c841bf6132875e9994dd76598c47074ed8e6640e4983bd9fa9b8bb26edc8" - } + "checked_at": "2026-10-30T11:53:42.906027+00:00", + "name": "SGC - Sistema de Gestão de Contratações", + "tagline": "Aquisições, serviços e pessoas", + "signature": "Uma solução TEMPO", + "acronym": "SGC", + "php_tests": 35, + "assertions": 228, + "react_inertia_tests": 21, + "typescript": "passed", + "targeted_lint": "passed", + "pint": "passed", + "build_exit": 0, + "local_entry_http": "passed", + "migrations_applied": false, + "business_data_changed": false, + "domain_installed": false, + "visual_review": false, + "source_sha256": { + "resources/js/components/sgc-workspace-shell.tsx": "4c6857d4e66bd5732af61c7ff52659fd38db7ea7805173f58398acb7a4a0f287", + "resources/js/components/sgc-shell.tsx": "76e8059c5b5a9ae1e4351ee8efaa0e376394dc7133bc7524b5ee653009836687", + "resources/js/pages/home.tsx": "719c1feb0ed0070545a98b00e012b09ef2a8dbd2877c94a0fbb0f0ba25548d87", + "resources/js/pages/auth/login.tsx": "13256348dc44f9f19105c320782ba7f54ddea9e92bd95f2dabc38dc86958ffa6", + "resources/js/layouts/auth/auth-simple-layout.tsx": "a08bee2476691273897ff1218f93c9da2e26a7d0e9b98558c3aa78a49f76edc4", + "resources/views/app.blade.php": "d16385dff24a46c10efe39ee201ad5de9441eaa7dd88407540330c00894fac13", + "resources/views/purchases/opening.blade.php": "7a630cf84e8189c65d3e24b477b5685a5411d9f1ca06da238c91c46a1a2d9592", + "resources/views/purchases/recommendation-print.blade.php": "6854c841bf6132875e9994dd76598c47074ed8e6640e4983bd9fa9b8bb26edc8" + } } diff --git a/docs/proofs/submission-forms-http.json b/docs/proofs/submission-forms-http.json index 4fc1d1c..345a8eb 100644 --- a/docs/proofs/submission-forms-http.json +++ b/docs/proofs/submission-forms-http.json @@ -1,9 +1,9 @@ { - "checked_at": "2026-10-30T16:47:29.726Z", - "admin": 200, - "warehouse": 403, - "modalities": 6, - "initial_saved_versions": 0, - "availability_location": true, - "external_portal_available": false + "checked_at": "2026-10-30T16:47:29.726Z", + "admin": 200, + "warehouse": 403, + "modalities": 6, + "initial_saved_versions": 0, + "availability_location": true, + "external_portal_available": false } diff --git a/docs/proofs/submission-forms-pg.json b/docs/proofs/submission-forms-pg.json index 383f2fa..9188255 100644 --- a/docs/proofs/submission-forms-pg.json +++ b/docs/proofs/submission-forms-pg.json @@ -1,15 +1,15 @@ { - "checked_at": "2026-10-30T16:45:32+00:00", - "database": "disposable PostgreSQL", - "application_role_reused_without_privilege_change": true, - "result": "passed", - "test_files": [ - "SubmissionAnswersTest", - "SubmissionFormsTest", - "PeopleHiringTest" - ], - "original_evaluation_untouched": true, - "database_removed": true, - "tests": 44, - "assertions": 1088 + "checked_at": "2026-10-30T16:45:32+00:00", + "database": "disposable PostgreSQL", + "application_role_reused_without_privilege_change": true, + "result": "passed", + "test_files": [ + "SubmissionAnswersTest", + "SubmissionFormsTest", + "PeopleHiringTest" + ], + "original_evaluation_untouched": true, + "database_removed": true, + "tests": 44, + "assertions": 1088 } diff --git a/docs/proofs/submission-forms.json b/docs/proofs/submission-forms.json index 62d183c..2b65093 100644 --- a/docs/proofs/submission-forms.json +++ b/docs/proofs/submission-forms.json @@ -1,61 +1,61 @@ { - "checked_at": "2026-10-30T16:48:55.574914+00:00", - "scope": [ - "six independently versioned company intake form configurations", - "immutable append-only definitions and history", - "stale update rejection and audit rollback", - "frozen form definition at preparation of new people opportunities", - "structured province district locality availability field and reusable validation" - ], - "full_suite": { - "tool": "pest", - "result": "passed", - "tests": 710, - "passed": 708, - "assertions": 6904, - "duration_ms": 149093, - "skipped": 2 - }, - "module_sqlite_tests": 44, - "module_assertions": 1088, - "disposable_postgresql_tests": 44, - "disposable_postgresql_assertions": 1088, - "react_inertia_tests": 49, - "phpstan_errors": 0, - "typescript": "passed", - "pint": "passed", - "targeted_lint": "passed", - "build_exit": 0, - "menu_code_proof": "menu-code-contract.json", - "menu_links_proof": "menu-links.json", - "runtime_sha256_files": 18, - "postgresql_proof": "submission-forms-pg.json", - "installation_proof": "submission-forms-install.json", - "http_proof": "submission-forms-http.json", - "visual_review": false, - "domain_installed": false, - "external_portal_available": false, - "external_AI_calls": 0, - "original_document_changed": false, - "outstanding": [ - "external identity and reusable candidate profile", - "submission uploads security verification receipt and triage", - "complements and revisions", - "official territory validation and multiple availability locations", - "privacy and retention configuration before public operation" - ], - "source_sha256": { - "database/migrations/2026_10_30_000036_create_submission_forms.php": "158a2a4dbe7a5b1af281281619e13e9fef573dc4e2afe5a6e79c56dd1ecb9e7a", - "app/Services/SubmissionForms.php": "033c65865c3a8bdb354a297585ce0728c954b94a78ccb7fbd95c93b8be9b1236", - "app/Services/SubmissionAnswers.php": "49c203f85b3eec68d6a343e9f1c9b693eb56d42411d6d3b798c359e12eddc130", - "app/Services/PeopleHiring.php": "18ffaaa08774b1a5a0ec3f9a06898f40cc20ee564b89e252113ff8e7ad81b5a3", - "app/Http/Controllers/SubmissionFormsController.php": "c9c937e8b03c24410c156d70fbbc0c6e65ede3e57e741dfe6849c2f2cee0eefa", - "resources/js/pages/company/submission-forms.tsx": "ebe9b36d1ae9b42780d3f54cb86770358f1333bfc822b602ba1ca5dbfbbc9271", - "resources/js/pages/company/parameters.tsx": "80f8bc5304066fcaceb5727374c2f5b3a9cc9e61194d8c35cf64e093b1aee3d3", - "resources/js/pages/people/show.tsx": "d7dcd65a1f70b0e30223ac0a8bb1062f991443dc4ed9700be97a9b02eca2307f", - "tests/Feature/SubmissionFormsTest.php": "06e567b030486fdfec459ef69d125bc5b6916a6c54968ef1666471cc52d5bda8", - "tests/Feature/SubmissionAnswersTest.php": "a152ba6fd7129490d6fa6294645d01ed824a8c4c73342ce38a1fb3d95a3044c4", - "tests/Feature/PeopleHiringTest.php": "52028989c405043e96a33807232250a64e8c7e48b8f49eac282664c894e1cb9c", - "tests/frontend/submission-forms.test.tsx": "e0460f9227964d27f331c1f0801339998f4fd8693cc5b27e13bcf1d51c5fc156" - } + "checked_at": "2026-10-30T16:48:55.574914+00:00", + "scope": [ + "six independently versioned company intake form configurations", + "immutable append-only definitions and history", + "stale update rejection and audit rollback", + "frozen form definition at preparation of new people opportunities", + "structured province district locality availability field and reusable validation" + ], + "full_suite": { + "tool": "pest", + "result": "passed", + "tests": 710, + "passed": 708, + "assertions": 6904, + "duration_ms": 149093, + "skipped": 2 + }, + "module_sqlite_tests": 44, + "module_assertions": 1088, + "disposable_postgresql_tests": 44, + "disposable_postgresql_assertions": 1088, + "react_inertia_tests": 49, + "phpstan_errors": 0, + "typescript": "passed", + "pint": "passed", + "targeted_lint": "passed", + "build_exit": 0, + "menu_code_proof": "menu-code-contract.json", + "menu_links_proof": "menu-links.json", + "runtime_sha256_files": 18, + "postgresql_proof": "submission-forms-pg.json", + "installation_proof": "submission-forms-install.json", + "http_proof": "submission-forms-http.json", + "visual_review": false, + "domain_installed": false, + "external_portal_available": false, + "external_AI_calls": 0, + "original_document_changed": false, + "outstanding": [ + "external identity and reusable candidate profile", + "submission uploads security verification receipt and triage", + "complements and revisions", + "official territory validation and multiple availability locations", + "privacy and retention configuration before public operation" + ], + "source_sha256": { + "database/migrations/2026_10_30_000036_create_submission_forms.php": "158a2a4dbe7a5b1af281281619e13e9fef573dc4e2afe5a6e79c56dd1ecb9e7a", + "app/Services/SubmissionForms.php": "033c65865c3a8bdb354a297585ce0728c954b94a78ccb7fbd95c93b8be9b1236", + "app/Services/SubmissionAnswers.php": "49c203f85b3eec68d6a343e9f1c9b693eb56d42411d6d3b798c359e12eddc130", + "app/Services/PeopleHiring.php": "18ffaaa08774b1a5a0ec3f9a06898f40cc20ee564b89e252113ff8e7ad81b5a3", + "app/Http/Controllers/SubmissionFormsController.php": "c9c937e8b03c24410c156d70fbbc0c6e65ede3e57e741dfe6849c2f2cee0eefa", + "resources/js/pages/company/submission-forms.tsx": "ebe9b36d1ae9b42780d3f54cb86770358f1333bfc822b602ba1ca5dbfbbc9271", + "resources/js/pages/company/parameters.tsx": "80f8bc5304066fcaceb5727374c2f5b3a9cc9e61194d8c35cf64e093b1aee3d3", + "resources/js/pages/people/show.tsx": "d7dcd65a1f70b0e30223ac0a8bb1062f991443dc4ed9700be97a9b02eca2307f", + "tests/Feature/SubmissionFormsTest.php": "06e567b030486fdfec459ef69d125bc5b6916a6c54968ef1666471cc52d5bda8", + "tests/Feature/SubmissionAnswersTest.php": "a152ba6fd7129490d6fa6294645d01ed824a8c4c73342ce38a1fb3d95a3044c4", + "tests/Feature/PeopleHiringTest.php": "52028989c405043e96a33807232250a64e8c7e48b8f49eac282664c894e1cb9c", + "tests/frontend/submission-forms.test.tsx": "e0460f9227964d27f331c1f0801339998f4fd8693cc5b27e13bcf1d51c5fc156" + } } diff --git a/docs/proofs/supplier-evaluations-http.json b/docs/proofs/supplier-evaluations-http.json index 369e196..b4a0208 100644 --- a/docs/proofs/supplier-evaluations-http.json +++ b/docs/proofs/supplier-evaluations-http.json @@ -1,15 +1,15 @@ { - "checked_at": "2026-10-30T07:33:29.638Z", - "base": "http://127.0.0.1:8005", - "report_path": "/fornecedores/avaliacoes/1/relatorio", - "revision_path": "/fornecedores/avaliacoes/2", - "create_submit_return_correct_approve": true, - "self_approval_refused": true, - "stale_write_refused": true, - "approved_edit_refused": true, - "prior_approved_revision_preserved": true, - "history_events": 6, - "synthetic_example_only": true, - "financial_commands": 0, - "visual_review": false + "checked_at": "2026-10-30T07:33:29.638Z", + "base": "http://127.0.0.1:8005", + "report_path": "/fornecedores/avaliacoes/1/relatorio", + "revision_path": "/fornecedores/avaliacoes/2", + "create_submit_return_correct_approve": true, + "self_approval_refused": true, + "stale_write_refused": true, + "approved_edit_refused": true, + "prior_approved_revision_preserved": true, + "history_events": 6, + "synthetic_example_only": true, + "financial_commands": 0, + "visual_review": false } diff --git a/docs/proofs/supplier-improvement-report-http.json b/docs/proofs/supplier-improvement-report-http.json index c27905e..5c18404 100644 --- a/docs/proofs/supplier-improvement-report-http.json +++ b/docs/proofs/supplier-improvement-report-http.json @@ -1,24 +1,16 @@ { - "checked_at": "2026-10-30T07:51:21.312Z", - "base": "http://127.0.0.1:8005", - "path": "/relatorios/medidas-fornecedores", - "readers": [ - "admin", - "procurement", - "finance", - "department_head" - ], - "denied": [ - "requester", - "warehouse" - ], - "total": 1, - "filtered_total": 1, - "filters_and_csv_match": true, - "csv_ignores_page": true, - "closed_not_overdue": true, - "invalid_range_refused": true, - "linked_evaluation_and_report": true, - "business_commands": 0, - "visual_review": false + "checked_at": "2026-10-30T07:51:21.312Z", + "base": "http://127.0.0.1:8005", + "path": "/relatorios/medidas-fornecedores", + "readers": ["admin", "procurement", "finance", "department_head"], + "denied": ["requester", "warehouse"], + "total": 1, + "filtered_total": 1, + "filters_and_csv_match": true, + "csv_ignores_page": true, + "closed_not_overdue": true, + "invalid_range_refused": true, + "linked_evaluation_and_report": true, + "business_commands": 0, + "visual_review": false } diff --git a/docs/proofs/supplier-improvement-report.json b/docs/proofs/supplier-improvement-report.json index 6d3fbdb..e595708 100644 --- a/docs/proofs/supplier-improvement-report.json +++ b/docs/proofs/supplier-improvement-report.json @@ -1,29 +1,29 @@ { - "checked_at": "2026-10-30T07:52:09.806123+00:00", - "targeted_tests": 36, - "assertions": 542, - "new_report_test_cases": 6, - "csv_batch_test_rows": 207, - "phpstan_errors": 0, - "typescript": "passed", - "lint_and_format_targeted": "passed", - "pint_targeted": "passed", - "build": "passed", - "build_log": "storage/logs/supplier-improvement-report-build.log", - "menu_entries": 106, - "roles": 6, - "evaluation_catalog_pages": 22, - "schema_changes": false, - "business_commands": 0, - "domain_installed": false, - "visual_review": false, - "sources": { - "app/Http/Controllers/SupplierImprovementReportController.php": "fdaf0d5484e91481cdd5d676eb6951f8575bcc328961e993acf3290f5d8343cc", - "app/Models/SupplierImprovement.php": "762af10d9c14d70dd03e51ef6d9a80efe36171a9a0121a985ae0c17f06f03d4e", - "resources/js/pages/reports/supplier-improvements.tsx": "070d4c5eaf0a75439751504b21262df1c2f0e60d59e93538ff5d9c5959fe6398", - "resources/js/components/supplier-improvements.tsx": "7add7f51d907943682d3f132dc135f0e41b726dd67ddf2478852cf30ba5a21dd", - "resources/js/lib/procurement-navigation.ts": "a2a26bbd50c288e7cde589c7d8c2aaa3929f5ae20fc8b01c502db031d95085d4", - "tests/Feature/SupplierImprovementReportTest.php": "daf90f8da729a489bdc5116b318514c82a91b89ffbfb2c082b11457661544985", - "scripts/supplier-improvement-report-check.mjs": "60c57d36ebc83928198734573b5072240291504b57f2b88be3167f8f7c40c906" - } + "checked_at": "2026-10-30T07:52:09.806123+00:00", + "targeted_tests": 36, + "assertions": 542, + "new_report_test_cases": 6, + "csv_batch_test_rows": 207, + "phpstan_errors": 0, + "typescript": "passed", + "lint_and_format_targeted": "passed", + "pint_targeted": "passed", + "build": "passed", + "build_log": "storage/logs/supplier-improvement-report-build.log", + "menu_entries": 106, + "roles": 6, + "evaluation_catalog_pages": 22, + "schema_changes": false, + "business_commands": 0, + "domain_installed": false, + "visual_review": false, + "sources": { + "app/Http/Controllers/SupplierImprovementReportController.php": "fdaf0d5484e91481cdd5d676eb6951f8575bcc328961e993acf3290f5d8343cc", + "app/Models/SupplierImprovement.php": "762af10d9c14d70dd03e51ef6d9a80efe36171a9a0121a985ae0c17f06f03d4e", + "resources/js/pages/reports/supplier-improvements.tsx": "070d4c5eaf0a75439751504b21262df1c2f0e60d59e93538ff5d9c5959fe6398", + "resources/js/components/supplier-improvements.tsx": "7add7f51d907943682d3f132dc135f0e41b726dd67ddf2478852cf30ba5a21dd", + "resources/js/lib/procurement-navigation.ts": "a2a26bbd50c288e7cde589c7d8c2aaa3929f5ae20fc8b01c502db031d95085d4", + "tests/Feature/SupplierImprovementReportTest.php": "daf90f8da729a489bdc5116b318514c82a91b89ffbfb2c082b11457661544985", + "scripts/supplier-improvement-report-check.mjs": "60c57d36ebc83928198734573b5072240291504b57f2b88be3167f8f7c40c906" + } } diff --git a/docs/proofs/supplier-improvements-http.json b/docs/proofs/supplier-improvements-http.json index a0f641a..048d37a 100644 --- a/docs/proofs/supplier-improvements-http.json +++ b/docs/proofs/supplier-improvements-http.json @@ -1,19 +1,19 @@ { - "checked_at": "2026-10-30T07:41:16.109Z", - "base": "http://127.0.0.1:8005", - "evaluation_path": "/fornecedores/avaliacoes/1", - "measure_id": 1, - "create_retry_idempotent": true, - "missing_evidence_refused": true, - "self_closure_refused": true, - "planner_closure_refused": true, - "return_replan_correct_submit_close": true, - "stale_plan_refused": true, - "closed_edit_refused": true, - "parent_evaluation_unchanged": true, - "history_events": 7, - "report_includes_closed_measure": true, - "synthetic_example_only": true, - "financial_commands": 0, - "visual_review": false + "checked_at": "2026-10-30T07:41:16.109Z", + "base": "http://127.0.0.1:8005", + "evaluation_path": "/fornecedores/avaliacoes/1", + "measure_id": 1, + "create_retry_idempotent": true, + "missing_evidence_refused": true, + "self_closure_refused": true, + "planner_closure_refused": true, + "return_replan_correct_submit_close": true, + "stale_plan_refused": true, + "closed_edit_refused": true, + "parent_evaluation_unchanged": true, + "history_events": 7, + "report_includes_closed_measure": true, + "synthetic_example_only": true, + "financial_commands": 0, + "visual_review": false } diff --git a/docs/proofs/supplier-responses-http.json b/docs/proofs/supplier-responses-http.json index 881bcb9..c04bc8b 100644 --- a/docs/proofs/supplier-responses-http.json +++ b/docs/proofs/supplier-responses-http.json @@ -1,20 +1,20 @@ { - "checked_at": "2026-10-30T07:57:43.108Z", - "base": "http://127.0.0.1:8005", - "evaluation_path": "/fornecedores/avaliacoes/1", - "response_id": 1, - "idempotent_creation": true, - "incomplete_submit_refused": true, - "stale_save_refused": true, - "self_decision_refused": true, - "return_correction_independent_conclusion": true, - "accepted_follow_up_required": true, - "concluded_edit_refused": true, - "parent_evaluation_unchanged": true, - "history_events": 7, - "individual_report": true, - "synthetic_example_only": true, - "external_messages_sent": 0, - "financial_commands": 0, - "visual_review": false + "checked_at": "2026-10-30T07:57:43.108Z", + "base": "http://127.0.0.1:8005", + "evaluation_path": "/fornecedores/avaliacoes/1", + "response_id": 1, + "idempotent_creation": true, + "incomplete_submit_refused": true, + "stale_save_refused": true, + "self_decision_refused": true, + "return_correction_independent_conclusion": true, + "accepted_follow_up_required": true, + "concluded_edit_refused": true, + "parent_evaluation_unchanged": true, + "history_events": 7, + "individual_report": true, + "synthetic_example_only": true, + "external_messages_sent": 0, + "financial_commands": 0, + "visual_review": false } diff --git a/docs/proofs/supplier-responses.json b/docs/proofs/supplier-responses.json index 7ce338c..8931840 100644 --- a/docs/proofs/supplier-responses.json +++ b/docs/proofs/supplier-responses.json @@ -1,28 +1,28 @@ { - "checked_at": "2026-10-30T07:59:03.931961+00:00", - "targeted_tests": 39, - "assertions": 505, - "new_test_cases": 11, - "phpstan_errors": 0, - "typescript": "passed", - "lint_format_pint_targeted": "passed", - "build": "passed", - "build_log": "storage/logs/supplier-responses-build.log", - "menu_entries": 106, - "roles": 6, - "installed_in_local_evaluation": true, - "domain_installed": false, - "external_messages_sent": 0, - "visual_review": false, - "source_hashes": { - "app/Models/SupplierResponse.php": "fc3877f2e787483cb56f31ca877eb2dc4f2d266c2eefa47dab1b1ae3ecf163fc", - "app/Services/SupplierResponseWorkflow.php": "772af0878f55cd9818cddec62aca3850ae4868c13acf86fe7dd003bac1fbb0b5", - "app/Http/Controllers/SupplierResponseController.php": "6960500484974f6ba2be1c63bb1156abde976c9e42837f6d3101a1f8a73092d3", - "app/Http/Controllers/SupplierEvaluationController.php": "2523eb6a858fdb62c494d74a8ce7988e7f29d4e0c51c53d3f0899de02987f17d", - "database/migrations/2026_10_30_000026_create_supplier_responses.php": "d414f637587088e589d886f792d678674337707e8391a0ab0fcf86dc9ebfaaf4", - "resources/js/components/supplier-responses.tsx": "ec0becd110e879f5929a7179c61352e1f31478674e654a41b1f85c64ecd1adf1", - "resources/js/pages/suppliers/evaluation.tsx": "509d27438a2a3b5337572357b9c69a2703201789ea75a487b36dfc301f65c8db", - "tests/Feature/SupplierResponseTest.php": "00faa0131f7335e1d2f18d781aa16cb914bf13acb1090ab902269f737b87c3c6", - "scripts/supplier-response-check.mjs": "31c7b741bbb0becc0426d0437a1d9853616199a86730831dc09b902e66f469c2" - } + "checked_at": "2026-10-30T07:59:03.931961+00:00", + "targeted_tests": 39, + "assertions": 505, + "new_test_cases": 11, + "phpstan_errors": 0, + "typescript": "passed", + "lint_format_pint_targeted": "passed", + "build": "passed", + "build_log": "storage/logs/supplier-responses-build.log", + "menu_entries": 106, + "roles": 6, + "installed_in_local_evaluation": true, + "domain_installed": false, + "external_messages_sent": 0, + "visual_review": false, + "source_hashes": { + "app/Models/SupplierResponse.php": "fc3877f2e787483cb56f31ca877eb2dc4f2d266c2eefa47dab1b1ae3ecf163fc", + "app/Services/SupplierResponseWorkflow.php": "772af0878f55cd9818cddec62aca3850ae4868c13acf86fe7dd003bac1fbb0b5", + "app/Http/Controllers/SupplierResponseController.php": "6960500484974f6ba2be1c63bb1156abde976c9e42837f6d3101a1f8a73092d3", + "app/Http/Controllers/SupplierEvaluationController.php": "2523eb6a858fdb62c494d74a8ce7988e7f29d4e0c51c53d3f0899de02987f17d", + "database/migrations/2026_10_30_000026_create_supplier_responses.php": "d414f637587088e589d886f792d678674337707e8391a0ab0fcf86dc9ebfaaf4", + "resources/js/components/supplier-responses.tsx": "ec0becd110e879f5929a7179c61352e1f31478674e654a41b1f85c64ecd1adf1", + "resources/js/pages/suppliers/evaluation.tsx": "509d27438a2a3b5337572357b9c69a2703201789ea75a487b36dfc301f65c8db", + "tests/Feature/SupplierResponseTest.php": "00faa0131f7335e1d2f18d781aa16cb914bf13acb1090ab902269f737b87c3c6", + "scripts/supplier-response-check.mjs": "31c7b741bbb0becc0426d0437a1d9853616199a86730831dc09b902e66f469c2" + } } diff --git a/docs/reutilizacao-dados.md b/docs/reutilizacao-dados.md index 4d3744d..d63940f 100644 --- a/docs/reutilizacao-dados.md +++ b/docs/reutilizacao-dados.md @@ -16,16 +16,16 @@ Registos sem vínculo de cadastro continuam em compatibilidade; não foram ligad ## Matriz transversal de cobertura -| Percurso | Reutilização observada/implementada | Evolução ainda necessária | -| --- | --- | --- | -| Empresa, utilizadores, departamentos e centros | Identificadores seleccionados; contexto do actor usado nos pedidos; regras preservadas nos processos | Conferir reutilização de campos em todos os documentos e associações de funções/unidades | -| Fornecedor → proposta → adjudicação/ordem | Cadastro por ID e linhas/fonte herdadas; dados preservados na emissão | Inventariar referências/documentos repetidos e uniformizar selecção de evidências | -| Requisição → proposta → ordem | Catálogo de artigos publicados pelo armazém/administração para insumos/outros bens; descrição, categoria, unidade e tipo vêm da fonte; versão preservada por linha e na ordem | Equipamento/peças mantêm roteiro técnico; serviços continuam manuais; conferir referências documentais repetidas | -| Ordem → recepção/factura | Linhas, fornecedor e valores de origem usados; artigo do catálogo identificado automaticamente na recepção; quantidades e datas são novos eventos | Conferir os restantes formulários e associações sem reintrodução de descrições | -| Pessoas → candidaturas → avaliação/selecção | Novo cadastro reutilizável, selecção autorizada e snapshot por candidatura; avaliações usam a mesma candidatura | Reconciliação assistida dos históricos e campos de cadastro adicionais quando forem definidos | +| Percurso | Reutilização observada/implementada | Evolução ainda necessária | +| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| Empresa, utilizadores, departamentos e centros | Identificadores seleccionados; contexto do actor usado nos pedidos; regras preservadas nos processos | Conferir reutilização de campos em todos os documentos e associações de funções/unidades | +| Fornecedor → proposta → adjudicação/ordem | Cadastro por ID e linhas/fonte herdadas; dados preservados na emissão | Inventariar referências/documentos repetidos e uniformizar selecção de evidências | +| Requisição → proposta → ordem | Catálogo de artigos publicados pelo armazém/administração para insumos/outros bens; descrição, categoria, unidade e tipo vêm da fonte; versão preservada por linha e na ordem | Equipamento/peças mantêm roteiro técnico; serviços continuam manuais; conferir referências documentais repetidas | +| Ordem → recepção/factura | Linhas, fornecedor e valores de origem usados; artigo do catálogo identificado automaticamente na recepção; quantidades e datas são novos eventos | Conferir os restantes formulários e associações sem reintrodução de descrições | +| Pessoas → candidaturas → avaliação/selecção | Novo cadastro reutilizável, selecção autorizada e snapshot por candidatura; avaliações usam a mesma candidatura | Reconciliação assistida dos históricos e campos de cadastro adicionais quando forem definidos | | Perfil externo → candidatura electrónica → avaliação | Perfil versionado com disponibilidade província/distrito/localidade; respostas pré-preenchidas e comprovativo preservado; aceitação explícita para análise aproveita nome/resumo/referência/data na candidatura interna e identifica a fonte/versão | Anexos verificados, complementos/revisões, modalidades espontâneas e eventual inclusão em cadastro por decisão própria; não fundir por nome | -| Minutas/modelos de documentos | Processos e decisões preservam os seus dados; minuta interna de Pessoas ainda recebe termos específicos | Modelos versionados por empresa e preenchimento de variáveis por fontes autorizadas, mantendo termos novos editáveis | -| Relatórios, indicadores e sínteses | Derivam dos registos originais autorizados, sem novo preenchimento | Conferir cobertura funcional e visual de todos os relatórios; não confundir síntese com nova evidência | +| Minutas/modelos de documentos | Processos e decisões preservam os seus dados; minuta interna de Pessoas ainda recebe termos específicos | Modelos versionados por empresa e preenchimento de variáveis por fontes autorizadas, mantendo termos novos editáveis | +| Relatórios, indicadores e sínteses | Derivam dos registos originais autorizados, sem novo preenchimento | Conferir cobertura funcional e visual de todos os relatórios; não confundir síntese com nova evidência | ## Critério para fechar cada lacuna diff --git a/resources/js/components/app-sidebar.tsx b/resources/js/components/app-sidebar.tsx index 3291bad..4160355 100644 --- a/resources/js/components/app-sidebar.tsx +++ b/resources/js/components/app-sidebar.tsx @@ -56,7 +56,11 @@ export function AppSidebar() { ...(canReadPurchases ? [ { title: 'Fornecedores', href: '/fornecedores', icon: Users }, - { title: 'Avaliação de fornecedores', href: '/fornecedores/avaliacoes', icon: Users }, + { + title: 'Avaliação de fornecedores', + href: '/fornecedores/avaliacoes', + icon: Users, + }, { title: 'Cotações', href: '/cotacoes', icon: Scale }, { title: 'Ordens de compra', @@ -157,7 +161,14 @@ export function AppSidebar() { icon: FileCheck2, }, ...(payablesAvailable === true - ? [{title: 'Obrigações a fornecedores', href: '/obrigacoes-fornecedores', icon: FileCheck2, fullPage: true}] + ? [ + { + title: 'Obrigações a fornecedores', + href: '/obrigacoes-fornecedores', + icon: FileCheck2, + fullPage: true, + }, + ] : []), { title: 'Pagamentos externos', diff --git a/resources/js/components/sgc-workspace-shell.tsx b/resources/js/components/sgc-workspace-shell.tsx index 7e71387..e3171df 100644 --- a/resources/js/components/sgc-workspace-shell.tsx +++ b/resources/js/components/sgc-workspace-shell.tsx @@ -34,6 +34,9 @@ import { roleLabels } from '@/types/procurement'; export function SgcWorkspaceShell({ children }: { children: ReactNode }) { const page = usePage(); const user = page.props.auth?.user; + const publicNavigation = page.props.publicNavigation as + | { paths: string[] } + | undefined; const [mobileOpen, setMobileOpen] = useState(false); const [search, setSearch] = useState(''); const [expanded, setExpanded] = useState>({}); @@ -44,6 +47,7 @@ export function SgcWorkspaceShell({ children }: { children: ReactNode }) { const groups = procurementNavigation( access?.active ? access.permissions : (user?.purchasing_role ?? ''), page.props.payablesAvailable === true, + publicNavigation?.paths, ); const activeId = activeProcurementEntry(groups, page.url); const activeGroup = groups.find((group) => @@ -274,6 +278,13 @@ export function SgcWorkspaceShell({ children }: { children: ReactNode }) { ); return (
+ {publicNavigation && ( +

+ Consulta pública de desenvolvimento · Sem organização + seleccionada e sem registos privados. Alterações exigem + autenticação. +

+ )} ({ ...group, - entries: group.entries.filter( - (entry) => - (entry.id !== 'new_request' || - !Array.isArray(role) || - role.includes('requester')) && - (!entry.roles || - entry.roles.some((permission) => - (Array.isArray(role) ? role : [role]).includes( - permission, - ), - )), + entries: group.entries.filter((entry) => + publicPaths + ? publicPaths.includes( + new URL(entry.path, 'http://local').pathname, + ) + : (entry.id !== 'new_request' || + !Array.isArray(role) || + role.includes('requester')) && + (!entry.roles || + entry.roles.some((permission) => + (Array.isArray(role) ? role : [role]).includes( + permission, + ), + )), ), })) .filter((group) => group.entries.length); diff --git a/resources/js/pages/budgets/index.tsx b/resources/js/pages/budgets/index.tsx index 466534d..428795b 100644 --- a/resources/js/pages/budgets/index.tsx +++ b/resources/js/pages/budgets/index.tsx @@ -222,7 +222,7 @@ export default function Budgets({ Dotação acumulada: {money(b.approved_total_minor)}

{b.reason}

- {!b.approved_by && b.created_by !== auth.user.id && ( + {!b.approved_by && b.created_by !== auth.user?.id && (