fix: refactor audit to SSE streaming, improve error handling
- Changed from blocking JSON endpoint to SSE streaming (like sync-all/repair-icons) - Progress updates during each audit phase with item counts - Proper error handling with typed AuditEvent for every failure path - AbortController support for the client - Shows real-time progress for each check section
This commit is contained in:
1 parent
19e4e10b1d
commit
bebd65c056
3 files changed
+400
-159
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -1,13 +1,46 @@
|
|||||||
import { withAdmin } from "@/lib/api-handler";
|
import { withAdmin } from "@/lib/api-handler";
|
||||||
import { apiError, apiOk } from "@/lib/api-response";
|
|
||||||
import { PERMS } from "@/lib/permissions";
|
import { PERMS } from "@/lib/permissions";
|
||||||
import { runCatalogAudit } from "@/lib/services/catalog-audit";
|
import { runCatalogAudit } from "@/lib/services/catalog-audit";
|
||||||
|
|
||||||
export const POST = withAdmin({ permission: PERMS.ASSETS_IMPORT }, async () => {
|
function sseEvent(data: unknown): string {
|
||||||
try {
|
return `data: ${JSON.stringify(data)}\n\n`;
|
||||||
const result = await runCatalogAudit();
|
|
||||||
return apiOk(result as unknown as Record<string, unknown>);
|
|
||||||
} catch (err) {
|
|
||||||
return apiError(`Audit failed: ${(err as Error).message}`, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const POST = withAdmin({ permission: PERMS.ASSETS_IMPORT }, async () => {
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
|
||||||
|
const stream = new ReadableStream({
|
||||||
|
async start(controller) {
|
||||||
|
const send = (data: unknown) => {
|
||||||
|
try {
|
||||||
|
controller.enqueue(encoder.encode(sseEvent(data)));
|
||||||
|
} catch {
|
||||||
|
/* stream closed */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await runCatalogAudit(send);
|
||||||
|
} catch (err) {
|
||||||
|
send({
|
||||||
|
type: "error",
|
||||||
|
message: `Audit threw: ${(err as Error).message}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
controller.close();
|
||||||
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Response(stream, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "text/event-stream",
|
||||||
|
"Cache-Control": "no-cache",
|
||||||
|
Connection: "keep-alive",
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user