# Bill Tracker — Future Improvements

**This document tracks potential future enhancements for Bill Tracker.**

**Last Updated:** 2026-05-10  
**Current Version:** v0.20.5

## How to Use This Document

This file is a living document. Agents should:
1. Read this file before proposing changes
2. Add new recommendations with priority levels
3. Never add completed items — move those to HISTORY.md instead
4. Reference this file when dispatching improvement tasks
5. Only Ripley can remove items from this list.

### Priority Format

All items must include the priority emoji in their heading, matching the section they belong to:

| Priority | Emoji | Heading Format |
|----------|-------|---------------|
| CRITICAL | 🔴 | `### 🔴 Title — CRITICAL` |
| HIGH | 🟠 | `### 🟠 Title — HIGH` |
| MEDIUM | 🟡 | `### 🟡 Title — MEDIUM` |
| LOW | 🔵 | `### 🔵 Title — LOW` |
| NICE TO HAVE | 💭 | `### 💭 Title — NICE TO HAVE` |

Items are grouped under their priority section heading (`## 🔴 CRITICAL`, `## 🟠 HIGH`, etc.) and sorted most-impactful-first within each tier.


## Pending Recommendations

### 🔴 CRITICAL





### 🟠 HIGH

### Features: Missing Audit Logging for Critical Operations
**Priority:** HIGH  
**Added:** 2026-05-08 by Neo

**Description:**
Security-sensitive operations lack comprehensive audit trails.

**Rationale:**
- Password changes (via `/api/profile/change-password`) not logged
- User role changes (admin routes) not logged
- Session invalidation events not tracked
- Import/export operations only tracked via `import_history` table, missing details
- CSRF token validation failures not logged

**Implementation Notes:**
- Files to modify: `/home/kaspa/.openclaw/Projects/bill-tracker/services/auditService.js` (new file), route files
- Estimated effort: 4 hours
- Add audit table:
  ```sql
  CREATE TABLE IF NOT EXISTS audit_log (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER,
    action TEXT NOT NULL,
    entity_type TEXT,
    entity_id INTEGER,
    details_json TEXT,
    ip_address TEXT,
    user_agent TEXT,
    created_at TEXT DEFAULT (datetime('now'))
  );
  CREATE INDEX IF NOT EXISTS idx_audit_log_user ON audit_log(user_id, created_at);
  ```
- Log: password changes, role changes, login attempts (success/fail), session invalidation

### Add keyboard navigation and accessible ARIA labels
**Priority:** HIGH  
**Added:** 2026-05-08 by Scarlett

**Description:**
While many components use semantic HTML, several interactive elements lack proper ARIA attributes, keyboard navigation, or focus management, making the app inaccessible to screen reader users and keyboard-only users.

**Rationale:**
Accessibility compliance and broader user reach. Bill Tracker should be usable by everyone. WCAG 2.1 Level A compliance requires:
- Proper labeling of interactive elements
- Keyboard navigation support
- Focus management in modals
- Screen reader announcements for dynamic content

**Implementation Notes:**
- Audit all interactive components for missing ARIA labels:
  - Buttons without `aria-label` or visible text
  - Icons used as buttons
  - Custom selects and dropdowns
  - Modal dialogs (missing `role="dialog"` and `aria-modal`)
- Add focus management to modals (trap focus, return focus on close)
- Ensure keyboard navigation works through all pages
- Add proper `aria-live` regions for toast notifications
- Ensure color contrast meets WCAG AA standards (verify with axe DevTools)
- Files likely to be modified: `client/components/*.jsx`, `client/pages/*.jsx`
- Estimated effort: 2-3 hours for comprehensive audit and fixes

---

### 🟡 MEDIUM

### Billing Cycle Sub-categories for Weekly/Monthly
**Priority:** MEDIUM  
**Added:** 2026-05-08 by _null

**Description:**
Add sub-categories to billing cycles. Current cycles (1st, 15th, Other) work for monthly bills, but need weekly and monthly options with sub-categories for due dates.

**Rationale:**
Supports users with weekly bills (rent, subscriptions, etc.) and more complex monthly schedules. Requires backend schema changes and frontend updates.

**Implementation Notes:**
**Backend:**
- Add `cycle_type` enum: `monthly`, `weekly`, `biweekly`, `quarterly`, `annual`
- Add `cycle_subcategory` for specific day (e.g., "Monday", "1st", "15th")
- Migration for existing bills (default to `monthly`)
- Update bill creation/edit endpoints

