R73-A2 收敛 VAT OCR 归一化与质量门槛

这个提交包含在:
2026-04-28 21:13:21 +08:00
父节点 82fbd39114
当前提交 b7c018922c
共修改 9 个文件,包含 600 行新增和 14 行删除
@@ -36,7 +36,7 @@ function buildMultipartRequest({ filename, contentType, content, fields = [] })
};
}
async function buildApp() {
async function buildApp({ ocrProvider = "off" } = {}) {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "hyb-oa-r71-invoice-upload-"));
const invoicePoolCreate = vi.fn(async ({ data }) => ({
id: "11111111-1111-4111-8111-111111111111",
@@ -62,7 +62,7 @@ async function buildApp() {
storageDir: tempDir,
maxUploadSizeBytes: 5 * 1024 * 1024,
invoiceArchiveUnusedDays: 30,
ocrProvider: "off",
ocrProvider,
});
app.decorate("authenticate", async (request) => {
if (!request.headers.authorization) {
@@ -164,4 +164,46 @@ describe("invoicePool upload route", () => {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
it("puts VAT uploads into pending_ocr when OCR provider is enabled", async () => {
const { app, prisma, tempDir } = await buildApp({ ocrProvider: "mock" });
try {
const requestPayload = buildMultipartRequest({
filename: "invoice.png",
contentType: "image/png",
content: "mock-image",
fields: [["ocr_type", "vat"]],
});
const response = await app.inject({
method: "POST",
url: "/api/invoice-pool/upload",
headers: {
authorization: "Bearer test",
...requestPayload.headers,
},
payload: requestPayload.payload,
});
expect(response.statusCode).toBe(200);
expect(response.json().data).toEqual(
expect.objectContaining({
invoicePoolId: "11111111-1111-4111-8111-111111111111",
status: "pending_ocr",
}),
);
expect(prisma.invoicePool.create).toHaveBeenCalledWith(
expect.objectContaining({
data: expect.objectContaining({
ocr_type: "vat",
status: "pending_ocr",
}),
}),
);
} finally {
await app.close();
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});