WFDASH-WEBAPP/docs/collection-ai-checks.md
Dave cba2d84549 docs(collection-ai): runbook tick table, audit scope; spec content_hash index is non-unique
F2: tick table (SKU green via the code match incl. AI fills, grey per tick,
pairing failure -> all grey, different product -> red), stock lines use the
line SKU, Add to POS needs a SKU, SKU fills audited for order lines only.
F3: content_hash is a non-unique index (identical uploads share a hash,
skipped PDFs have an empty hash) - matches the migration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 10:21:25 +02:00

6.1 KiB

Collection Confirm AI checks runbook

Design: docs/superpowers/specs/2026-10-17-collection-confirm-ai-checks-design.md.

What it does

On Collection Confirm, drivers upload photos of the supplier's tax invoice or delivery note. The AI (the provider set in Settings, AI) reads each photo, pairs the document lines with our order lines, and shows four ticks per line (SKU, quantity, description, price), plus a POS column and an "AI findings" box when something at document level looks wrong.

  • It runs automatically (n8n clock, every 5 minutes) on files not yet read, and on demand with the Check with AI button on a card.
  • Check with AI needs only the global AI switch. The scheduled tick needs both the global AI switch and "Collection checks enabled".
  • A file is read once (by content hash, stored in collection_doc_reads). A failed photo read is retried only by the Check with AI button, not by the tick.
  • Lines with no AI check look exactly as before, with no ticks.
  • Add to POS is a manual feature (per line, or "Confirm and add to POS" on the card). It creates a stock_items row with zero stock. A line needs a SKU first (the button is disabled without one); the toast reports lines added, failed and still needing a SKU.

What the AI writes: only ai_check on the order/stock line, the document reads, and an empty SKU, and only when it is sure. It never overwrites a SKU a person set, never confirms a collection, and never changes status. On order lines the SKU fill is audited as an ordinary sku change; stock purchase lines (stock_purchase_items) are not covered by the audit hook, so a SKU fill there is not in the audit log.

Going live (manual steps, in this order)

  1. Migrate PocketBase. Run against the live PB: npm run pb:migrate:collection-ai (creates collection_doc_reads, adds ai_check to order_items and stock_purchase_items, and the collection_ai_* fields on ai_settings).
  2. Redeploy the audit hook pocketbase/pb_hooks/audit_log_utils.js to the PB server's pb_hooks/. It now ignores ai_check; until then the only cost is noisy history (a large JSON diff on every re-run).
  3. Deploy the app. Pushing to main does not auto-deploy; it is a manual deploy that takes 5 to 10 minutes.
  4. Activate the n8n workflow (below). Create it inactive, activate it after steps 1 to 3.
  5. Turn it on in Settings, AI: the global "AI enabled" switch must be on, then switch on "Collection checks enabled" in the Collection checks section and click Save.

The tick does nothing until both switches are on, so steps 4 and 5 are safe in either order.

n8n workflow: "WFDASH Collection check tick"

n8n only acts as a clock; the app decides whether anything is due.

Node Setting
Name WFDASH Collection check tick
Trigger Schedule Trigger, every 5 minutes
Action HTTP Request
Method / URL POST https://wfdash.apphub.co.za/api/v1/collection-confirm/ai/tick
Authentication The WFDASH Agent API Key credential (Authorization: Bearer <AGENT_API_KEY>). Do not create a new secret.
Body none
Options Timeout 120000 ms (120 s); Never Error (neverError) on
Status inactive until the app is deployed and migrated

After deploy, Execute workflow once. Expected responses: {"ran":false,"reason":"disabled"} while off, {"ran":false,"reason":"running"} while an earlier run is still going, {"ran":true,"summary":{...}} when it ran. A 401 means the credential is wrong.

Each run is bounded: at most 10 files, and it stops starting new files after 90 seconds, so it normally answers inside the 120 s timeout; leftovers carry to the next run. Runs never overlap: a run holds a lease for up to 10 minutes, and if a run dies without writing its summary the next tick after that takes over.

The last run (files read, cards checked) is shown in Settings, AI, Collection checks, and stored in ai_settings.collection_ai_last_run_summary.

Reading the ticks

Colour Meaning
Green The document agrees with our line: our SKU equals the document code after normalising (uppercase, letters and digits only; this is also how a SKU the AI filled goes green), quantity equals what was collected and what was ordered, the AI is sure it is the same item, unit price within 1 cent
Amber Close but worth a look: our SKU differs from the document code; collected quantity matches the document but the ordered quantity differs; the AI thinks it is the same item but is only "likely" sure
Red Mismatch or missing: no SKU on our line, quantity differs from the document, price differs or we have no cost, or the line is not on the document or the AI says it is a different product (all four red)
Grey Can't check, per tick: SKU when the document line shows no code; Qty when it shows no quantity; Price on a delivery note or when the document line shows no price; all four when the AI couldn't pair the document (see the AI findings box for the reason; Check with AI retries)

For stock purchase lines the SKU tick and robot use the line's own SKU (the one a rep or the AI set on the purchase line), not the catalogue SKU.

Hover a tick for the values compared (ours vs the document). A robot icon marks a SKU the AI filled. Click the document chip on a card to see the extracted lines next to the photo.

Errors

  • "Collection checks are not set up yet: run npm run pb:migrate:collection-ai against PocketBase first" is the guard. The service refuses to run until ai_check exists on the live PB, because PB silently drops unknown fields and results would vanish. Run step 1 above.
  • "AI is disabled in settings" from Check with AI: switch on the global AI switch in Settings, AI.

Changing the prompt

Settings, AI, Collection checks prompt. "Reset to default" loads the built-in prompt; empty means the built-in default. Keep it to the submit_document_read tool's fields.

Stopping it

Switch off "Collection checks enabled" in Settings, AI and Save, or deactivate the n8n workflow. Existing ticks stay until the card is re-checked or the line is cleared.