Commit graph

12 commits

Author SHA1 Message Date
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
4bc9fe52ae chore: add onboarding flow — capture user name/department, inject into CSV/PDF reports 2026-06-17 12:23:21 +00:00
be3aa7a036 chore: add postbox — generate report package, download or email link 2026-06-17 12:13:34 +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
aa07ff3c50 feat: changing event exchange rate recalculates all expense converted amounts
- 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
2026-06-03 08:24:46 +00:00
bb34528bf5 feat: single OTP field, event metadata on page, delete event
- OTP: 6 separate inputs → single 6-digit field with copy/paste support
- Event page: shows name, currency, exchange rate at top
- Edit toggle: unlock to edit fields, lock to save (via PUT)
- Delete button with confirmation popup
- DeleteEvent handler + DB function + route
- Backward compatible: collectOTP strips non-digits
2026-06-03 07:46:12 +00:00
5f5f2be75b feat: event editing — change exchange rate and currency
- Added Edit button on open event cards in dashboard
- EditEvent handler returns dashboard.html with pre-filled form
- UpdateEvent handler (PUT /events/{id}) saves new currency + rate
- UpdateEvent in db.go updates base_currency and exchange_rate
- Form auto-switches between create (POST) and edit (PUT) mode
- Reuses the same conversion sample pattern as event creation
2026-06-03 07:33:37 +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
6de9c27f9c chore: switch from mattn/go-sqlite3 (CGO) to modernc.org/sqlite (pure Go)
- Zero CGO dependencies — builds with CGO_ENABLED=0
- Fully static binaries, no libc required
- Cross-compilation now works without any GCC cross-compilers
- ldd confirms: 'not a dynamic executable'
- Updates go.mod to Go 1.23 (required by modernc.org/sqlite)
2026-05-30 15:02:07 +00:00
ded4954c72 feat: add expense editing - view and edit all existing receipts
- Added ✏️ edit button on every expense in the list
- Clicking loads the receipt form pre-filled with the expense data
- Changes are saved via PUT /expenses/{id}
- Receipt form auto-switches between create (POST) and edit (PUT) mode
- Full HTMX multi-target response: form resets + list refreshes
2026-05-30 12:43:33 +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
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