Privacy / security
Order text stays
on your computer.
The installed app and its model run locally. Your catalogue, learned names and exports stay in plain CSV files in the project folder.
The app server binds to 127.0.0.1 only. Ollama runs on the same machine; order text is sent to 127.0.0.1:11434. There are no cloud calls during matching.
The local boundary
What data goes where
Everything below is inside the shop’s computer. Internet is needed to install the software and download the model.
- Browser
You paste an order into the local review page.
127.0.0.1:5178 - App server
Code reads numbers, matches catalogue text and checks each row.
- Ollama, only if needed
Hard lines go to the local model, which picks a product from the shortlist.
127.0.0.1:11434 - Local files
Confirmed exports and explicitly remembered names are saved as CSV on disk.
The checked answer returns to the browser for review before export. CSV export is for manual import into billing software.
No reporting service
The app has no telemetry, analytics or crash reporting, and loads no external scripts, fonts or styles. This documentation site also uses local assets only.
Your files, your backup
data/real/, data/app/, data/train/ and results/ are gitignored. Back up the catalogue and data/app/ yourself.
If optional fine-tuning is used later, it is a one-time cloud step and should use synthetic or consented data only.
Optional Sentry tracing exists only in the evaluation tool (npm run eval). It is off unless a SENTRY_DSN is set, and refused for anything outside the synthetic and fixture data. The shop app never loads it, and a test checks that. What tracing sends.
Threat model
What the design protects
| Asset | Threat | Mitigation or accepted risk |
|---|---|---|
| Customer list, prices, order volume | Leaking to a third party | Local server and local model; no cloud calls during matching. |
| Invoice correctness | A wrong row exported to billing | 16 safety rules, server-side re-check of confirmed rows, and evaluation that measures dangerous rows. |
| Learned names | A mistaken correction poisons a name | Only explicitly confirmed rows with Remember ticked can teach names. Known catalogue names cannot be learned. Later entries override earlier ones; the plain CSV can be edited. |
| Local server | Another program on the computer calls its API | Accepted risk for a single-user desktop tool. There is no authentication. Do not run untrusted software on the shop computer. |
| Review page | Order text injects a script | Every order-derived string is HTML-escaped before display. |
External test pass
Fixed issues
- CSV formula injection: exported text beginning with
=,+,-or@, including after whitespace, receives an apostrophe. This includes skipped rows; carriage returns are quoted too. - Oversized and malformed requests: oversized bodies return HTTP 413 and are drained without retaining excess bytes. Malformed JSON and invalid request shapes return 400.
- Client disconnects: matching calls are aborted, later lines stop and the matching slot is released. Concurrent request bodies cannot bypass the single-order guard.
- Unconfirmed learned names: a remembered entry must match an explicitly confirmed row’s product words and SKU. Skipped, automatic, missing and unrelated rows cannot teach names.
- Export overwrite: filenames include a timestamp and UUID, preserving orders exported within the same second.
Open issue
No local authentication
The local server has no authentication. This is an accepted risk for one shop and one operator on one computer. The server must not be exposed to a network as it is.
This is a challenge project without a formal security process. Report a problem with reproduction steps in a repository issue. Use the synthetic catalogue and do not include real shop data.