# Filament Inventory A single-user, mobile-first filament spool tracker. Vanilla PHP + SQLite + vanilla JS — no third-party code, no build step. ## Requirements - PHP 8.0+ with `pdo_sqlite` enabled (standard on nearly every host) - Any web server (Apache, nginx, or `php -S`) - The `data/` directory must be writable by the web server ## Install Copy the whole folder to your web root and open it in a browser. On first visit you'll be asked to set the admin password (stored as a hash in `data/pass.hash`). The SQLite database (`data/filaments.sqlite`) is created automatically. **nginx users:** `data/.htaccess` only protects the database on Apache. On nginx add: ``` location ^~ /autofeed/data/ { deny all; } ``` ## Features - Inventory list is public read-only (set `public_view` to `false` in `inc/config.php` to require login for everything); adding, editing, and using filament require the password. - Logins last until you actually log out. A "remember me" cookie (selector/validator, only the validator's hash is stored) re-establishes the session even after PHP's session garbage collection sweeps it — the default 24-minute idle window was why logins kept lapsing. Logging out deletes the token server-side, so a copied cookie is dead the moment you log out. - Passkeys: sign in with a fingerprint, face, or screen lock instead of the password. Add one per device on the **Keys** page. Hand-rolled WebAuthn (ES256/RS256, no dependencies); attestation is intentionally not verified, since on a personal site any authenticator the owner chooses is acceptable. Passkeys are bound to the hostname they were created on, so one made at `localhost` will not work on the live domain — register one on each address you use. Needs HTTPS (or `localhost`); the Keys page says so plainly when the connection is not secure. The password always keeps working as the fallback if you lose your devices. - Spool fields: type, color, brand, total weight, empty spool weight, cost, abrasive, high-flow, silk, matte, rainbow/multicolor, color-shifting/two-tone, transparent/clear, notes. Silk spools get a shine sweep on their swatch, rainbow spools an animated all-hue ring, two-tone spools fade between their two colors, and transparent/clear spools show an image-editor-style checkerboard through the color. Remaining filament = total − spool, reduced as you log usage. Re-weigh a spool and update its weights to reset the remaining amount. - Color can be sampled with the phone camera (live view needs HTTPS; the "Photo" button works everywhere) — the image never leaves the phone. - Logged usage can be corrected: every entry in the Use page's history has Edit and Delete. Deleting puts the grams back on the spool; editing can change the amount, the print-file label, or move the entry to a different spool (the old spool is refunded and the new one charged). "Show all" opens the full history to reach older mistakes, and a spool's last-used date is recomputed whenever an entry moves or disappears. - When a deduction empties a spool, the Use page offers to delete it from the inventory, saying up front how many logged prints will go with it. The offer is re-checked against the spool's real remaining amount, so undoing the usage withdraws it. - "Use filament": drop or pick a `.gcode`/`.bgcode` file and the grams used are read from the slicer metadata (PrusaSlicer, OrcaSlicer, Bambu Studio; Cura is estimated from meters via material density). Parsing happens in the browser — the print file is never uploaded. Manual gram entry also works. - Adding a spool is quick: one-tap presets for the common spool amounts (1 kg / 500 g / 250 g / 100 g), and the empty-spool weight auto-fills from the most common value among the same brand's existing spools (manufacturers reuse one spool design) — a hand-typed weight is never overwritten. - CSV export and import (Report page, login required). Export downloads the whole inventory as a spreadsheet-friendly CSV that doubles as a backup. Import accepts that same file back (rows whose `id` matches update the existing spool; others are added) or a CSV from elsewhere — only a `type` column is required, `,` and `;` delimiters and decimal commas are handled, and a database backup is taken first. - Email report: from the Report page, send the inventory report (spools listed lowest-first, CSV attached) one-time, or enable a daily morning email. The daily report goes out on the first page visit after the chosen hour; for exact timing point a cron job or uptime monitor at the tokenized `cron.php` URL shown on that page. Sending uses PHP's `mail()`; if your host is picky about sender domains, set `mail_from` in `inc/config.php`. - The inventory list has a filter panel: narrow by type, manufacturer, amount left (nearly full / partly used / low), special properties, or a free-text search across color names, brands, and notes. Groups combine with AND, choices within a group with OR, and changes apply instantly. - Dark mode follows the system preference. - Every change (add, edit, delete, bulk edit, usage deduction, CSV import) first snapshots the database to `data/backups/`; the newest 10 snapshots are kept. To undo a mistake, copy the relevant backup over `data/filaments.sqlite`.