- Add migration 0016 to drop notes column from roasters table
- Remove notes from domain structs, repositories, views, CLI, routes
- Remove notes from AI extraction prompts and ExtractedRoaster struct
- Remove notes from scan page form and submission handler
- Update templates, bootstrap script, backup module, and tests
- Add migration 0014 to drop the notes column from cafes table
- Remove notes from domain structs, repository, view model, CLI, routes
- Remove notes textarea/column from web templates
- Update bootstrap script and all test files
- Add migration to extend gear CHECK constraint with 'filter_paper'
and add nullable filter_paper_id column to brews
- Add FilterPaper variant to GearCategory enum
- Add filter_paper_id to Brew, NewBrew, and BrewWithDetails
- Add filter_paper_id to TimelineBrewData
Database:
- Add slug, roaster_slug, brew_data_json columns to timeline_events
- Migration backfills existing data from related tables
- Remove 9-way LEFT JOIN from list query, read directly from columns
Frontend:
- Use CSS :nth-of-type(odd/even) for alternating timeline layout
- Remove JavaScript class manipulation when appending month events
- Simplify infinite scroll month-merging logic
This eliminates query-time JOINs across 5 tables and ~20 lines of
client-side JavaScript for pattern maintenance.
The notes field was not providing enough value to justify its presence.
Simplified the Gear entity by removing notes from:
- Domain structs (Gear, NewGear, UpdateGear)
- SQL repository queries and GearRecord
- HTTP client methods
- CLI commands (--notes flag)
- Web views and templates
- All related tests
Added migration 0008_remove_gear_notes.sql to drop the column.
Add Gear entity to track brewing equipment (grinders and brewers) with complete domain layer implementation.
Database changes:
- migrations/0006_add_gear.sql: Create gear table with category CHECK constraint and indexes
- migrations/0007_update_timeline_for_gear.sql: Document 'gear' as valid timeline entity type
Domain layer:
- Add GearId typed ID wrapper
- Create domain/gear.rs with:
- GearCategory enum (Grinder/Brewer) with string conversion methods
- Gear entity with make, model, notes fields
- NewGear and UpdateGear DTOs
- GearFilter for category-based filtering
- GearSortKey with Make (default), Model, Category, CreatedAt options
- Add GearRepository trait to domain/repositories.rs with standard CRUD operations
- Register gear module in domain/mod.rs
This follows the same architectural pattern as the Bag entity.
- Add sessions table to store session tokens with expiration
- Create Session domain model and SessionRepository trait
- Implement SqlSessionRepository for session persistence
- Update is_authenticated() to validate tokens against database
- Sessions expire after 30 days
- Session tokens hashed with SHA-256 before storage
- Delete sessions from database on logout
- Update all page handlers to properly validate sessions
This prevents session hijacking by ensuring only valid, unexpired
tokens stored in the database can authenticate requests.
Co-authored-by: jnsgruk <668505+jnsgruk@users.noreply.github.com>