DEV Community

AI Finance Ops Copilot
AI Finance Ops Copilot

Posted on

How I Built an AI-Powered Finance Dashboard for SaaS Founders

Most SaaS founders track their metrics in spreadsheets. I did too — until I missed a churn spike and lost 30% of my MRR in one month. That's when I built AI Finance Ops Copilot, an AI-powered financial dashboard that connects to Stripe and automates everything founders hate doing manually.

Here's how I built it, what I learned, and why the tech stack matters.

The Problem

I was running a bootstrapped SaaS and tracking MRR, churn, and runway in Google Sheets. The problems:

  • Manual data entry — copying Stripe data every week
  • No forecasting — I couldn't predict cash flow
  • Reactive, not proactive — I found out about problems after they happened
  • Spreadsheet errors — one broken formula = wrong decisions

I looked at tools like Baremetrics ($308/mo) and ChartMogul ($59/mo). Too expensive for a solo founder.

So I built my own.

Tech Stack

Frontend:  Next.js 16 (App Router)
Styling:   Tailwind CSS
Database:  Supabase (PostgreSQL)
Auth:      Supabase Auth
Payments:  Stripe + LemonSqueezy
AI:        OpenAI GPT-4 for insights
Hosting:   Vercel
Enter fullscreen mode Exit fullscreen mode

Why this stack?

Next.js 16 — Server-side rendering for the marketing site, API routes for Stripe webhooks, and App Router for clean file-based routing. The new use hook and server components made data fetching trivial.

Supabase — Postgres database with real-time subscriptions, auth, and row-level security. Free tier is generous enough for MVP.

Stripe Connect — Users connect their Stripe account via OAuth. I pull subscription data, invoices, and payment events in real-time.

Architecture

┌─────────────────┐     ┌──────────────┐     ┌─────────────┐
│  Marketing Site │     │   Dashboard  │     │   Stripe    │
│  (Next.js SSR)  │     │  (Client)    │     │   Webhooks  │
└────────┬────────┘     └──────┬───────┘     └──────┬──────┘
         │                     │                     │
         └─────────┬───────────┘                     │
                   │                                 │
              ┌────▼────┐                     ┌──────▼──────┐
              │ Supabase│◄────────────────────│  Webhook    │
              │   DB    │                     │  Processor  │
              └─────────┘                     └─────────────┘


The key insight: **process Stripe webhooks server-side**, not client-side. This means:

1. Real-time data (no polling)
2. Reliable (webhooks retry on failure)
3. Secure (Stripe signs every webhook)

## Building the MRR Calculator

The core feature is MRR tracking. Here's the simplified logic:

Enter fullscreen mode Exit fullscreen mode


typescript
// src/lib/mrr.ts
export function calculateMRR(subscriptions: Subscription[]): number {
return subscriptions.reduce((total, sub) => {
const monthlyAmount = sub.recurring.amount /
(sub.recurring.interval === 'year' ? 12 : 1);
return total + monthlyAmount;
}, 0);
}


But MRR alone isn't enough. Founders need:

- **MRR breakdown** (new, expansion, churned, reactivation)
- **Net MRR** (new + expansion - churn)
- **MRR movement** (month-over-month change)

 Adding AI Insights

The "AI" part isn't just a buzzword. I use GPT-4 to analyze metrics and generate actionable insights:

Enter fullscreen mode Exit fullscreen mode


typescript
async function generateInsights(metrics: Metrics) {
const prompt = `
Analyze these SaaS metrics and provide 3 actionable insights:
MRR: $${metrics.mrr}
Churn Rate: ${metrics.churnRate}%
LTV: $${metrics.ltv}
CAC: $${metrics.cac}

Focus on: revenue growth, churn reduction, and cash flow.
Enter fullscreen mode Exit fullscreen mode

`;

const response = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: prompt }],
});

return response.choices[0].message.content;
}


Real examples of AI insights the dashboard generates:

- "Your churn rate increased 12% this month. Consider reaching out to users on annual plans expiring in 60 days."
- "LTV/CAC ratio is 3.2x — healthy. But CAC increased 8% while LTV stayed flat. Monitor ad spend."
- "Runway is 14 months at current burn rate. If you reduce Churn by 0.5%, runway extends to 18 months."

 The Hard Part: Real-time Calculations

The hardest technical challenge was calculating metrics in real-time as Stripe webhooks arrive.

**The problem:** MRR depends on all active subscriptions. When one subscription changes, you need to recalculate everything.

**Solution:** Event sourcing with materialized views.

Enter fullscreen mode Exit fullscreen mode


sql
-- Store every subscription change
CREATE TABLE subscription_events (
id UUID PRIMARY KEY,
stripe_subscription_id TEXT,
event_type TEXT, -- 'created', 'updated', 'deleted'
amount INTEGER,
interval TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Materialized view for current MRR
CREATE MATERIALIZED VIEW current_mrr AS
SELECT
SUM(amount / CASE WHEN interval = 'year' THEN 12 ELSE 1 END) as mrr
FROM subscription_events
WHERE status = 'active';


On each webhook, I refresh the materialized view. PostgreSQL handles the heavy lifting.

 Deployment on Vercel

Vercel makes deployment trivial:

Enter fullscreen mode Exit fullscreen mode


bash
git push origin main

Auto-deploys to production


But there's a catch with Next.js 16 and large sites. My sitemap has 76+ pages. Build times were 3-4 minutes.

**Fix:** Use `export const dynamic = 'force-static'` on marketing pages and incremental static regeneration (ISR) for blog posts.

Enter fullscreen mode Exit fullscreen mode


typescript
// app/blog/[slug]/page.tsx
export const revalidate = 3600; // Revalidate every hour




 Results

After 3 months:

- **46 blog posts** targeting SaaS finance keywords
- **8 interactive calculators** (MRR, churn, LTV, runway, etc.)
- **100+ organic visitors/month** (growing 20% MoM)
- **Performance score: 100** on Lighthouse

The calculators are the biggest traffic drivers. Founders Google "MRR calculator" and land on my tool.

 What I'd Do Differently

1. **Start with the database schema** — I redesigned it 3 times
2. **Webhook-first architecture** — Don't poll Stripe API
3. **Blog from day one** — Each post is a long-term traffic asset
4. **Free tier first** — Let users experience value before paying

 Try It

The dashboard is live at aifinanceops.app. Free tier includes:

- MRR tracking
- Churn analysis
- Basic forecasting
- 3 AI insights/day

Paid plans ($29-$79/mo) add unlimited AI insights, custom reports, and team access.

---

*Built with Next.js 16, Supabase, Stripe, and OpenAI. Open to feedback and contributions.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)