A single-container, self-hosted Manufacturing Resource Planning (MRP) app built around printable QR-coded traveler cards. Designed for small fabrication shops running on an Unraid server with phone-based operators.
- **4.** Operator scan flow — phone scan resolves `/op/scan/<token>`, single-claim enforced at DB level, Start / Pause / Done with inline QC for steps that require it, TimeLog rows for every claim.
- **5.** PDF traveler generation — per-operation card + per-part cover sheet with the full operation list and file manifest. Printed via `pdf-lib` (no native deps).
- **6.** Fasteners + purchase orders — per-project BOM of fasteners with unresolved-need rollups, PO lifecycle (`draft → sent → partial → received`, or `cancelled`), per-line receipt entry with auto-advance, and vendor-ready PDF downloads.
- **8.** In-browser STEP viewer — OpenCascade (WASM, via `occt-import-js`) parses STEP/STP, `three.js` renders with OrbitControls. Thumbnails are captured from the first rendered frame, uploaded to the content-addressed file store, and displayed on the assembly parts list. No native deps, no server-side GL.
The primary deployment target is **Unraid**, using an image built by a **Gitea Actions** runner on every push to `main` and pulled from the private registry at **`registry.alwisp.com`** into Unraid's Docker GUI.
```
push to main ─► Gitea Actions (docker-build.yml) ─► registry.alwisp.com
(docker build + push) <owner>/<repo>:latest
│
▼
Unraid Docker tab ─► pull / force-update
```
Two deploy paths are supported; pick one:
- **`docker pull`** — Unraid pulls a prebuilt image the Gitea runner already tagged. Fastest, this is what the runner is for.
- **`docker build`** — Unraid clones this repo and builds the image locally, no registry required.
See [`docs/DEPLOY.md`](docs/DEPLOY.md) for the full, click-by-click Unraid GUI walkthrough (template fields, volume mapping, env vars, update flow, backups).
### TL;DR Unraid install
1.**Docker tab → Add Container**.
2.**Repository**: `registry.alwisp.com/<owner>/<repo>:latest` (the owner/repo path matches `${{ gitea.repository }}` from the workflow).
Point Unraid at `registry.alwisp.com/<owner>/<repo>:latest` and use **Check for Updates / Force Update** (or the *CA Auto Update Applications* plugin) to roll new builds.
The top-level `AGENTS.md`, `SKILLS.md`, `hubs/`, and `skills/` directories are the coding-agent instruction suite this project was started from. They are reference material for AI assistants, are listed in `.dockerignore`, and are not shipped in the Docker image.