Operations reference. The full technical handbook — architecture, where keys live, account IDs — is kept in the private code repo (HANDBOOK.md), not here.
What this is
TopoCut tracks every part from order intake through laser cutting, finishing, and packing/shipping. Orders come from Paperless Parts (customer orders) and Katana (internal Sherpa runs). Operators open the app on a tablet, pick their station, and work the queue of parts at that station. "Login" is just picking your name — there's no real password on the floor app.
The production workflow
Each part carries an ordered list of operations. It moves through stations in this order:
RadBend/Export → Tool → Nest → Load Laser → Pick → finishing (Deburr / Timesaver / Tumble / Machining / Bend / Countersink / Tap / Insert Hardware / Assembly) → Powder → Pack
- At most stations, hitting Done advances the part to its next operation automatically.
- Nest → Load Laser → Pick is sheet-driven: a nest (one sheet) is built, scheduled or queued on the Load Laser screen, loaded onto the laser, cut, then parts are picked off it. Loading a nest moves its parts to Pick — but only once all the sheets a part lives on are loaded.
- Big jobs span many identical sheets (e.g. [6of14]), all tied to the same part. Losing pieces on one sheet spawns a [RECUT] part for the lost count.
- Queue = a nest built but parked off the schedule; promote it when ready. The red Overdue strip = scheduled sheets whose start time passed but weren't loaded.
Reading the board (why a tab is red)
- Station tabs color by the most urgent work there: red = overdue/at-deadline, yellow = due soon, green = on track. Tool & Nest only go red when truly overdue.
- Parts someone has started, or that are flagged (floor note), still count but don't drive a tab red.
- Load Laser red but the screen looks clear? The tab counts parts at the step; the screen shows nests. A part can get stuck at Load Laser after its sheet was already cut, or with no sheet at all — invisible on the board but still overdue. Fix: advance stuck parts (sheets already cut → Pick; no sheet → back to Nest).
Flags you'll see on parts
- Rush / Urgent — priority; floats to the top of queues.
- Customer Material — the customer supplies the raw material (auto-detected when there's no material cost on the order). Shown on Tool / Nest / Load Laser / Queue.
- Order / Awaiting Material — shown automatically on pre-cut parts from stock levels: ⚠ Order Material when none is on hand or on order, ⏳ Awaiting Material once it's on order (Katana expected), and it clears itself the moment stock arrives (a PO receipt or accepted customer sheets). Nothing to toggle by hand.
Day-to-day runbooks
- Ship an app change: commit and push to the main branch — the live site auto-deploys in about a minute. (Never push to other branches.)
- Change the order importer (Paperless → app): edit the code step in Zapier. The repo holds the source-of-record copy.
- See what the backend is doing: Cloudflare dashboard → Workers → logs (live tail).
- A part is stuck / in the wrong place: it can be corrected directly in Airtable (the database), or ask whoever maintains the code. Most "stuck" cases are a part whose step didn't advance — set its current_step to where it should be.
- Refresh material stock from Katana: the Materials screen has a Sync from Katana button (shows a drift preview before applying) — this is the month-end reconcile.
Automated jobs & schedules
Work the system does on its own — no one has to click anything. Grouped by what triggers them.
Behind-schedule scan — every workday around 5:00am MT (cron 0 11 * * 1-4 UTC, in the katana-webhook Worker).
- Does: walks every open sales order past half its lead time, FIFO-allocates the open Katana MOs to those orders (skipping orphaned kits of already-shipped orders), and rates each as on-track / thin-buffer / can't-make-it / overdue. It also runs the zombie-part sweep: any active part whose Katana MO was hard-deleted (a 404) is auto-cancelled with a dated note — the backstop for a missed delete webhook.
- Results land in: the Schedule Flags Airtable table, which the dashboard's Behind Schedule card reads. Last-run time + a summary are stamped into Tracker Config (key last_scan) — hover the "scanned …" label on the card to see it.
- Run it now: the Rescan now button on the dashboard card (queued — takes a few minutes).
- Configurable in the Tracker Config table: lead_time_weeks (also editable right on the dashboard card), scan_start_frac, min_days_per_station, amber_slack_frac, overdue_horizon_frac.
Katana webhooks — instant, not scheduled. Katana calls the Worker the moment something changes:
- MO created → the part appears on the floor, with its photo + dimensions auto-attached from the catalog.
- MO updated → the part's details are re-synced.
- MO done (Katana-DONE completion sync) → when an MO is marked done in Katana, the Worker logs an Operation Log row (by katana) for each remaining step, and the advancement automation walks the part to Complete — the same path as a shop-floor completion. This is how Shipping-department jobs (worked in Katana's app for now) close out on the board.
- MO deleted → the part is cancelled.
- Ingredients in stock → material-blocked parts are unblocked and rejoin their queue.
- PO row received → that sheet's stock is incremented in Materials.
Paperless Parts → Airtable (Zapier) — event-driven on Paperless Parts order webhooks. Creates the TopoCut orders/parts, and also creates the Shopify draft orders. It lives in Zapier (a code step): changes require pasting zapier/zap-code.js into the Zap editor — and the two Shopify credential constants must be re-filled from the live Zap each time you paste.
App version check — the running app polls for a newer deployed build every ~5 minutes and whenever you refocus the tab. When the live version differs from the one you loaded, a "New version available — Refresh now" banner drops in. It never polls on a local/dev build.
Caches & how stale data can get — so a number that looks behind isn't a bug:
- Order Tracker indexes (MOs, throughput, queues, open-order demand) — 10 minutes.
- Variant / product names — 7 days (in your browser; the Worker keeps a matching 7-day copy).
- Behind-schedule scan recipe rows — 72 hours (Cloudflare KV, so back-to-back scans build on each other).
- Throughput report — fetched fresh every time you open the page; the range toggles and drill-downs re-render off that one snapshot without re-fetching.
Known quirks
- Material tracking is a sandbox — the Materials/Stock screen, customer-supplied flag, and to-order worklist are built but not wired into the live cut flow yet. Nothing breaks if the numbers are off.
- Security is in "warn" mode — the backend logs suspicious requests but doesn't block them yet. Flipping to enforce is a small config change (documented in the technical handbook).
- Lead time = calendar days (set in Paperless). The app uses Paperless's ship date directly and counts calendar days everywhere.
- Webhook queue limits — heavy Katana activity can hit a free-tier limit; the system falls back to processing inline so nothing is lost. Details in the technical handbook.
What's next (roadmap)
- Finish the Shopify order-number sync (shows shipping which order to fulfill on the Pack page).
- Flip the security gates to enforce once logs are clean.
- Phase 2 material: stock now decrements live as sheets are cut (and returns on unload). Next: auto-clear "awaiting material" when stock arrives.
- Auto-heal parts that get stranded at Load Laser.
For the full technical handbook — architecture, integrations, where every key lives and how to rotate it, account IDs, and detailed runbooks — see HANDBOOK.md in the private code repository.