Skip to main content

Document Processing

Il motore di document processing trasforma un documento in un insieme versionato e verificabile di evidenze. Non appartiene a uno specifico verticale: ogni applicazione sceglie un workflow pubblicato e il control plane ne esegue il grafo.

Principi

  • Il workflow è un DAG versionato nel database; nodi e archi non sono codificati nei worker.
  • Il control plane decide routing, join, condizioni, priorità e retry.
  • Ogni worker svolge un solo compito, completa il job BullMQ e comunica l'esito al control plane.
  • I worker non scelgono il passo successivo.
  • PostgreSQL conserva la verità e la provenance; Qdrant contiene indici derivati e ricostruibili.
  • I metadati persistenti passano da data-service. I worker non accedono direttamente a DataHub o PostgreSQL.
  • Ogni job conserva userId, documentId, processingRunId, versione del workflow e riferimenti agli artefatti. Gli accessi sono nuovamente verificati da data-service.
  • I payload di coda trasportano identificativi e riferimenti, non il PDF o grandi risultati di elaborazione.

Workflow corrente

Il workflow pubblicato file-text-only@1.5.0 ha due ingressi: LIVE, con priorità alta, e BATCH, con priorità inferiore.

LIVE / BATCH
|
v
Fingerprint SHA-256
|
+-- copia esatta --> collega documento canonico --> Completed
|
+-- contenuto nuovo
|-------------------------------|
v v
Text extraction Visual extraction
| |
v v
Index text Index visuals/layout
| |
+-------------- join -----------+
|
v
Similar-document search
|
v
Completed

Text e visual extraction lavorano in parallelo. Anche l'indicizzazione è incrementale: ciascun ramo può salvare il proprio contributo senza attendere l'altro; il terminale viene raggiunto soltanto quando entrambi sono conclusi.

Evoluzione pianificata

Prima della classificazione saranno aggiunte ricerca di documenti simili e identificazione dell'issuer.

Text indexed --------------------|
+--> Similar-document search --------|
Visual/layout indexed -----------| |
+--> Evidence fusion
Text + visual evidence ----------+--> Local issuer resolution --------| |
v
issuer sufficientemente certo?
| sì | no
| v
| Web issuer enrichment
| |
+---- join+
|
v
Classification context
|
v
Document classification

La ricerca di similarità e la raccolta dei candidati issuer possono iniziare dopo il join degli indici. La fusione usa entrambi i risultati. L'accesso al web è un fallback condizionale e non blocca workflow che non lo consentono.

Stato dei componenti

ComponenteStatoResponsabilità
document-processing-control-planeOperativoEsecuzione del DAG, code, join, retry e osservabilità
document-fingerprint-workerOperativoHash SHA-256 e rilevazione copie esatte
document-text-extraction-workerOperativoTesto PDF e fallback OCR
document-visual-extraction-workerOperativoRendering, elementi grafici, layout e normalizzazione
document-knowledge-indexing-workerOperativoCatalogo delle evidenze e indici Qdrant
document-similarity-workerOperativoRicerca e ranking multimodale dei documenti simili
document-issuer-resolution-workerOperativoRisoluzione locale e deterministica dell'issuer
issuer-web-enrichment-workerPianificatoRicerca web controllata degli issuer non risolti

Dati e isolamento

Le evidenze appartenenti a un documento, i candidati di similarità e le osservazioni issuer sono sempre scoped per utente/tenant. Il catalogo verificato degli issuer può essere globale, ma non deve rivelare documenti, testo o relazioni di altri utenti. Ogni query Qdrant deve applicare il filtro di ownership presente nel payload.

La classificazione di un documento simile è un'evidenza, non una verità: una conferma umana pesa più di una classificazione automatica. Le associazioni issuer -> document type devono essere apprese solo da conferme o da politiche esplicite ad alta confidenza, evitando cicli di auto-conferma.

Contratto di avanzamento

Ogni worker produce un output piccolo e versionato, salva gli artefatti tramite i servizi proprietari e completa il job. Il control plane riceve l'esito tramite l'avanzamento BullMQ idempotente e valuta gli archi uscenti. Job concorrenti possono terminare insieme: l'idempotenza e lo stato persistito del run rendono sicura la valutazione del join.