Receber documentos privados e locais de disponibilidade nas candidaturas
tests / ci (push) Canceled after 0s

This commit is contained in:
2026-10-30 20:52:10 +02:00
parent 2134aa084b
commit bf84575d10
26 changed files with 2756 additions and 49 deletions
+24
View File
@@ -1,5 +1,29 @@
# Desenvolvimento do SGC
## CV e documentos na candidatura electrónica, 30 de Outubro de 2026
Recepção de documentos integrada no mesmo envio da candidatura. A obrigatoriedade, formatos (PDF, DOCX, JPG e PNG) e limite por ficheiro vêm do formulário preservado na preparação do processo, sem procurar a versão actual da empresa. Recusados documentos desconhecidos, obrigatórios em falta, tamanho excessivo e divergência de extensão/MIME/conteúdo. DOCX exige estrutura Word/XML válida, sem declarações de entidades/DOCTYPE, macros ou executáveis conhecidos, com limites de entradas e expansão do arquivo. A conferência de formato não constitui antivírus, prova de autenticidade, validação do mérito ou aprovação documental.
Armazenamento privado separado, nomes físicos gerados e nome apresentado sanitizado. A candidatura conserva nome, tamanho, MIME e SHA-256, sem expor caminhos internos. Downloads separados para titular e equipa; conferem conta/sessão, empresa, processo e permissões actuais, registam consulta e verificam integridade dos bytes. Entrega como anexo, sem pré-visualização activa no portal. A tabela de documentos recebidos tem vínculo composto à submissão e protecção contra alteração/eliminação corrente. O comprovativo original não pode ser substituído por novo envio; mesmo identificador e mesmos ficheiros devolvem a submissão anterior, conteúdo diferente é recusado. Falha transaccional limpa os ficheiros gravados.
Limite técnico do conjunto por pedido configurável por `CANDIDATE_DOCUMENTS_MAX_TOTAL_KB` (inicialmente 102400 KB); limites específicos continuam na parametrização da empresa. Não existe ainda quota acumulada por candidato/empresa nem integração antivírus. Na entrega ao domínio, conferir extensões PHP DOM/ZIP/fileinfo, limites PHP/proxy e armazenamento persistente privado com backup/restauro; não activar uploads numa pasta efémera da release. Complementos, substituições e reabertura precisam de um percurso versionado próprio, sem alterar estes originais.
Migração aditiva `2026_10_30_000041_create_candidate_submission_documents` instalada apenas na avaliação local 8005. Backup fresco de 501935 bytes e restauro verificados; conteúdos anteriores das 104 tabelas preservados e nova tabela vazia. Sem alterar contas/grants, repetir outras migrações ou instalar no domínio. Prova `proofs/candidate-documents-install.json`. PostgreSQL descartável: 62 testes/1323 asserções aprovados, incluindo perfis e Pessoas; base removida. Suíte integral: 745 testes PHP, 743 aprovados, dois anteriormente ignorados e 7619 asserções. Módulo final SQLite: 24 testes/298 asserções; frontend integral: 83 testes aprovados. Tipos, PHPStan sem erros, Pint, lint dirigido, compilação e diff conferidos. A prova `proofs/candidate-documents.json` regista o âmbito e hashes. Os testes de navegação pública passam a usar uma fixture sintética versionada em tests/Fixtures, deixando de depender de um ficheiro privado ignorado pelo Git. A conferência visual dirigida mantém-se pendente.
## Disponibilidade geográfica múltipla do candidato, 30 de Outubro de 2026
O perfil permite manter o local principal e adicionar ou retirar outros locais, cada um com província, distrito e localidade. A morada continua separada. Entradas incompletas e locais repetidos (sem distinguir maiúsculas ou espaços exteriores) são recusados no servidor. Existe um limite técnico inicial de 20 locais adicionais por pedido, sem constituir uma política territorial ou uma classificação de candidatos. O cadastro territorial oficial continua pendente.
Cada gravação cria uma versão. Pedidos anteriores que omitem o novo campo preservam os locais adicionais já guardados; uma lista explicitamente vazia retira-os apenas da nova versão. No formulário de candidatura, o candidato pode escolher um local guardado para preencher o campo de disponibilidade, mantendo a possibilidade de o ajustar para aquela candidatura. A submissão preserva todos os locais da versão do perfil enviada. O comprovativo e a recepção interna mostram essa versão, sem consultar por arrasto o perfil actual. Não são criadas migrações, alteradas permissões ou executadas chamadas de IA.
Validação dirigida: 18 testes PHP/247 asserções nos módulos de perfil e submissões, incluindo conservação das versões, pedidos anteriores, rejeição de duplicados/incompletos e conservação da candidatura após alteração do perfil. Oito testes frontend, TypeScript, PHPStan sem erros, Pint, lint dirigido, compilação e verificação do diff aprovados. O comando global de formatação identificou três ficheiros JSON de histórico anteriores a este incremento; estes não foram alterados para o fazer passar. Conferência visual e PostgreSQL deste incremento ainda pendentes. Alteração apenas local, sem publicação no domínio. Próximo incremento funcional: anexos verificados para candidaturas, com requisitos e versões preservados, sem retirar exigências documentais existentes.
## Consulta pública confirmada em produção, 30 de Outubro de 2026
Commit `2134aa084be2d7be0a3bcaba74cc5eae604e6663` integrado em main, enviado e instalado pelo processo existente. Activação de `SGC_PUBLIC_NAVIGATION=true` no `.env` partilhado, com backup fresco da configuração e cache Laravel. A primeira tentativa foi revertida: PHP 8.5 CLI sem DOM/mbstring/XML. Activação concluída com PHP 8.4.27; restantes definições da cache conferidas como inalteradas. Sem migrações ou alterações de dados de negócio.
Conferência HTTP anónima no domínio: raiz encaminha para dashboard, 21 ecrãs públicos com HTTP 200 e componentes esperados, utilizador nulo e âmbito de dados vazio; seis percursos privados encaminham para login. O proprietário confirmou que o acesso funciona. Isso confirma o acesso observado, sem equivaler à conferência visual completa de todos os percursos afectados. Prova técnica local em `C:/laragon/worktrees/compras-public-delivery/storage/app/private/compras-production-http.json`.
## Triagem electrónica e aproveitamento na avaliação, 30 de Outubro de 2026
Recepção interna permite «Aceite para análise» ou «Não aceite para análise». Preparador com função e atribuição actuais, fora de manutenção, declara ausência de conflito e regista motivo interno e comunicação pública em campos separados. A decisão é preservada por inserção, com responsável/data/operação; repetição idêntica é idempotente e alteração posterior é recusada enquanto não existir percurso de revisão. Aceitar para análise não inclui a pessoa na base nem selecciona ou contrata.
@@ -0,0 +1,16 @@
{
"checked_at": "2026-10-30T18:48:58+00:00",
"migration": "2026_10_30_000041_create_candidate_submission_documents",
"environment": "local evaluation 8005",
"backup_file": "C:\/laragon\/data\/sgf-tempo\/backups\/compras-candidate-documents-20261030-184854\/before.dump",
"backup_sha256": "e3bd53977bceecdbdc716a574caa14f1ee9cb2ae8c3e3c988a00700d2fe1822e",
"backup_bytes": 501935,
"restore_verified": true,
"existing_tables_preserved": 104,
"new_tables": {
"candidate_submission_documents": 0
},
"accounts_or_grants_changed": false,
"other_migrations_applied": false,
"domain_installed": false
}
+16
View File
@@ -0,0 +1,16 @@
{
"checked_at": "2026-10-30T18:48:38+00:00",
"database": "disposable PostgreSQL",
"application_role_reused_without_privilege_change": true,
"result": "passed",
"test_files": [
"CandidateSubmissionsTest",
"PeopleHiringTest",
"CandidatePortalTest",
"CandidateDocumentFormatsTest"
],
"original_evaluation_untouched": true,
"database_removed": true,
"tests": 62,
"assertions": 1323
}
+71
View File
@@ -0,0 +1,71 @@
{
"checked_at": "2026-10-30T18:51:58.536440+00:00",
"base_commit": "2134aa084be2d7be0a3bcaba74cc5eae604e6663",
"scope": [
"multiple versioned candidate availability locations",
"reuse locations without re-entry",
"private immutable submission documents",
"versioned form document requirements",
"format MIME extension and size checks",
"bounded Word XML validation",
"same-operation retry and changed-content rejection",
"candidate and staff download authorisation",
"download SHA-256 verification",
"transaction failure cleanup",
"tracked anonymous public test fixtures"
],
"full_suite": {
"tool": "pest",
"result": "passed",
"tests": 745,
"passed": 743,
"assertions": 7619,
"duration_ms": 174707,
"skipped": 2
},
"module_sqlite": {
"tests": 24,
"assertions": 298,
"passed": true
},
"postgresql": {
"tests": 62,
"assertions": 1323,
"disposable_database_removed": true
},
"frontend": {
"tests": 83,
"passed": true
},
"typescript": true,
"phpstan_errors": 0,
"pint": true,
"targeted_lint": true,
"build": true,
"global_format_check": "blocked by three pre-existing ignored history JSON files; changed files checked separately",
"migration_installed": "local evaluation 8005 only",
"production_installed": false,
"visual_review": "pending",
"limitations": [
"no antivirus integration or authentication of document contents",
"no accumulated tenant storage quota",
"no document replacement or complements yet",
"production persistent storage PHP extensions and request limits must be checked before installation"
],
"source_sha256": {
"app/Services/CandidateProfiles.php": "287bec37f58fe2eb9f0fdcfb879a8e037d91b704d1de3af5a401364d2414eeae",
"app/Services/CandidateSubmissions.php": "3a89a181e288c7c1be5b417e943e0857c81058fb37118e8f86681d771c56860b",
"app/Services/CandidateDocuments.php": "898985829d6b1674baeadca9142e334c0b9624de00d71a7a3bcab727328a6604",
"app/Http/Controllers/CandidatePortalController.php": "9bad527126e939c95aa3b78f72deec4143bdd50ec77ddc5162d1dd33ee99639a",
"routes/web.php": "6400c72ebb90d796307af286b082ded8c8f019c0595b1a77f43a0eb059161c23",
"config/filesystems.php": "d627e636c65680051f12da58ff6cf0a8b1bd69ab054ae39824ca5a8d85110416",
"config/candidate_documents.php": "9ce54226b6701dd53df98613107e13c505ca9c42a13f9586a4015986a29fc7ae",
"database/migrations/2026_10_30_000041_create_candidate_submission_documents.php": "01e80309c5b193f262076d8f7f52a88a3ba75fb073bad369c22c2561c79663a9",
"resources/js/pages/candidate/profile.tsx": "ddf7f38aeff924bb5709d2c308c22cd726fad7eb904e09f6f31f52c51f275ce7",
"resources/js/pages/candidate/opportunity.tsx": "ffc86485fb488a62da6b25d6ca96bf208ac0cc6b9a480876aec28002a2a83008",
"resources/js/pages/candidate/receipt.tsx": "86a9ac93b5aa2b44aca8ee1a035a8bcce42c1482d5d50045770bc8c708028c78",
"resources/js/pages/people/submissions.tsx": "966f38a4a77e49fb3f66fde7def7ec1a617dcbe29516b41f2a8756d91fbb3acf",
"resources/js/components/candidate-documents.tsx": "6464f982bbd26cf2da714b517f758799974a6d953a18b27733f755ade07cc206",
"resources/js/components/candidate-availability.tsx": "4f44943790e0fac7b0edaf212912bc0264338cb70e7072acdfb5b1fde86d47d8"
}
}
+2
View File
@@ -16,6 +16,8 @@ Registos sem vínculo de cadastro continuam em compatibilidade; não foram ligad
## Matriz transversal de cobertura
Actualização de 30/10: o perfil externo admite vários locais de disponibilidade. A candidatura reutiliza um local guardado e conserva todos os locais da versão enviada. CV/documentos já podem acompanhar a submissão, com formato e limites do formulário preservado; o comprovativo e a recepção interna usam os mesmos anexos privados e hashes, sem novo carregamento pela equipa. Complementos e reutilização de um documento noutra candidatura ainda exigem um percurso próprio; não se associa um ficheiro de outra pessoa ou empresa por nome. Esta actualização substitui a indicação de anexos por desenvolver na linha de perfil externo abaixo.
| 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 |