SGEProduto · Domínio · Desenvolvimento
Repositório

integration-contract · defined

Geração de documentos DOCX e variáveis

Arquitetura da geração DOCX, validação de templates e catálogo canônico de variáveis.

Decisão técnica

Cada upload validado de um DOCX diferente cria uma versão do template lógico. O catálogo de variáveis é fixo no código; cada arquivo usa as variáveis necessárias. A geração usa a versão validada mais recente e registra a versão exata em generated_documents, sem criar uma versão nova por documento. Se uma correção substituir um arquivo já usado, o anterior permanece; versões nunca usadas podem ser excluídas fisicamente.

O arquivo DOCX versionado será processado localmente com PhpOffice\PhpWord\TemplateProcessor. A dependência phpoffice/phpword deverá ser direta no composer.json; a imagem de execução precisa das extensões zip, xml, dom, mbstring e intl. brick/math também será dependência direta porque o código de moeda o utiliza, ainda que Laravel já o instale transitivamente.

O marcador canônico é ${NOME_DA_VARIAVEL}: letras maiúsculas, números e _, sem espaços, barras, acentos ou chaves duplas. Somente essa sintaxe será aceita nos templates cadastrados.

Componentes

ComponenteResponsabilidade
TemplateVariableCatalogDefine nomes permitidos, tipo, sensibilidade, origem e formatação.
TemplateInspectorLê o DOCX como ZIP/XML e encontra variáveis inclusive em tabelas, cabeçalhos e rodapés.
TemplateValidatorRejeita variável desconhecida, obrigatória ausente, arquivo inválido e conteúdo inseguro.
DocumentSnapshotBuilderCarrega FKs e snapshots do estágio e produz um contexto imutável.
DocumentVariableResolverResolve somente as variáveis declaradas pela versão do template.
RemunerationParagraphFormatterProduz o texto completo de ${PARAGRAFO_REMUNERACAO}.
DocxDocumentGeneratorAplica valores no template, verifica sobras e salva em arquivo temporário privado.
GenerateInternshipDocumentAutoriza, bloqueia concorrência, registra snapshot/status e entrega o arquivo.

Helpers continuam restritos a formatação pura (CurrencyHelper, NumberToWordsHelper, datas e documentos). Regra jurídica, consulta ao banco, autorização e persistência pertencem aos serviços/Actions acima.

Fluxo de geração

  1. o Setor escolhe um template lógico e a versão validada mais recente compatível com o campus e o tipo documental;
  2. a Policy valida o vínculo ativo e o estágio;
  3. a Action adquire lock por estágio, versão e token idempotente;
  4. o builder carrega o contexto histórico, sem usar cadastro atual no lugar de snapshot já congelado;
  5. o resolver produz somente as variáveis declaradas no schema da versão;
  6. o gerador preenche uma cópia privada e temporária do DOCX;
  7. uma inspeção final rejeita qualquer ${...} restante;
  8. após geração bem-sucedida, generated_documents registra template, hash, nome de saída e snapshot dos valores;
  9. o arquivo é transmitido ao usuário autorizado e apagado em finally;
  10. nova emissão cria novo registro; um retry com o mesmo token não duplica a geração.

Geração unitária será síncrona para permitir download imediato sem armazenamento definitivo. Lotes futuros poderão usar Job, mas o resultado permanecerá em armazenamento temporário privado com prazo curto e limpeza automática. DOCX/PDF final e documento assinado não são acervo do SGE.

Validação e segurança do upload

  • aceitar apenas .docx OOXML; rejeitar .docm, OLE e executáveis embutidos;
  • validar MIME, assinatura ZIP, tamanho total, quantidade e tamanho descompactado das entradas;
  • rejeitar relacionamentos externos, links de template remoto e macros;
  • calcular SHA-256 e impedir duplicata acidental dentro do mesmo template;
  • extrair variáveis de corpo, tabelas, cabeçalhos, rodapés, notas e caixas de texto suportadas;
  • rejeitar variáveis fora do catálogo e variáveis obrigatórias do schema que não estejam no arquivo;
  • registrar relatório de validação e impedir ativação enquanto houver erro;
  • gerar com dados fictícios, renderizar e exigir confirmação visual do Setor antes da ativação;
  • nunca incluir o comprovante de emancipação, tokens, senhas, logs ou metadados internos no contexto documental.

Catálogo de variáveis

Cada versão declara quais itens abaixo são obrigatórios ou opcionais. Uma variável conhecida não se torna automaticamente disponível em todo template: o tipo de documento e a Policy limitam o contexto.

Documento e instituição

