Changelog
Changelog
All notable changes to Kitted are documented here.
The format follows Keep a Changelog. Versioning follows Semantic Versioning.
[Unreleased]
[0.4.0] — 2026-03-23
Where-used lookup, sales returns, location stock views, GTIN/tags, average cost tracking, VAT on purchase orders, and print support throughout.
Added
"Where used" reverse BoM lookup
- Stock item detail page shows every assembly whose bill of materials references that component
- Useful for impact analysis: instantly see which finished goods are affected if a component becomes unavailable
Sales returns
- Record customer returns against a prior sale with line-level return quantities
- Stock is automatically reversed on returned quantities, generating adjustment movements
- Returns listed under the originating sale record
Location stock detail view
- Each location now has a dedicated detail page showing a full breakdown of stock held there, item by item
- Backs a new API endpoint
GET /api/v1/locations/:id/stockreturning per-item quantities at that location
GTIN and tags on stock items
- GTIN (barcode) field added to stock items for scanning workflows and catalogue integration
- Free-form tags field for custom grouping and filtering
Average cost tracking
- Weighted average cost automatically recalculated on every goods receipt
- Replaces last-price-only approach for more accurate cost-of-goods-sold figures
VAT on purchase orders
- Optional VAT rate field on purchase orders; net subtotal, VAT amount, and grand total all calculated and displayed
- VAT line included in the printable purchase order view
Print views
- Purchase orders: printable HTML view with supplier details, line items, VAT, and grand total
- Stock takes: printable HTML view with expected vs. counted quantities, suitable for clipboard use
Supplier address fields
- Supplier records now store a full address: address lines, city, county, postcode, and country
- Address printed on purchase orders
Sales order reference fields
- External reference number, customer email, and customer phone fields added to sale records
Location-scoped stock takes
- Stock takes can now be scoped to a specific location; location name included in responses and print views
Changed
- Application renamed from Prod-Man to Kitted throughout the codebase and UI
[0.3.7] — 2026-03-19
Automatic sign-in for localhost users.
Added
Localhost auto-login
- Users opening the app on the same machine it is running on are signed in automatically — no password prompt
- Server endpoint
GET /api/v1/auth/local-tokenissues a standard JWT only when the request originates from a loopback address (127.0.0.1/::1); always returns 403 for remote LAN clients - Login page detects
localhost/127.0.0.1hostname and attempts auto-login on load; shows a brief "Connecting…" placeholder during the check to avoid a flash of the login form - Settings → Security card: "Require password on this machine" toggle (default off) — stores
requireLocalLoginin settings; set this on shared machines or kiosk deployments where individual accounts matter
[0.3.6] — 2026-03-18
Reorder workbench, drag-and-drop attachments, low stock tray notifications, and contextual hint banners.
Added
Reorder workbench
- Reorder Suggestions page rebuilt as a full purchasing workbench
- Row checkboxes: select which items to action in one pass
- Per-row quantity field pre-populated from net shortfall (gap minus already-on-order quantity), editable before creating POs
- Per-row supplier selector: defaults to preferred supplier; falls back to first configured supplier; optgroup separates "Configured for this item" (preferred marked ★) from all other suppliers
- Create Purchase Orders button groups selected rows by supplier and creates one PO per supplier in a single action; unit price pre-filled from linked supplier config
- After creation, navigates automatically to the purchase orders list
- Actionable items (have a supplier, not already fully covered) shown in main workbench table with select-all checkbox
- Already-covered items (open PO quantity ≥ shortfall) shown in a muted "Already covered" section with strikethrough shortfall, no checkbox
- Items with no supplier configured shown in an amber "No supplier configured" section with a link to add one
- Assemblies that appear below min stock shown in a separate informational section (they are built, not purchased) with a link to raise a production order
- Assembly items now correctly excluded from the purchasable reorder list (server-side
is_assemblyflag added toReorderSuggestion)
Drag-and-drop file attachments
AttachmentsCardcomponent now accepts drag-and-drop: dragging a file over the card highlights a dashed drop zone; releasing triggers the upload- Applies to all pages that render the attachments card: stock item detail, supplier detail, production order detail, purchase order detail
Low stock tray notifications
- OS tray notification fires when a stock movement causes any item to fall below its
min_stock_level(Electron builds only) - Rate-limited to one notification per item per hour to prevent spam during bulk operations such as completing a large production order
- Settings → Notifications: "Low stock alerts" toggle (default on)
Contextual hint banners
- New reusable
HintBannercomponent: indigo info strip with a × dismiss button; renders nothing once dismissed - Dismissed hint IDs persisted in
dismissed_hintssetting (comma-separated) so they stay dismissed across restarts - Hint banners added to eight key first-encounter points:
- Production orders — components deducted and finished goods added on completion
- Assemblies — define BOM to enable production orders and cost roll-ups
- Sales — recording a sale deducts stock automatically
- Stock takes — expected vs counted; confirming generates adjustment movements
- Purchase orders — Draft → Sent → Receive Goods workflow; stock only updated on receipt
- CSV import — download the template first; map columns before importing
- Reorder workbench — assign supplier per row; one PO per supplier created
- Assembly detail (BoM tab) — yield factor explanation (0.9 = 10% waste)
Changed
- Low stock dashboard card and stock list badges now link to the reorder workbench rather than the low stock report
[0.3.5] — 2026-03-17
Adds the Electron desktop app wrapper, cross-platform installers with CI-based releases, and in-app auto-update.
Added
Electron desktop app
- Electron 41 shell wrapping the existing Fastify + Vite stack; no changes to server or client code required
- Fastify server spawned as a
utilityProcess.fork()subprocess (avoids spawning a second full Electron instance, which would conflict with the single-instance lock) - System tray icon with context menu: Open, Check for Updates, Quit
- Window hides to tray on close rather than quitting; tray left-click restores the window
- Single-instance lock: second launch focuses the existing window instead of opening a duplicate
Cross-platform installer pipeline
- Windows NSIS installer via
electron-builder: one-click and custom install path supported; Start Menu + desktop shortcuts - macOS DMG via
electron-builder:.icnsgenerated at CI build time usingiconutil/sipson themacos-latestrunner - Linux AppImage +
.debviaelectron-builder
GitHub Actions release workflow
.github/workflows/release.yml: fires onv*tag push; three parallel jobs (windows-latest,macos-latest,ubuntu-latest) each build and upload their platform artifact to the GitHub Release usingsoftprops/action-gh-releaseelectron-builderruns with--publish neveron each runner; artifact upload is handled by the Actions step so no GitHub token scoping issues ariselatest.yml/latest-mac.yml/latest-linux.ymlblock-map update metadata uploaded alongside installers to supportelectron-updater
npm run release script
- Interactive CLI (
scripts/tag-release.ts): shows latest git tag and currentpackage.jsonversion, prompts for new version, bumpspackage.jsonif needed, commits, creates an annotated tag, and pushes — triggering the CI release workflow automatically
Auto-update (electron-updater)
electron-updaterintegrated in Electron main process; silentcheckForUpdates()on startup (production-packaged builds only)- Tray "Check for Updates…" item label updates dynamically: shows download percentage while downloading, changes to "Restart to Install Update" when ready
- IPC bridge in preload (
contextBridge): exposesonUpdateAvailable,onUpdateDownloaded,restartAndInstallto the renderer - Non-blocking indigo banner in
AppShell: "A new version is available — downloading…" transitions to "Update downloaded — restart to install" with Restart now and Later buttons; no-op when running outside Electron
Changed
better-sqlite3upgraded from v11 to v12.8.0 (v11 uses removed V8 APIs incompatible with Electron 41)- All esbuild-bundled packages moved from
dependenciestodevDependencies; onlybetter-sqlite3andelectron-updaterremain as true runtime dependencies, preventing electron-builder from auto-including hundreds of MB of node_modules in the installer - Installer output directory changed to
packages/(excluded from git); previously built todist/which caused recursive inclusion of old installer artifacts on subsequent builds authorfield inpackage.jsonexpanded to object form withemail(required by.debmaintainer metadata)
[0.2.0] — 2026-03-13
First beta milestone. Adds purchase orders, supplier price tracking, production stage management, and BoM version history.
Added
Purchase orders
- Full purchase order lifecycle: create, edit (while open), receive goods (partial or full), and cancel
- Goods receipt deducts outstanding quantity from PO lines and updates stock levels; also records and updates
last_priceon the supplier link - Draft editing mode: PO lines can be amended while the order remains open
- Purchase orders list page with status filter
Supplier pricing
- Volume / quantity-break pricing:
supplier_price_breakstable; per-tier prices shown on supplier item cards - BoM cost roll-up accepts optional
modelQtyparameter to apply best-available price break per component - Supplier price history: an immutable log row is written every time
last_pricechanges (goods receipt or manual edit); chart on supplier item detail page - Supplier prices comparison report expanded to include price-break tiers
Open purchase order quantity on reorder suggestions
- Reorder suggestions page now shows how many units of each item are already on open POs, so the shortfall figure accounts for in-flight orders
Production stage tracking
production_order_eventstable records each stage transition with timestamp and optional notes- Stages:
planned → picking → in_progress → qc → complete; step back by one stage permitted; jump directly tocompletepermitted from any stage - Stage stepper UI on production order detail page
- Stage badge column on production orders list page
- Filter production orders by current stage on the list page
- Initial
plannedevent inserted automatically when an order is raised
Picklists
GET /production/:id/picklistendpoint: components grouped by storage location with required quantity and current stock at that location- "Generate Picklist" button on production order detail page; opens a modal with full component × location breakdown
- Advancing an order to the
pickingstage automatically opens the picklist modal - CSV export and print (landscape A4/Letter, full-page print layout; action buttons hidden in print)
BoM version history UI
- Production order detail page shows a diff between the snapshotted BoM lines (at order creation) and the current live BoM
- Changed quantities highlighted amber; removed components highlighted red; newly added components highlighted green with "new" badge
- Diff suppressed automatically when snapshot and live BoM are identical
Cost price display on stock items list
- Optional "Show cost prices" toggle on the stock items list page
[0.1.0] — 2026-03-12
First alpha release.
Added
Project foundation
- TypeScript + Vite + Tailwind CSS project scaffold
- Fastify backend with SQLite via Drizzle ORM; shared schema types between server and client
- JWT authentication with secure secret resolution (env var → persisted file → dev fallback)
- Setup wizard (first-run flow: create admin account, set business name and currency)
- Font Awesome icons throughout navigation and UI
Stock management
- Stock items with SKU (auto-generation + uniqueness validation), unit of measure, cost price, sale price, min stock level, and image attachments
- Stock movements: adjustments (in/out) and transfers between locations with per-location quantity tracking
- Locations management (create, archive)
- Low stock indicator on stock movements page with link to reorder suggestions
- Default stock location preference (pre-fills location dropdowns app-wide)
Assemblies & Bill of Materials
- Assembly (recipe/formula) management with multi-level BoM
- BoM line add/edit/remove with quantity and yield factor
- Cost price roll-up on assembly detail page
- Estimated build time field on assemblies
- Stock links from assembly detail page to component stock items
Production orders
- Production order creation, completion, and cancellation
- On creation: BoM snapshot written to
production_order_lines(independent of live BoM, so later edits don't affect in-progress orders) - On completion: component deductions use snapshotted lines; falls back to live BoM for pre-migration orders
- Production order detail page showing components used from snapshot
Sales
- Sale creation with line items (stock item, quantity, unit price); deducts finished goods stock on save
- Sales list with date filter and totals
- Sale detail view
- CSV export of sales history
- Currency symbol shown on sale totals
Stock takes
- Stock take workflow: create → system pre-fills expected quantities → user enters counted quantities → confirm generates adjustment movements for all discrepancies
- Stock take history list
CSV import
- Import stock items from CSV: upload → column mapping → preview with validation errors → confirm
- Duplicate SKU handling: skip or update (user chooses)
- Template CSV download (pre-filled headers)
Suppliers & reorder
- Supplier management with stock item price links and preferred flag
- Reorder suggestions page (items below min stock level)
- Supplier price comparison report (all suppliers for a selected item, side by side)
Reports
- Stock levels report (per item, per location)
- Stock valuation report (quantity × cost price, subtotalled by location; items without cost price flagged)
- Stock movements report (filterable by item and date range)
- Production history summary (planned vs completed quantities per assembly over a date range)
- Supplier price comparison report
Dashboard
- Summary cards: total stock items, low stock count, pending production orders, recent sales
- Quick links to key workflows
Settings
- General settings: business name, currency, business profile (manufacturer / food / craft), default stock location
- Change password
- Data management: database path + size display, configurable data directory (persisted to
~/.kitted-config.json; prompts restart) - Open data folder button
- Startup error screen if data directory or database is unreachable
Business profiles & terminology
businessProfilesetting (manufacturer|food|craft) drives a terminology maplabels()helper inappState.tsreturns profile-appropriate strings- Terminology applied throughout: Assemblies page, Assembly Detail, BoM forms, Production page, navigation sidebar
- Business profile selector in setup wizard and Settings
Backup
- Manual backup: timestamped
.zipof the database and attachments folder - Scheduled backup: configurable daily/weekly schedule (default 02:00 daily), configurable destination folder (default
backups/inside the data directory), configurable retention count (default 7; older backups auto-pruned) - Backup status shown in Settings ("Last backup: …"); last error surfaced if present
- "Back up now" button in Settings
Demo data
- "Brightwick Co." demo dataset: ~20 stock items, 3 locations, 4 suppliers, 3 assemblies (including multi-level BoM), production runs and movements
- Load during setup wizard final step or from Settings at any time
- All demo records flagged
is_demo = true; "Clear demo data" in Settings removes them without affecting real data
Licensing
- Custom licence server (
src/licence-server/): Fastify + Hypertable data layer; endpoints for key creation (admin), activation, check-in - 30-day trial with countdown;
firstRunAtstored insettingson first startup - Trial warning banner in AppShell when ≤ 7 days remain; links to Settings
- Expired trial and revoked-licence blocking modal in AppShell; allows navigation to Settings only
- Licence card in Settings: status badge, key input + Activate button, Deactivate button, machine ID display
POST /api/v1/licence/activateproxies to the licence server and persists the result locally- Background check-in: fires on every app startup plus a cron job every 12 hours (only calls out if 7+ days since last successful check-in); 14-day grace period if server unreachable
- Machine binding via
node-machine-id(hashed)
Packaging & distribution
npm run package— Windows x64 standalone binary via@yao-pkg/pkgnpm run package:mac— macOS x64 binary (must be built on a Mac)- System tray icon (Windows and macOS) with "Open" and "Quit" items; opens browser on launch
- PNG icon support for macOS/Linux; ICO for Windows
- JWT secret auto-generated and persisted on first run of the packaged binary
- GitHub release script for automated versioning and artifact uploads
Notes
- The licence server (
src/licence-server/) is deployed separately to DigitalOcean App Platform;LICENCE_SERVER_URLin the kitted environment points to it (default:http://localhost:3100for development) - Linux packaging is deferred to v1 (Wayland/AppIndicator fragmentation)
- Multi-user roles, audit log, full PO workflow, and in-app updater are deferred to v1
For the pre-alpha development roadmap see ALPHA_PLAN.md. For architecture decisions and implementation rationale see IMPLEMENTATION_PLAN.md.