<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: AI Finance Ops Copilot</title>
    <description>The latest articles on DEV Community by AI Finance Ops Copilot (@mbwhisper).</description>
    <link>https://dev.to/mbwhisper</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4077858%2F8b7793c6-43d7-4661-b1ab-070df4b313bc.png</url>
      <title>DEV Community: AI Finance Ops Copilot</title>
      <link>https://dev.to/mbwhisper</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mbwhisper"/>
    <language>en</language>
    <item>
      <title>How I Built an AI-Powered Finance Dashboard for SaaS Founders</title>
      <dc:creator>AI Finance Ops Copilot</dc:creator>
      <pubDate>Fri, 14 Aug 2026 14:52:18 +0000</pubDate>
      <link>https://dev.to/mbwhisper/how-i-built-an-ai-powered-finance-dashboard-for-saas-founders-383n</link>
      <guid>https://dev.to/mbwhisper/how-i-built-an-ai-powered-finance-dashboard-for-saas-founders-383n</guid>
      <description>&lt;p&gt;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 &lt;a href="https://aifinanceops.app" rel="noopener noreferrer"&gt;AI Finance Ops Copilot&lt;/a&gt;, an AI-powered financial dashboard that connects to Stripe and automates everything founders hate doing manually.&lt;/p&gt;

&lt;p&gt;Here's how I built it, what I learned, and why the tech stack matters.&lt;/p&gt;

&lt;p&gt;The Problem&lt;/p&gt;

&lt;p&gt;I was running a bootstrapped SaaS and tracking MRR, churn, and runway in Google Sheets. The problems:&lt;/p&gt;

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

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

&lt;p&gt;So I built my own.&lt;/p&gt;

&lt;p&gt;Tech Stack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why this stack?&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Supabase&lt;/strong&gt; — Postgres database with real-time subscriptions, auth, and row-level security. Free tier is generous enough for MVP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stripe Connect&lt;/strong&gt; — Users connect their Stripe account via OAuth. I pull subscription data, invoices, and payment events in real-time.&lt;/p&gt;

&lt;p&gt;Architecture&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────┐     ┌──────────────┐     ┌─────────────┐
│  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:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
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:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
typescript&lt;br&gt;
async function generateInsights(metrics: Metrics) {&lt;br&gt;
  const prompt = `&lt;br&gt;
    Analyze these SaaS metrics and provide 3 actionable insights:&lt;br&gt;
    MRR: $${metrics.mrr}&lt;br&gt;
    Churn Rate: ${metrics.churnRate}%&lt;br&gt;
    LTV: $${metrics.ltv}&lt;br&gt;
    CAC: $${metrics.cac}&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Focus on: revenue growth, churn reduction, and cash flow.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;`;&lt;/p&gt;

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

&lt;p&gt;return response.choices[0].message.content;&lt;br&gt;
}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
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.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
On each webhook, I refresh the materialized view. PostgreSQL handles the heavy lifting.

 Deployment on Vercel

Vercel makes deployment trivial:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
git push origin main&lt;/p&gt;

&lt;h1&gt;
  
  
  Auto-deploys to production
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
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.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
typescript&lt;br&gt;
// app/blog/[slug]/page.tsx&lt;br&gt;
export const revalidate = 3600; // Revalidate every hour&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


 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.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>buildinpublic</category>
      <category>saas</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
