Commit graph

28 commits

Author SHA1 Message Date
f1b029949e feat: PDF — total claim in header, wider merchant column (52mm) 2026-07-14 13:48:31 +00:00
47fb82d109 fix: PDF reports show local+claim columns, totals in claim currency, remove grand total 2026-07-14 12:17:42 +00:00
10e6b78940 feat: prepend user name to email report subjects (Claus Lohmar | Monthly Expense Report: ...) 2026-07-14 10:18:18 +00:00
64844baa83 fix: landscape PDF reports, full text, wider columns, include CSV+PDF in monthly ZIP 2026-07-14 10:06:31 +00:00
d65c0cd5fa feat: add month hierarchy, AI categories, and UI polish
- 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)
2026-07-14 09:29:26 +00:00
1c9ab4554a chore: always include both CSV and PDF in report ZIP instead of picking one format 2026-07-13 09:10:12 +00:00
517e95adc2 chore: rebrand ReceiptNext to NextExpense
- 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
2026-06-21 18:39:48 +00:00
24451b4f4f chore: put currency labels in proper CSV/PDF columns, not jammed into number cells 2026-06-17 13:05:18 +00:00
95762cd1ae chore: add base currency to CSV totals row too 2026-06-17 12:58:33 +00:00
b50699fc0e chore: add base currency label to PDF totals row 2026-06-17 12:57:41 +00:00
7c84c0858f chore: add totals row to PDF reports (local + converted currency) 2026-06-17 12:54:16 +00:00
a943c258bb chore: use request Host header for download links, not BASE_URL 2026-06-17 12:41:38 +00:00
5aa5523e8b chore: remove eager token cleanup on regenerate to prevent breaking emailed links 2026-06-17 12:34:22 +00:00
64d7494e33 chore: flat ZIP structure + event-name download filenames (/dl/{token}/{name}.zip) 2026-06-17 12:28:20 +00:00
4bc9fe52ae chore: add onboarding flow — capture user name/department, inject into CSV/PDF reports 2026-06-17 12:23:21 +00:00
8759b31e47 chore: log addToZip errors instead of silently dropping 2026-06-17 12:14:37 +00:00
be3aa7a036 chore: add postbox — generate report package, download or email link 2026-06-17 12:13:34 +00:00
44309dc189 chore: surface SMTP error message to user on filing failure 2026-06-17 11:45:45 +00:00
422aaa08ab chore: fix invisible filing errors — add HTMX error feedback and loading indicator 2026-06-17 11:08:01 +00:00
90c9df6cce fix: receipt images missing from filed event ZIP + feat: delete individual expenses
- Fix createReceiptZip path traversal guard blocking new ImagePath entries
  (UploadReceipt stores bare filenames, guard required 'storage/' prefix)
- Add DeleteExpense DB function, handler with ownership verification,
  DELETE /expenses/{id} route, and 🗑️ button in both expense templates
- Uses existing htmx.trigger confirm pattern for delete UX
2026-06-14 11:46:43 +00:00
92f070440f refactor: implement best-practice recommendations from code review
MUST FIX:
- M1: Fixed ignored errors in AI providers (json.Marshal, http.NewRequest, json.Unmarshal)
- M2: Template cache — pre-parse all templates once at startup, reuse via getTemplate()
- M3: Fixed silent ParseFloat error fallbacks — now returns HTTP 400 on invalid amounts
- M4: Wrapped readFile errors with context (fmt.Errorf with %w)
- M5: Deleted stale llm.go placeholder file
- M6: Renamed utils.New() to utils.NewUUID() for clarity
- M7: Validate current_event_id cookie UUID format, prevent tampering

SHOULD FIX:
- S4: Added utils.Timestamp() helper to replace repeated time.Now().Format() calls
- S6: Added request ID middleware for concurrent request log tracing
- S7: Increased DB pool from 1 to 4 connections (HTMX concurrency)
- S8: Graceful shutdown via http.Server.Shutdown() on SIGINT/SIGTERM
- S9: Storage served behind auth middleware with path traversal check

COULD FIX:
- C2: renderOTPForm uses cached template (not per-request Must)
- C3: CSP pinned to unpkg.com/htmx.org@1.9.10
- C4: Added ReadHeaderTimeout, ReadTimeout, WriteTimeout, IdleTimeout
- C7: PDF generation auto-adds page breaks when content overflows

ADDITIONAL:
- Pass config to AI provider constructors (newGeminiProvider, newOpenAIProvider)
- Value receivers on geminiProvider/openaiProvider (empty structs)
- Added envOrDefault() helper in ai/receipt.go
- Session cleanup goroutine started in main.go
- Removed duplicate imports and unused html/template from handlers
2026-05-31 02:13:07 +00:00
e831fcf617 fix: resolve 7 critical security findings from code review
CR-1: Path traversal in createReceiptZip — validate image_path is within storage/
CR-2: Missing authz on EditExpense/UpdateExpense — verify event ownership
CR-3: OTP timing side-channel — use crypto/subtle.ConstantTimeCompare
CR-4: Logout doesn't invalidate session — moved to AuthHandler with Sessions.Delete()
CR-5: OTP reuse race condition — mutex lock around validate+delete
CR-6: Live credentials on disk — removed .env from disk entirely
CR-7: No TLS — documented as expected behind-proxy deployment

Additional:
- Removed stale github.com/expenseflow import path from auth.go
- Made EnvironmentFile optional (prefix with -) so .env is not required
- App runs and starts clean without any .env file
2026-05-31 01:50:08 +00:00
f50048e833 chore: rename to ReceiptNext + deployment scripts
- Full rename: module path, imports, directory structure
- install.sh: one-command bare-metal deployment
- contrib/receiptnext.service: systemd service file
- Makefile: build, install, manage service
- .gitenv updated to ReceiptNext
- New Releases page on git.lohmar.co.uk/cclohmar/ReceiptNext
2026-05-30 14:20:49 +00:00
646378df64 feat: gallery upload + PDF receipt support
- Two upload buttons: Camera (capture) and Upload (gallery/PDF)
- PDF receipts from Uber/email now accepted and processed by Gemini Vision
- PDF detection via %PDF magic bytes in both handler and AI module
- Descriptions updated to reflect broader file support
2026-05-30 13:50:22 +00:00
dcb43b08a0 feat: send receipt images as ZIP attachment with report
- Email now includes both report (CSV/PDF) + ZIP of all receipt images
- ZIP images named {event-name}-{index}.{ext} matching list order
- Uses Go's archive/zip (stdlib, no external deps)
- Sender.SendReport now accepts []*Attachment for multiple files
- Gracefully skips missing image files with warnings
2026-05-30 13:38:23 +00:00
4895b3d608 feat: add KES support + base currency + exchange rate for expense claims
- Added KES and 12+ additional currencies to receipt form
- Events now have base_currency (claim currency) and exchange_rate fields
- Receipts show original amount + auto-computed converted amount
- Converted amounts stored per expense in database
- CSV and PDF reports include both original and converted amounts
- Dashboard shows claim currency per event card
2026-05-30 12:23:31 +00:00
6b6196a59a fix: nil pointer panic when EmailSender is not configured 2026-05-29 20:05:01 +00:00
ca970104ee chore: initial commit — ExpenseFlow AI-Powered Expense Tracker
- Passwordless email OTP authentication
- Event-based expense tracking with HTMX UI
- AI receipt extraction via DeepSeek Vision API
- CSV/PDF report generation with email filing
- PWA with service worker and manifest
- Mobile-first responsive design
- SQLite database with auto-migration
2026-05-29 19:43:30 +00:00