**Frontend:**
- Dropdown for cycle type
- Conditional sub-category selector based on type
- Update Tracker to group by cycle type
- Files likely to be modified: `db/schema.sql`, `db/database.js`, `routes/bills.js`, `client/pages/BillsPage.jsx`, `client/components/BillModal.jsx`
- Estimated effort: 6-8 hours

### Previous Month Paid Amount on Tracker Page
**Priority:** MEDIUM  
**Added:** 2026-05-08 by _null

**Description:**
Display the previous month's total paid amount on the Tracker page, positioned between "Expected" and "Paid" columns.

**Rationale:**
Context for users to compare current month spending vs. previous month at a glance. Helps with budgeting and spotting anomalies.

**Implementation Notes:**
- Fetch previous month's payment data alongside current month
- New column: "Last Month" between Expected and Paid
- Option to show/hide via settings
- Consider sparkline mini-chart for trend
- Files likely to be modified: `routes/tracker.js`, `client/pages/TrackerPage.jsx`
- Estimated effort: 3 hours

### 3-Month Trend Indicator with Up/Down Arrows
**Priority:** MEDIUM  
**Added:** 2026-05-08 by _null

**Description:**
Add trend indicators showing whether the last 3 months of payments went up or down compared to current month. Display as up/down arrow with percentage change.

**Rationale:**
Visual trend indicator helps users identify spending patterns without navigating to Analytics page.

**Implementation Notes:**
- Calculate 3-month rolling average
- Compare current month vs. previous 3-month average
- Show green up arrow if trending up (more paid), red down arrow if trending down
- Display percentage change
- Position in Tracker header or Summary card
- Files likely to be modified: `routes/analytics.js` (new endpoint), `client/pages/TrackerPage.jsx` or `client/pages/SummaryPage.jsx`
- Estimated effort: 4 hours

### Add loading skeletons and better async state management
**Priority:** MEDIUM  
**Added:** 2026-05-08 by Scarlett

**Description:**
Many pages show only "Loading..." or no state between async API calls and data rendering. Pages like TrackerPage, AnalyticsPage, and BillsPage have inconsistent loading states.

**Rationale:**
Perceived performance. Users should see immediate visual feedback when data is loading, even if the actual data loads slowly. Skeleton loaders prevent layout shifts and set proper expectations about wait times.

**Implementation Notes:**
- Add loading skeleton components for:
  - Summary cards (4 skeleton cards for TrackerPage)
  - Table rows (skeleton rows for bills tracker tables)
  - Chart placeholders (shimmer effect for analytics)
  - Form fields (skeleton inputs for modals)
- Create reusable Skeleton components in `client/components/ui/Skeleton.jsx`
- Implement loading state with proper transitions (fade in/out)
- Consider adding `aria-busy` attributes during load
- Files likely to be modified: `client/components/ui/`, `client/pages/TrackerPage.jsx`, `client/pages/AnalyticsPage.jsx`, `client/pages/BillsPage.jsx`
- Estimated effort: 60-90 minutes

### Add React Query (TanStack Query) for server state management
**Priority:** MEDIUM  
**Added:** 2026-05-08 by Scarlett

**Description:**
Currently using manual `useState`/`useEffect` patterns with custom `api` wrapper for data fetching. This leads to duplicated loading/error handling, stale data issues, and no request caching.

**Rationale:**
Developer experience and performance. React Query provides:
- Automatic request caching and stale-while-revalidate
- Background refetching
- Optimistic updates
- Request deduplication
- Built-in loading/error states

**Implementation Notes:**
- Replace manual API calls in pages with `useQuery`, `useMutation`
- Add query keys for cache invalidation
- Implement global query client with React Query DevTools
- Gradual migration: start with TrackerPage, then BillsPage, then AnalyticsPage
- Files likely to be modified: `client/pages/*.jsx`, add `client/hooks/useQueryClient.js`
- Estimated effort: 4-6 hours for full migration

### Architecture: Business Logic Mixed with Route Handlers
**Priority:** MEDIUM  
**Added:** 2026-05-08 by Neo

**Description:**
Many routes contain business logic that should be extracted to service layers.

**Rationale:**
- `bills.js` contains `parseDueDay()`, `parseInterestRate()` — validation logic
- `tracker.js` contains date/range calculations that are reused across routes
- `admin.js` has complex OIDC config building mixed with routing
- `analytics.js` has complex date-building logic (`buildMonths`, `monthKey`, etc.)

