Financial Planning
Rules
- MRR calculation: sum of all active subscription monthly values — annual plans divided by 12, exclude one-time charges
- ARR: MRR * 12 — display both on dashboard, use MRR for monthly trends, ARR for annual planning
- MRR components: track new MRR, expansion MRR (upgrades), contraction MRR (downgrades), churn MRR (cancellations), reactivation MRR — display as waterfall chart
- Burn rate: (starting cash - ending cash) / months — calculate monthly, display runway in months at current burn
- Revenue dashboard: show MRR, ARR, MRR growth rate (MoM%), net revenue retention, total customers — update daily
- Financial projections: model 3 scenarios (conservative, base, optimistic) — vary growth rate and churn rate, project 12-24 months
- Currency handling: store all amounts in cents (integers) — never use floating point for money — display with
Intl.NumberFormat - Date ranges: default to last 12 months, allow custom range — aggregate by month for trends, by day for recent activity
Dashboard Data Model
CREATE TABLE revenue_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
type TEXT NOT NULL, -- 'new' | 'expansion' | 'contraction' | 'churn' | 'reactivation'
amount_cents INTEGER NOT NULL,
customer_id UUID NOT NULL,
occurred_at DATE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
Aggregate MRR per month: SELECT date_trunc('month', occurred_at), type, SUM(amount_cents) FROM revenue_events GROUP BY 1, 2.
Avoid
- Floating point for money — use integer cents everywhere
- Counting MRR without separating components — you need to know why MRR changed
- Monthly-only granularity — store daily events, aggregate for display
- Ignoring contraction MRR — downgrades are early churn signals