1인 개발자로서 어떻게 프로덕션급 AI SaaS를 구축했는가
요약
1인 개발자가 AI SaaS인 Statementory를 구축하며 겪은 아키텍처 설계와 트러블슈팅 경험을 공유합니다. 긴 AI 처리 시간을 해결하기 위한 백그라운드 작업 분리, 웹훅 핸들러 최적화, 커스텀 인증 구현 및 PDF 렌더링 이슈를 다룹니다.
핵심 포인트
- AI의 긴 응답 시간을 해결하기 위해 요청과 작업을 분리하는 아키텍처가 필수적임
- 웹훅 핸들러에서는 핵심 작업 트리거 외의 부가 작업(이메일 등)을 기다리지 말 것
- 라이브러리 의존성을 줄이기 위해 필요 시 커스텀 인증 방식을 고려할 것
- 헤드리스 브라우저를 이용한 PDF 생성 시 유니코드 렌더링 문제를 주의할 것
저는 AI를 통해 UCAS 자기소개서를 검토하는 Statementory를 구축했습니다. 100점 만점의 점수, 줄 단위 주석, 재작성, 개선 계획을 제공합니다. 마치 좋은 선생님이 주는 피드백처럼, 마감 전날 새벽 2시에도 이용할 수 있습니다.
혼자서 이를 구축하며 배운 점들을 공유합니다.
모든 것은 하나의 제약 사항에서 시작됩니다: AI가 5분이 걸린다는 점입니다.
Claude가 전체 자기소개서를 처리하고 구조화된 피드백을 생성하는 데는 5분에서 10분이 소요됩니다. Vercel의 서버리스 함수 (Serverless functions)는 요금제에 따라 10초에서 60초 내에 타임아웃 (Timeout)이 발생합니다. 따라서 라우트 핸들러 (Route handler)에서 AI API를 직접 호출하는 명백한 접근 방식은 결코 작동할 수 없었습니다.
해결책은 요청 (Request)에서 작업 (Job)을 분리하는 것이었습니다. API 라우트가 백그라운드 작업 (Background job)을 트리거하고 즉시 응답을 반환합니다. 작업은 필요한 만큼 별도의 워커 (Worker)에서 실행됩니다. 작업이 완료되면 사용자는 이메일을 받게 됩니다.
이것은 다른 모든 것이 의존하게 되는 아키텍처 (Architecture) 결정입니다. 느린 AI 호출이 포함된 무언가를 구축하고 있다면, 이 문제를 가장 먼저 해결하십시오.
첫 고객들의 리뷰를 잡아먹은 버그
Stripe 웹훅 (Webhook)이 실행되고, 백그라운드 작업을 트리거하면 끝입니다. 충분히 간단해 보입니다.
하지만 저는 작업을 트리거하기 전에 이메일 전송을 기다리고(awaiting) 있었습니다. Resend는 가끔 느려졌습니다. 이메일 전송이 너무 오래 걸리면, 작업이 실행되기도 전에 서버리스 함수가 타임아웃되었습니다. 결제는 완료되었지만, 리뷰는 생성되지 않았습니다.
해결책: 작업이 조건 없이 가장 먼저 실행되도록 합니다. 그 외의 모든 것 — 이메일, 로깅 (Logging), 분석 (Analytics) — 은 그 이후에 최선을 다해(best effort) 처리합니다.
저는 Stripe 결제 내역과 생성된 리뷰를 교차 확인하여 누락된 리뷰를 다시 트리거하는 복구 스크립트 (Recovery script)를 작성해야 했습니다. 즐거운 일요일이었죠.
교훈: 웹훅 핸들러 (Webhook handler)에서 중요한 유일한 것은 다운스트림 작업 (Downstream job)을 트리거하는 것입니다. 그 외의 모든 것은 기다려야 합니다.
라이브러리 대신 커스텀 인증 (Custom auth)
처음에는 인증 라이브러리 (Auth library)를 사용해 보았습니다. 하지만 제가 필요로 하는 기능에 비해 App Router 지원이 미흡하게 느껴졌고, 라이브러리가 도움이 되기보다는 추상화 (Abstraction)와 싸우는 데 더 많은 시간을 쓰고 있었습니다.
커스텀 매직 링크 인증 (Custom magic-link auth)은 결국 약 200줄 정도로 끝났습니다. 사용자가 이메일을 입력하면 링크를 받고, 이를 클릭하면 세션 쿠키 (Session cookie)를 받게 됩니다. OAuth의 복잡함도 없고, 제공업체 (Provider)에 대한 의존성도 없으며, 제가 원하는 방식 그대로 작동합니다.
트레이드오프 (Tradeoff)는 유지보수입니다. 만약 나중에 OAuth가 필요해진다면 직접 구현해야 할 것입니다. 하지만 지금은 괜찮습니다.
아무도 경고해주지 않는 PDF 문제
리뷰는 HTML 이메일과 다운로드 가능한 PDF로 제공됩니다. PDF는 헤드리스 브라우저 (Headless browser)에서 HTML을 렌더링하여 생성됩니다.
아무도 말해주지 않는 사실은, 특정 유니코드 (Unicode) 문자들이 헤드리스 브라우저에서 렌더링되지 않는다는 점입니다. 보고서에 포함된 아이콘들이 PDF에서는 빈 사각형으로 표시되었습니다. 디버깅하는 데 예상보다 더 많은 시간이 걸렸습니다. 해결 방법은 유니코드 문자를 순수 CSS 도형으로 교체하는 것이었습니다.
PDF는 로컬 머신이 아닌 실제 생성 환경에서 테스트하세요. 폰트와 문자 지원 방식이 다릅니다.
시작할 때의 나에게 해주고 싶은 말
세 가지입니다:
첫째, 다른 어떤 것을 작성하기 전에 느린 AI 호출 문제를 먼저 해결하세요. 이 문제는 모든 부분에 영향을 미칩니다.
둘째, 서드 파티 API (Third party API) 버전을 상수로 고정하고 모든 곳에서 임포트 (Import)하세요. 여러 파일에 걸친 버전 불일치는 디버깅하기 매우 고통스러운 일입니다.
Statementory는 statementory.com에서 라이브로 서비스 중입니다. 댓글로 질문해 주시면 기꺼이 답변해 드리겠습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기