StyleSense 구축기: Amazon Aurora 및 Vercel 기반의 AI 가상 피팅 서비스
요약
AI 기반 가상 피팅 서비스인 StyleSense의 구축 과정을 다룹니다. Amazon Aurora Serverless v2와 Vercel을 활용하여 해커톤 기간 동안 확장성과 보안성을 확보하며 서비스를 구현한 기술적 사례를 소개합니다.
핵심 포인트
- Amazon Aurora Serverless v2를 통한 비용 최적화 및 급격한 부하 대응
- IAM 인증을 활용하여 코드 내 데이터베이스 비밀번호 노출 방지
- FastAPI와 SQLAlchemy를 이용한 IAM 토큰 기반의 동적 연결 구현
- Next.js, Supabase, Runway ML 등 현대적인 기술 스택 조합
온라인 의류 반품은 업계에 연간 8,160억 달러 이상의 비용을 발생시킵니다. 근본적인 원인은 간단합니다. 쇼핑객들이 구매 전에 옷이 자신의 몸에 어떻게 보이는지 확인할 수 없기 때문입니다. 우리는 이를 해결하기 위해 StyleSense를 구축했습니다. 셀카를 업로드하고, 어떤 제품 URL에서든 옷을 추가하면, 즉시 자신이 그 옷을 입고 있는 모습을 볼 수 있는 AI 기반의 가상 옷장(virtual wardrobe)입니다.
우리가 이를 어떻게 구축했는지, 그리고 왜 72시간 해커톤 빌드에 Amazon Aurora PostgreSQL과 Vercel이 적합한 선택이었는지 소개합니다.
기술 스택 (The Stack)
- 프론트엔드 (Frontend): Next.js 14 App Router + TypeScript + Tailwind CSS, Vercel에 배포
- 백엔드 (Backend): 50개 이상의 REST 엔드포인트를 가진 FastAPI (Python 3.12)
- 기본 데이터베이스 (Primary database): Amazon Aurora PostgreSQL Serverless v2 (ap-south-1)
- 인증 + 실시간 (Auth + Realtime): Supabase (JWT, Storage, 소셜 기능)
- AI: Runway ML (피팅, 비디오, 보이스 아바타) + Anthropic Claude (스타일리스트 채팅, 비전)
왜 Amazon Aurora PostgreSQL인가
우리는 다음과 같은 상황을 처리할 수 있는 데이터베이스가 필요했습니다:
- 라이브 데모 중 발생하는 급격한 쓰기 작업 (Bursts of writes) (여러 심사위원이 동시에 '생성(Generate)' 버튼을 누르는 상황)
- 유휴 비용 제로 (Zero idle cost) — 아무도 테스트하지 않을 때 크레딧을 지불하고 싶지 않았습니다.
- 코드 내 비밀 정보 없음 (No secrets in code) — 해커톤 저장소(repo)는 공유되므로, 자격 증명(credentials)이 포함되어서는 안 됩니다.
Aurora Serverless v2는 이 세 가지를 모두 해결했습니다. 테스트 실행 사이에는 규모를 0으로 축소(scales to zero)하고, 부하가 걸리면 즉시 확장(scales up)하며, **IAM 인증 (IAM authentication)**을 지원합니다. 즉, 우리의 FastAPI 백엔드는 데이터베이스 비밀번호를 절대 저장하지 않습니다.
FastAPI에서의 IAM 인증 — 핵심 패턴
비밀번호가 포함된 정적인 DATABASE_URL 대신, 우리는 boto3를 사용하여 연결 시점에 수명이 짧은 토큰을 생성(mint)합니다:
import boto3
def get_iam_token():
...
우리는 새로운 연결이 이루어지기 전에 토큰을 갱신하는 커스텀 creator 함수를 통해 이를 SQLAlchemy의 연결 풀(connection pool)에 연결합니다. 토큰은 15분 후에 만료되므로 이는 필수적입니다:
from sqlalchemy import create_engine
engine = create_engine(
...
.env 파일에 비밀번호가 없습니다. CI에도 비밀번호가 없습니다. 저장소에도 비밀번호가 없습니다. 오직 IAM 역할(role)만 존재합니다.
스키마 설계 (Schema design)
우리는 구조를 가볍게 유지했습니다. Aurora에는 4개의 핵심 테이블이 있습니다:
| 테이블 | 저장 내용 |
|---|---|
users | 셀피 URL, 스타일화된 아바타 URL, 신체 분석 데이터 |
| ... |
인증 및 소셜 기능(친구 관계, 채팅 스레드)은 이미 행 레벨 보안 (Row-Level Security)과 실시간 (Realtime) 기능이 내장된 Supabase에 유지됩니다. Aurora는 "이 사용자가 착장(outfit)으로 저장한 카테고리 X 아이템들에 대한 모든 가상 피팅(try-on) 결과를 보여줘"와 같이 SQL 조인 (join) 및 완전한 ACID 트랜잭션 (ACID transactions)의 이점을 얻을 수 있는 데이터를 처리합니다.
Vercel: 설정이 필요 없는 프론트엔드 배포 (Zero-Config Frontend Deploys)
우리의 Next.js 프론트엔드는 세 개의 환경 변수(environment variables)와 설정 파일 없이 Vercel에 배포됩니다. 가장 큰 차이를 만든 요소들은 다음과 같습니다:
인증을 위한 엣지 미들웨어 (Edge middleware for auth): Supabase 세션 갱신(session refresh)이 모든 요청마다 엣지(edge)에서 실행되므로, 보호된 페이지에서 인증되지 않은 콘텐츠가 잠깐 나타나는 현상이 발생하지 않습니다. 이는 하나의 middleware.ts 파일로 구현됩니다:
// middleware.ts
import { createServerClient } from "@supabase/ssr";
import { NextResponse } from "next/server";
...
Mumbai 리전 (Mumbai region): Vercel 프론트엔드(bom1)와 Aurora(ap-south-1)를 모두 Mumbai에 배포하여, 데이터베이스 왕복(round-trip)에 대한 API 지연 시간(latency)을 20ms 미만으로 유지했습니다.
주의할 점 (The one gotcha): Runway ML은 모든 이미지 URL이 공개된 HTTPS여야 합니다. localhost URL은 오류 없이 실패합니다. 모든 셀피와 옷장 이미지는 Runway API 호출로 전달되기 전에 Supabase Storage로 다시 호스팅됩니다. Vercel의 환경 변수 덕분에 개발(dev)과 운영(prod) URL 간의 전환을 고통 없이 수행할 수 있었습니다.
AI 파이프라인 (The AI Pipeline)
우리가 데모에서 보여준 "와우 모먼트(wow moment)" 흐름은 다음과 같습니다:
- 셀카 업로드 (Upload selfie) → Claude vision이 체형(body type) 감지
- Amazon URL 붙여넣기 → 스크래퍼(scraper)가 제품 이미지 추출 → Runway garment cleaner가 의류만 분리
- 가상 피팅 (Try-on): Runway gen4_image가 셀카에 의류를 합성 (~10초, 5 크레딧)
- 이벤트 장면 (Event scene): Runway gen4_image가 사용자를 "해변 결혼식" 또는 사용자가 설명하는 어떤 배경에도 배치
- 애니메이션 (Animate): Runway gen4.5가 정지 영상을 5초 길이의 런웨이 워킹 영상으로 변환 (~60초, 60-100 크레딧)
- 보이스 스타일리스트 (Voice stylist): Aria (Runway Characters API 아바타)가 사용자의 옷장에 관한 질문에 실시간으로 답변 — 그녀의 지식 베이스(knowledge base)는 매 세션 시작 시 Aurora로부터 동기화됨
전체 파이프라인은 비동기(async)로 작동합니다. FastAPI가 각 Runway 작업을 실행하고 작업 ID(task ID)를 반환하면, 프론트엔드는 페이지 탐색 중에도 유지되는 Zustand 스토어 상태를 통해 폴링(polling)합니다.
도전 과제 (Challenges)
커넥션 풀(connection pools) 내 Aurora IAM 토큰 갱신: SQLAlchemy의 커넥션 풀은 연결을 재사용하므로, 시작 시 발급된 토큰이 세션 중간에 만료됩니다. 해결책은 NullPool을 사용하거나 creator를 오버라이드하여 논리적 연결마다 새로운 토큰이 발급되도록 하는 것입니다. 저희는 creator 방식과 짧은 풀 재순환(pool recycle) 시간을 선택했습니다.
Runway 이미지 URL 요구 사항: Runway로 전송되는 모든 이미지 URL은 반드시 공개된 HTTPS URL이어야 합니다. 개발 과정에서 이는 모든 로컬 업로드 파일이 Runway 호출 전에 Supabase Storage로 다시 호스팅되어야 함을 의미합니다. 추가적인 왕복(round-trip)이 발생하지만 필수적인 과정입니다.
크레딧 예산 관리: Runway gen4.5 영상은 5초당 60-100 크레딧이 소모됩니다. 50,000 크레딧의 예산 내에서, 모든 개발 테스트에는 gen4_image_turbo (2 크레딧)를 사용하고, 데모 녹화 시에만 고품질 모델을 사용하도록 예약했습니다.
다르게 시도한다면 (What We'd Do Differently)
- Aurora DSQL을 사용했다면 커넥션 관리를 완전히 제거할 수 있었을 것입니다. 이는 구성할 인스턴스가 없는 서버리스(serverless) SQL 데이터베이스입니다. 옷장 브라우징과 같이 읽기 집약적인(read-heavy) 워크로드에는 더 적합할 것입니다.
- 작업 큐(task queue)를 위해 DynamoDB를 사용했을 것입니다. 현재의 인메모리(in-memory) 작업 저장소는 서버 재시작 시 초기화됩니다. DynamoDB의 TTL(Time To Live)을 사용했다면 영구적인 백그라운드 작업 이력을 가질 수 있었을 것입니다.
직접 해보기
전체 소스 코드는 GitHub에 공개되어 있습니다. 라이브 데모는 Vercel에서 https://style-sense-steel.vercel.app/를 통해 실행할 수 있습니다.
H0: Hack the Zero Stack with Vercel v0 and AWS Databases 해커톤을 위해 72시간 만에 구축되었습니다.
#H0Hackathon
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기