9 Featured WorksProjects
  1. Home
  2. /Projects
  3. /FabWorks
full stack2025Featured

FabWorks

Steel Fabrication Platform

Start a project
rohith-a.me/projects/proj-3
01

The challenge

A steel fabrication business ran its leads, estimates and customer follow-ups by phone and paper, with no way to quote consistently or show customers where their order stood.

02

The approach

Built a Next.js 16 application that is both the public website and the back office.

What shipped
  • Lead and quotation intake protected by Cloudflare Turnstile and rate limiting
  • An admin panel with a costed fabrication-estimate engine (templates, material rates per kg, charges, tax and margin)
  • A seven-state quotation lifecycle with an activity log
  • PDF quotes rendered through a hosted browser API
  • MongoDB persistence
  • OCI Object Storage for drawings and attachments
  • A client project-tracking portal
03

The outcome

Leads become costed quotations that are emailed as PDFs and accepted, rejected or sent back for changes by the customer through a single-use secure link, with stale quotes expired by a daily job and every step recorded.

At a glance

Year
2025
Type
full stack
Stack
6 technologies
Scope
7 core capabilities

Built with

Next.js 16TypeScriptMongoDBZodNodemailerTailwind CSS
System design

How FabWorks is put together

A Next.js Pages Router application that is both the public website and the business back office: lead and quotation intake, a client project-tracking portal, and an admin panel with a costed fabrication-estimate engine and a quotation lifecycle that ends in a customer accepting or rejecting a PDF quote by secure link.

quotation states, enforced transitions
7
single-use quote links, stored hashed
256-bit
MongoDB models
16
function budget the PDF design fits
1 GB / 10 s

01 · Clients

client

Visitors & customers

client

Admin staff

02 · Next.js app

gateway

Middleware

per-route cache policy

service

Public site

services, gallery, quotes, tracking · i18n

service

Admin panel

content, leads, estimates

03 · API

service

API routes

Zod DTOs, JWT cookie, rate limits

service

Quotation engine

calc engine, state machine, audit log

worker

Vercel Cron

expire quotations daily

04 · Data

database

MongoDB

Mongoose

16 models

object store

OCI Object Storage

drawings, attachments

05 · Third-party

third-party

PDF render API

hosted browser · Chrome fallback

third-party

SMTP

Nodemailer

third-party

Cloudflare Turnstile

bot check on public forms

Hover a component to trace its connections, or a request-flow step to follow it through the system.

clientgatewayserviceworkerdatabaseobject storethird-partyrequest / responseasync · event · schedule

14 connections

  • Visitors & customers→MiddlewareHTTPS
  • Admin staff→MiddlewareHTTPS
  • Middleware→Public site
  • Middleware→Admin panel
  • Public site→API routesleads · quotes · respond
  • Admin panel→API routesCRUD · estimates
  • API routes→Cloudflare Turnstileverify
  • API routes→Quotation engine
  • Quotation engine→MongoDB
  • API routes→MongoDB
  • API routes→OCI Object Storageupload
  • Quotation engine→PDF render APIHTML → PDF
  • Quotation engine→SMTPquote email · async
  • Vercel Cron→Quotation engineexpire stale · async
›14 connections as text
  • Visitors & customers→MiddlewareHTTPS
  • Admin staff→MiddlewareHTTPS
  • Middleware→Public site
  • Middleware→Admin panel
  • Public site→API routesleads · quotes · respond
  • Admin panel→API routesCRUD · estimates
  • API routes→Cloudflare Turnstileverify
  • API routes→Quotation engine
  • Quotation engine→MongoDB
  • API routes→MongoDB
  • API routes→OCI Object Storageupload
  • Quotation engine→PDF render APIHTML → PDF
  • Quotation engine→SMTPquote email · async
  • Vercel Cron→Quotation engineexpire stale · async

Request flow · From lead to accepted quotation

  1. 1A visitor requests a quote by materials, an uploaded drawing or a gallery design; Turnstile and a rate limit screen the form and the API stores an intake record.
  2. 2Staff build a costed quotation from line items, templates and material rates; the engine computes subtotals, charges, tax and margin.
  3. 3Sending renders the quote to PDF and emails it with a link carrying a random 256-bit token, of which only the hash is stored.
  4. 4The customer accepts, rejects or requests changes through that link; the state machine allows only legal transitions and a daily cron expires what was never answered.

Design decisions

An explicit state machine
draft → sent → viewed → accepted / rejected / expired, with cancellation from any open state; every transition is checked and written to an activity log.
Links as hashed bearer tokens
A quote link carries a random token; only its hash is stored, so a database read never yields a working link, and expired or revoked links answer 410 or 404.
PDF rendering off the function
Vercel Hobby limits (1 GB, 10 s) are too tight for in-process Chromium, so PDFs render through a hosted browser API behind one htmlToPdfBuffer() entry point.
Intake and estimate stay separate
A public request is a lead; a costed fabrication quotation is a bill of materials. Keeping them apart stops marketing forms from shaping estimating data.
Cache policy at the edge
Middleware marks forms and admin as no-store, catalog APIs as cacheable and static assets as immutable.

Trade-offs & known limits

  • The client tracking portal is gated by order id and phone with a sessionStorage marker: convenient, but not a full authenticated session.
  • WhatsApp sending is a pre-filled wa.me link the admin opens, not automated delivery.

Have something similar in mind?

I'm open for freelance and contract work — let's talk about what you're building.

Get in touchSee more workBack to home
←PreviousQuickImportdeveloper toolsNext→3D Portfolio Websiteopen source
Rohith. A

© 2026 All rights reserved.

Available for work