asu_tools_service/handlers/reports/parseExcel.handler.js
2026-08-26 12:56:59 +03:00

80 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { BadRequestError, ServiceUnavailableError } from "#root/http-server/index.js";
import { clients } from "#root/index.js";
import { reportsService } from "#services/index.js";
import { serializeError } from "serialize-error";
/** @import { HttpRouteHandler } from "#root/http-server/types/http-server.js" */
const MAX_CONCURRENT_PARSE_CLIENT = Number.parseInt(process.env.REPORT_CONCURRENT_PARSE_CLIENTS || "3", 10);
/**
* URL: /api/reports_excel_file_parse
* Method: POST
* Description: Принимает на вход файл отчетов в формате Excel, парсит его, проверяет связи с БД,
* отдает идентификатор на статус парсинга.
*
* @type {HttpRouteHandler}
*/
export default async (ctx) => {
const { res, searchParams } = ctx;
const [, files] = ctx.data;
const clientId = searchParams.get("clientId");
const excelFilepath = files?.report?.at(0)?.filepath;
if (!ctx.data) {
throw new BadRequestError("Cannot proceed uploaded file");
}
if (!clientId) {
throw new BadRequestError('"clientId" parameter is required');
}
const sseClientCtx = clients.get(clientId);
const parseProcessClients = clients
.values()
.filter((sseClientCtx) => sseClientCtx.local?.isParsing)
.toArray();
if (parseProcessClients.length >= MAX_CONCURRENT_PARSE_CLIENT) {
throw new ServiceUnavailableError(`Maximum concurrent parse clients reached limit`);
}
if (!sseClientCtx) {
throw new ServiceUnavailableError("Cannot proceed request due to unknown client");
}
if (sseClientCtx.local.isParsing) {
throw new ServiceUnavailableError("Your request on parsing is processing");
}
/** @param {ParsedReport} report */
const onParseProgress = async (report) => sseClientCtx.res.sendSSEJson(report, "progress");
const cancelAnalyzeCond = () => Boolean(sseClientCtx.local?.isClosed);
if (excelFilepath) {
try {
const reports = reportsService.parseExcelFile(excelFilepath);
const { result, reports: reportsPromises } = reportsService.analyzeParseResult(
reports,
cancelAnalyzeCond,
onParseProgress
);
sseClientCtx.local.isParsing = true;
res.sendJson({ message: "OK" });
await Promise.all(reportsPromises);
sseClientCtx.res.sendSSEJson(result, "done");
} catch (error) {
console.error(error);
sseClientCtx.res.sendSSEJson({ error: serializeError(error) }, "parseError");
} finally {
sseClientCtx.local.isParsing = false;
}
} else {
throw new BadRequestError();
}
return;
};