Skip to main content

Arquitetura de storage

O módulo de upload usa MinIO (compatível com S3) com dois buckets de propósitos distintos:
BucketVisibilidadeAcessoUsado para
MINIO_BUCKETPrivadoPresigned URL (expira em 15min)CPF, RG, comprovante, contratos assinados
MINIO_BUCKET_FOTOSPúblicoURL permanenteFotos de imóveis, inspeções, inventário
Nunca salve Presigned URLs no banco de dados — elas expiram em 15 minutos. Salve apenas a key e gere a URL sob demanda via GET /upload/:recurso/:id/documento.

Limites

ParâmetroValor
Tamanho máximo20MB por arquivo
Tipos aceitosimage/jpeg, image/png, image/webp, application/pdf, video/mp4, video/quicktime
Máx. arquivos10 (imóvel, inventário) / 20 (inspeção)

Status do MinIO

Endpoint público — não requer autenticação. Útil para verificar se o storage está operacional antes de iniciar uploads.
GET /upload/status
Resposta 200
{
  "minioAtivo": true,
  "endpoint": "https://minio.seudominio.com",
  "bucketPrivado": {
    "nome": "patrimonion-docs",
    "tipo": "PRIVADO — documentos sensíveis (Presigned URLs, 15 min)",
    "uso": ["CPF", "RG", "comprovante de residência", "contratos assinados"]
  },
  "bucketPublico": {
    "nome": "patrimonion-fotos",
    "tipo": "PÚBLICO — fotos e mídias (URLs permanentes)",
    "uso": ["fotos de imóveis", "fotos de inspeções", "fotos de inventário"]
  }
}

Documentos do locatário

Upload

Aceita até 4 campos simultâneos via multipart/form-data. Todos vão para o bucket privado.
CampoDescrição
doc_cpfFoto ou scan do CPF (1 arquivo)
doc_rgFoto ou scan do RG (1 arquivo)
doc_comprovanteComprovante de residência (1 arq.)
doc_outrosOutros documentos (até 10)
POST /upload/locatario/:locatarioId
Cookie: imob_session=<session_cookie>
Content-Type: multipart/form-data

doc_cpf: <arquivo>
doc_rg: <arquivo>
Resposta 201
{
  "message": "2 tipo(s) de documento enviado(s) com sucesso.",
  "documentos": {
    "cpf": {
      "key": "uid123/locatarios/loc456-joao-da-silva/cpf/1706123456789.jpg",
      "nome": "cpf_joao.jpg",
      "enviadoEm": "2025-02-01T10:00:00.000Z"
    }
  }
}

Gerar URL de visualização

GET /upload/locatario/:locatarioId/documento?tipo=cpf
Cookie: imob_session=<session_cookie>
tipo
string
required
Tipo do documento: cpf, rg, comprovante, outros.
index
number
default:"0"
Índice do arquivo (somente para tipo=outros).
Resposta 200
{
  "url": "https://minio.seudominio.com/...",
  "expiresInMinutes": 15,
  "aviso": "Esta URL expira em 15 minutos. Não salve — gere uma nova quando precisar."
}

Contrato assinado

Aceita apenas PDF. Vai para o bucket privado e atualiza o campo contratoAssinadoKey no Firestore.
POST /upload/contrato/:contratoId
Cookie: imob_session=<session_cookie>
Content-Type: multipart/form-data

arquivo: <arquivo.pdf>
Resposta 201
{
  "message": "Contrato assinado enviado com sucesso.",
  "key": "uid123/contratos/con789/1706123456789.pdf"
}

Gerar URL de visualização

GET /upload/contrato/:contratoId/documento
Cookie: imob_session=<session_cookie>

Fotos do imóvel

Aceita até 10 arquivos por requisição. URLs permanentes no bucket público.
POST /upload/imovel/:imovelId
Cookie: imob_session=<session_cookie>
Content-Type: multipart/form-data

arquivos: <arquivo1>, <arquivo2>, ...
Resposta 201
{
  "message": "3 foto(s) enviada(s).",
  "fotos": [
    {
      "key": "uid123/imoveis/abc123/1706123456789.jpg",
      "url": "https://minio.seudominio.com/patrimonion-fotos/uid123/imoveis/abc123/foto.jpg",
      "nome": "sala.jpg",
      "enviadoEm": "2025-02-01T10:00:00.000Z"
    }
  ]
}

Listar fotos

GET /upload/imovel/:imovelId/fotos
Cookie: imob_session=<session_cookie>

Mídias de inspeção

Aceita até 20 arquivos (fotos e vídeos). A API separa automaticamente em fotosKeys e videosKeys com base no mimetype.
POST /upload/inspecao/:inspecaoId
Cookie: imob_session=<session_cookie>
Content-Type: multipart/form-data

arquivos: <arquivo1>, <arquivo2>, ...

URL de vídeo

Valida o vínculo entre a key e a inspeção antes de retornar a URL.
GET /upload/inspecao/:inspecaoId/video?key=uid123/inspecoes/vis001/videos/video.mp4
Cookie: imob_session=<session_cookie>

Fotos de inventário

Aceita até 10 arquivos por item. O campo fotosKeys armazena tanto fotos quanto vídeos.
POST /upload/inventario/:itemId
Cookie: imob_session=<session_cookie>
Content-Type: multipart/form-data

arquivos: <arquivo1>, <arquivo2>, ...

Deletar arquivo

Remove o arquivo do MinIO e limpa a referência no Firestore em uma única operação.
key
string
required
Caminho completo do arquivo no MinIO (ex: uid123/imoveis/abc123/foto.jpg).
publico
string
"true" se o arquivo está no bucket público. Padrão: bucket privado.
DELETE /upload/:colecao/:docId/arquivo?key=uid123/imoveis/abc123/foto.jpg&publico=true
Cookie: imob_session=<session_cookie>

Coleções válidas

ValorFirestore Collection
locatariolocatarios
imovelimoveis
inspecaoinspecoes
inventarioinventario
contratocontratos
Resposta 200
{
  "message": "Arquivo e referência deletados com sucesso."
}
A key deve sempre começar com o userId do usuário autenticado. Tentativas de deletar arquivos de outros usuários retornam 403 Forbidden.