MEGAINFRA-WEBAPP/docs/n8n/delivery-note-ocr.md

4.3 KiB
Raw Blame History

n8n Workflow — Delivery Note Tick

This is the handoff doc for the n8n workflow that drives the delivery note inbox pipeline. The pipeline itself (extract → segment → split → checks → promote) lives in src/lib/dn-pipeline/ and is run entirely inside Next.js. n8n's only job is to call the tick endpoint every minute.

What this workflow does

Two nodes. That's it.

  1. Schedule Trigger — fires every 1 minute.
  2. HTTP Request — POST https://mega.dash.apphub.co.za/api/dn-batches/tick with header x-ingest-secret: <credential value>.

The Next.js route (src/app/api/dn-batches/tick/route.ts) picks up the call, walks every dn_batches row whose status is one of inbox / analysing / needs_attention, and advances each one through the pipeline until it reaches processed (or stays in needs_attention until a human acts). All OCR, segmentation, checks, and PocketBase writes happen in Next.js — n8n does not see a slip.

When this workflow runs

Every minute, on the minute. The trigger has no special cadence.

What you configure in n8n

Nodes

# Node Type Notes
1 Tick Schedule Trigger interval: 1 minute
2 POST /api/dn-batches/tick HTTP Request method POST, URL https://mega.dash.apphub.co.za/api/dn-batches/tick, header x-ingest-secret from a credential

Connect Tick → POST.

Credentials to set after import

Credential name Type Value
DN Ingest Secret (or whatever you name it) Header Auth x-ingest-secret = the rotated N8N_INGEST_SECRET value

The HTTP Request node should reference the credential by name — do not paste the secret as a literal in the node's headers table. Anyone exporting the workflow will leak the secret otherwise, and that's exactly what happened with the previous four-node workflow.

Save and keep active

After both nodes are in place and the credential is wired, save and flip the workflow Active. The pipeline is idempotent: running the tick twice produces identical figures and no duplicate rows, so a double-fire from a transient n8n restart is harmless.

Why it collapsed to two nodes

The previous workflow polled PocketBase for processing_status = "pending" rows, downloaded each slip, ran an LLM extraction, and POSTed results back. Tasks 1–16 of the unit-fix plan moved every one of those steps into Next.js:

  • Upload route (src/app/api/delivery-notes/upload/route.ts) hashes the file, creates a dn_batches row with status = "inbox", and persists the bytes to PocketBase.
  • Tick route (src/app/api/dn-batches/tick/route.ts) is the one place pipeline progression lives.
  • Pipeline modules in src/lib/dn-pipeline/:
    • extract.ts — page-by-page OCR / PDF read.
    • segment.ts — group pages into candidate notes.
    • split.ts — resolve ambiguous segmentations (unassigned, needsSubsplit).
    • checks.ts — per-note and per-batch gating.
    • promote.ts — write promoted notes to delivery_notes / delivery_note_items.
    • run.ts — the orchestrator the tick route calls.

What used to be eight nodes is now one HTTP call. Anyone tempted to "just add the OCR back into n8n" should read the pipeline modules first — the rules (no cross-page inference, idempotent re-runs, check-gated promotion) only hold because the steps run in deterministic order inside one process.

What an operator sees

  • dn_batches.status = "inbox" — uploaded, not yet ticked.
  • dn_batches.status = "analysing" — a tick is running for this batch.
  • dn_batches.status = "needs_attention" — pipeline stopped; open the row in the inbox board to see why.
  • dn_batches.status = "processed" — done. notes_promoted > 0 means new rows landed on the purchasing page.

If the n8n workflow is OFF, batches will sit in inbox until it comes back. There is no fallback timer inside Next.js — the tick is the heartbeat.

Reference

  • Pipeline spec: this repository, docs/n8n/delivery-note-ocr.md (this file) and src/lib/dn-pipeline/types.ts for the data shapes.
  • Tick route implementation: src/app/api/dn-batches/tick/route.ts.
  • Existing workflow id in n8n: wVbLw4paISkbrIpE (name: "Delivery Note OCR" — the name is historical; the workflow body is now the two-node tick).