Data points migrated
Manual work reduced
Subscription automation
The project and the problem.
End-to-end SaaS platform processing 240,000+ data points with subscription billing, AWS storage, and automated email workflows.
The client needed a production-grade platform that could ingest a massive parallel dataset, gate it behind a subscription paywall, and handle complex automated workflows all while maintaining sub-2-second page loads and a polished UX. Off-the-shelf tools could not handle the data volume or the custom logic.
- Consolidate 240,000+ records into one reliable source of truth
- Gate the product behind fully automated subscription billing
- Cut manual operational workload while holding sub-2s page loads
The approach and process.
We started with a custom design phase in Figma so the client could review every screen in real time, then engineered the platform end-to-end with a dedicated focus on scale and reliability.
- 01
Sitting With the Data
2 weeksBefore any code, we spent two weeks with the client and the data. The legacy dataset wasn't one thing. It was four copies of the same records that had drifted apart over the years. The first real decision was which version got to be the truth. We picked a source-of-truth hierarchy, drafted the new schema, and modeled subscription tiers as their own entity instead of feature flags scattered through the codebase.
Source-of-truth hierarchy doc · New Postgres schema (ERD) · Subscription tier model · Risk log + rollback plan
- 02
Figma First
3 weeksWe designed the whole product in Figma before writing a line of UI. The client joined live review calls twice a week, which stopped us building screens nobody wanted. By the end of the phase, every state was already in the file: empty, loading, error, paid, lapsed, refunded.
40+ screens, every state covered · Component library + design tokens · Twice-weekly client review (~25 hours total) · Handoff doc with motion + edge cases
- 03
Auth, RBAC, and the Bones
4 weeksStandard scaffolding, except we stopped to get role-based access right early. A mistake here would have leaked paid data to free users, and we did not want to discover that in week ten. Role checks happen at the database layer, so a bug in a route handler can't bypass them.
Production VPS + S3 set up · Sign-up, login, password reset · Role matrix enforced at the DB layer · CI pipeline with a staging mirror
- 04
Migration + Stripe
3 weeksThe first migration run took six hours and corrupted about 300 rows because of an encoding mismatch in one of the source files. We added a quarantine table, made the job idempotent, and re-ran it in 90 minutes with zero data loss. Stripe got wired the same sprint. Checkout, Customer Portal, and webhooks that update entitlements inside a single Postgres transaction.
ETL pipeline with quarantine + checkpointing · Stripe checkout + Customer Portal · Tier-gated middleware · Webhook reconciliation report
- 05
Automation + Performance
2 weeksEmail automation took longer than expected. The client kept finding edge cases ("what if someone resubscribes after 90 days?") and we wanted each one handled. Performance work moved load times from a 6-second average to 1.4 seconds, mostly by paginating two ugly queries and caching one expensive aggregate.
Event-driven email pipeline · Two query rewrites + a cache layer · QA across active / lapsed / refunded states · Accessibility audit
- 06
Launch
1 weekSoft launch on a Tuesday morning. We kept staging warm for a week in case we had to roll back. We didn't. The client trained their team off a 12-page runbook we wrote during QA.
Production cutover · Monitoring + alerting · 12-page operator runbook · 30-day post-launch support
The reasoning and the value.
We took a process that lived in four near-duplicate spreadsheets and one overworked person, and turned it into a Stripe-billed product that runs itself.
The platform launched on schedule and replaced what had been a fragile manual process reducing operational workload by ~80% while serving customers a polished, fast, fully automated experience.
240,000+ data points migrated
Built a custom ingestion pipeline to move a massive parallel dataset into a fresh Postgres-backed schema with zero data loss.
Subscription billing with delivery logic
Implemented Stripe end-to-end (checkout, plans, webhooks, dunning) with custom server-side delivery rules per subscription tier.
AWS S3 + VPS infrastructure
Provisioned and configured S3 for asset storage and a VPS deployment for the application layer, with secure environment isolation.
Automated email workflows
Onboarding, billing, retention, and transactional emails wired through a single send pipeline no manual sends required.
Auth + role-based access
Sign-up, login, password recovery, and role-gated data access integrated cleanly with the subscription tier model.
Custom Figma design system
Designed every screen in Figma with real-time client review, then handed off to engineering with a documented component library.
What changed.
A side-by-side of what the client had before we engaged, and what we shipped.
- 240K records living in four near-duplicate spreadsheets that had quietly drifted apart over the years
- Subscriptions confirmed by hand. Somebody checked the inbox and updated a sheet
- Anyone with the public link could pull the entire dataset; there was no real access layer
- Assets dropped into whichever folder was open at the time
- Welcome emails sent manually, usually a day late, occasionally forgotten
- The heaviest query took 8–12 seconds and timed out on bad days
- Every new screen was redrawn from scratch. Buttons didn't match across the product
- One normalized Postgres schema, populated by a migration script we can re-run without fear
- Stripe runs every checkout, renewal, failed card, and refund. No one touches a dashboard
- Tier and role are checked at the database, so a bug in a route handler can't leak paid data
- Three S3 buckets (public, paid, processed), with signed URLs that expire when the subscription does
- Onboarding, billing, retention, and product emails all fire from product events instead of someone's calendar
- Median page load sits at 1.4 seconds, even on the heaviest views
- 40+ screens share one Figma library and one Tailwind config. It finally feels like one product
Technology stack.
The tools behind the build, and the reasoning behind each choice.
App Router with server-rendered pages. The product is data-heavy and Google had to be able to read it.
Most of the bugs we caught in code review during this build were type bugs that would have shipped without strict mode.
One config that mirrors the Figma tokens. New screens take an hour instead of a day.
Picked over a hosted document store because the 240K records had real relationships and we needed real joins. Indexed early.
One repo, one deploy, one set of types. No separate Node server until the load actually called for it. It hasn't.
Off-the-shelf tools couldn't handle the source-of-truth merge across four near-duplicate datasets, so we wrote our own.
Public assets, paid downloads (signed URLs), and processed thumbnails. Each on its own bucket with its own IAM role.
We tried serverless first; cold starts wrecked dashboard load. Moved to a VPS, halved the bill, kept latency flat.
Webhooks are the only place tier entitlements get written. The UI reads them, never writes them. That rule has held.
One template registry, one send function, every email triggered by a product event. We deleted ~200 lines of ad-hoc send code when this landed.
Stripe event → entitlement update → access change, all in one Postgres transaction. A partial failure can't leave a user half-upgraded.
Twice-weekly client review during design. By launch the client had spent ~25 hours in the file and there were no surprises in QA.
Raja and his entire Code Nativex team successfully completed a project that connects all the front- and back-end components and all the required logic.



