- Restructure hierarchy: Month → Event → Expense (new months table, FK)
- Add MonthHandler with CRUD, monthly reports, dropdown create form
- Events now scoped under months with extended ownership chain
- AI extraction: 16 specific expense categories (Airfare, Meals, etc.)
- UI: category dropdown, button-consistent cards, centered mobile shell on desktop
- Dashboard/month views show claim totals per card
- Description field now mandatory, forms simplified
- Months sorted by name chronologically (latest first)
- Rename Go module from github.com/cclohmar/ReceiptNext to NextExpense
- Update all import paths across 7 Go source files
- Update templates (titles, headings, branding)
- Update static files (manifest.json, sw.js, CSS)
- Update config (Makefile, install.sh, .env.example)
- Update README with new name and URLs
- Rename service file receiptnext.service -> nextexpense.service
- Update install paths, service names, log paths in install.sh
- Removed all pre-built binary download logic from install.sh
- install.sh now installs Go (via apt/dnf/apk) if not present
- Always builds from source — ensures latest code, correct platform
- Removed dist/ binaries from local disk (not tracked in git)
- New RecalculateExpenses DB function updates all expenses for an event
- Expenses in different currency: converted = ROUND(amount * new_rate, 2)
- Expenses already in base currency: left unchanged
- Called from UpdateEvent handler after saving the new event rate
- Moves chown to the very beginning of the update
- Ensures app user can write to /opt/receiptnext/ before build
- Removes redundant chown later in update (already done upfront)
- go build can't overwrite a root-owned binary as app user
- Added rm -f app before go build in both update and fresh install paths
- Also chown the app binary alongside .go cache
- Build cache may be root-owned from previous builds
- Added sudo_if chown before both update and fresh build steps
- Prevents 'permission denied' on go mod cache writes
- Event page now shows read-only metadata only (no edit/delete buttons)
- Edit works from dashboard (Edit button on event cards)
- Delete added to the edit form as a button alongside Save/Cancel
- htmx.trigger #delete div in the edit form fragment
- form.submit() triggered standard GET submission with query params
- hx.trigger() is not a valid function — htmx.trigger() is the correct API
- Both edit save and delete now properly fire HTMX requests
- Uses stat to get original owner:group before backup
- chown restores backup file to original owner
- Prevents database becoming readonly after update
- Was using its own inline template with 6 digit_0..digit_5 fields
- Now calls getTemplate('otp_form') which has the single 6-digit input
- templates.go already had the correct single-field version