H1-H10 优化OCR实时体验闭环
这个提交包含在:
@@ -38,6 +38,8 @@ function buildMultipartRequest({ filename, contentType, content, fields = [] })
|
||||
|
||||
async function buildApp({
|
||||
ocrProvider = "off",
|
||||
jobDriver = "cron",
|
||||
bossSend = null,
|
||||
invoiceConflicts = [],
|
||||
statusRows = [],
|
||||
permissionCodes = ["invoice.upload"],
|
||||
@@ -75,7 +77,11 @@ async function buildApp({
|
||||
maxUploadSizeBytes: 5 * 1024 * 1024,
|
||||
invoiceArchiveUnusedDays: 30,
|
||||
ocrProvider,
|
||||
jobDriver,
|
||||
});
|
||||
if (bossSend) {
|
||||
app.decorate("boss", { send: bossSend });
|
||||
}
|
||||
app.decorate("authenticate", async (request) => {
|
||||
if (!request.headers.authorization) {
|
||||
throw new AppError({ code: "AUTH_001", message: "未登录", statusCode: 401 });
|
||||
@@ -177,8 +183,13 @@ describe("invoicePool upload route", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("puts VAT uploads into pending_ocr when OCR provider is enabled", async () => {
|
||||
const { app, prisma, tempDir } = await buildApp({ ocrProvider: "mock" });
|
||||
it("puts VAT uploads into pending_ocr and enqueues a directed OCR job when OCR provider is enabled", async () => {
|
||||
const bossSend = vi.fn(async () => ({ id: "ocr-job-1" }));
|
||||
const { app, prisma, tempDir } = await buildApp({
|
||||
ocrProvider: "mock",
|
||||
jobDriver: "pgboss",
|
||||
bossSend,
|
||||
});
|
||||
|
||||
try {
|
||||
const requestPayload = buildMultipartRequest({
|
||||
@@ -214,6 +225,9 @@ describe("invoicePool upload route", () => {
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(bossSend).toHaveBeenCalledWith("ocr.invoice", {
|
||||
invoiceId: "11111111-1111-4111-8111-111111111111",
|
||||
});
|
||||
} finally {
|
||||
await app.close();
|
||||
await fs.rm(tempDir, { recursive: true, force: true });
|
||||
|
||||
在新工单中引用
屏蔽一个用户