사주 엔진을 짜다 — 화조당의 첫 일주일
천간·지지·오행의 세계에 발을 들이고, 사주 계산 엔진을 밑바닥부터 만들었다. MVP를 배포하고 관리자 모드까지 올린 7일간의 기록.
왜 사주인가

AI로 뭔가를 만들겠다고 마음먹은 건 오래됐다. 소설을 쓰고, 투자를 하고, 교육 콘텐츠를 만들면서 — 매번 빠지지 않는 질문이 있었다. "AI가 진짜 사람 수준으로 해석을 해줄 수 있는 분야가 뭘까?"
사주(四柱)가 떠올랐다. 천간(天干)과 지지(地支), 오행(五行)의 조합으로 사람의 운을 읽는 체계. 수천 년간 쌓인 동양 명리학의 논리 구조는 놀라울 정도로 체계적이다. 규칙 기반 계산과 맥락적 해석이 동시에 필요한 분야 — 이건 AI가 정말 잘할 수 있는 영역이다.
4월 4일, 프로젝트를 시작했다. 사주 SaaS 웹앱. 이름은 나중에 정하기로 하고, 일단 기술 스택부터 확정했다.
기술 스택 확정
기술 선택에서 고민은 짧았다. 요즘 개인 프로젝트든 프로덕션이든, 내 기본 스택은 거의 정해져 있다.
- Next.js 15 (App Router) — 서버 컴포넌트, API Routes, 미들웨어까지 하나로
- shadcn/ui — Tailwind 기반 컴포넌트 라이브러리. 커스터마이징이 자유롭다
- Vercel Postgres — 배포와 DB를 한 곳에서. 관리 부담 최소화
- Claude API — 사주 해석의 핵심 두뇌. GPT도 써봤지만, 한국어 맥락 이해와 긴 텍스트 생성에서 Claude가 더 나았다
과금 모델도 빠르게 정했다. 크레딧 충전제. 1회 해석에 1,500원. 구독 모델은 이 서비스 특성에 안 맞는다. 사주는 매일 보는 게 아니라 필요할 때 보는 거니까. 충전해두고 필요할 때 차감하는 게 사용자 입장에서도 자연스럽다.
MVP는 4~5주 안에 끝내기로 했다. Phase 1에서 핵심 기능만 넣고 빠르게 시장 반응을 보자.
화조당(花鳥堂)의 탄생

