Skip to main content
< Sai Komal/>
Back to Portfolio

Independent · 3D Commerce Platform

Reality 3D

Designed and developed a 3D-printing commerce experience with product discovery and customer-facing manufacturing workflows; implemented front-end features and backend/API integrations.

Reality 3D home page — Manufacturing, reimagined: turn digital designs into physical products
Objective

The product objective

An on-demand manufacturing storefront: browse a catalogue of printable products, or upload your own model, inspect it in 3D and get a manufacturing quote — with what can and cannot be made stated plainly to the customer.

Role
Independent project — product, design, front-end and integration
Timeline
Independent Project
Deployment
Deployed on Vercel.
Stack

Technology stack

  • Next.js 16 (App Router)
  • React 19
  • TypeScript
  • three.js (WebGL)
  • Payload CMS 3
  • PostgreSQL · Drizzle
  • Supabase Auth
  • S3-compatible object storage
Ownership

Designed, implemented, integrated

What I did on each side of the project — kept separate, because they are different kinds of work. AI tools accelerated implementation; understanding the code, reviewing the output, integrating it and validating it stayed with me.

What I designed

  • Product discovery: catalogue browse, filter, search and sort, each with empty, loading and error states.
  • The custom-print workflow: upload, analyse, configure, quote.
  • A capability model customers can read — available, coming soon, unavailable — so nothing unapprovable can be quoted or ordered.
  • An operations console for orders, customers, designs, production and issues.

What I implemented

  • One WebGL viewer behind an imperative engine class: React owns mounting, teardown and controls; the engine owns everything on the GPU.
  • Format loaders for STL, OBJ and glTF/GLB, each imported on demand.
  • A deterministic exploded view — pure maths, no randomness — so a model separates identically on every load.
  • A quote engine with request validation and pricing rules, plus cart, checkout, guest order tracking and the account area.

What I integrated

  • Payload CMS as the catalogue and admin back end, on PostgreSQL with Drizzle migrations.
  • Supabase authentication for customer accounts.
  • S3-compatible object storage with presigned URLs for uploaded model files.
  • Route handlers for quotes, models, designs, orders, checkout and health checks.

Where AI assisted

  • Built in documented phases with AI coding assistance (Claude); each phase was reviewed, tested and committed separately.
  • A self-run production audit and screen-and-state inventory record what is verified and what is not, rather than assuming generated code works.
Problem solving

Challenges and decisions

  1. 01

    Challenge

    Customers upload STEP files, which are a boundary representation, not a mesh.

    Approach

    The custom-print analysis says so plainly — dimensions and volume cannot be measured from surfaces — while the file can still be quoted and manufactured, instead of failing silently.

  2. 02

    Challenge

    An exploded view that rearranges itself between viewings is not a drawing anyone can read.

    Approach

    Explosion directions are pure and deterministic — radial from the assembly centre, with fixed fallback axes by scene order for centred parts.

  3. 03

    Challenge

    The storefront must never sell a material or process the business has not approved.

    Approach

    Capability status comes from a business decision ledger; the quote engine, cart, checkout and order creation all refuse anything not approved.

Validation

How it is verified

  • Unit and stress tests on Node's built-in test runner — pricing, catalogue, cart and checkout, orders, security, storage, geometry and the viewer's maths.
  • A written MVP production audit and screen-and-state inventory listing what is implemented, reachable and functional.
Code

From the repository

How a component travels in the exploded view — deterministic, so the same model explodes identically every time.

src/lib/viewer/explode.tsView on GitHub
export function explodeDirection(
  component: ExplodeComponent,
  assembly: AssemblyBounds,
): Vector3 {
  const radial = new Vector3().subVectors(component.center, assembly.center);
  const threshold = Math.max(assembly.radius * CENTRED_EPSILON, Number.EPSILON);

  if (radial.length() > threshold) return radial.normalize();

  const axis = FALLBACK_AXES[component.index % FALLBACK_AXES.length];
  // The table is non-empty and the index is taken modulo its length.
  return axis ? axis.clone() : new Vector3(0, 1, 0);
}
Honest limits

Not built yet

  • Checkout runs on a mock payment adapter — no live payment provider is integrated yet.

Want to work together?

Let's build the next one together.