feat: implement db layout caching for parsed ocr & reprocess batch test with corrected parser alignment

This commit is contained in:
Rafhan Mazaya Fathurrahman committed 2026-07-03 16:43:24 +07:00
1 parent 2900eb670b
commit 095dd4cb8b
6 files changed
+1140 -263

No files matched your search

+83 -60
View File
@@ -68,75 +68,98 @@ export async function POST(req: NextRequest) {
const b64 = fileBuffer.toString("base64");
// Form payload
const payload = {
file: b64,
matchHistoryJob: false,
useLayoutDetection: true,
fileType: 1,
useDocUnwarping: false,
useDocOrientationClassify: true
};
// Check if we already have a parsed document in the database with the exact filename (and has valid layout_parsing_result)
const cachedDoc = await query(
"SELECT layout_parsing_result, processing_logs FROM documents WHERE filename = $1 AND parsed = true",
[safeFile]
);
// Post to Pipeline API
const pipelineUrl = process.env.PIPELINE_URL || "http://localhost:7871/layout-parsing";
console.log(`Forwarding request to pipeline API: ${pipelineUrl}`);
const response = await fetch(pipelineUrl, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
if (!response.ok) {
const errText = await response.text();
console.warn(`Pipeline API error for ${safeFile}: ${errText}. Marking document as parsed with default metadata.`);
try {
await query(
"UPDATE documents SET parsed = true, metadata = $1 WHERE filename = $2",
[JSON.stringify({
tanggal: "Not Found",
noPO: "Not Found",
noSO: "Not Found",
noDO: "Not Found",
vendorInfo: "Not Found",
customerInfo: "Not Found",
items: []
}), safeFile]
);
} catch (dbErr) {
console.error("Failed to mark document as parsed on pipeline error:", dbErr);
}
return NextResponse.json({ error: `Pipeline API error: ${errText}` }, { status: response.status });
}
let data = await response.json();
// Check if the image is not straight (tilt > 1.0 degree)
const tilt = calculateAverageTilt(data);
let data: any = null;
let tilt = 0;
let unwarped = false;
if (tilt > 1.0) {
console.log(`Parsed document ${safeFile} is not straight (average tilt: ${tilt.toFixed(2)} deg). Re-running with unwarping and orientation classification enabled...`);
const unwarpPayload = {
...payload,
useDocUnwarping: true,
if (cachedDoc.rows.length > 0 && cachedDoc.rows[0].layout_parsing_result) {
console.log(`[Cache Hit] Found cached layout result for ${safeFile}. Skipping Pipeline API.`);
const rawData = cachedDoc.rows[0].layout_parsing_result;
const parsedData = typeof rawData === "string" ? JSON.parse(rawData) : rawData;
data = parsedData.result || parsedData;
const procLogs = cachedDoc.rows[0].processing_logs;
if (procLogs) {
const parsedLogs = typeof procLogs === "string" ? JSON.parse(procLogs) : procLogs;
tilt = parsedLogs?.pipeline_info?.tilt !== undefined ? Number(parsedLogs.pipeline_info.tilt) : 0;
unwarped = parsedLogs?.pipeline_info?.unwarped ?? false;
}
} else {
// Form payload
const payload = {
file: b64,
matchHistoryJob: false,
useLayoutDetection: true,
fileType: 1,
useDocUnwarping: false,
useDocOrientationClassify: true
};
const unwarpResponse = await fetch(pipelineUrl, {
// Post to Pipeline API
const pipelineUrl = process.env.PIPELINE_URL || "http://localhost:7871/layout-parsing";
console.log(`Forwarding request to pipeline API: ${pipelineUrl}`);
const response = await fetch(pipelineUrl, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(unwarpPayload)
body: JSON.stringify(payload)
});
if (unwarpResponse.ok) {
data = await unwarpResponse.json();
console.log(`Document unwarped successfully.`);
unwarped = true;
} else {
console.error(`Unwarping failed with status ${unwarpResponse.status}`);
if (!response.ok) {
const errText = await response.text();
console.warn(`Pipeline API error for ${safeFile}: ${errText}. Marking document as parsed with default metadata.`);
try {
await query(
"UPDATE documents SET parsed = true, metadata = $1 WHERE filename = $2",
[JSON.stringify({
tanggal: "Not Found",
noPO: "Not Found",
noSO: "Not Found",
noDO: "Not Found",
vendorInfo: "Not Found",
customerInfo: "Not Found",
items: []
}), safeFile]
);
} catch (dbErr) {
console.error("Failed to mark document as parsed on pipeline error:", dbErr);
}
return NextResponse.json({ error: `Pipeline API error: ${errText}` }, { status: response.status });
}
data = await response.json();
// Check if the image is not straight (tilt > 1.0 degree)
tilt = calculateAverageTilt(data);
if (tilt > 1.0) {
console.log(`Parsed document ${safeFile} is not straight (average tilt: ${tilt.toFixed(2)} deg). Re-running with unwarping and orientation classification enabled...`);
const unwarpPayload = {
...payload,
useDocUnwarping: true,
useDocOrientationClassify: true
};
const unwarpResponse = await fetch(pipelineUrl, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(unwarpPayload)
});
if (unwarpResponse.ok) {
data = await unwarpResponse.json();
console.log(`Document unwarped successfully.`);
unwarped = true;
} else {
console.error(`Unwarping failed with status ${unwarpResponse.status}`);
}
}
}