112 lines
5.4 KiB
Markdown
112 lines
5.4 KiB
Markdown
# 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.
|
|
|
|
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.
|
|
The SKU fill is audited as an ordinary `sku` change.
|
|
|
|
## 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 (SKU matches after normalising, quantity equals what was collected and what was ordered, AI is sure it is the same item, unit price within 1 cent) |
|
|
| Amber | Close but worth a look: 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 AI could not pair the line (all four red) |
|
|
| Grey | Not applicable: the document shows no code or quantity, or no price (delivery notes never have a price tick) |
|
|
|
|
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.
|