How We Cranked Out a Full SaaS in 20 Days – No Fluff
The Challenge
We had a client who needed a B2B lead‑gen tool yesterday. The deadline was 20 days, budget ₹85K‑₹3L, and the product had to run on Vercel with zero‑downtime. Most agencies would say ‘impossible’, but we love a good jugaad. I remember pulling an all‑nighter at 3 AM, coffee‑stained, debugging a Supabase trigger that kept firing duplicate rows. That night taught me one thing: you either ship or you chase perfection forever. This was wrong – perfection kills velocity.
We scoped a razor‑thin MVP. Core: user auth, CSV import, AI‑powered scoring, and a dashboard. Anything beyond that was ‘nice to have’ and got cut. The client was fine with a ‘paisa‑vasool’ product that solved their pain now, not later. I told them, ‘We’ll give you sab kuch that works, not half‑baked fluff.’
Result: a live SaaS in 20 days, under ₹2 L, with a 99.8% uptime claim. The timeline was non‑negotiable, so we built a sprint board, locked scope, and went full‑steam. The rest of this post is the exact play‑by‑play.
Choosing the Stack
We went serverless, because server‑management is a time‑sink. Next.js on Vercel for the front‑end, Supabase for Postgres + Auth, n8n for workflow automation, and Razorpay for payments. All of these have generous free tiers, which kept the cost under ₹1 L for the first month.
Why not Laravel or Django? Those are great, but the deployment friction is higher. Vercel’s preview URLs let us share builds instantly – a lifesaver when the client wants to see progress daily. Plus, Next.js gives us built‑in API routes, so we didn’t have to spin up a separate backend server.
Our data model was simple. One table for users, one for leads, one for scores. Supabase’s row‑level security (RLS) let us enforce that a user only sees their own leads without writing extra code. Here’s the schema we used:
create table users (id uuid primary key default uuid_generate_v4(),
email text unique not null,
created_at timestamp default now()
);
create table leads (
id uuid primary key default uuid_generate_v4(),
user_id uuid references users(id),
name text,
email text,
imported_at timestamp default now()
);
create table scores (
lead_id uuid references leads(id),
score numeric,
generated_at timestamp default now()
);
That took me 30 minutes to spin up. No migrations headaches.
Day‑by‑Day Sprint
Day 1‑3: Authentication & Boilerplate. We cloned the Vercel‑Next.js starter, added Supabase client, and wired up email‑magic‑link login. The code was under 150 lines, but the biggest win was the instant preview link that let the client test login on their phone.
Day 4‑7: CSV Import Engine. The client wanted to drop a 10 k‑row CSV and have it instantly appear on the dashboard. We built a tiny n8n workflow: upload → parse → batch‑insert into Supabase. The whole workflow lives at https://n8n.io and costs ₹0 because we used the open‑source Docker image on a cheap Linode.
Day 8‑12: AI Scoring. We hooked the OpenAI API (gpt‑3.5‑turbo) to a Supabase function that runs whenever a new lead is inserted. The function sends the lead data, receives a relevance score, and writes it back to the scores table. Sample code:
export default async function handler(req, res) {const { lead } = req.body;
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: { 'Authorization': Bearer ${process.env.OPENAI_KEY} },
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: Score this lead: ${JSON.stringify(lead)} }]
})
});
const { score } = await response.json();
await supabase.from('scores').insert({ lead_id: lead.id, score });
res.status(200).json({ ok: true });
}
We capped usage at ₹12 K per month, which is peanuts compared to a full‑blown data‑science pipeline.
Core Features Implementation
Dashboard UI was built with Tailwind. No design hand‑off, just a quick Figma mock we made in 2 hours. The grid shows lead name, email, and the AI score as a progress bar. Clicking a row opens a modal with raw data – all client‑side, no extra API calls.
Payments via Razorpay. We needed a subscription model (₹2 500/mo). Razorpay’s checkout script is a single