Arquivos (GridFS)
files grava arquivos no MongoDB do App (bucket oon_files), isolados por tenant e compartilhados entre réplicas.
O módulo files substitui a pasta local uploads, que é de cada pod: com várias réplicas, um arquivo gravado em uma delas não aparecia nas outras e se perdia no reinício. Agora os arquivos ficam em GridFS no banco do próprio App, no bucket oon_files, sempre com escopo de tenant.
Uso em uma rota
const { defineRoutes, files, GenericError } = require("@oondemand/oon-core-back");
defineRoutes("/anexos", (router) => {
router.private.post("/", { permission: "anexos.write" }, async (req, res) => {
const { filename, contentType, base64 } = req.body ?? {};
if (!filename || !base64) throw new GenericError("Envie o arquivo.", { statusCode: 422, code: "ANEXO_INVALIDO" });
const saved = await files.forRequest(req).save({
data: Buffer.from(base64, "base64"),
filename,
contentType,
metadata: { origem: "upload" },
});
res.status(201).json(saved);
});
router.private.get("/:id", { permission: "anexos.read" }, async (req, res) => {
await files.forRequest(req).send(res, req.params.id, { download: true });
});
router.private.get("/", { permission: "anexos.read" }, async (req, res) => {
res.json(await files.forRequest(req).list({ limit: 50 }));
});
});
files.forRequest(req) usa o tenant de req.accessContext; sem tenant (Apps none), o escopo é global.
API
| Função | Descrição |
|---|---|
saveFile({ data, filename, contentType?, metadata?, maxBytes?, tenantId | global }) |
Grava Buffer, string ou Readable; devolve os metadados |
getFileInfo(id, owner) |
Metadados no escopo |
openFile(id, owner) |
{ file, stream } para leitura em stream |
readFile(id, owner) |
{ file, data: Buffer } |
listFiles(owner, { limit?, filename? }) |
Lista do mais recente ao mais antigo (limite até 500) |
deleteFile(id, owner) |
Remove; { deleted: true, id } |
sendFile(res, id, owner, { download? }) |
Responde com Content-Type, Content-Length, nosniff e Content-Disposition |
forRequest(req) |
Atalho com save, info, open, read, list, remove, send |
Metadados retornados:
{ "id": "…", "filename": "nota.pdf", "length": 48213, "contentType": "application/pdf", "tenantId": "t-1", "metadata": { "origem": "upload" }, "uploadDate": "…" }
Limites e erros
| Código | Status | Causa |
|---|---|---|
FILE_TENANT_REQUIRED |
400 | Operação sem tenant e sem global: true |
FILE_NOT_FOUND |
404 | ID inexistente ou de outro tenant |
FILE_TOO_LARGE |
413 | Acima de maxBytes (padrão 25 MB) |
FILE_NAME_INVALID |
422 | Nome vazio, maior que 255 caracteres ou com /, \ ou NUL |
FILE_STORAGE_UNAVAILABLE |
503 | Banco indisponível |