**Implementation Notes:**
- Files to modify: Multiple route files + new service files in `/services/`
- Estimated effort: 8 hours
- Proposed structure:
  ```
  /services/billsService.js
  /services/trackerService.js
  /services/analyticsService.js
  /services/authService.js (existing)
  /services/oidcService.js (existing)
  /services/cleanupService.js (existing)
  ```
- Route handlers should call services, not contain business logic

### Performance: N+1 Query Patterns in Tracker and Analytics
**Priority:** MEDIUM  
**Added:** 2026-05-08 by Neo

**Description:**
Looping over bills and querying payments/state individually causes N+1 queries.

**Rationale:**
- `tracker.js` line 27-37: iterates over `bills`, runs `mbsStmt.get()` per bill
- `analytics.js` uses `bills.map()` and builds maps with per-bill lookups
- With 50 bills, this creates 100+ extra queries per request

**Implementation Notes:**
- Files to modify: `/home/kaspa/.openclaw/Projects/bill-tracker/routes/tracker.js`, `/analytics.js`
- Estimated effort: 3 hours
- Use batch queries instead:
  ```js
  // Fetch all monthly states for bills in one query
  const states = db.prepare(`
    SELECT * FROM monthly_bill_state
    WHERE bill_id IN (${billIds.join(',')}) AND year=? AND month=?
  `).all(billIds, year, month);
  ```

### Security: Session Token Not Rotated on Auth Events
**Priority:** MEDIUM  
**Added:** 2026-05-08 by Neo

**Description:**
Session tokens are not rotated on password change or logout events.

**Rationale:**
- `admin.js` deletes sessions on password change, but this is inconsistent
- `/api/profile/change-password` does not invalidate other sessions
- Logout only removes current session, doesn't invalidate others
- Session tokens are static — no rotation mechanism

**Implementation Notes:**
- Files to modify: `/home/kaspa/.openclaw/Projects/bill-tracker/services/authService.js`
- Estimated effort: 4 hours
- Add:
  - `session_version` or `token_seed` column in `users` table
  - Increment seed on password change, logout all
  - Validate seed in `getSessionUser()`
  - Logout invalidates only current session (more usable)

### Skip First-Login User Creation When ENV Seeds Users
**Priority:** MEDIUM  
**Added:** 2026-05-09 by _null

**Description:**
When `INIT_ADMIN_USER`/`INIT_ADMIN_PASS` (and optionally `INIT_REGULAR_USER`/`INIT_REGULAR_PASS`) are set via environment variables, the app still forces the first-login user creation flow. This is redundant — the admin user already exists from the seed, so presenting a "create your first user" form on login is confusing and unnecessary.

**Implementation Notes:**
- When `INIT_ADMIN_USER` is set, the app should skip the first-login user creation screen
- Admin should go directly to the main app after login
- The `first_login` flag on seeded users should be `0` (not forced to change password or create account)
- If no env vars are set, keep the current first-run flow unchanged
- Files likely to be modified: `setup/firstRun.js`, `server.js` seed logic, possibly frontend login flow

### No Rollback Capability for Failed Migrations
**Priority:** MEDIUM  
**Status:** PENDING  
**Added:** 2026-05-09 by Neo

**Description:**
No way to rollback or recover from failed migrations without manual database repairs.

**Rationale:**
- If a migration fails, no automatic recovery
- Admin must manually fix database state
- No rollback scripts to revert breaking changes
- Risk: extended downtime on production

**Implementation Notes:**
- Design migrations with rollback functions
- Store rollback SQL alongside migration
- Implement `ROLLBACK_LAST_MIGRATION` functionality
- Document manual recovery procedures

### Limited Error Handling and Logging for Migrations
**Priority:** MEDIUM  
**Status:** PENDING  
**Added:** 2026-05-09 by Neo

**Description:**
Migration failures don't produce clear error messages or logs, making debugging difficult.

**Rationale:**
- Migration errors are silent or unclear
- No logging of which migration failed or why
- No way to diagnose schema inconsistencies
- Risk: slow debugging on production issues

**Implementation Notes:**
- Add detailed logging: `[migration] Applying v0.20.0: Add user_groups table`
- Include timing: `[migration] v0.20.0 completed in 234ms`
- Log precondition checks: `[migration] Checking: table_exists('users')`
- Error log with context: `[migration-error] v0.20.0 failed: UNIQUE constraint failed on users.username`