4월 5일. 프로젝트 둘째 날인데, 오늘은 세팅과 브랜딩에 집중했다.
Next.js 15 보일러플레이트를 세팅하고, shadcn/ui를 얹고, Pretendard 폰트를 넣었다. 다크모드도 이날 구현했는데 — 사주 앱의 분위기를 생각하면 다크모드가 기본이어야 했다. 신비롭고, 몰입감 있는 톤.
그리고 이름이 나왔다. 화조당(花鳥堂). 꽃과 새의 집. 동양적이면서 따뜻한 느낌. 사주라는 주제가 자칫 무겁고 진지해질 수 있는데, '화조당'이라는 이름이 그 무게를 살짝 들어올려 준다.
캐릭터도 만들었다. 유나. 화조당에서 사주를 봐주는 AI 상담사 캐릭터다. Midjourney로 여러 버전을 돌려보다가, RPG 비주얼 노벨 스타일의 일러스트가 가장 잘 어울렸다. 한복 모티프에 현대적 감각을 섞은 디자인. 사용자가 '유나'라는 캐릭터와 대화하면서 사주 해석을 받는 경험 — 단순한 데이터 출력이 아니라 이야기가 되는 것.
UI도 이 방향으로 잡았다. RPG 비주얼 노벨 스타일. 캐릭터가 화면 한쪽에 서 있고, 대화창에서 해석이 흘러나오는 구조. 사주 앱이지만 게임처럼 즐거운 경험을 주고 싶었다.
프로덕션 배포와 인증
4월 6일, 셋째 날. 이날은 진짜 많은 걸 했다.
Vercel 프로덕션 배포부터 시작했다. 개발 환경에서만 돌리다가 실제 도메인에 올리니 느낌이 확 다르다. 진짜 서비스가 되는 거구나.
인증은 카카오 OAuth와 Google OAuth 두 개를 넣었다. 한국 사용자 대부분이 카카오 계정은 있으니까 필수고, 해외 사용자나 구글 선호 사용자를 위해 구글도 함께. 이 두 가지면 충분하다.
크레딧 시스템도 이날 구현했다. 가입 시 무료 크레딧 지급, 해석 요청 시 차감, 잔액 부족 시 충전 안내. 단순하지만 과금의 뼈대가 되는 로직이다. Vercel Postgres에 크레딧 테이블을 만들고, 트랜잭션으로 차감 로직을 감쌌다. 동시성 문제가 나중에 터질 수 있으니 FOR UPDATE 락도 걸어뒀다.
MVP 전략도 이날 확정했다. "완벽한 해석보다 작동하는 해석이 먼저다." 사주 계산 엔진은 만세력(만년력) 기반으로 정확하게 만들되, 해석의 깊이는 점진적으로 개선한다. 처음부터 100점짜리 해석을 만들려고 하면 영원히 출시를 못 한다.
관리자 모드 구축
4월 9일. 며칠간 자잘한 버그들을 잡았다.
i18n(국제화) 관련 버그가 몇 개 있었다. 십신(十神) 이름을 표시하는 폰트가 한글/영문에서 다르게 렌더링되는 문제, 툴팁이 특정 조건에서 작동하지 않는 문제, 한국어와 영어 레이아웃의 폭 차이 문제. 하나하나는 사소하지만, 이런 것들이 쌓이면 사용자 경험을 갉아먹는다.
그리고 이날 관리자 모드 전체를 구축했다. 대시보드, 사용자 관리, 통계. 서비스를 운영하려면 어드민이 필수다. 사용자가 몇 명이고, 크레딧이 얼마나 소진되고 있는지, 어떤 해석이 인기 있는지. 이런 데이터가 없으면 방향을 잡을 수 없다.
대시보드에는 핵심 지표를 한눈에 볼 수 있게 배치했다. 가입자 수, 일일 활성 사용자, 해석 요청 수, 크레딧 사용량. 사용자 관리에서는 개별 사용자의 크레딧 잔액, 해석 이력, 가입일을 확인할 수 있게 했다. 이 정도면 초기 운영에는 충분하다.
해석 UX 대수술 — 문제 제거의 힘
4월 11일. 이 날의 경험은 기록해둘 만하다.
해석 결과를 표시하는 UI에서 볼드 처리 문제가 터졌다. Claude API가 반환하는 해석 텍스트에 마크다운 볼드(텍스트)가 들어오는데, 이걸 파싱해서 렌더링하는 과정이 지옥이었다. 중첩 볼드, 볼드 안의 특수문자, 줄바꿈 사이의 볼드… 엣지 케이스가 끝도 없이 나왔다.
처음에는 정규식을 고치고, 파서를 개선하고, 예외 처리를 추가하면서 문제를 해결하려고 했다. 두 시간을 쏟았는데 케이스 하나를 고치면 다른 케이스가 깨졌다. 전형적인 삽질 루프.
그러다 멈추고 생각했다. "이 문제를 해결하는 게 아니라, 이 문제가 존재하지 않게 만들면 어떨까?"
접근을 바꿨다. 마크다운 볼드 파싱을 포기하고, 대신 형광펜(하이라이트) 디자인을 도입했다. 강조하고 싶은 키워드는 볼드가 아니라 형광펜 처리. 파싱이 훨씬 단순해진다. 그리고 사주 전문 용어(천간, 지지, 십신 등)는 자동 감지 팝오버를 만들었다. 텍스트 안에서 사주 용어가 나오면 자동으로 감지해서, 마우스를 올리면 팝오버로 해당 용어의 설명이 뜬다.
결과적으로 볼드 파싱 지옥은 완전히 사라졌고, 대신 더 나은 UX가 탄생했다. 형광펜은 시각적으로 더 눈에 띄고, 용어 팝오버는 사주를 모르는 사용자에게 교육적 가치까지 준다.
"문제 해결보다 문제 제거가 강력하다." 이 교훈은 반복해서 배우는 것 같다. 어떤 문제와 씨름하고 있다면, 잠깐 멈추고 물어보자 — 이 문제 자체가 존재하지 않게 만들 수 있는가?
PDF 출력도 이날 개선했다. 해석 결과를 PDF로 다운로드할 수 있게 했는데, 형광펜과 용어 설명이 PDF에서도 잘 보이도록 스타일을 맞추는 데 시간이 좀 걸렸다.
첫 일주일을 돌아보며
7일. 아이디어에서 시작해서 프로덕션 배포, 인증, 과금, 관리자 모드까지. 속도가 빨랐다. Claude를 페어 프로그래머로 쓰면서 코드 작성 속도가 체감상 3~4배는 빨라진 것 같다.
가장 만족스러운 건 화조당이라는 정체성이 일찍 잡힌 것이다. 이름, 캐릭터, 비주얼 스타일 — 이게 확정되니 이후의 모든 결정이 쉬워진다. "이건 화조당답나?" 한 문장으로 판단할 수 있게 된다.
가장 큰 교훈은 볼드 파싱 사건에서 얻었다. 문제를 해결하려고 달려들기 전에, 그 문제가 존재할 필요가 있는지부터 묻자. 때로는 문제를 없애는 것이 풀어내는 것보다 훨씬 강력한 해결책이다.
다음 주는 사주 계산 엔진의 정확도를 높이고, 해석 품질을 개선할 차례다. 천간·지지의 조합에서 십신을 뽑고, 오행의 균형을 읽고, 대운과 세운의 흐름까지 — 아직 갈 길이 멀다. 하지만 뼈대는 섰다. 이제 살을 붙일 차례.