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

107 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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).