/** * Background processing for one inbox document: run the extraction pipeline on * the PDF bytes and persist the result (status → parsed) or the error * (status → error) via the REST store. Called fire-and-forget from upload (with * the in-memory buffer) and reparse (buffer re-fetched from Strapi). Never throws. * * The captured ctx carries the iDempiere token obtained at request time; OCR jobs * finish well within the token lifetime. */ import { setInboxParsed, setInboxError, type InboxCtx } from './inboxDb' import { runPipeline } from './extractPipeline' import { renderThumbDataUrl } from './rasterizePdf' export const processInboxDocument = async ( ctx: InboxCtx, id: number, pdf: Buffer, meta: { mimeType?: string; filename?: string } = {} ): Promise => { try { const res = await runPipeline(pdf, { ctx, mimeType: meta.mimeType, filename: meta.filename }) // page-1 thumbnail for the inbox cards (Strapi can't thumbnail PDFs); best-effort let thumb = '' if (!/xml/i.test(meta.mimeType || '')) { try { thumb = await renderThumbDataUrl(pdf) } catch {} } const extracted: any = thumb ? { ...(res.extracted || {}), __thumb: thumb } : res.extracted await setInboxParsed(ctx, id, { sourceTier: res.sourceTier, vendorFingerprint: res.vendorFingerprint, extracted, confidence: res.confidence, bbox: res.bbox }) } catch (e: any) { try { await setInboxError(ctx, id, e?.message || 'Processing failed') } catch {} } } export default processInboxDocument