FRQN®

Work / Diin Associations

Sleek Interio

A lead engine for a luxury interior design firm. An interactive cost calculator qualifies visitors step by step, saves their progress before they can abandon it, and hands the sales team scored, routable leads.

Sole engineerMarch to June 2026Visit live site ↗
Draft recovery window
24h
Rate-limit layers
3
Monorepo packages
6
Engineer
1

01 / The problem

Interior design quotes are complicated. Area, rooms, service scope, budget tier, timeline. A plain contact form collects junk, and a long form loses people halfway through. Every abandoned form is a lead the firm paid marketing money to attract and then silently lost.

The firm needed three things: a form people actually finish, a way to recover the ones who do not, and enough signal on each lead for the sales team to know who to call first.

02 / What I built

Sleek Interio is a Turborepo monorepo: a Next.js site, an Express API in TypeScript with a controller, service and repository structure, and shared packages for UI, types and config. Prisma models the lead pipeline in Neon Postgres. Upstash Redis sits in front for everything transient.

The calculator computes an internal complexity score and an estimated revenue range for every submission. The sales team sees the full picture in an admin dashboard with audit-logged status changes. The visitor only ever sees a clean public summary.

03 / Deep dive

Drafts live in Redis, leads live in Postgres

Half-finished forms are valuable but they are not records. Writing them to the primary database pollutes it with noise and lock contention.

So the calculator autosaves every step to Redis with a 24 hour TTL. Close the tab at step four, come back tomorrow, and the form resumes where you left it. Only a completed, validated submission graduates into Postgres. The primary database only ever contains real leads.

  • Autosave on every step, sub-second Redis writes
  • 24h TTL expires abandoned drafts on its own
  • Postgres receives only completed submissions
CALCULATORmulti-step formREDISdrafts, 24h TTLVALIDATIONZod, full payloadPOSTGRESreal leads onlyAUTOSAVE EVERY STEPRESUME AFTER DROP-OFFSUBMITGRADUATESABANDONED AT STEP 4? THE DRAFT WAITS 24 HOURSTHE PRIMARY DATABASE NEVER SEES A HALF-FINISHED FORM
Fig 01 · Redis drafts, Postgres leads

04 / Deep dive

The browser never sees a secret

The pricing logic is the firm's competitive edge, and API keys in browser code are a breach waiting to happen. Both problems have the same answer: the client talks only to the Next.js server.

Server Actions proxy every request to the Express API and attach the bearer key server-side. On the way back, a serializer strips the internal fields, complexity score, revenue estimate, budget tier, before anything reaches the client. Admins see the full record; visitors see only their own quote.

  • Server Actions as a backend-for-frontend gateway
  • Bearer-key middleware guards every protected route
  • Public serializer masks internal scoring fields
BROWSERzero secretsSERVER ACTIONBFF gatewayEXPRESS APIauth middlewareSERIALIZERstrips internal fieldsBEARER KEYFULL RECORDPUBLIC FIELDS ONLYCOMPLEXITY SCORE, REVENUE ESTIMATE, BUDGET TIER:NEVER LEAVE THE SERVER
Fig 02 · Backend-for-frontend gateway

05 / Deep dive

Spam hits a sliding window

A public lead form is a magnet for bots. Validation alone does not stop a script submitting plausible data a thousand times.

Every endpoint sits behind Redis sliding-window rate limits: a general 10 requests per minute per IP, and a strict 3 submissions per 10 minutes keyed on IP plus email for lead creation. Zod validates every payload at the boundary, Helmet sets the security headers, and every admin action lands in an audit log.

  • 10 req/min general, 3 per 10 min for submissions
  • Window keyed on IP plus email, not IP alone
  • Zod-validated DTOs, audit trail on every status change
REQUESTpublic internetWINDOW 110 req / min / IPWINDOW 23 / 10 min / IP+emailZOD DTOboundary validationHANDLERaudit-loggedOVER EITHER WINDOW: 429KEYED ON IP PLUS EMAIL, A BOTNET CANNOT HIDE BEHIND ONE INBOXEVERY ADMIN STATUS CHANGE LANDS IN THE AUDIT LOG
Fig 03 · Sliding-window defense

06 / Outcomes

  • Live lead engine for a real firm, built and shipped solo
  • Mid-funnel drop-offs come back to a saved form instead of starting over
  • Sales works from scored leads with a full audit history
  • Pricing logic never leaves the server

Stack

Frontend
Next.js 15, React 19, Zustand, React Hook Form, Framer Motion
API
Node.js, Express, TypeScript, Zod, Prisma
Data
Neon Postgres, Upstash Redis
Ops
Turborepo, Clerk, Resend, Helmet, Husky

Next case study

Wheelness