A client came to us with a sharp problem. Creative professionals applying for the O-1B visa (extraordinary ability in the arts) had two options: pay an immigration attorney $500+ for an initial assessment, or spend hours reading contradictory forum advice. Neither option scaled. Neither gave people a fast, structured answer.
The brief: build a multi-user SaaS platform where users take a free quiz, get a score, and pay $100 to unlock a full dashboard with document checklists, letter templates, gap analysis, and PDF evidence exports. Dark editorial design. Stripe payments. Live in four weeks.
Four weeks later, canigeto1.com was processing live Stripe payments. What we shipped was not an MVP in the “barely works” sense. It was 54,000 lines of source code, 37 pages, 40+ React components, 14 Supabase edge functions, 14 database tables with row-level security, and 60 automated post-deploy checks. This saas development case study covers exactly what we built and the technical decisions that made the timeline possible.
The Problem
The O-1B visa has specific eligibility criteria that vary by discipline. A film director, a music producer, and a fashion designer all qualify through different evidence paths. The criteria weight differently depending on whether you are in motion picture/television, arts, or business.
Immigration attorneys handle this during consultations. That works for people who can afford $300-$500 per session and wait two weeks for an appointment. It does not work for the thousands of creative professionals who just want to know: “Do I even have a case?”
The client wanted a product that answered that question in four minutes, then converted qualified leads into paying users who get six months of structured preparation tools.
What Users See
The user-facing product has more surface area than most SaaS platforms twice its age.
The quiz. Fifteen questions, takes about four minutes. Each question includes micro-affirmations so users do not feel like they are filling out a government form. The quiz adapts based on profession. MPTV, Arts, and Business paths weight criteria differently because the evidence that matters for a film editor is not the same evidence that matters for a sculptor.
Score and tier. After the quiz, users receive a tier classification: Strong, Good, Possible, or Too Early. This is the free hook. Good enough to be useful. Not detailed enough to replace the paid dashboard.
Lead capture. Users enter their email to see results. Cloudflare Turnstile handles CAPTCHA. At this point, the quiz-submit function saves them as a lead in the database. No auth account is created. No password. They are a lead, not a user. That distinction matters architecturally.
Payment. One click from the results page takes them to Stripe checkout. $100 for six months of full access. $50 renewal after that. No trial. No freemium. Direct-to-Stripe redirect.
Account creation. Here is where the flow gets deliberate. Stripe’s webhook fires after payment. The webhook handler creates the user’s Supabase auth account and sends an invite email via Resend. The user sets their password and lands on the dashboard. Auth accounts only exist for paying customers. The database never fills with window shoppers who created an account and disappeared.
The dashboard. Each paying user gets their own:
- Personal dashboard with score context, per-criteria breakdown, and gap analysis
- Document checklist with progress tracking (what evidence they have, what they still need)
- Letter templates for recommendation letters, pre-structured for O-1B requirements
- PDF evidence export formatted for attorneys
- Profession-specific criteria variants so the advice matches their discipline
- Settings page and full purchase history
This is not a quiz result page. It is a six-month workspace for building an immigration case.
Platform Features Beyond the Core Product
The product sits inside a full content and trust platform.
Attorney directory. Profiles of immigration attorneys with specialization details. Basic info is public. Contact details and detailed profiles are access-gated behind the paid subscription. This gives attorneys a reason to refer clients to the platform, and gives users a reason to stay inside the ecosystem.
Blog. Eleven articles covering O-1 visa requirements, evidence categories, common mistakes, and preparation guides. Not filler content. Each article targets a specific question that potential users search for before they know the product exists.
Success stories. Social proof section featuring anonymized case outcomes. Converts skeptical visitors who wonder if an online tool can actually help with immigration.
Legal suite. Terms of Service, Privacy Policy, Cookie Policy, Accessibility Statement, and a Do Not Sell My Personal Information page. Full CCPA and GDPR coverage. Not boilerplate. Written for this specific product’s data practices.
SEO infrastructure. Nineteen per-route static HTML pages generated by a custom build script, each with JSON-LD structured data. The site ranks for long-tail immigration keywords because every page has proper meta tags, canonical URLs, and schema markup baked in at build time.
The Admin Panel
The client needed to run the business, not just ship the product. The admin panel has 10 tabs, accessible through hidden URLs (not /admin):
- Overview. Revenue metrics, funnel conversion rates, user growth. The numbers that matter for a SaaS business.
- Users. Search, filter, view funnel status, perform admin actions on individual accounts.
- Leads. Everyone who submitted the quiz but has not paid yet. The pre-payment pipeline.
- Attorneys. Full CRUD for managing the attorney directory.
- Quiz Responses. Every submitted quiz with answers and scores. CSV export for analysis.
- Email Analytics. Delivery rates, open rates, click rates across all transactional and marketing emails. CSV export.
- Tester Access. Override controls for granting dashboard access without payment. Used for QA, demos, and partnerships.
- Support Queue. Incoming support requests with bulk resolve capability.
- Activity Log. Full audit trail of admin actions and system events.
- Settings. Platform-wide configuration.
The admin panel alone would be a significant project for most teams. Here, it was one of several systems built in the same four-week window.
Technical Architecture
The stack was chosen for speed of development without sacrificing production reliability.
Frontend: React 18, Vite, TypeScript, Tailwind CSS, and motion/react for animations. The design is dark-only, editorial and cinematic. Think Pentagram meets premium legal. Not generic SaaS. Separate desktop and mobile landing pages. Not responsive breakpoints on the same components; entirely different component trees for each viewport. This gave the design team full control over each experience without fighting CSS compromises.
Server: nginx in Docker on Google Cloud Run. The Dockerfile runs nginx as a non-root user for security. Nine security headers are applied in every nginx location block: Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, Referrer-Policy, Permissions-Policy, and three others. Rate limiting is configured at the nginx level.
Backend: Fourteen Supabase Edge Functions written in Deno. Auth is verified internally via getUser() calls; the functions deploy with --no-verify-jwt by design. This was a deliberate decision: JWT key rotation on the Supabase side broke production for 11 days during an earlier iteration. Removing the external JWT verification layer and handling auth inside each function eliminated that single point of failure.
Database: Supabase PostgreSQL with 14 tables. Row-Level Security policies on every table. Fourteen tracked migrations (001 through 014). The schema handles users, leads, quiz responses, scores, document checklists, attorney profiles, support tickets, email logs, activity audit trails, and platform settings.
Auth: Supabase Auth with email/password and magic link options. The critical design constraint: accounts are created only after payment. Before payment, quiz takers exist as leads, not auth users. This keeps the user table clean and the auth system focused on paying customers.
Payments: Stripe in live mode. $100 for full access, $50 for renewal. Direct-to-Stripe checkout, one click from the results page. The stripe-webhook edge function listens for completed payments, creates the auth account, and triggers the invite email through Resend. The entire payment-to-access flow is automated with zero manual steps.
Email: Resend API with SPF, DKIM, and DMARC configured. Four editable marketing email templates. An email cron job runs on a Google Compute Engine VM every five minutes, processing the outbound queue. Transactional emails (account invites, password resets) go through the same Resend pipeline.
Community: A Discord bot running on a GCE VM. AI-powered Q&A for common immigration questions with prompt injection protection built in. USCIS immigration updates posted automatically. Pro role sync so paid platform users get verified status in the Discord server.
Analytics: GA4 and Google Ads conversion tracking. Both load only after cookie consent. No consent, no tracking scripts. This is not a “we added a cookie banner” checkbox. The analytics code literally does not execute until the user accepts.
CAPTCHA: Cloudflare Turnstile on the lead capture form. Less intrusive than reCAPTCHA, no Google tracking.
Security and Reliability
Security was not a phase. It was a constraint applied to every decision.
Code scanning. The entire codebase was scanned with Semgrep Pro. Zero vulnerabilities found. This is a 54,000-line codebase, so that result required discipline throughout development, not a cleanup pass at the end.
nginx hardening. Strict Content Security Policy. Nine security headers on every response. Rate limiting to prevent abuse. Non-root Docker user.
Database security. Row-Level Security on all 14 Postgres tables. Users can only access their own data. Admin queries use a separate privilege path.
Deployment process. Cloud Run staged rollout: 5% of traffic to the new revision, then 25%, then 50%, then 100%. At each stage, the team monitors for errors before proceeding. If something breaks at 5%, only 5% of users are affected.
Post-deploy verification. Sixty automated checks run after every deployment. Not unit tests. Production verification: can users load the quiz, does Stripe checkout work, do edge functions respond, are security headers present, do email sends succeed. Sixty checks. Mandatory. No deployment is considered complete until all 60 pass.
Rollback playbook. Documented triggers for when to roll back a deployment and step-by-step instructions for doing it. Cloud Run’s revision system makes rollbacks a single command, but the decision criteria for when to pull the trigger are written down, not left to judgment under pressure.
Key Technical Decisions
Several architecture choices departed from convention. Each one solved a specific problem.
No auth until payment. Most SaaS platforms let anyone create an account. This one does not. Quiz takers exist as leads. Auth accounts are created by the Stripe webhook after payment clears. This means the user table contains only paying customers. No cleanup jobs. No “re-engage dormant users” campaigns for people who never intended to pay. The database stays clean by design.
Dual scoring. The quiz score calculates on both the frontend and the backend independently. The frontend shows the user their results immediately after the quiz. The backend recalculates authoritatively when the quiz-submit edge function fires. If someone manipulates the frontend score in dev tools, the backend score is what gets stored.
Separate landing pages per viewport. Desktop and mobile are not the same components with different CSS. They are entirely separate component trees. This added development time but eliminated the design compromises that come from forcing one layout to serve two fundamentally different screen sizes.
Cookie consent gates analytics execution. GA4 and Google Ads scripts do not load in a deferred or hidden state and then activate on consent. They do not exist in the DOM at all until the user accepts. This is the difference between legal compliance and actual privacy compliance.
Edge function JWT handling. Supabase Edge Functions deploy with --no-verify-jwt. Auth verification happens inside each function via getUser(). This was not laziness. JWT key rotation on Supabase’s side caused an 11-day production outage in an earlier version. Moving auth verification inside the function boundary eliminated the external dependency that caused the failure.
Admin URL obfuscation. The admin panel is not at /admin. The routes are non-obvious. This is not security through obscurity as a primary defense; RLS policies and auth checks handle that. But it eliminates the casual probing that every /admin URL attracts from bots and curious visitors.
Supabase double-wrapping handler. Supabase’s admin API sometimes returns data wrapped in an extra layer. The unwrapAdminData() utility function handles this quirk consistently across all admin panel queries. Without it, every admin component would need its own unwrapping logic.
The Timeline
Four weeks. Here is how they broke down:
| Week | What Shipped |
|---|---|
| 1 | Discovery, architecture, database schema (14 tables), auth system, quiz engine, lead capture flow, core UI components |
| 2 | Scoring algorithm with profession-specific weighting, user dashboard, document checklist, letter templates, PDF export, payment integration with Stripe |
| 3 | Admin panel (10 tabs), attorney directory, blog (11 articles), SEO infrastructure (19 static pages with JSON-LD), email system with Resend |
| 4 | Discord bot with AI Q&A, deployment pipeline, 60 post-deploy checks, security hardening, staged rollout, production launch |
This timeline was possible because the client arrived with a defined product vision and made decisions fast. Discovery compressed into two days because the scope was clear. No feature debates mid-sprint. No redesigns after approval. Every decision was filtered through one question: does this ship a working business in four weeks?
If you want to understand what realistic timelines look like for different project types, our MVP development cost guide breaks down the numbers.
What Was Delivered
At the end of four weeks, the client had:
- A live multi-user SaaS platform at canigeto1.com processing Stripe payments
- 54,000+ lines of production source code
- 37 pages and views across the platform
- 40+ React components with dark editorial design
- 14 Supabase Edge Functions handling auth, payments, scoring, email, and admin operations
- 14 PostgreSQL tables with Row-Level Security on every one
- Profession-specific quiz variants for MPTV, Arts, and Business disciplines
- Personal dashboards with gap analysis, document checklists, letter templates, and PDF export
- 10-tab admin panel with revenue metrics, user management, support queue, and audit log
- Attorney directory with access-gated profiles
- 11 blog articles for SEO content
- 19 static HTML pages with JSON-LD structured data
- Email system with 4 marketing templates and 5-minute cron processing
- Discord community bot with AI Q&A and prompt injection protection
- GA4 and Google Ads conversion tracking gated behind cookie consent
- Staged Cloud Run deployment with 60 mandatory post-deploy checks
- Semgrep Pro scan with zero vulnerabilities
- Complete source code ownership, no vendor lock-in, no licensing fees
This was not a prototype. Not a demo. A production business with paying users, automated operations, and a deployment process more disciplined than most Series B companies run.
What This Project Demonstrates
Building a SaaS platform does not require six months and a quarter-million-dollar budget. It requires a clear problem, a defined user, a team that ships, and a client who makes decisions without committees.
The architecture choices here — no auth until payment, dual scoring, edge functions with internal auth, cookie consent that actually gates analytics — are not clever tricks. They are the result of a team that has built enough custom software to know where the real problems hide. Every decision solved a specific, concrete issue that would have caused pain in production.
Fifty-four thousand lines of code in four weeks is not about typing speed. It is about knowing what to build, what to skip, and what to get right the first time. Our development process is designed for exactly this kind of engagement: clear scope, fast execution, working software at every milestone.
Ready to Build?
If you have a SaaS product that needs to exist in weeks, not quarters, we should talk. Our team builds production platforms with real payments, real security, and real deployment discipline.
Schedule a free 30-minute consultation and bring your idea. We will tell you what is realistic, what it costs, and how fast we can ship it.