VariávelOrigem/formato
${DOCUMENTO_NUMERO}identificador público da geração, quando aplicável.
${DOCUMENTO_DATA_EMISSAO}data da geração em dd/mm/aaaa.
${DOCUMENTO_DATA_EMISSAO_EXTENSO}data por extenso em pt_BR.
${DOCUMENTO_TITULO}nome lógico aprovado da versão.
${CAMPUS_NOME}snapshot do campus.
${CAMPUS_CNPJ}CNPJ formatado.
${CAMPUS_EMAIL} / ${CAMPUS_TELEFONE}contatos institucionais.
${CAMPUS_ENDERECO}endereço composto.
${CAMPUS_LOGRADOURO} / ${CAMPUS_NUMERO} / ${CAMPUS_BAIRRO}partes do endereço.
${CAMPUS_CIDADE} / ${CAMPUS_UF} / ${CAMPUS_CEP}localidade formatada.
${CAMPUS_REPRESENTANTE_NOME}pessoa representante no snapshot da geração.
${CAMPUS_REPRESENTANTE_CARGO}cargo institucional no vínculo/snapshot.
${CAMPUS_RESPONSAVEL_ESTAGIOS_NOME}signatário institucional configurado para o documento.
${CAMPUS_RESPONSAVEL_ESTAGIOS_CARGO}cargo exibido do signatário.
${SEGURO_SEGURADORA} / ${SEGURO_APOLICE}configuração institucional vigente, congelada na geração.

Discente, curso e responsável

VariávelOrigem/formato
${ALUNO_NOME}student_snapshot.name.
${ALUNO_EMAIL} / ${ALUNO_TELEFONE}contatos do snapshot.
${ALUNO_MATRICULA}matrícula do vínculo discente.
${ALUNO_PERIODO}ano/semestre declarado e validado.
${ALUNO_NASCIMENTO}dd/mm/aaaa.
${ALUNO_CPF} / ${ALUNO_RG}documentos formatados.
${ALUNO_RG_ORGAO} / ${ALUNO_RG_DATA_EMISSAO}emissor e data.
${ALUNO_ENDERECO}endereço completo de internships.student_address_id, quando houver; a cidade é resolvida por city_id.
${ALUNO_LOGRADOURO} / ${ALUNO_NUMERO} / ${ALUNO_BAIRRO}partes do endereço.
${ALUNO_CIDADE} / ${ALUNO_UF} / ${ALUNO_CEP}localidade formatada.
${CURSO_NOME}curso do estágio.
${RESPONSAVEL_NOME} / ${RESPONSAVEL_CPF}somente para menor não emancipado.
${RESPONSAVEL_PARENTESCO} / ${RESPONSAVEL_EMAIL}dados do responsável legal.
${BLOCO_RESPONSAVEL_LEGAL}bloco completo ou vazio; emancipação validada não expõe comprovante.

Parte concedente

VariávelOrigem/formato
${CONCEDENTE_NOME}granting_party_snapshot.name.
${CONCEDENTE_DOCUMENTO}CPF/CNPJ formatado conforme o tipo.
${CONCEDENTE_EMAIL} / ${CONCEDENTE_TELEFONE}contatos do snapshot.
${CONCEDENTE_AREA_ATUACAO}área de atuação.
${CONCEDENTE_ENDERECO}endereço completo de internships.workplace_address_id, preservado na formalização; a concedente atual não substitui essa referência histórica.
${CONCEDENTE_LOGRADOURO} / ${CONCEDENTE_NUMERO} / ${CONCEDENTE_BAIRRO}partes do endereço.
${CONCEDENTE_CIDADE} / ${CONCEDENTE_UF} / ${CONCEDENTE_CEP}localidade formatada.
${CONCEDENTE_REPRESENTANTE_NOME}representante legal.
${CONCEDENTE_REPRESENTANTE_CARGO}cargo do representante.
${CONCEDENTE_CONSELHO_PROFISSIONAL}vazio quando não houver.
${CONCEDENTE_REGISTRO_CONSELHO}vazio quando não houver.
${CONCEDENTE_PROCESSO_CREDENCIAMENTO}obrigatório apenas no modelo que o exigir.

Orientação e supervisão

VariávelOrigem/formato
${ORIENTADOR_NOME} / ${ORIENTADOR_EMAIL}snapshot do vínculo orientador.
${ORIENTADOR_MATRICULA}matrícula institucional, se exigida.
${SUPERVISOR_NOME}supervisor_snapshot.name.
${SUPERVISOR_EMAIL} / ${SUPERVISOR_TELEFONE}contatos do snapshot.
${SUPERVISOR_CARGO}cargo/função na concedente.
${SUPERVISOR_QUALIFICACAO}qualificação declarada e aprovada.
${SUPERVISOR_FORMACAO} / ${SUPERVISOR_EXPERIENCIA}opcionais conforme o documento.

