# How We Built StyleSense: AI Virtual Try-On Powered by Amazon Aurora & Vercel

> Source: <https://dev.to/ihddirmas/how-we-built-stylesense-ai-virtual-try-on-powered-by-amazon-aurora-vercel-dgf>
> Published: 2026-06-29 23:49:03+00:00

Online clothing returns cost the industry over $816 billion a year. The root cause is simple: shoppers can't see how clothes look on *their* body before buying. We built **StyleSense** to fix that — an AI-powered virtual wardrobe where you upload a selfie, add clothes from any product URL, and instantly see yourself wearing them.

Here's how we built it, and why Amazon Aurora PostgreSQL and Vercel were the right choices for a 72-hour hackathon build.

We needed a database that could handle:

Aurora Serverless v2 solved all three. It scales to zero between test runs, scales up instantly under load, and supports **IAM authentication** — meaning our FastAPI backend never stores a database password.

Instead of a static `DATABASE_URL`

with a password, we use boto3 to mint a short-lived token at connection time:

``` python
import boto3

def get_iam_token():
    client = boto3.client("rds", region_name="ap-south-1")
    return client.generate_db_auth_token(
        DBHostname="stylesense.cluster-c9cswq8kqykn.ap-south-1.rds.amazonaws.com",
        Port=5432,
        DBUsername="stylesense_app",
        Region="ap-south-1",
    )
```

We wire this into SQLAlchemy's connection pool via a custom `creator`

function that refreshes the token before each new connection — tokens expire in 15 minutes, so this is essential:

``` python
from sqlalchemy import create_engine

engine = create_engine(
    "postgresql+psycopg2://",
    creator=lambda: psycopg2.connect(
        host=AURORA_HOST,
        port=5432,
        dbname="stylesense",
        user="stylesense_app",
        password=get_iam_token(),
        sslmode="require",
    )
)
```

No password in `.env`

. No password in CI. No password in the repo. Just an IAM role.

We kept it lean — 4 core tables in Aurora:

| Table | What it stores |
|---|---|
`users` |
Selfie URLs, stylized avatar URLs, body analysis |
`wardrobe_items` |
Clothing images, categories, colors, source URLs |
`try_on_results` |
Generated try-on images, event scenes, video URLs |
`outfits` |
Saved outfit combinations |

Auth and social (friendships, chat threads) stay in Supabase, which already has Row-Level Security and Realtime built in. Aurora handles the data that benefits from SQL joins and full ACID transactions — like "show me all try-ons for items in category X that this user saved as outfits."

Our Next.js frontend deploys to Vercel with three environment variables and zero configuration files. The things that made the biggest difference:

**Edge middleware for auth**: Supabase session refresh runs at the edge on every request, so protected pages never flash unauthenticated content. This is one `middleware.ts`

file:

``` js
// middleware.ts
import { createServerClient } from "@supabase/ssr";
import { NextResponse } from "next/server";

export async function middleware(request: NextRequest) {
  // Refreshes the Supabase session cookie on every request
  // Redirects to /login if the user is not authenticated
}
```

**Mumbai region**: We deployed both the Vercel frontend (`bom1`

) and Aurora (`ap-south-1`

) in Mumbai, keeping API latency under 20ms for the database round-trip.

**The one gotcha**: Runway ML requires all image URLs to be public HTTPS. Localhost URLs fail silently. Every selfie and wardrobe image gets re-hosted to Supabase Storage before being passed to any Runway API call — Vercel's environment variables made switching between dev and prod URLs painless.

The "wow moment" flow that we demoed:

The entire pipeline is async. FastAPI fires each Runway task and returns a task ID; the frontend polls via Zustand store state that survives page navigation.

**Aurora IAM token refresh in connection pools**: SQLAlchemy's connection pool reuses connections, so a token minted at startup expires mid-session. The fix: use `NullPool`

or override the `creator`

so a fresh token is minted for every logical connection. We went with the `creator`

approach and a short pool recycle time.

**Runway image URL requirement**: Every image URL sent to Runway must be a public HTTPS URL. During development this means all local uploads get re-hosted to Supabase Storage before the Runway call — an extra round-trip but essential.

**Credit budget discipline**: Runway gen4.5 video costs 60-100 credits per 5 seconds. With a 50,000-credit budget, we used gen4_image_turbo (2 credits) for all dev testing and reserved the full quality models for demo recordings.

The full source is on GitHub. The live demo runs on Vercel at [[https://style-sense-steel.vercel.app/](https://style-sense-steel.vercel.app/)].

Built in 72 hours for the **H0: Hack the Zero Stack with Vercel v0 and AWS Databases** hackathon.

*#H0Hackathon*
