Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
Issue Manager / issue-manager (push) Failing after 9s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
614 lines
24 KiB
Markdown
614 lines
24 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Spoolman is a self-hosted web service for managing 3D printer filament spools. It tracks inventory, monitors usage, and integrates with OctoPrint and Klipper/Moonraker.
|
|
|
|
**Tech Stack:**
|
|
- Backend: Python 3.9-3.12, FastAPI, SQLAlchemy 2.0 (async), Alembic
|
|
- Frontend: React 19, TypeScript, Vite, Ant Design, Refine framework
|
|
- Databases: SQLite (default), PostgreSQL, MySQL, CockroachDB
|
|
|
|
## Common Commands
|
|
|
|
### Python (PDM)
|
|
|
|
```bash
|
|
pdm install # Install all dependencies including dev
|
|
pdm sync --prod --no-editable # Install production dependencies only
|
|
pdm run app # Run backend server (uvicorn)
|
|
pdm run itest # Run integration tests (all databases)
|
|
pdm run docs # Generate API documentation
|
|
```
|
|
|
|
### Frontend
|
|
|
|
```bash
|
|
cd client
|
|
npm ci # Install dependencies
|
|
npm run dev # Development server with hot reload
|
|
npm run build # Production build
|
|
npm run tsc # Type check only
|
|
```
|
|
|
|
### Linting/Formatting
|
|
|
|
```bash
|
|
black . # Format Python code
|
|
ruff check . --fix # Lint and auto-fix Python
|
|
pre-commit run --all-files # Run all pre-commit hooks
|
|
```
|
|
|
|
### Integration Tests
|
|
|
|
Tests run in Docker containers against multiple database types:
|
|
|
|
```bash
|
|
python tests_integration/run.py sqlite # Single database
|
|
python tests_integration/run.py sqlite postgres # Multiple databases
|
|
pdm run itest # All databases
|
|
```
|
|
|
|
Run a single test:
|
|
```bash
|
|
pytest tests_integration/tests/spool/test_add.py::test_add_spool_remaining_weight -v
|
|
```
|
|
|
|
### Database Migrations
|
|
|
|
1. Edit models in `spoolman/database/models.py`
|
|
2. Run the server to update local SQLite
|
|
3. `pdm run alembic revision -m "description" --autogenerate`
|
|
4. Review generated migration, format with Black/Ruff
|
|
|
|
## Architecture
|
|
|
|
### Backend (`/spoolman/`)
|
|
|
|
- `main.py` - FastAPI app entry, startup/shutdown, SPA mounting
|
|
- `env.py` - Environment variable parsing and configuration
|
|
- `ws.py` - WebSocket manager for real-time updates
|
|
- `api/v1/` - REST endpoints and WebSocket handlers
|
|
- `router.py` - Main router with WebSocket root endpoint
|
|
- `spool.py`, `filament.py`, `vendor.py` - CRUD endpoints per resource
|
|
- `models.py` - Pydantic response models
|
|
- `database/` - SQLAlchemy models and async database operations
|
|
- `models.py` - ORM definitions (Vendor, Filament, Spool, Setting, *Field)
|
|
- `database.py` - Connection setup, backup logic, migrations
|
|
|
|
### Frontend (`/client/src/`)
|
|
|
|
- `App.tsx` - Routing and Refine framework setup
|
|
- `pages/` - Page components (spools/, filaments/, vendors/, settings/)
|
|
- `components/dataProvider.ts` - REST API integration
|
|
- `components/liveProvider.ts` - WebSocket live updates
|
|
|
|
### Data Model
|
|
|
|
```
|
|
Vendor (1) ──→ (many) Filament (1) ──→ (many) Spool
|
|
```
|
|
|
|
All entities support custom fields via *Field tables (VendorField, FilamentField, SpoolField).
|
|
|
|
### API Patterns
|
|
|
|
- REST: Standard CRUD at `/api/v1/{resource}`
|
|
- WebSocket: Real-time events at `WS /api/v1/` or `WS /api/v1/{resource}`
|
|
- Query params: `?skip=0&limit=50&sort_by=name&sort_order=asc`
|
|
|
|
### Key Configuration
|
|
|
|
Environment variables (see `.env.example`):
|
|
- `SPOOLMAN_DB_TYPE` - Database type (sqlite/mysql/postgres/cockroachdb)
|
|
- `SPOOLMAN_PORT` - Server port (default: 7912)
|
|
- `SPOOLMAN_DEBUG_MODE` - Enables permissive CORS
|
|
- `VITE_APIURL` - Frontend API base URL (e.g., `/api/v1`)
|
|
|
|
## Code Quality
|
|
|
|
- Line length: 120 characters
|
|
- Python target: 3.9
|
|
- Pre-commit hooks enforce Black formatting and Ruff linting
|
|
- Backend is fully async using SQLAlchemy AsyncSession
|
|
|
|
## Gitea Repository
|
|
|
|
- **URL:** http://192.168.0.5:3022/tonym/spoolman2
|
|
- **API Token:** 8a04b3cb5dbb54e2d895b707305523c3ad83a945
|
|
- **Upstream:** https://github.com/Donkie/Spoolman (remote: `upstream`)
|
|
|
|
This is a fork with UX improvements. Issues are tracked on the Gitea instance above.
|
|
|
|
## UX Improvement Issues (Gitea)
|
|
|
|
| # | Title | Status |
|
|
|---|-------|--------|
|
|
| 1 | Inline Creation Modals | ✅ DONE |
|
|
| 2 | Smart Density Defaults | ✅ DONE |
|
|
| 3 | QR Code Sizing Fixes | ✅ DONE |
|
|
| 4 | Layout Max-Width | ✅ DONE |
|
|
| 5 | Temperature Ranges | ✅ DONE |
|
|
| 6 | Spool Adjustment History | ✅ DONE |
|
|
| 7 | 3dfilamentprofiles Integration | ❌ REMOVED |
|
|
| 8 | (duplicate of #7) | ✅ DONE |
|
|
| 9 | Hierarchical Locations (Room/Bin) | ✅ DONE |
|
|
| 10 | Database Import/Export | ✅ DONE |
|
|
| 11 | Slicer Integration / Print Jobs | ✅ DONE |
|
|
| 12 | Redesign Home Page Dashboard | ✅ DONE |
|
|
| 13 | Batch Operations (Multi-Select Edit) | ✅ DONE |
|
|
| 14 | Extra Weight Field (DryPods, etc.) | ✅ DONE |
|
|
| 15 | Spool Count per Filament in List | ✅ DONE |
|
|
| 16 | Filter Spools by Color | ✅ DONE |
|
|
| 17 | Image Attachments for Filaments | **Open** |
|
|
| 18 | QR Code Labels for Filaments | **Open** |
|
|
| 19 | Integration with filamentcolors.xyz | ✅ DONE |
|
|
| 20 | Gallery View for Spools (Color Grid) | ✅ DONE |
|
|
| 21 | QR Code Version/Complexity Config | **Open** |
|
|
| 23 | Reporting & Data Export | **Open** |
|
|
| 24 | NFC/RFID Tag Support | **Open** |
|
|
| 25 | Sort Spools by Custom Fields | ✅ DONE |
|
|
| 26 | Label Template Enhancements | **Open** |
|
|
| 27 | QR Scanner Camera Device Selector | **Open** |
|
|
| 28 | Mobile-Friendly UI / Responsive | **Open** |
|
|
| 29 | Table Column Customization | **Open** |
|
|
| 30 | Printer Management & Parts Inventory | **Open** |
|
|
| 31 | Special Filament Properties | **Open** |
|
|
| 32 | SpoolType Model (Cardboard/Plastic/Metal) | **Open** |
|
|
| 34 | Color Swatch Border for Dark Mode | ✅ DONE |
|
|
| 35 | Global Search Box | ✅ DONE |
|
|
| 36 | Spool-Level Overrides (Color, Price) | ✅ DONE |
|
|
| 37 | Plugin System for Extensions | **Open** |
|
|
| 39 | Usage Statistics & Cost Tracking | ✅ DONE |
|
|
| 40 | Storage vs Active Spool Status | **Open** |
|
|
| 41 | Load Cell / Scale Integration | **Open** |
|
|
| 42 | Allow Spools Heavier Than Max | ✅ DONE |
|
|
| 43 | Show Filament Fields on Spool View | ✅ DONE |
|
|
| 44 | HomeAssistant Add-On Packaging | **Open** |
|
|
| 45 | Filament Swatch Card Generator | **Open** |
|
|
| 46 | Project-Based Spool Grouping | **Open** |
|
|
| 47 | G-code Filament Usage Estimation | **Open** |
|
|
|
|
### Other Features (not tracked in Gitea)
|
|
- ✅ Theme Colors (5 options)
|
|
- ✅ Clickable Dashboard Cards
|
|
- ✅ QR Code Size Setting
|
|
- ✅ Parse Temps from Comments
|
|
- ✅ Prev/Next Navigation on Edit Pages
|
|
- ✅ Price/Cost Tracking (remaining value, inventory value)
|
|
- ✅ Print History on Spool Detail
|
|
- ✅ Usage Analytics Dashboard
|
|
- ✅ Color Column in Spool List (with filter)
|
|
|
|
### Issue #1 Complete - Inline Creation Modals
|
|
|
|
Added ability to create filament/vendor inline without leaving the page:
|
|
- `client/src/components/vendorCreateModal.tsx` - Quick vendor creation
|
|
- `client/src/components/filamentCreateModal.tsx` - Quick filament creation with nested vendor modal
|
|
- Modified spool create to add "Create Filament" in dropdown
|
|
- Modified filament create to add "Create Manufacturer" in dropdown
|
|
- Uses `dropdownRender` pattern (same as location select)
|
|
- Uses `useInvalidate` to refresh lists after creation
|
|
|
|
### Issue #2 Complete - Smart Density Defaults
|
|
|
|
Auto-fill density based on material type:
|
|
- `client/src/utils/materialDefaults.ts` - Density lookup table with fuzzy matching
|
|
- Material field converted to AutoComplete (dropdown suggestions + free text)
|
|
- Fuzzy matching: "PLA Silk" → PLA (1.24 g/cm³)
|
|
- New filaments default to 1.75mm diameter and 1.24 g/cm³ (PLA)
|
|
- Applied to both full create page and FilamentCreateModal
|
|
- Edit page not affected (preserves user customizations)
|
|
|
|
Material densities in lookup:
|
|
```
|
|
PLA: 1.24, ABS: 1.04, PETG: 1.27, NYLON: 1.52, TPU: 1.21
|
|
PC: 1.3, WOOD: 1.28, CF: 1.3, PC/ABS: 1.19, HIPS: 1.03
|
|
PVA: 1.23, ASA: 1.05, PP: 0.9, POM: 1.4, PMMA: 1.18, FPE: 2.16
|
|
```
|
|
|
|
### Issue #3 Complete - QR Code Sizing Fixes
|
|
|
|
See upstream issue: https://github.com/Donkie/Spoolman/issues/671
|
|
|
|
Changes:
|
|
- Removed fixed 50% max-width constraint (now uses fit-content by default)
|
|
- Added `qrCodePadding` setting (0-10mm, default 2mm)
|
|
- Added `qrCodeMaxWidth` setting (0-100%, 0 = auto)
|
|
- Added UI controls with slider + input number for both settings
|
|
|
|
Files modified:
|
|
- `client/src/pages/printing/printing.tsx` - Added settings to interface
|
|
- `client/src/pages/printing/qrCodePrintingDialog.tsx` - CSS and UI controls
|
|
|
|
### Issue #4 Complete - Layout Max-Width
|
|
|
|
Changes:
|
|
- Added 1400px max-width container in `SpoolmanLayout`
|
|
- Added 800px max-width for forms via CSS override in `overrides.css`
|
|
- Content is centered on wide screens
|
|
|
|
### Issue #5 Complete - Temperature Ranges
|
|
|
|
Store extruder and bed temperatures as min/max ranges:
|
|
- Added 4 new DB columns: `settings_extruder_temp_min/max`, `settings_bed_temp_min/max`
|
|
- Old single-value columns kept for backward compatibility (deprecated)
|
|
- Alembic migration copies existing values to both min and max
|
|
- Frontend uses Space.Compact with min/max input pairs
|
|
- Label template shows ranges: "ET: 190-220 °C"
|
|
|
|
Files:
|
|
- `spoolman/database/models.py` - New columns
|
|
- `migrations/versions/2025_01_15_0200-*.py` - Migration
|
|
- `spoolman/api/v1/models.py`, `filament.py` - API changes
|
|
- `client/src/pages/filaments/create.tsx` - Form updates
|
|
- `client/src/pages/printing/spoolQrCodePrintingDialog.tsx` - Template tags
|
|
|
|
### Issue #6 Complete - Spool Adjustment History
|
|
|
|
Track history of all spool weight/length adjustments with timestamps and comments.
|
|
|
|
Backend:
|
|
- `spoolman/database/models.py` - Added `SpoolAdjustment` model with relationship to Spool
|
|
- `migrations/versions/2025_01_15_0300-*.py` - Migration for spool_adjustment table
|
|
- `spoolman/api/v1/models.py` - Added `SpoolAdjustment` Pydantic model
|
|
- `spoolman/api/v1/spool.py` - Added comment field to use/measure endpoints, GET /spool/{id}/adjustments endpoint
|
|
- `spoolman/database/spool.py` - Updated use_weight, use_length, measure functions to record adjustments
|
|
|
|
Frontend:
|
|
- `client/src/pages/spools/model.tsx` - Added `ISpoolAdjustment` interface
|
|
- `client/src/pages/spools/show.tsx` - Collapsible adjustment history table
|
|
- `client/public/locales/en/common.json` - Translation keys for history table
|
|
|
|
### Issue #7 REMOVED - 3dfilamentprofiles Integration
|
|
|
|
**Removed** - 3dfilamentprofiles.com has Vercel bot protection blocking automated requests.
|
|
Their GitHub repo only has sample data (~3 filaments). SpoolmanDB has 6,957+ filaments, so this was unnecessary.
|
|
|
|
### Issue #10 Complete - Database Import/Export
|
|
|
|
Full backup/restore functionality for migrating between databases (PostgreSQL ↔ SQLite).
|
|
|
|
Backend (`spoolman/api/v1/backup.py`):
|
|
- `GET /api/v1/backup/export` - Downloads all data as single JSON file
|
|
- `POST /api/v1/backup/import` - Imports JSON with `replace` option
|
|
- Exports: vendors, filaments, spools, spool_adjustments, settings
|
|
- Handles ID remapping to maintain relationships
|
|
- Requires `python-multipart` package for file uploads
|
|
|
|
Frontend (`client/src/pages/settings/generalSettings.tsx`):
|
|
- "Backup & Restore" section in Settings page
|
|
- "Download Backup" button for export
|
|
- File upload with "Import (Merge)" or "Import (Replace All)" options
|
|
- Confirmation dialog for destructive replace operation
|
|
|
|
Migration workflow:
|
|
1. Export from PostgreSQL instance via Settings → Download Backup
|
|
2. Reconfigure container for SQLite
|
|
3. Import via Settings → Import (Replace All)
|
|
|
|
---
|
|
|
|
## Local Development Setup
|
|
|
|
To run locally against the Unraid PostgreSQL database:
|
|
|
|
```bash
|
|
# Create virtualenv and install deps
|
|
python3 -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -e ".[postgres]"
|
|
|
|
# Start backend (reads .env file)
|
|
source .venv/bin/activate
|
|
export $(grep -v '^#' .env | xargs)
|
|
uvicorn spoolman.main:app --host 0.0.0.0 --port 7912
|
|
|
|
# Start frontend (separate terminal)
|
|
cd client
|
|
VITE_APIURL=http://localhost:7912/api/v1 npm run dev
|
|
```
|
|
|
|
Access at http://localhost:5173
|
|
|
|
### Issue #11 Complete - Theme Colors
|
|
|
|
Added theme color selector with 5 color options:
|
|
- `client/src/contexts/color-mode/index.tsx` - Theme color system with THEME_COLORS constant
|
|
- Colors: orange, teal, red, green, blue
|
|
- Persists in localStorage
|
|
- Settings page has color selector buttons
|
|
|
|
### Issue #12 Complete - Clickable Dashboard Cards
|
|
|
|
Dashboard cards now link to their respective list pages:
|
|
- `client/src/pages/home/index.tsx` - Card body is clickable, links to list
|
|
- Only the + button stays independent (for create)
|
|
|
|
### Issue #13 Complete - QR Code Size Setting
|
|
|
|
Added explicit QR code size control:
|
|
- `client/src/pages/printing/printing.tsx` - Added `qrCodeSize` to interface
|
|
- `client/src/pages/printing/qrCodePrintingDialog.tsx` - Slider for size in mm (0=auto)
|
|
|
|
### Issue #15 Complete - Print Job Tracking / Slicer Integration
|
|
|
|
Track pending print jobs from slicer and manage filament deduction after prints complete.
|
|
|
|
**Workflow:**
|
|
1. Slicer post-processing script parses G-code for filament usage
|
|
2. Script creates pending print job in Spoolman via API
|
|
3. After print completes, user visits Print Queue UI
|
|
4. Complete: Deducts filament from spool, records adjustment history
|
|
5. Cancel: Flags spool for manual weigh-in (no automatic deduction)
|
|
|
|
**Backend:**
|
|
- `spoolman/database/models.py` - `PrintJob` model, `needs_weighing` field on Spool
|
|
- `spoolman/database/print_job.py` - CRUD operations for print jobs
|
|
- `spoolman/api/v1/print_job.py` - REST API endpoints
|
|
- `POST /print-job` - Create pending job
|
|
- `POST /print-job/{id}/complete` - Complete job, deduct filament
|
|
- `POST /print-job/{id}/cancel` - Cancel job, flag spool for weighing
|
|
- `GET /print-job` - List jobs with status filter
|
|
- `migrations/versions/2025_01_15_0400-c3d4e5f6g7h8_add_print_jobs.py`
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/print-queue/index.tsx` - Print Queue UI page
|
|
- `client/src/pages/spools/model.tsx` - `IPrintJob` interface, `needs_weighing` on ISpool
|
|
|
|
**Slicer Script:**
|
|
- `scripts/slicer_post_process.py` - Elegoo/Orca Slicer post-processing script
|
|
- Parses G-code comments for filament usage (weight in grams)
|
|
- Creates pending print job via API
|
|
- Configure via env vars: `SPOOLMAN_URL`, `SPOOLMAN_SPOOL_ID`
|
|
- Or config file: `~/.config/spoolman/slicer.conf`
|
|
|
|
### Color Column in Spool List
|
|
|
|
Added optional color column to the spool list with filtering capability.
|
|
|
|
**Backend:**
|
|
- `spoolman/database/filament.py` - `find_colors()` function to get distinct color hex codes
|
|
- `spoolman/api/v1/other.py` - `GET /api/v1/color` endpoint to list all colors
|
|
- `spoolman/api/v1/spool.py` - Added `filament.color_hex` query parameter for filtering
|
|
- `spoolman/database/spool.py` - Filter implementation (supports comma-separated values)
|
|
|
|
**Frontend:**
|
|
- `client/src/components/column.tsx` - `ColorFilterColumn` component renders color swatches
|
|
- `client/src/components/otherModels.tsx` - `useSpoolmanColors()` hook to fetch colors
|
|
- `client/src/pages/spools/list.tsx` - Added color column (hidden by default)
|
|
- `client/public/locales/en/common.json` - Added "Color" translation key
|
|
|
|
**Features:**
|
|
- Color displayed as small swatch with hex tooltip
|
|
- Filter dropdown shows swatches with hex codes
|
|
- Multi-select filtering (can filter by multiple colors)
|
|
- Column hidden by default (enable via column selector)
|
|
|
|
### Issue #9 Complete - Hierarchical Locations
|
|
|
|
Storage locations can now be organized in a tree structure (Room > Shelf > Bin).
|
|
|
|
**Backend:**
|
|
- `spoolman/database/models.py` - Added `Location` model with self-referential parent
|
|
- `spoolman/database/location.py` - CRUD operations, tree building, full path resolution
|
|
- `spoolman/api/v1/location.py` - REST API for locations
|
|
- `migrations/versions/2025_01_21_0100-*.py` - Migration for location table
|
|
|
|
**Frontend:**
|
|
- `client/src/components/LocationTreeSelect.tsx` - Tree-based location picker
|
|
- `client/src/components/LocationCreateModal.tsx` - Inline location creation
|
|
|
|
**Features:**
|
|
- Hierarchical structure with parent/child relationships
|
|
- Location types: room, shelf, bin, drawer, box, other
|
|
- Legacy flat location string preserved for backward compatibility
|
|
- API endpoints: GET /location, GET /location/tree, POST/PATCH/DELETE
|
|
|
|
### Issue #12 Complete - Dashboard Redesign
|
|
|
|
Redesigned home page with better visualizations and quick stats.
|
|
|
|
**Backend:** No changes needed - uses existing endpoints.
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/home/index.tsx` - Refactored layout
|
|
- `client/src/pages/home/components/AlertCards.tsx` - Low stock, pending jobs, needs weighing alerts
|
|
- `client/src/pages/home/components/MaterialDistributionChart.tsx` - Pie chart by material (recharts)
|
|
- `client/src/pages/home/components/QuickStats.tsx` - Total spools, filaments, vendors, weight
|
|
|
|
**Dependencies:**
|
|
- Added `recharts` package for charts
|
|
|
|
### Issue #13 Complete - Batch Operations
|
|
|
|
Multi-select spools with bulk archive/delete/move actions.
|
|
|
|
**Backend:**
|
|
- `spoolman/api/v1/spool.py` - Added bulk endpoints:
|
|
- POST /spool/bulk/archive
|
|
- POST /spool/bulk/delete
|
|
- POST /spool/bulk/update
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/list.tsx` - Added row selection
|
|
- `client/src/pages/spools/components/BatchActionBar.tsx` - Floating action bar
|
|
- `client/src/pages/spools/functions.tsx` - Bulk helper functions
|
|
|
|
**Features:**
|
|
- Checkbox selection with select-all
|
|
- Floating action bar shows when items selected
|
|
- Archive, unarchive, delete, move to location
|
|
- Confirmation modals for all destructive actions
|
|
|
|
### Issue #14 Complete - Extra Weight Field
|
|
|
|
Track extra weight from DryPods, custom spool holders, or other accessories.
|
|
|
|
**Backend:**
|
|
- `spoolman/database/models.py` - Added `extra_weight` column to Spool model
|
|
- `spoolman/database/spool.py` - Updated `measure()` to account for extra weight
|
|
- `spoolman/api/v1/spool.py` - Added `extra_weight` to create/update parameters
|
|
- `migrations/versions/2025_01_21_0200-*.py` - Migration for extra_weight column
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/create.tsx` - Added extra_weight form field
|
|
- `client/src/pages/spools/edit.tsx` - Added extra_weight form field
|
|
- Weight calculations updated to include extra_weight in gross weight
|
|
|
|
**Features:**
|
|
- Optional field for tracking additional weight on spool
|
|
- Automatically subtracted when measuring spool weight
|
|
- Useful for DryPods, custom spool holders, reel adapters
|
|
|
|
### Issue #15 Complete - Spool Count per Filament
|
|
|
|
Already implemented - filament list shows `spool_count` and `total_remaining_weight` columns.
|
|
|
|
### Price & Cost Tracking
|
|
|
|
Track spool purchase price and calculate remaining value.
|
|
|
|
**Backend:**
|
|
- `spoolman/api/v1/models.py` - Added `remaining_value` computed field
|
|
- Formula: `remaining_value = (remaining_weight / initial_weight) * price`
|
|
- Price falls back to filament price if not set on spool
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/list.tsx` - Added remaining_value column (hidden by default)
|
|
- `client/src/pages/home/components/QuickStats.tsx` - Added "Inventory Value" stat
|
|
|
|
### Print History on Spool Detail
|
|
|
|
Show print job history on the spool detail page.
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/show.tsx` - Added collapsible print history table
|
|
- Fetches print jobs filtered by spool_id
|
|
- Shows: Created date, Filename, Filament Used, Status, Finished date
|
|
|
|
### Usage Analytics Dashboard
|
|
|
|
Time-series charts showing filament consumption trends.
|
|
|
|
**Backend:**
|
|
- `spoolman/api/v1/other.py` - New analytics endpoints:
|
|
- `GET /analytics/usage?days=N` - Daily usage from SpoolAdjustments
|
|
- `GET /analytics/by-material?days=N` - Usage breakdown by material
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/home/components/UsageAnalytics.tsx` - New component
|
|
- Area chart showing daily consumption (recharts)
|
|
- Period selector: 7, 30, or 90 days
|
|
- Material breakdown cards showing usage by filament type
|
|
|
|
---
|
|
|
|
## Deployment
|
|
|
|
### Production (Unraid)
|
|
|
|
Deployed on Unraid with br0 network:
|
|
- **URL:** http://192.168.0.11:8000 or https://spoolman.nastynas.xyz
|
|
- **Database:** SQLite
|
|
- **Network:** br0 (own IP: 192.168.0.11)
|
|
|
|
Update script: `/mnt/user/appdata/spoolman2-build/update.sh`
|
|
|
|
```bash
|
|
ssh root@192.168.0.5 "/mnt/user/appdata/spoolman2-build/update.sh"
|
|
```
|
|
|
|
---
|
|
|
|
### Issue #42 Complete - Allow Spools Heavier Than Max
|
|
|
|
Removed weight validation cap that prevented spools from exceeding their theoretical initial weight.
|
|
|
|
**Backend:**
|
|
- `spoolman/database/spool.py` - Removed `max(..., 0)` clamps from create/update; when remaining > initial, adjusts initial upward
|
|
- `spoolman/api/v1/models.py` - Removed `max(..., 0)` from remaining_weight computation
|
|
|
|
### Issue #43 Complete - Show Filament Fields on Spool View
|
|
|
|
Display filament custom fields on the spool detail page.
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/show.tsx` - Added `filamentExtraFields` section after spool extra fields
|
|
|
|
### Issue #25 Complete - Sort by Custom Fields & Remaining Weight
|
|
|
|
**Backend:**
|
|
- `spoolman/database/spool.py` - Added `extra.{key}` sort support via outerjoin on SpoolField table
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/list.tsx` - Added `sorter: true` to weight/length NumberColumns
|
|
- `client/src/components/column.tsx` - Changed CustomFieldColumn to sortable with `dataId: extra.{key}`
|
|
|
|
### Issue #35 Complete - Global Search Box
|
|
|
|
**Backend:**
|
|
- `spoolman/api/v1/spool.py` - Added `q` parameter to find endpoint
|
|
- `spoolman/database/spool.py` - OR-based search across filament name, material, vendor name, location, lot_nr, comment
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/list.tsx` - Added `Input.Search` component, passes `q` via meta.queryParams
|
|
|
|
### Issue #20 Complete - Gallery View for Spools
|
|
|
|
Color grid view for spools with progress bars and material labels.
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/components/SpoolGallery.tsx` - Grid of color cards with progress bars
|
|
- `client/src/pages/spools/list.tsx` - View mode toggle (table/gallery)
|
|
|
|
### Issue #36 Complete - Spool-Level Overrides
|
|
|
|
Per-spool color override with ColorPicker (price and initial_weight already existed).
|
|
|
|
**Backend:**
|
|
- `spoolman/database/models.py` - Added `color_hex` field to Spool model
|
|
- `spoolman/api/v1/spool.py` - Added `color_hex` to create/update params
|
|
- `migrations/versions/2025_01_22_0100-g7h8i9j0k1l2_add_spool_color_hex.py`
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/spools/create.tsx`, `edit.tsx` - ColorPicker form field
|
|
- All display locations updated to prefer `spool.color_hex` over `filament.color_hex`
|
|
|
|
### Issue #39 Complete - Usage Statistics & Cost Tracking
|
|
|
|
Added cost analytics endpoint and total spent / avg cost per kg stats.
|
|
|
|
**Backend:**
|
|
- `spoolman/api/v1/other.py` - Added `GET /analytics/cost` endpoint returning total_spent, avg_cost_per_kg, cost_by_material
|
|
|
|
**Frontend:**
|
|
- `client/src/pages/home/components/QuickStats.tsx` - Added "Total Spent" and "Avg Cost/kg" stat cards
|
|
- `client/src/pages/home/components/UsageAnalytics.tsx` - Added cost per material in breakdown cards
|
|
|
|
### Issue #19 Complete - filamentcolors.xyz Integration
|
|
|
|
Color lookup from filamentcolors.xyz database (2134 swatches, 317 manufacturers).
|
|
|
|
**Backend:**
|
|
- `spoolman/api/v1/other.py` - Proxy endpoints:
|
|
- `GET /filamentcolors/manufacturers` - List all manufacturers
|
|
- `GET /filamentcolors/search` - Search swatches by manufacturer, color, filament type
|
|
|
|
**Frontend:**
|
|
- `client/src/components/filamentColorLookup.tsx` - Modal with manufacturer filter + color grid
|
|
- Added search button next to ColorPicker on filament create and edit forms
|
|
- Click a swatch to apply its measured hex color
|
|
|
|
### Bug Fixes
|
|
|
|
- **Filament Select Refresh**: Fixed race condition where form value was set before options re-rendered. Uses `pendingFilamentId` state + useEffect.
|
|
- **Parse Temps from Comments**: Added regex-based temperature parser button on filament edit page.
|
|
|
|
## Known Issues / TODO
|
|
|
|
### Issue #7 - 3dfilamentprofiles Integration REMOVED
|
|
The 3dfilamentprofiles.com website has Vercel bot protection that blocks automated requests. Their GitHub repo (jklewa/filament-profiles-data) only provides sample data (~3 filaments). Since SpoolmanDB already has 6,957+ filaments from major brands, the 3dfp integration was removed rather than maintaining dead code.
|