Wire It All Together
Connect all the pieces into one working architecture. Six services, one product, revenue from day one. This lesson is the capstone — everything you have learned converges here.
The Complete Architecture
Every service you have learned about in this course serves a specific purpose. Together, they form a production-ready AI-powered web app. No service is redundant — remove any one, and you lose a critical capability.
Hosts your Next.js app. Auto-deploys from GitHub on every push to main. Serves from 50+ global edge servers. Preview deploys for every pull request. Zero-config SSL. Cost: $0/mo (Hobby tier).
Your entire data layer. Postgres database with RLS, user authentication with JWT, Edge Functions for serverless backend logic, pgvector for AI embeddings. One platform replaces five services. Cost: $25/mo (Pro plan).
Hosts checkout pages, processes credit cards, manages subscriptions. You never touch raw card data — Stripe handles PCI compliance. Sends webhooks on payment events. Cost: 2.9% + $0.30 per transaction.
Sends transactional emails — welcome messages, receipts, notifications. Clean API, high deliverability, React email templates. Cost: $0/mo (100 emails/day free).
Connects services without direct integrations. Slack alerts, spreadsheet logging, content scheduling — all without writing code. Cost: $0/mo (1,000 ops/month free).
The brain that coordinates everything. Processes natural language, makes decisions, generates content. Accessed via Edge Functions with the Anthropic API. Cost: ~$4/mo (pay-per-token).
Build It: The 6-Step Wiring Guide
Follow these steps in order. Each step builds on the previous one. By step 6, you have a fully wired, revenue-generating AI product.
Step 1: Supabase — Create Tables + RLS (Foundation)
Create your core tables. The subscribers table stores everyone who signs up (with a unique email constraint so duplicates are rejected). The revenue table tracks every payment with the Stripe session ID for cross-referencing. Enable Row Level Security on both.
-- Core tables for a revenue-generating AI app
CREATE TABLE subscribers (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
email text UNIQUE NOT NULL,
name text,
created_at timestamptz DEFAULT now()
);
CREATE TABLE revenue (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
amount int4, -- in cents (Stripe standard)
product text,
customer_email text,
stripe_session_id text UNIQUE, -- prevents duplicate processing
created_at timestamptz DEFAULT now()
);
-- Enable RLS — critical for security
ALTER TABLE subscribers ENABLE ROW LEVEL SECURITY;
ALTER TABLE revenue ENABLE ROW LEVEL SECURITY;
Step 2: Edge Function — subscribe (Email Capture)
This edge function receives an email from your frontend form, stores it in Supabase, and sends a welcome email via Resend. It runs at the edge — globally distributed, close to every user.
import { createClient } from "https://esm.sh/@supabase/supabase-js@2"
import { Resend } from "https://esm.sh/resend"
const supabase = createClient(
Deno.env.get("SUPABASE_URL")!,
Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!
)
const resend = new Resend(Deno.env.get("RESEND_API_KEY")!)
Deno.serve(async (req) => {
const { email, name } = await req.json()
// 1. Store in Supabase (UNIQUE constraint rejects duplicates)
const { error } = await supabase
.from("subscribers")
.insert({ email, name })
if (error?.code === "23505") {
// Already subscribed — not an error, just skip
return new Response(JSON.stringify({ status: "already_subscribed" }))
}
// 2. Send welcome email via Resend
await resend.emails.send({
from: "hello@yourdomain.com",
to: email,
subject: `Welcome, ${name || "friend"}!`,
html: `<p>Thanks for joining. You're in.</p>`
})
return new Response(JSON.stringify({ status: "subscribed" }))
})
Step 3: Edge Function — create-checkout (Payments)
Creates a Stripe checkout session and returns the URL. Your frontend redirects users there. Stripe hosts the entire payment page — you never touch credit card data.
import Stripe from "https://esm.sh/stripe@14"
const stripe = new Stripe(Deno.env.get("STRIPE_SECRET_KEY")!)
Deno.serve(async (req) => {
const { price_id } = await req.json()
// Create checkout session — Stripe hosts the payment page
const session = await stripe.checkout.sessions.create({
mode: "payment",
line_items: [{ price: price_id, quantity: 1 }],
success_url: "https://yourdomain.com/success",
cancel_url: "https://yourdomain.com",
})
// Return the Stripe-hosted checkout URL
return new Response(JSON.stringify({ url: session.url }))
})
Step 4: Stripe Webhook Handler (Revenue Tracking)
Listens for checkout.session.completed, verifies the signature (critical — prevents spoofed events), and logs revenue to Supabase. This is the code from the Webhooks Deep Dive lesson, wired into the full stack.
// Verify signature → Process event → Log revenue
const body = await req.text() // Raw text — never req.json()
const sig = req.headers.get("stripe-signature")!
const event = stripe.webhooks.constructEvent(
body, sig, Deno.env.get("STRIPE_WEBHOOK_SECRET")!
)
if (event.type === "checkout.session.completed") {
const session = event.data.object
await supabase.from("revenue").insert({
amount: session.amount_total,
customer_email: session.customer_details?.email,
stripe_session_id: session.id // UNIQUE — idempotent
})
}
Step 5: Vercel — Deploy Frontend (Go Live)
Push your Next.js app to GitHub. Vercel auto-deploys to production. Set your Supabase URL and anon key as environment variables — these are the only credentials the frontend needs (RLS protects your data).
# Deploy to production
git add . && git commit -m "wire complete stack"
git push origin main
# Vercel auto-deploys from main → live in ~60 seconds
# Required environment variables in Vercel dashboard:
NEXT_PUBLIC_SUPABASE_URL=https://<ref>.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOi...
Step 6: Make.com — Wire Automations (Glue)
Create Make.com scenarios for everything that does not need custom code: new subscriber notifications to Slack, revenue alerts, daily analytics digests. Make.com connects the services that do not have direct API integrations.
// Make.com Scenarios to create:
Scenario 1: New Subscriber Alert
Trigger: Supabase webhook (INSERT on subscribers)
→ Slack: Post to #growth channel
Scenario 2: Revenue Celebration
Trigger: Supabase webhook (INSERT on revenue)
→ Filter: amount > 5000 // $50+ (amounts in cents)
→ Slack: Post to #revenue channel
→ Google Sheets: Log to analytics spreadsheet
Scenario 3: Daily Digest
Trigger: Schedule (every day at 9am)
→ Supabase: Count today's subscribers + revenue
→ Slack: Post daily summary to #dashboard
This lesson is for Pro members
Unlock all 520+ lessons across 52 courses with Academy Pro.
Already a member? Sign in to access your lessons.