The revenueAnalytics router runs 4–6 queries per page load, all filtering invoices by project_id and paid_at. The invoices table schema has no indexes defined (neither in billing-schema.ts nor in the migrations directory). As the invoices table grows with billing activity, every revenue analytics query (MRR time series, movement, ARR summary) will perform a full sequential scan. The arrSummary procedure runs 4 parallel queries all hitting the same unindexed table.
Category: database
File: src/db/billing-schema.ts
Recommendation: Add composite indexes: (project_id, paid_at, status) on invoices for time-series and aggregation queries. Also add (customer_id, paid_at) for the revenue movement sub-queries that join on customer. Add (product_id) on invoice_line_items for the topProducts query. These are write-time costs but will make revenue dashboard queries go from full-table-scan to index-range-scan.
Estimated Improvement: Revenue dashboard load time: from O(n) full scan to O(log n) index scan — 10-100x improvement as invoice volume grows