114 lines
4.7 KiB
Markdown
114 lines
4.7 KiB
Markdown
---
|
|
type: rule
|
|
name: caminho-arquivos-minio
|
|
description: Padronização obrigatória de caminhos de arquivos persistidos no MinIO em quatro segmentos ({inquilino}/{tabela_origem}/{codigo_origem}/{id})
|
|
scope: global
|
|
trigger: model_decision
|
|
updatedAt: "2026-10-14"
|
|
---
|
|
|
|
# Regra: Padronização Obrigatória de Caminhos de Arquivos no MinIO
|
|
|
|
## Contexto
|
|
|
|
Todos os arquivos persistidos e referenciados no MinIO dentro dos módulos do ecossistema (identificados via `modulo-id` em `memorias-ia/modulo.yml`) devem seguir uma estrutura canônica hierárquica e determinística composta por **exatamente quatro segmentos**:
|
|
|
|
```
|
|
{inquilino}/{tabela_origem}/{codigo_origem}/{id}
|
|
```
|
|
|
|
Essa padronização evita colisão de arquivos entre inquilinos ou entidades, permite identificação imediata da origem do arquivo e padroniza a gestão de permissões e storage.
|
|
|
|
---
|
|
|
|
## 1. Regra de Formato e Validação Canônica
|
|
|
|
Todo caminho de arquivo enviado para o MinIO deve ser construído via função canônica `caminhoMinio` exportada pelo pacote `<modulo>-comuns` (onde `<modulo>` é extraído de `memorias-ia/modulo.yml`) e validado por `regexCamninhoMinio`:
|
|
|
|
```typescript
|
|
/** Valida quatro segmentos e exige extensão no id. */
|
|
export const regexCamninhoMinio = /^[\w$.-]+\/\w+\/[\w.-]+\/[\w.%$-]+\.\w+$(?![\s\S])/
|
|
|
|
export type CaminhoMinioParams = {
|
|
inquilino: string
|
|
tabela_origem: string
|
|
codigo_origem: string
|
|
id: string
|
|
}
|
|
|
|
export const caminhoMinio = ({
|
|
inquilino,
|
|
tabela_origem,
|
|
codigo_origem,
|
|
id,
|
|
}: CaminhoMinioParams): string => {
|
|
const partes = [inquilino, tabela_origem, codigo_origem, id]
|
|
const caminho = partes.join("/")
|
|
|
|
if (partes.some((parte) => parte.includes("/")) || !regexCamninhoMinio.test(caminho)) {
|
|
throw new Error("Caminho MinIO inválido")
|
|
}
|
|
|
|
return caminho
|
|
}
|
|
```
|
|
|
|
### Regras dos Quatro Segmentos
|
|
1. **`inquilino`**: Identificador do município / cliente / tenant (ex.: `padrao-rs`). Não pode conter barras.
|
|
2. **`tabela_origem`**: Nome canônico da tabela no banco de dados (ex.: `tabelas.licenciamentos`, `tabelas.denuncias`, `tabelas.oficios`).
|
|
3. **`codigo_origem`**: UUID ou identificador único do registro na tabela de origem (ou identificador de escopo como `sistema` para brasões/ativos globais do tenant).
|
|
4. **`id`**: Identificador único do arquivo acompanhado obrigatoriamente de sua extensão (ex.: `01J...pdf`, `brasao.png`, `oficio_123.pdf`).
|
|
|
|
---
|
|
|
|
## 2. Persistência Obrigatória no Banco de Dados
|
|
|
|
É **mandatório** que toda coluna do banco de dados que armazena referências a arquivos salve a **string completa retornada por `caminhoMinio`** (os 4 segmentos unidos por barras).
|
|
|
|
Exemplos de colunas que armazenam o caminho completo:
|
|
- `licencas.codigo_arquivo`
|
|
- `anexos.codigo_arquivo`
|
|
- `denuncias.codigo_pdf_documento`
|
|
- `oficios.codigo_pdf_documento`
|
|
- `documentos_registros.codigo_pdf_documento`
|
|
- `auto_de_infracao.codigo_pdf_documento`
|
|
- `fluxos_recebimentos.codigo_pdf_documento`
|
|
- `entidades.prefeitura_brasao`
|
|
|
|
> ⚠️ **Atenção:** Nunca salve apenas o último segmento (`id`) de arquivos gerados ou anexados. A string armazenada no banco deve ser a chave completa de 4 segmentos.
|
|
|
|
---
|
|
|
|
## 3. Upload e Integração com Plugins MinIO
|
|
|
|
No backend (`<modulo>-back`):
|
|
- O plugin `enviarArquivoMiniO` valida o `codigoArquivo` recebido contra `regexCamninhoMinio`.
|
|
- Caso `codigoArquivo` já contenha barras, o plugin reconhece que o inquilino já está incorporado no primeiro segmento e faz o upload direto para essa chave, sem duplicar o prefixo do inquilino.
|
|
- No download ou cache temporário (`baixarArquivoMiniO`), caso a chave possua barras, o nome do arquivo temporário local em disco deve substituir as barras por underscores (`replace(/\//g, "_")`) para evitar erros de diretórios inexistentes em `/tmp`.
|
|
|
|
---
|
|
|
|
## 4. Miniaturas e Resoluções Gráficas
|
|
|
|
No caso de imagens que possuem geração de miniaturas (thumbnails via Sharp):
|
|
- A miniatura adiciona o sufixo `_y{tamanho}` **antes da extensão no 4º segmento**:
|
|
`{inquilino}/{tabela_origem}/{codigo_origem}/{id_base}_y200.{ext}`
|
|
- No frontend (`<modulo>-front`), helpers como `urlArquivoBaixar` devem utilizar `lastIndexOf(".")` para formatar a URL da miniatura mantendo a hierarquia intacta.
|
|
|
|
---
|
|
|
|
## 5. Compatibilidade Legada
|
|
|
|
O helper `bucket().caminho` em `<modulo>-comuns` é retrocompatível:
|
|
- Se `id` contém barras (`/`), ele já representa o caminho estruturado completo e é retornado sem alteração.
|
|
- Se `id` não contém barras, ele trata como registro legado de 1 segmento e compõe `{inquilino}/{id}`.
|
|
|
|
---
|
|
|
|
## Referências
|
|
|
|
- Identidade do Módulo: `memorias-ia/modulo.yml`
|
|
- `<modulo>-comuns/src/minio.ts`
|
|
- `<modulo>-back/src/plugins/MiniO/enviarArquivoMiniO.ts`
|
|
- `<modulo>-back/src/plugins/MiniO/baixarArquivoMiniO.ts`
|
|
- `<modulo>-front/src/api/recursos/arquivos.ts`
|