Estágio, jornada e remuneração

VariávelOrigem/formato
${ESTAGIO_TIPO}nome do tipo congelado.
${ESTAGIO_SETOR}setor/área de realização.
${ESTAGIO_ATIVIDADES}texto do plano de atividades.
${ESTAGIO_DATA_INICIO}dd/mm/aaaa.
${ESTAGIO_DATA_TERMINO_PREVISTA}resultado vigente do cálculo.
${ESTAGIO_CARGA_TOTAL} / ${ESTAGIO_CARGA_TOTAL_EXTENSO}horas exigidas.
${ESTAGIO_CARGA_DIARIA_MAXIMA} / ${ESTAGIO_CARGA_DIARIA_MAXIMA_EXTENSO}maior jornada diária da vigência usada.
${ESTAGIO_CARGA_SEMANAL} / ${ESTAGIO_CARGA_SEMANAL_EXTENSO}soma semanal da vigência usada.
${ESTAGIO_JORNADA_DESCRICAO}descrição por dia da semana, pronta para bloco textual.
${ESTAGIO_REMUNERADO}Sim ou Não; usar apenas quando o modelo realmente pedir.
${ESTAGIO_BOLSA_VALOR} / ${ESTAGIO_BOLSA_EXTENSO}moeda BRL e valor por extenso.
${ESTAGIO_AUXILIO_TRANSPORTE_VALOR} / ${ESTAGIO_AUXILIO_TRANSPORTE_EXTENSO}moeda BRL e valor por extenso.
${PARAGRAFO_REMUNERACAO}§1º completo e descritivo; substitui definitivamente ESPECIAL.
${ESTAGIO_PROTOCOLO_SIGAA}protocolo, quando já existir e o documento permitir.

Aditivo e rescisão

VariávelOrigem/formato
${ADITIVO_NUMERO}sequência do aditivo dentro do estágio.
${ADITIVO_VIGENCIA_INICIO}data em que a alteração passa a valer.
${ADITIVO_DESCRICAO_ALTERACAO}texto produzido a partir das mudanças aprovadas.
${RESCISAO_DATA_EFETIVA}data aprovada no pedido de cancelamento.
${RESCISAO_JUSTIFICATIVA}motivo aprovado, sem texto fixo no template.
${RESCISAO_SOLICITANTE_NOME}pessoa/parte que solicitou, quando exigido.

Atestado de orientação e notas

VariávelOrigem/formato
${ESTAGIO_NOTA_SUPERVISOR}nota aprovada na escala de seu peso.
${ESTAGIO_NOTA_RELATORIO} / ${ESTAGIO_NOTA_APRESENTACAO}contribuições lançadas pelo orientador.
${ESTAGIO_NOTA_FINAL}soma consolidada de 0 a 10.
${ESTAGIO_PERIODO}início e término formatados em uma expressão.
${ATESTADO_CARGA_ORIENTACAO}somente se existir regra institucional própria.

Parágrafo de remuneração

Não existe variável ${ESPECIAL}. ${PARAGRAFO_REMUNERACAO} recebe o parágrafo completo e é resolvida por regra de domínio:

  • não remunerado: texto institucional informando ausência de bolsa e auxílio-transporte;
  • remunerado: texto institucional com bolsa e auxílio-transporte, cada valor em BRL e por extenso;
  • ausência de auxílio: usar o texto aprovado para zero/ausência, sem produzir R$ 0,00 por acidente;
  • valores são decimal/BigDecimal, nunca float;
  • o texto efetivamente usado entra no snapshot da geração.

O texto jurídico deve ser aprovado uma vez pela instituição e coberto por teste de snapshot. O discente não edita o parágrafo.

Dados obrigatórios por template

A versão armazena required_variables e optional_variables. Na geração, valor vazio em variável obrigatória interrompe o processo e informa os campos faltantes. Variável opcional vazia vira string vazia ou bloco omitido conforme o contrato. Blocos compostos devem ser preferidos quando remover apenas um valor deixaria rótulos, pontuação ou linhas vazias no documento.

Testes de aceitação

  • template válido e inválido, variável desconhecida e marcador remanescente;
  • marcador dividido em múltiplos runs do Word, em tabela, cabeçalho e rodapé;
  • acentos, quebras de linha, &, <, > e texto longo;
  • maior, menor com responsável e menor emancipado sem exposição da prova;
  • remunerado, não remunerado e auxílio ausente;
  • TCE padrão, credenciamento, SEDUC, EMATER, aditivo, rescisão e atestado;
  • falha antes/depois da criação do temporário com limpeza garantida;
  • duas requisições concorrentes e retry idempotente;
  • renderização visual de todas as páginas antes de disponibilizar cada versão.

Referências