HIGH: No process-level unhandledRejection/uncaughtException handler
Overview page — Upcoming bills field hard to read
HIGH: Payment UPDATE/DELETE lack user_id in WHERE clause (defense-in-depth)
HIGH: SQL injection surface in analyticsService.js - string interpolation in WHERE clause
Both patterns are safe and no changes are needed. The report confused "string interpolation of SQL fragments" (safe, it's just building the query structure) with "string interpolation of user…
HIGH: SQL injection surface in analyticsService.js - string interpolation in WHERE clause
CRITICAL: Incomplete user deletion - orphaned data risk
CRITICAL: SMTP password stored in plaintext in SQLite
CRITICAL: Async route handlers lack try/catch - unhandled rejections crash process
cycle_type and billing_cycle not acted on in statusService
updateCheckService.js Forgejo URL is hard-coded with no env override
Bill grouping and reorganization API
UI for defining recurring bill generation rules
LOW: Auto-generated encryption key stored in same SQLite database as encrypted data
LOW: OIDC client secret stored in plaintext in user_settings table