Don't Panic
in Etc ☕ 4분 읽기

설계를 진짜 서비스로 — '구독 다이어트' 3주차 구현 정리

목차

구독 다이어트 — 3주차 구현 정리

목표: 설계를 실제로 동작하는 서비스로. 멀티 에이전트 오케스트레이션 + Token maxxing 활용. 결과: 회원가입·DB·영속까지 갖춘 웹앱을 공개 URL로 배포subscription-diet.vercel.app


1. 스택 (확정)

  • Next.js 16 (App Router, TypeScript) + Tailwind CSS v4 — 웹앱
  • Prisma 6 + PostgreSQL(로컬은 SQLite → 배포는 Vercel/Neon Postgres)
  • 인증 직접 구현 — bcryptjs(비밀번호 해시) + jose(JWT, httpOnly 쿠키)
  • 배포: Vercel → 공개 URL (폰 브라우저·PWA·웹뷰 테스트)
  • 아키텍처 = 웹뷰형 마이데이터 플러그인 (2주차 설계와 동일 결)

왜 웹앱? 하나면 URL 접속 · PWA · 웹뷰 임베드 · (Capacitor) .apk 를 다 커버한다.


2. 진행 요약 (단계별)

  1. 계획 — 계획서·WBS 간트로 작업을 T-01~T-19로 분해
  2. 기반 굳히기 — 공유 “계약”(타입·샘플거래·탐지로직·상태스토어·공용컴포넌트·디자인토큰)을 먼저 확정
  3. 화면 병렬 구현 — 에이전트 4명이 화면 7개를 동시에 제작
  4. 백엔드 승격 — “껍데기 아니냐” 지적 → 회원·DB·영속을 진짜로 (3장)
  5. 팀 검증 — 서로 다른 렌즈의 에이전트 4명 투입 (4장)
  6. 배포 — Vercel + Postgres, 방화벽 우회 (5장)
  7. 다듬기 + 기능 4종 추가 — 온보딩·설정·로고 정비 + 목표/직접추가/캘린더/인사이트 (6장)

멀티 에이전트의 핵심: “얼마나 똑똑한 에이전트냐”보다 “공유 계약을 얼마나 명확히 주느냐.” 기반(인터페이스)을 먼저 굳히지 않고 병렬로 던지면 서로 다른 가정으로 통합 때 깨진다.


3. “껍데기 → 진짜 서비스” — 백엔드 승격

