81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
|
|
import { Router } from "express";
|
||
|
|
import multer from "multer";
|
||
|
|
import { checkClarizenAuth, createClarizenClient, getApiKey } from "../clarizen/client.js";
|
||
|
|
import { ExcelParseError, parseExcelBuffer } from "../excel/parse.js";
|
||
|
|
import { buildWorkItemHeaderResolver } from "../import/field-headers.js";
|
||
|
|
import { processImport } from "../import/processor.js";
|
||
|
|
import { ClarizenApiError } from "@arco/clarizen-lib";
|
||
|
|
|
||
|
|
const upload = multer({
|
||
|
|
storage: multer.memoryStorage(),
|
||
|
|
limits: { fileSize: 10 * 1024 * 1024 },
|
||
|
|
fileFilter: (_req, file, cb) => {
|
||
|
|
const name = file.originalname.toLowerCase();
|
||
|
|
if (name.endsWith(".xlsx") || name.endsWith(".xls")) {
|
||
|
|
cb(null, true);
|
||
|
|
} else {
|
||
|
|
cb(new Error("Envie um arquivo .xlsx ou .xls"));
|
||
|
|
}
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
export const importRouter = Router();
|
||
|
|
|
||
|
|
importRouter.post(
|
||
|
|
"/import",
|
||
|
|
upload.single("file"),
|
||
|
|
async (req, res) => {
|
||
|
|
try {
|
||
|
|
if (!getApiKey()) {
|
||
|
|
res.status(500).json({
|
||
|
|
error: "Defina CLARIZEN_API_KEY ou API_KEY_AW no arquivo .env",
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!req.file) {
|
||
|
|
res.status(400).json({ error: "Nenhum arquivo enviado. Use o campo 'file'." });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const clarizen = createClarizenClient();
|
||
|
|
const auth = await checkClarizenAuth(clarizen);
|
||
|
|
if (!auth.ok) {
|
||
|
|
res.status(auth.status ?? 502).json({
|
||
|
|
error: `Falha de autenticação no Clarizen: ${auth.message}`,
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const resolver = await buildWorkItemHeaderResolver(clarizen);
|
||
|
|
const parsed = parseExcelBuffer(req.file.buffer, resolver);
|
||
|
|
const result = await processImport(clarizen, parsed);
|
||
|
|
res.json({ ...result, headerMapping: resolver.mapping });
|
||
|
|
} catch (err) {
|
||
|
|
if (err instanceof ExcelParseError) {
|
||
|
|
res.status(400).json({ error: err.message });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (err instanceof multer.MulterError) {
|
||
|
|
res.status(400).json({ error: err.message });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (err instanceof Error && err.message.includes(".xlsx")) {
|
||
|
|
res.status(400).json({ error: err.message });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (err instanceof ClarizenApiError) {
|
||
|
|
res.status(err.status >= 400 && err.status < 600 ? err.status : 502).json({
|
||
|
|
error: err.message,
|
||
|
|
errorCode: err.errorCode,
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
console.error("[import]", err);
|
||
|
|
res.status(500).json({
|
||
|
|
error: err instanceof Error ? err.message : "Erro interno ao importar",
|
||
|
|
});
|
||
|
|
}
|
||
|
|
},
|
||
|
|
);
|