---

### 🔵 LOW

### Add comprehensive unit and integration tests
**Priority:** LOW  
**Added:** 2026-05-08 by Scarlett

**Description:**
Currently no unit tests exist for components or hooks. The only testing appears to be functional tests in `test-functional.js`. Component-level testing is missing.

**Rationale:**
Code quality and maintainability. Unit tests catch regressions and document component behavior. Bill Tracker has complex business logic (bill calculations, monthly state, analytics) that should be tested.

**Implementation Notes:**
- Set up Jest + React Testing Library
- Test key components: BillModal, TrackerPage row, BillsTableInner
- Test hooks: useAuth, custom form hooks
- Test utility functions in `client/lib/utils.js`
- Consider vitest for faster test execution
- Add CI integration for test execution
- Files likely to be modified: Add `client/test/` directory, add `jest.config.cjs`
- Estimated effort: 8-12 hours for baseline coverage

### Features: Missing Export for User-Specific Reports
**Priority:** LOW  
**Added:** 2026-05-08 by Neo

**Description:**
No built-in way to export filtered data (e.g., "all bills in category X for last 6 months").

**Rationale:**
- `/api/analytics/summary` exists but returns JSON only
- Users cannot generate Excel/PDF reports
- No programmatic way to get export links for specific filters
- `/api/export/user-excel` exports everything, not filtered views

**Implementation Notes:**
- Files to modify: `/home/kaspa/.openclaw/Projects/bill-tracker/routes/export.js`
- Estimated effort: 6 hours
- Add endpoints:
  - `GET /api/export/user-excel?category_id=1&start=2026-01&end=2026-06`
  - `GET /api/export/user-json?filter=bills&status=missed`
  - Add report title/description to export metadata

### Features: Missing Bill Grouping and Reorganization API
**Priority:** LOW  
**Added:** 2026-05-08 by Neo

**Description:**
No way to reorder bills, drag-and-drop, or group by custom criteria.

**Rationale:**
- `bills` table has `due_day` ordering but no manual sort order
- Frontend likely orders by `due_day` only
- Users cannot create bill groups or categories for bills
- No way to mark bills as "hidden" or "archived" without deactivating

**Implementation Notes:**
- Files to modify: `/home/kaspa/.openclaw/Projects/bill-tracker/db/schema.sql`, `/routes/bills.js`
- Estimated effort: 6 hours
- Add:
  - `sort_order` column to bills table (default NULL, ordered first by sort_order then due_day)
  - `PUT /api/bills/reorder` endpoint accepting `{bill_id: new_index}`
  - `PUT /api/bills/:id/archived` to soft-dearchive (sets `archived` flag)

---

### 💭 NICE TO HAVE

### Add consistent form state management pattern
**Priority:** MEH  
**Added:** 2026-05-08 by Scarlett

**Description:**
Form state management is inconsistent across components. Some use `useState` for each field, others use form libraries. Validation patterns vary.

**Rationale:**
Consistency and maintainability. A consistent pattern makes it easier to add new forms and reduce bugs.

**Implementation Notes:**
- Consider react-hook-form for complex forms
- Create reusable form field components (InputField, SelectField, etc.)
- Standardize validation approach
- Files likely to be modified: `client/components/*.jsx`
- Estimated effort: 4-6 hours for migration

---

## Template for New Recommendations

```markdown
### [Feature Name]
**Priority:** CRITICAL / HIGH / MEDIUM / LOW / MEH  
**Added:** YYYY-MM-DD by [Agent]

**Description:**
Brief description of the improvement.

**Rationale:**
Why this matters.

**Implementation Notes:**
- Technical approach
- Files likely to be modified
- Estimated effort

**Depends On:**
Any prerequisites or blocking issues.
```

## Completed Items

### ✅ Security: Rate Limiting on /api/about-admin — MEDIUM
**Completed:** 2026-05-09 (v0.19.0)
**Fix:** `adminActionLimiter` (30 req/15min) applied to `/api/about-admin` route.

### ✅ Security: Markdown Sanitization in AboutPage — MEDIUM
**Completed:** 2026-05-09 (v0.19.0)
**Fix:** `rehype-sanitize` added to `AboutPage.jsx` ReactMarkdown component.

### ✅ Security: aboutAdmin() in API Client — LOW
**Completed:** 2026-05-09 (v0.19.0)
**Fix:** `aboutAdmin` endpoint function added to `client/api.js`.

---
