클라이언트는 회사가 아니라 영업 매니저 개인입니다 — 자기만의 리드 채널이 필요했던 장기렌트 담당자입니다. 가격 조회의 기준은 "가격은 계산하지 않는다, 조회한다"입니다. 차량마다 12칸 매트릭스 — 계약기간 3종 × 주행거리 2종 × 보증금 2종 — 에 확정 월 대여료가 들어 있어서, 방문자가 보는 견적은 추정치가 아니라 실제 계약서에 적힐 그 숫자입니다. 방문자가 조건을 고르면 그에 맞는 확정가를 보여준다는 점에서 정적 가격표 사이트와 차이가 있습니다.
애플리케이션은 Next.js 16 App Router와 React 19, TypeScript로 작성했고 Tailwind로 스타일링했습니다. DB는 Drizzle ORM을 통한 Neon Postgres, 배포는 Vercel, 차량 이미지는 비공개 Blob 스토리지에 둡니다. 별도의 백엔드 서버는 없습니다 — 앱의 API route 8개가 곧 백엔드이고, JWT 인증 관리자 게이트 뒤에 있습니다.
관리자 화면에서는 다음 기능을 제공합니다. 이미지 업로드와 12칸 가격 그리드를 갖춘 차량 CRUD, 상담 리드 관리, 그리고 클라이언트가 실제로 읽을 수 있는 계측 — 견적 탐색→상담 진입 전환 퍼널, 차종별 전환율, 견적 이벤트 이상치 탐지, 12칸 중 빈 칸이 있는 차량을 잡아내는 건전성 점검. 배포는 유닛 테스트부터 배포 후 스모크까지 7개 게이트를 지나는 단일 스크립트로만 나갑니다.
검색 노출을 위해 다음을 준비했습니다 — 구조화 데이터, sitemap, llms.txt, 공유 카드, Safari가 실제로 읽는 ICO 인코딩에 바이트 수준으로 맞춰 다시 만든 파비콘, 그리고 같은 날 밤 검색콘솔 3종 등록과 색인 요청까지. 본사가 "공식 사이트로 오인될 수 있다"는 우려를 제기했을 때, 저는 사이트의 운영 주체를 구분하는 장치를 마련했습니다 — 담당자 선행 명명, 오인 방지 고지, 공식 도메인과 구조적으로 분리하는 앵커. 그리고 사흘 뒤, 클라이언트와 다시 마주 앉은 끝에 그것을 전부 걷어내고 브랜드 선행으로 돌아갔습니다. 경쟁 사이트도 브랜드를 앞세우고 있었고, 우리도 같은 방식을 쓰기로 했습니다.
서버리스 함수와 데이터베이스가 처음에는 사용자에게서 먼 지역에 있었는데, 둘 다 사용자 쪽으로 옮기자 콜드 스타트가 실측 81% 줄었습니다. DB 이전 중에는 연결 풀 장애도 겪었습니다 — pg_dump 결과물 때문에 커넥션 풀러의 재사용 세션에 빈 search_path가 남아, 분명히 존재하는 테이블이 조회되지 않는 상태가 됐고, 오염된 백엔드 프로세스를 강제 종료하고서야 풀렸습니다.
개발에는 3주가 걸렸고, 소스 파일 94개와 커밋 100여 개가 남았습니다. 독립 도메인에 공개하고 검색 색인과 계측을 연결한 뒤, 클라이언트가 직접 사용할 운영 매뉴얼과 함께 인도했습니다.
