Design for AP AutoExtract to Fluxx Extraction requirements
Activities (high level)
- generate_invoice_id
- Purpose: Create canonical invoiceID (content hash of PDF) and initialize invoice document record with initial stage/status/stepper/resolutions.
- Inputs: pdf_path, client_id, client_name, workflow_id, pdf_prefix.
- External calls: Blob download (get_blob_content), client config fetch (get_client), Cosmos insert (store_document).
- Outputs/State: Sets data.invoiceID, data.invoice_document, workflow_status/substatus.
- Idempotency: Hash is deterministic; re-run should detect existing record if logic added.
- generate_images
- Purpose: Produce per-page JPEG images from source PDF and store in blob; persist image URLs.
- Inputs: invoiceID (from prior), pdf_path (unless pre-generated image_urls provided), pdf_prefix.
- External calls: Blob get (PDF), blob upload (each page), SAS URL generation, Cosmos update (image_urls, substatus).
- Outputs: data.image_urls, data.image_prefixes, invoice document updated.
- Optimizations: Skips work if images already present.
- Constraints: Page count limited by config.MAX_PAGES.
- get_bounding_regions
- Purpose: Run Document Intelligence (AI extraction) to produce structured JSON (layout / bounding regions) and persist JSON blob reference.
- Inputs: pdf_path, pdf_prefix, client_id, invoiceID.
- External calls: SAS URL gen (optional), analyze_pdf(), blob_exists(), blob upload for DI JSON, Cosmos update (di_json_url).
- Outputs: di_json_url, di_json_prefix in state.
- Idempotency: Skips re-analysis if JSON blob already exists.
- extract_invoice
- Purpose: AI (OpenAIExtractor) semantic extraction (key header fields, line items, totals) from PDF + DI rotations.
- Inputs: pdf_path, di_json_prefix, client_config.
- External calls: Blob get (PDF + DI JSON), OpenAIExtractor invocation.
- Outputs: ai_extracted_content dict stored in state.
- Fallback: On extractor failure returns empty dict (allows downstream transform path).
- map_invoice
- Purpose: Convert AI extracted raw dict into internal Invoice model (simple mapping only AI output).
- Inputs: ai_extracted_content, invoiceID.
- External calls: Cosmos update (invoice field).
- Outputs: invoice JSON (only AI mapping), updates invoice_document.
- transform_invoice
- Purpose: Parse DI JSON to build Invoice model; optionally merge with AI extracted data (combine header totals & line items).
- Inputs: di_json_url, ai_extracted_content (optional), invoiceID.
- External calls: Blob get (DI JSON), combine/transform functions, Cosmos update (invoice).
- Merge Logic: Prefers AI-derived financial fields & PO number if DI missing; fuzzy merging of line items.
- post_processing
- Purpose: Apply client-specific normalization rules (freight/tariff redistribution), adjust invoice subtotal/shipping/tariff amounts, optionally push to mocked ERP.
- Inputs: invoice document (with lineItems), client_config.ingest_config patterns.
- External calls: Cosmos update (adjusted invoice), HTTP POST to mocked ERP if provider == ‘cla-mocked’.
- Logic: Detect freight/tariff line items via vendor-specific patterns, move amounts to invoice-level fields, remove matched line items.
- check_duplicate_document
- Purpose: Detect potential duplicate invoice based on configured unique_identifier_fields.
- Inputs: invoice document, ingest_config.unique_identifier_fields.
- External calls: Cosmos query (via DatastoreInterface), Cosmos update (duplicate_invoice if found).
- Outputs: Status failed + substatus if duplicate; else success.
Example workflow configuration JSON with per‑activity enable/disable, ordering, retry, skip logic, and per‑activity parameters:
Key Helper Functions (brief)
- create_images: Render PDF pages to JPEG buffers.
- transform / transform_items: Build Invoice & LineItem objects from DI JSON schema.
- map_openai_extraction: Map OpenAI extraction object to internal Invoice.
- combine_extractions / combine_line_items / fuzzy matching helpers: Reconcile DI vs AI line items using fuzzy description & amount heuristics.
- _score_line_item: Consistency score for amount vs quantity*unit_price.
- strip_vendor_name: Normalizes vendor string for pattern matching.
- Separate mapping vs merging responsibilities for clarity.