초기엔 코드에 박제된 12개 구독 + localStorage였다. “동작”은 하지만 계정도, 데이터 유입 통로도 없는 반쪽. 그래서 승격했다.

  • 실연동은 불가(마이데이터 사업자 자격·기능적합성/보안 인증·기관 계약) → 연동이라는 “행위”만 모의하고, 그 뒤의 회원·DB·영속·계정별 데이터·탐지는 전부 진짜로 구현
  • 구조: proxy.ts(라우트 게이트) · lib/auth.ts+app/actions/*(인증·연동·구독) · lib/detect.ts(탐지) · lib/queries.ts+lib/store.tsx(스냅샷·상태)
  • 탐지 로직이 심장 — 거래를 가맹점별로 묶고 → 월 단위 반복 + 금액 안정성 → 구독 판정, 근거·신뢰도 동반. 데이터는 결정적(deterministic) 으로 만들어 하이드레이션 불일치 방지

최신 프레임워크의 함정 둘

  1. Prisma 7이 datasource 설정을 갈아엎어(driver adapter 요구) → 검증된 Prisma 6으로 다운
  2. Next 16이 미들웨어 규약을 middlewareproxy.ts(함수명 proxy) 로 변경

배운 것: 최신을 쓰면 “되는 코드”가 아니라 “이 버전에서 되는 코드”를 확인해야 한다.


4. 에이전트 팀 검증 (만든 손 ≠ 검증한 손)

리뷰어 3명은 읽기 전용, QA만 테스트 작성·실행:

에이전트렌즈
코드 리뷰어로직 결함·에러 처리·프레임워크 관례
보안 리뷰어인증·세션·권한·시크릿
디자이너빈/에러 상태·일관성·모바일
QA실제 브라우저 E2E
  • 핵심 버그(QA 발견): 로그아웃→재로그인 시 해지 구독이 되살아나 보임. DB는 멀쩡, 범인은 브라우저 Router Cache. revalidatePath로는 클라 캐시가 안 비워져 → 로그인을 하드 내비게이션(window.location.assign)으로 바꿔 캐시 폐기
  • 그 외: 연동 이중 적재 레이스 → 원자적 claim / 해지 실패 무음 삼킴 → 롤백+재동기화 / 폴백 시크릿 → 프로덕션 fail-closed
  • 교훈: 말보다 증거. QA 서술이 “미수정”이라 해도 실제 테스트를 다시 돌려 확인
  • 최종: 브라우저 E2E 14/14 통과 + 빌드 클린

5. 배포 — 방화벽이라는 벽

  • 서버리스는 파일 시스템에 못 쓴다 → SQLite → Postgres(Prisma는 provider 한 줄만 교체)
  • 함정: 개발망이 아웃바운드 DB 포트(5432)를 차단 → 로컬 prisma db push 실패(P1001)
  • 우회: 테이블 생성을 로컬이 아니라 Vercel 빌드 단계에서 실행 — 클라우드 빌드망은 DB에 닿는다
  • 라이브 검증: 배포 URL에 대고 가입→(모의)연동→홈 탐지까지 브라우저 프로브 통과

로컬 검증 ≠ 프로덕션 검증. 안 되면 “실행 위치”를 의심하라.


6. 다듬기 + 추가 기능 4종

다듬기: 온보딩을 실제 마이데이터풍 4단계(자산 미연결 → 간편인증 → 문자 PIN → 카드·계좌 선택)로, 생년월일·휴대폰 실검증, 브랜드 로고(딥그린 타일+하향 트렌드 심볼), 설정/마이페이지(계정 수정·연결 끊기·탈퇴·로그아웃).

기능 4종(데이터 계층 먼저 고정 → 화면 병렬):

  • 🎯 구독 다이어트 목표 — 월 목표 대비 지출 게이지
  • ✏️ 구독 직접 추가 — 자동 탐지 안 되는 구독 수동 CRUD (읽기 전용 탈피)
  • 📅 결제 캘린더 — 달력에 결제일·금액
  • 💡 스마트 인사이트 + 실데이터 알림 — 하드코딩 알림 → 실제 탐지 결과 기반 제안

처음 7화면이 16화면(12 라우트) 규모로 성장했다.


7. 최종 산출물 (제출용 최종본)

구분파일내용
발표자료(통합)구독다이어트_최종발표_설계구현.pptx37장 = 설계(26)+구현(11) 병합. 대표 제출본
기능명세서구독다이어트_기능명세서_v2.docxFR-01~24 + 16화면 갤러리 + ERD (실제 앱 기준)
데이터 모델구독다이어트_ERD.dbml실제 스키마 4테이블 (dbdiagram용)
동작 앱subscription-diet.vercel.app라이브 배포
블로그설계 정리 · 구현 정리 (이 시리즈)2·3주차 기록
  • 발표 분권 원본: 구독 다이어트_완성본.pptx(26장, 2주차 설계) · 구독다이어트_발표자료_v2.pptx(11장, 3주차 구현)
  • 부속: 라이브 16화면 캡처 + ERD 렌더 · 3주차 계획서/WBS · 앱 소스

8. 회고

  • 기반(계약)을 먼저. 병렬 개발은 공유 인터페이스가 굳어 있을 때만 안전하다.
  • “껍데기”를 스스로 의심하라. 화면이 눌러지는 것과 서비스가 도는 건 다르다.
  • 할 수 없는 건 솔직하게. 실연동은 제도의 벽 — 모의로 두고 나머지를 진짜로.
  • 검증은 남에게, 그리고 증거로. 만든 사람이 자기 걸 통과시키면 안 된다.
  • 로컬과 프로덕션은 다른 세계. 방화벽·파일시스템처럼 배포에서만 드러나는 벽이 있다.
  • 동작 → 검증 → 다듬기 순서. 예쁘게부터 만들면 헛수고가 되기 쉽다.