ilovegohyangai.org)까지 흩어져 있고, jQuery 3.x + 서버세션(jsessionid), productOld·0원 가격·평점 0 디렉터리가 라이브로 남아 Phase2 평점이 놀고팜 40.2 / 아이러브고향 34.2에 그친다. 이 기획서는 디자이너·기획자가 없는 조직에서 그 자체가 착수 근거가 되며, 통합 신규 플랫폼으로 총점 86.2(웰로 85.1·위기브 76.6 상회)를 목표한다. 핵심 차별점은 복제 불가능한 단일 동선 - 고향사랑기부 답례품으로 농촌체험 바우처·숙박을 제공하고 놀고팜의 실물 재고와 '바로결제'를 답례품 카탈로그에 직접 연결한다.| # | 결정 | 내용 | 폐기/대체 |
|---|---|---|---|
| D1 | 단일 도메인·단일 코드베이스 | 예약+기부+AI추천 3분할을 하나의 GNB·세션·장바구니·검색으로 통합. 외부 떠넘김 0건 | 2도메인 + ilovegohyangai.org 폐기 |
| D2 | 모던 SPA/SSR 스택 | Next.js류 모바일퍼스트 단일 반응형, TTFB<100ms, ISR, JSON-LD/canonical | jQuery 3.x + jsessionid 분기형 모바일 폐기 |
| D3 | 고향사랑e음 API 경유 | 기부접수·본인확인·세액공제 영수증은 공공 시스템(행안부/한국지역정보개발원) 경유. 현 백엔드 재사용 | 자체 영수증 발급 불가(법령) |
| D4 | 비로그인 전(全)과정 탐색 | 탐색·필터·계산 위젯까지 로그인 없이. 로그인은 결제 직전 1회만 | 조기 로그인 게이트 제거 |
| D5 | USP - 답례품=체험/숙박 | 놀고팜 실물재고+바로결제를 답례품으로 연결(30%룰 내). 복제 불가 단일 동선 | 경쟁사 대비 핵심 차별 |
| D6 | 단일 디자인시스템 | Pretendard Variable, 2축 팔레트(기부=신뢰/체험=생기), CTA 포인트 #F9AA24 | OTS 디코드 실패 폰트·텍스트 박힌 이미지 폐기 |
| D7 | 법령 룰 엔진 파라미터화 | 연 한도 2,000만, 10만 전액·초과 16.5%·10년 이월·답례품 30%룰을 설정값으로 분리 | 하드코딩 금지(법 개정 대응) |
| 축(가중치) | 현재(놀고팜/아이고) | 목표 | 핵심 판정 지표 |
|---|---|---|---|
| 정보구조·통합(20) | 2도메인+AI 3도메인 | 88+ | 단일 도메인 1개, 외부 떠넘김 0 |
| 기부 깊이(20) | 34.2 수준 | 90 | 분류+필터, 모금률%, 비로그인 탐색 |
| 디자인(15) | 폰트 디코드 실패 | 85+ | 단일 디자인시스템, 일관 위계 |
| 콘텐츠·리텐션(15) | 플레이스홀더 라이브 | 80+ | 아티클·커뮤니티·출석체크 |
| 기술(12) | jQuery+세션 | 85+ | TTFB<100ms, JSON-LD, h1=1 |
| 모바일(10) | 분기형 | 88+ | 단일 반응형 |
| 접근성(8) | 줌차단·alt 누락 | 85+ | alt 0누락, 줌 허용, 실제 텍스트 |
| 총점(100) | 40.2 / 34.2 | 86.2 | 웰로 85.1·위기브 76.6 상회 |
| 마일스톤 | 기간 | 핵심 산출 | 주력 인원 |
|---|---|---|---|
| M0 기반·디자인시스템 | W1-W3 | 스택·CI, Pretendard Variable, 토큰/컴포넌트 | FE2·디자인1 |
| M1 통합 IA·탐색 | W4-W7 | GNB·세션·검색·장바구니, 카탈로그 | FE2·BE2 |
| M2 기부 깊이·e음 연동 | W8-W11 | 모금률·세액공제 위젯, e음 API, 본인확인·영수증 | BE2·FE1 |
| M3 답례품↔체험 동선·결제 | W12-W14 | 바우처 연결, 바로결제, QA | 전원 |
| MVP 론칭 | ~W14 | 핵심 지자체 선론칭 + 마이그레이션(301) | - |
| M4 리텐션·확장 | W15-W24 | 커뮤니티·출석체크·축제·AI추천 | FE·BE |
인원 코어: PM 1, FE 2, BE 2, 디자인 1(외주/AI 보강), QA 1. 기획은 본 문서가 대체. 월 인프라(호스팅/CDN/DB/모니터링)는 12장 산정표 참조 - 단일 코드베이스로 운영비 통합 절감.
| 리스크 | 영향 | 대응 |
|---|---|---|
| 243개 지자체 개별 입점 계약(수수료 5~10%) 영업 병목 | 론칭 카탈로그 빈약 | 핵심 N개 지자체 선론칭 후 순차 확장, 셀프 입점 어드민 |
| 고향사랑e음 API 의존/장애 | 기부접수·영수증 중단 | 큐잉·재시도·멱등키, 장애 폴백 안내, 상태 모니터링 |
| 마이그레이션 중 SEO 유실(URL 변경) | 유입 급감 | 슬러그--UUID + 301 매핑, canonical/JSON-LD, productOld 제거 |
| 디자이너·기획자 부재 | 품질·속도 저하 | 본 기획서 + AI 에이전트 병렬 분배(13장), 단일 디자인시스템 토큰화 |
| 세액공제·30%룰·한도 법령 개정 | 계산 오류·규정 위반 | D7 룰 엔진 파라미터화, 답례품 가격이 최소 기부금 결정 로직 분리 |
현 자산은 3개 도메인으로 찢어진 구조다: 놀고팜(nolgofarm.com, 예약), 아이러브고향(ilovegohyang.nolgofarm.com, 기부), AI추천(ilovegohyangai.org). 사용자는 기부와 체험을 오가며 도메인·세션·장바구니가 모두 끊긴다. Phase2 평가(총 100점)에서 놀고팜 40.2점, 아이러브고향 34.2점으로, 통합 1위 웰로(85.1)·기부깊이 1위 위기브(76.6)에 압도적으로 뒤진다.
| 가중 항목(배점) | 놀고팜 | 아이러브고향 | 벤치마크 최고 | 통합 목표 |
|---|---|---|---|---|
| 정보구조·통합 (20) | 분산 3도메인 | 기부 떠넘김 | 웰로 88 | 88+ |
| 기부 깊이 (20) | 없음 | 얕은 목록 | 위기브 95 | 90 |
| 디자인 (15) | 위계 붕괴 | 팝업존 placeholder | 웰로 | 85+ |
| 콘텐츠·리텐션 (15) | 재고만 | 빈약 | 웰로 | 80+ |
| 기술 (12) | jQuery·jsessionid | 서버세션 | 웰로 | 85+ |
| 모바일 (10) | 분기형 | 줌차단 | - | 88+ |
| 접근성 (8) | alt 누락 | 텍스트박힌 이미지 | - | 85+ |
| 총점 | 40.2 | 34.2 | 85.1 | 86.2 |
낮은 점수의 구체 근거: 캠핑 카탈로그 245페이지가 무가격·리뷰 0, 스토어에 productOld 잔존·0원 가격 노출, Pretendard 폰트 OTS 디코드 실패, 홈 '팝업존' placeholder가 라이브 노출, URL에 jsessionid/productOld 파라미터 노출, alt 다수 누락·h1 다중·canonical/JSON-LD 부재, 모바일 분기형(m. 별도)으로 줌 차단. 기부 측은 답례품 분류·필터·모금 현황·세액공제 계산이 전무하여 기부깊이 95점 위기브와 격차가 60점에 달한다.
| 차별 축 | 웰로/위기브 등 경쟁 | 액티부키(우리) |
|---|---|---|
| 답례품 형태 | 농수산물·상품권 위주 | 실물 농산물 + 농촌체험·숙박 바우처(놀고팜 실물재고 직결) |
| 예약-기부 연결 | 기부만, 체험 동선 없음 | 기부 답례품→바로결제 예약까지 단일 동선(복제 불가 USP) |
| 세액공제 | 텍스트 안내 | 10만 전액→16.5%·30%룰 실시간 계산 위젯 |
| 탐색 진입장벽 | 일부 로그인 요구 | 비로그인 전과정 탐색, 결제 직전만 본인확인 |
| 지표 | 정의 | 현재(가설) | 출시+3M | 출시+6M |
|---|---|---|---|---|
| 북극성: 통합 GMV/월 | 기부+예약 총 결제액 | - | 1.0억 | 2.0억 |
| 기부 전환율 | 기부 상세 방문→기부 완료 | ~1.5% | 3.5% | 5.0% |
| 예약 전환율 | 상품 방문→바로결제 완료 | ~2.0% | 3.0% | 4.0% |
| MAU | 월 활성 사용자 | - | 4만 | 8만 |
| 재방문율(4주) | 출석체크·커뮤니티 견인 | ~10% | 25% | 35% |
| 객단가(기부) | 기부 1건 평균액 | ~9만 | 11만 | 13만 |
| 객단가(예약) | 예약 1건 평균액 | ~6만 | 7만 | 8만 |
| 크로스 전환율 | 기부자→예약(또는 역) 동일 세션 | 0% | 8% | 15% |
| TTFB / CLS | 기술 품질(보조) | 측정불가 | <150ms | <100ms·CLS<0.1 |
| 영역 | MVP 포함 (In) | MVP 제외 (Out / 차기) |
|---|---|---|
| 도메인·구조 | 단일 도메인 1개, 통합 GNB/세션/장바구니/검색, 슬러그--UUID·canonical·JSON-LD | ilovegohyangai.org AI 도메인 폐기·301 리다이렉트만 |
| 기부 | 답례품 계층분류+다중필터, 지정기부 모금률/목표/참여N/사용처, 세액공제 위젯, 비로그인 탐색 | 기부 정기결제, 기업기부, 단체 매칭펀딩 |
| 예약·체험 | 체험6/숙소/캠핑5 카탈로그(가격·리뷰 정비), 바로결제 배지, 답례품-바우처 연결 | 단체예약 자동견적, 오디오가이드 신규제작 |
| 콘텐츠·리텐션 | 아티클(여행/지역/제도), 출석체크, 후기 커뮤니티 | 축제 애그리게이터·동네소식(2차), AI 개인화추천 |
| 연동 | 고향사랑e음 API(접수·본인확인·영수증), e음 연동 백엔드 재사용 | 243개 지자체 전체 입점(초기 5~10곳 파일럿) |
| 기술·디자인 | Next.js류 SPA, Pretendard Variable 단일 DS, 모바일퍼스트 반응형, ISMS-P급 보안 | 네이티브 앱, 다국어, PWA 푸시 |
jsessionid·서버세션·productOld·0원 가격을 마이그레이션 시 정리해야 하며, Pretendard OTS 디코드 실패를 Variable 폰트로 교체 전제.nolgofarm.com · ilovegohyang.nolgofarm.com · ilovegohyangai.org)와 분리된 세션/장바구니/검색을 단일 도메인 1개 · 단일 GNB · 단일 세션 · 단일 장바구니 · 단일 통합검색으로 합친다. '예약/기부/AI추천 3분할'을 폐기하고, AI 추천은 별도 사이트가 아니라 통합검색·홈 추천 레일의 기능으로 흡수한다. 모든 사용자 동선은 자사 도메인 안에서 끝난다(외부 떠넘김 0건).최상위 GNB는 홈 / 농촌여행 / 고향사랑기부 / 콘텐츠 / 우수체험관 / 단체예약 / 마이페이지 7개. 농촌여행(놀고팜 자산)과 고향사랑기부(아이러브고향 자산)를 형제 메뉴로 나란히 두되, 답례품과 농촌여행 상품은 동일 카드 컴포넌트 · 동일 장바구니를 공유한다.
actibooky.com (통합 단일 도메인 / lang=ko / 모바일퍼스트 단일 반응형)
│
├─ 홈 /
│ ├─ 히어로 + 전역 통합검색 바
│ ├─ 추천 레일(농촌여행·답례품·지정기부 혼합 / 구 AI추천 흡수)
│ ├─ 마감임박 지정기부 모금률 게이지
│ └─ 동네소식·축제 최신 피드
│
├─ 농촌여행 /trip
│ ├─ 체험 /trip/experience (6하위: 농사·수확 / 먹거리·요리 / 공예·만들기
│ │ / 동물·교감 / 자연·생태 / 전통·문화)
│ ├─ 숙소 /trip/stay (농가민박·펜션·한옥)
│ ├─ 캠핑 /trip/camping (오토캠핑·글램핑 / 245p 무가격 디렉터리 정상화)
│ └─ 편의시설 /trip/facility (주차·매점·체험장 부대시설)
│
├─ 고향사랑기부 /donation
│ ├─ 일반기부 /donation/general (지자체 243곳 선택 → 기부)
│ ├─ 지정기부 /donation/project (제8조의2 / 모금액·달성률%·목표·참여N명·사용처)
│ ├─ 답례품 /donation/gift (계층 분류코드 + 다중필터 / '농촌체험 바우처·숙박' USP)
│ └─ 세액공제 계산기 /donation/tax-calculator (10만 전액→16.5% / 30%룰 인터랙티브)
│
├─ 콘텐츠 /content
│ ├─ 아티클 /content/article (농촌여행·지역·제도 가이드)
│ ├─ 동네소식 /content/local-news (지자체·지역 발신 소식)
│ └─ 축제 /content/festival (축제 애그리게이터 / 일정·지역 필터)
│
├─ 우수체험관 /premium (인증 체험관 큐레이션 / 놀고팜 우수체험관 자산)
│
├─ 단체예약 /group (B2B 단체 견적·예약 / 놀고팜 단체예약 자산)
│
└─ 마이페이지 /my
├─ 주문·예약내역 /my/orders (농촌여행 예약 + 답례품 결제 통합)
├─ 기부내역·영수증 /my/donations (e음 연동 세액공제 영수증)
├─ 출석체크·포인트 /my/attendance
├─ 후기·찜 /my/reviews
└─ 설정·본인인증 /my/settings
전역 요소: 헤더(GNB + 통합검색 + 장바구니 + 로그인) / 푸터(지자체 입점 안내 · 사업자정보 · 약관). 로그인은 결제·기부 직전에만 요구하고, 그 외 전 화면은 비로그인 전과정 탐색을 허용한다.
기존 놀고팜·아이러브고향의 모든 메뉴를 통합 GNB 위치에 1:1로 흡수한다. 중복·플레이스홀더·외부 떠넘김은 폐기 또는 흡수한다.
| 출처 | 기존 메뉴 | 통합 위치 | 경로 | 처리 |
|---|---|---|---|---|
| 놀고팜 | 농촌체험(6하위) | 농촌여행 › 체험 | /trip/experience | 하위 6분류 유지 |
| 놀고팜 | 숙소 | 농촌여행 › 숙소 | /trip/stay | 이전 |
| 놀고팜 | 캠핑(5하위) | 농촌여행 › 캠핑 | /trip/camping | 무가격·0리뷰 정상화 후 이전 |
| 놀고팜 | 편의시설 | 농촌여행 › 편의시설 | /trip/facility | 이전 |
| 놀고팜 | 우수체험관 | 우수체험관(GNB) | /premium | 상위 승격 |
| 놀고팜 | 스토어(productOld·0원) | 고향사랑기부 › 답례품 / 체험상품으로 분해 | /donation/gift · /trip/* | productOld·0원 폐기, 카탈로그 재구성 |
| 놀고팜 | 단체예약 | 단체예약(GNB) | /group | 상위 승격 |
| 놀고팜 | 오디오가이드·치유관광 | 콘텐츠 › 아티클 / 체험 태그 | /content/article | 콘텐츠로 흡수 |
| 아이고 | 지자체별 기부 | 고향사랑기부 › 일반기부 | /donation/general | 이전 |
| 아이고 | 지정기부 | 고향사랑기부 › 지정기부 | /donation/project | 달성률·사용처 강화 |
| 아이고 | 답례품몰 | 고향사랑기부 › 답례품 | /donation/gift | 계층코드+다중필터로 재편 |
| 아이고 | (세액공제 안내 정적) | 고향사랑기부 › 세액공제 계산기 | /donation/tax-calculator | 정적→인터랙티브 위젯화 |
| 아이고 | 홈 '팝업존'(플레이스홀더) | 홈 추천 레일 | / | 플레이스홀더 제거, 실데이터 레일로 대체 |
| 아이고 | 커뮤니티·후기 | 콘텐츠 › 동네소식 / 마이 › 후기 | /content/local-news · /my/reviews | 분리 흡수 |
| AI도메인 | ilovegohyangai.org 전체 | 홈·통합검색 추천 기능 | / · /search | 3번째 도메인 폐기, 기능으로 흡수 |
| 공통 | 마이페이지·장바구니·세션 | 마이페이지 / 단일 세션 | /my | 2계정 통합, 단일 장바구니 |
도메인별 idx 파편화(놀고팜 상품 idx ↔ 아이고 답례품 idx ↔ 스토어 productOld)와 세션 누출(;jsessionid=)을 제거한다. 모든 상세 URL은 사람이 읽는 슬러그 + 전역 유일 UUID 조합으로 표준화한다.
패턴 /{섹션}/{카테고리}/{slug}--{uuid8}
예시 /trip/experience/yangpyeong-strawberry-farm--a1b2c3d4
/donation/gift/hongseong-hanwoo-set--9f8e7d6c
/donation/project/imsil-cheese-festival-fund--2b4c6e8a
규칙
1. uuid8 = 내부 ULID 앞 8자(전역 유일). slug 바뀌어도 uuid로 동일 리소스 식별.
2. canonical = 항상 slug--uuid 정규형 1개. slug 불일치/생략 접근은 301로 정규형 흡수.
/trip/experience/old-name--a1b2c3d4 → 301 → 정규 slug 버전
/trip/experience/a1b2c3d4 (slug 생략) → 301 → 정규형
3. 레거시 idx 매핑: /product.do?idx=1234;jsessionid=XX → 301 → /trip/.../slug--uuid
productOld·0원 상품은 410 Gone(검색 인덱스에서 제거).
4. 쿼리스트링은 필터/정렬 전용. jsessionid·트래킹 파라미터는 canonical에서 배제.
5. 페이지네이션·필터 조합 URL은 <link rel="canonical">로 1차 카테고리에 귀속.
| 항목 | 레거시(Before) | 통합(After) |
|---|---|---|
| 세션 | ;jsessionid=3F2A... URL 노출 | 쿠키 기반, URL에서 완전 제거 |
| 상품 식별 | 도메인별 idx 충돌 + productOld | 전역 ULID 단일 키 |
| 캐노니컬 | 중복 URL 난립, 미선언 | rel=canonical 1리소스 1정규형 |
| 구조화데이터 | 없음 | Product/Event/Article JSON-LD |
두 도메인이 각자 운영하던 카테고리를 단일 카테고리 마스터 트리로 통합하고, 답례품은 별도 계층 분류코드를 부여해 다중필터를 가능하게 한다.
카테고리 마스터 (category_id = 전역 ULID, parent_id로 트리)
TRIP
TRIP.EXP (체험) ─ AGRI / FOOD / CRAFT / ANIMAL / NATURE / TRADITION
TRIP.STAY (숙소) ─ MINBAK / PENSION / HANOK
TRIP.CAMP (캠핑) ─ AUTO / GLAMP / ...
DONATION
DON.GIFT (답례품) ─ 분류코드 GcccNN 예) G0101 한우·육류, G0203 쌀·잡곡,
G0305 가공·반찬, G0410 농촌체험바우처, G0411 숙박권
DON.PROJECT / DON.GENERAL
정규화 매핑 테이블 legacy_category_map
(source_domain, legacy_idx) → category_id (1:1, 이관 1회 배치)
답례품 분류코드 GcccNN는 지자체·가격·기부유형 필터와 직교(orthogonal)하게 결합되어 다중필터를 지원한다. USP 연결: G0410 농촌체험바우처·G0411 숙박권은 TRIP.EXP/STAY 실물재고와 외래키로 묶여, 답례품 카탈로그에서 놀고팜 실재고를 그대로 노출한다(복제 불가 단일 동선).
헤더 검색 바 1개로 농촌여행·답례품·지정기부·콘텐츠·축제를 동시 검색한다. 구 AI추천 도메인의 추천 로직을 검색 랭킹·연관추천으로 흡수한다.
/search?q=검색 결과는 외부로 보내지 않고 모두 자사 상세(slug--uuid)로 연결된다. 0건 결과 시 인접 지역·유사 분류코드를 추천해 이탈을 막는다.
레거시는 결정적 동선(기부 접수·답례품 구매·상세 안내)을 외부 사이트로 떠넘겨 통합·정보구조 점수를 깎였다. 통합 플랫폼은 법령상 공공 경유가 강제된 지점만 외부 시스템을 호출하고, 그 외 모든 탐색·선택·결제 준비는 자사 도메인에서 완결한다.
| 동선 | 레거시 처리 | 통합 처리 | 외부 호출 |
|---|---|---|---|
| 답례품 탐색·선택 | 외부몰/팝업 이동 | 자사 /donation/gift 완결 | 없음 |
| 세액공제 안내 | 정적 PDF·외부 링크 | 인터랙티브 계산위젯 내장 | 없음 |
| 지정기부 상세 | 외부 캠페인 페이지 | 모금률·사용처 자사 상세 | 없음 |
| 기부 접수·본인확인 | 고향사랑e음 전체 이동 | 자사에서 입력→결제 직전만 e음 API 경유 | 법령상 강제(최소화) |
| 세액공제 영수증 | 외부 조회 | /my/donations에 e음 영수증 임베드 | 공공 시스템 경유(임베드) |
| 코드 | 플로우 | 로그인 시점 | 결제·접수 경유 | 핵심 차별 |
|---|---|---|---|---|
| A | 일반기부(지자체→답례품) | 결제 직전 간편인증 1회 | e음 기부접수 | 세액공제 위젯 인라인 |
| B | 지정기부(캠페인) | 응원/기부 직전 | e음 기부접수(제8조의2) | 모금률 게이지·사용처 명세 |
| C | 답례품→농촌체험 바우처 | 결제 직전 | e음 + 놀고팜 예약 | 기부로 받은 바우처 예약 전환 |
| D | 농촌여행 바로결제 예약 | 결제 직전 | PG 직접 결제 | 실물재고·바로결제 배지 |
| E | 회원/소셜+간편인증+주소지 검증 | - | e음 본인확인 | 본인 주소지 외 기부 룰 자동 |
| F | 통합 장바구니/결제 | 결제 직전 | e음 + PG 분기 정산 | 기부+예약 1회 결제 |
핵심 발상: 답례품 선택이 곧 기부 행위다(답례품 가격이 최소 기부금을 결정, 기부액의 30% 이내 룰). 탐색 전 과정은 비로그인.
/donate/jeonnam-goheung[A 일반기부 시퀀스]
이용자 ──지자체선택──▶ 답례품카탈로그(비로그인)
└─선택=기부──▶ 상세/기부패널 ──▶ 세액공제 위젯(실시간 계산)
│
[결제 직전] 간편인증 ──▶ 주소지 검증
│ (본인 주소지면 차단)
▼
e음 API(기부접수·본인확인) ──▶ 결제 ──▶ 영수증/배송추적
| 이탈 지점 | 현 사이트(아이러브고향) | 개선 |
|---|---|---|
| 탐색 진입 | 로그인 후 탐색 가능(게이트) | 비로그인 전과정 탐색, 결제 직전 1회만 인증 |
| 세액공제 이해 | 정적 안내 텍스트 | 금액 입력 실시간 환급액 위젯 |
| 최소 기부금 혼란 | 불명확 | 답례품 가격→최소 기부액 자동 표기(30%룰) |
| 주소지 룰 | 결제 후 거절 | 인증 직후 즉시 판별·대체 지자체 추천 |
제8조의2(2024.2.20 신설) 기반. 위기브식 '기부 깊이'(달성률·참여자·사용처)를 도입해 정서적 몰입을 만든다.
[B 지정기부 시퀀스]
캠페인 리스트 ──▶ 상세(모금률 게이지: 6,200만/1억=62%, 참여 318명, D-14)
│ └─ 좌:스토리 / 우:응원+기부 패널
├─응원·기부──▶ [결제 직전] 간편인증·주소지검증
│ └──▶ e음 접수 ──▶ 영수증
└─완료 후 ──▶ 사용처 명세/집행 리포트 ──▶ 리텐션(알림·재방문)
일반 답례품(농산물)이 아닌 '농촌체험/숙박'을 답례품으로 선택하면, 받은 바우처가 놀고팜 실물재고·예약 시스템으로 직결된다. 두 자산(e음 + 놀고팜)을 결합한 단일 동선.
[C 답례품→바우처 시퀀스]
체험·숙박 답례품 ──선택=기부──▶ e음 접수 ──▶ 바우처 적립(마이페이지)
│
┌───────┘ (별도 결제 0원)
▼
놀고팜 예약 캘린더(날짜·인원) ──▶ 바우처 차감 ──▶ 예약확정
| 구분 | 경쟁/현 자산 | 통합 후 |
|---|---|---|
| 답례품 성격 | 농수산물 일회성 배송 | 체험·숙박 = 지역 재방문 유발 |
| 재고/예약 | 놀고팜 캠핑 245p 무가격·0리뷰 디렉터리 | 실물재고·바로결제·예약 캘린더 연동 |
| 복제 가능성 | 웰로/위기브 모방 가능 | 기부+예약 단일 동선은 복제 불가 |
기부와 무관한 순수 여행 예약 동선(놀고팜 자산). 일반 e커머스 예약 UX.
[D 바로결제 예약]
여행상품 ──▶ 상세(예약패널·바로결제 배지) ──▶ 날짜/인원
└──▶ [결제 직전] 로그인 ──▶ PG 결제 ──▶ 예약확정
productOld·0원가격·분기형 모바일 폐기 → 모바일퍼스트 단일 반응형회원가입은 탐색에 불필요(선택). 기부 결제 시에만 간편인증으로 본인확인·주소지 판별이 강제된다(개인만·본인 주소지 외 기부 법령).
| 검증 항목 | 근거 | 처리 |
|---|---|---|
| 개인 여부 | 법인 기부 불가 | 간편인증 = 개인만 통과 |
| 본인 주소지 외 | 거주지 지자체 기부 금지 | 동일 시 자동 차단 |
| 연 한도 | 2,000만원/년 | 누적·잔여 한도 노출 |
| 본인확인·영수증 | e음 공공시스템 경유 | API 위임, 자체 보관 최소화(ISMS-P) |
개선점: 현 사이트의 '가입 후 탐색' 게이트 제거 → 인증은 결제 직전 단 1회. 소셜 로그인으로 가입 마찰 최소화.
기부(e음)와 여행예약(PG)이 서로 다른 정산 경로를 갖지만, 장바구니·세션·결제 진입은 하나다. 결제 단계에서 항목 성격별로 분기 정산.
[F 통합 장바구니/결제]
단일 카트 ─┬─ 기부(답례품/바우처) ──▶ e음 접수 ──▶ 세액공제 영수증
├─ 여행 예약 ─────────────▶ PG 결제 ──▶ 예약확정
└─ [결제 직전] 간편인증·주소지·한도(기부 항목 있을 때만)
└──▶ 통합 주문내역(영수증+배송+예약 한 화면)
| 이탈 방지 포인트 | 현 사이트(2도메인+AI 3도메인) | 통합 후 |
|---|---|---|
| 카트 분리 | 예약·기부 별도 사이트·별도 카트 | 혼합 단일 장바구니 |
| 외부 떠넘김 | 도메인 간 이동·재로그인 | 떠넘김 0건, 단일 세션 |
| 결제 신뢰 | jsessionid·서버세션 노출 | jsessionid 제거, 모던 SPA·ISMS-P급 |
| 주문 추적 | 분산 | 기부 영수증+예약+배송 통합 내역 |
놀고팜의 정체성은 단순 예약사이트가 아니라 농촌 공급의 절대량을 트랜잭션으로 전환하는 수직형 마켓플레이스다. 야놀자·여기어때(도심/일반숙박 OTA)와 정면충돌하지 않고, 그들이 다루지 않는 체험·촌캉스·캠핑·특산품·단체·치유관광의 농촌 버티컬을 독점한다. 경쟁 기부 플랫폼(웰로·위기브)에는 이 실물 공급 자산이 아예 없다.
| 축 | 야놀자/여기어때 | 웰로/위기브 | 놀고팜(목표) |
|---|---|---|---|
| 주력 재고 | 도심 호텔·모텔·펜션 | 없음(기부 중개) | 농촌 체험·촌캉스·캠핑·특산품 |
| 거래 형태 | 실시간 예약 | 기부 정산 | 예약+커머스+기부 단일 장바구니 |
| 지역 밀착 | 낮음(전국 일반) | 지자체 계약 | 전북 기반·우수체험관·치유농업 |
| 차별 무기 | 규모·가격 | 세액공제 | 실물 공급 × 기부 답례품 양방향 |
포지셔닝 한 줄: "농촌의 모든 하루를 예약하고, 그 지역에 기부까지 잇는 곳."
실측 IA(체험 6하위·숙소 3유형·캠핑 5하위·편의시설·스토어 5카테고리·단체예약·치유관광·오디오가이드)는 공급 폭이 넓다. 그러나 거래로 닫히지 않는 5가지 누수가 트랜잭션 마켓의 발목을 잡는다.
| 증상(실측) | 본질 문제 | 마켓 영향 | 리뉴얼 해결 방향 |
|---|---|---|---|
| '전화문의' 배지가 '바로결제'와 혼재 | 상당수 SKU 온라인결제 불가 | 전환 누수·GMV 미집계 | 전 SKU 결제화 강제, 전화는 fallback만 |
| 평점 '0.0(0)' 만연 | 리뷰 미마이그레이션·거래량 적음 | 사회적 증거 0 → 구매 회피 | 리뷰 이관+예약후 리뷰 트리거 |
| 캠핑 245p 무가격·무리뷰 집계 | 고캠핑식 공공데이터 디렉터리 | 질적 신뢰 낮음 | 예약가능 캠핑 우선노출, 디렉터리는 분리 |
| 스토어 productOld·0원 가격 | 마이그레이션 미완 | 구매 불가 상품 노출 | 0원 SKU 비공개+가격 정합 검수 |
| 단체/치유/오디오 톤 이질 | 제3의 미니사이트 동선 | 세션·장바구니 분절 | 단일 도메인·세션·검색으로 통합 |
| 페르소나 | 핵심 니즈 | 진입 동선 | 전환 시나리오 | 객단가 가설 |
|---|---|---|---|---|
| P1. 촌캉스·캠핑 MZ 25-34, 수도권 커플 | 감성 숙소·글램핑, 인스타블한 하루 | 검색바(지역·날짜·인원)→촌캉스 PLP | 금요일밤 촌캉스 독채 검색→리뷰 4.6 확인→바로결제→체크아웃에서 인근 '딸기수확' 크로스셀 추가 | 15-25만원 (숙박+체험1) |
| P2. 가족 체험여행 35-45, 초등 자녀 | 아이 교육형 수확·생태체험, 안전·후기 | 아이콘 그리드→체험(영농-수확) | 주말 '고구마캐기' 4인 예약→오디오가이드 동반→특산품(정육·꿀) 장바구니 추가→리뷰 작성 쿠폰 | 8-15만원 (체험+특산품) |
| P3. 학교/기관 단체 교사·기관 담당, B2G/B2B | 30-200인 견적·세금계산서·일정조율 | 단체예약(액티부키 X 놀고팜) | 40명 농촌 1박2일 견적 요청→담당 배정→일정·식사·체험 패키지 확정→계약·정산 | 300-2,000만원 (단체 패키지) |
P1/P2는 셀프서비스 트랜잭션(전환율·객단가 중심), P3는 리드→견적→계약(리드전환·계약액 중심)으로 KPI 체계를 분리 운영한다.
| KPI | 정의 | 현 추정 | 6개월 | 12개월 | 왜 중요한가 |
|---|---|---|---|---|---|
| 예약 전환율 | 방문→예약완료 | 1% 미만(전화누수로 미집계) | 2.0% | 3.5% | 디렉터리→마켓 전환의 핵심 단일지표 |
| 온라인 결제 비율 | 전 예약 중 온라인결제 % | ~40%(전화 혼재) | 80% | 95% | '전화문의 누수' 제거 = 트랜잭션화 |
| 리뷰 보유율 | SKU 중 리뷰≥1 비율 | 낮음(0.0 만연) | 50% | 75% | 사회적 증거 = 전환의 선행지표 |
| 결제가능 공급자 수 | 온라인예약 활성 공급자 | 미상(디렉터리 다수) | 800 | 1,500 | 마켓 양면성-공급측 유동성 |
| 재방문율(90일) | 90일 내 재구매 고객 % | ~10% | 20% | 30% | OTA+커머스 LTV 기반 |
| 객단가(AOV) | 주문당 결제액 | ~6만원 | 9만원 | 12만원 | 장바구니 묶음(숙박+체험+특산품) |
| 0원/0평점 SKU 비율 | 전 SKU 중 결함 SKU | 높음 | 5% | 0% | 카탈로그 위생-마켓 신뢰의 하한선 |
| 단체 리드 전환율 | 견적요청→계약 | 미집계 | 25% | 35% | B2G/B2B 고객단가 매출축 |
근거: 일반 여행 OTA 전환율 2-4%대, 리뷰 보유 상품은 무리뷰 대비 전환이 수배 높음(사회적 증거 효과). 현 놀고팜은 전화문의·0평점·0원 SKU로 인해 전환의 분모(방문)는 크지만 분자(결제완료)가 새고 있어, 위 KPI는 '누수 봉쇄'만으로도 단기 달성 여지가 크다.
전제: 답례품 공급주체는 지자체이므로, 우리 체험을 답례품화하려면 지자체 입점 계약 + 고향사랑e음 상품 등록이 선행되어야 한다(전북 기반 우선 추진).
experienceCategoryIdx·accommodationCategoryIdx·facilityCategoryIdx·productCategoryIdx)로 카탈로그가 4갈래로 파편화되어, 통합 검색·교차필터·패키지 번들·기부 답례품 연결이 모두 불가능하다. 이를 단일 product 테이블 + product_type enum + 통합 category 트리 + 다대다 tag로 재설계해, 모든 SKU가 하나의 검색 인덱스와 하나의 장바구니를 공유하게 한다.모든 상품은 단일 product 엔티티로 통합하고, 종류는 product_type 한 컬럼으로 구분한다. 기존 도메인별 카테고리 idx는 통합 category_id(전역 유니크)로 1회 마이그레이션한다.
| product_type | 현행 경로 / 파편 idx | 거래 모델 | 예약/결제 단위 | 현재 SKU 신뢰 이슈 |
|---|---|---|---|---|
| EXPERIENCE 체험 | /user/experience · experienceCategoryIdx(1~5,20) | 실시간/요청 예약 | 날짜·시간·인원(회차) | 썸네일 AI슬롭, 평점 0.0(0) |
| STAY 숙소 | /user/accommodation · accommodationCategoryIdx(2,3,6) | 실시간 예약(1박 단위) | 체크인/아웃·객실·인원 | 객실 재고/달력 정비 필요 |
| CAMPING 캠핑 | /user/facility?facilityType=CAMPING · facilityCategoryIdx | 상당수 디렉터리(고캠핑 집계) | 사이트·박 단위 | 245P 가격·리뷰 無, 공공데이터 |
| AMENITY 편의시설 | /user/facility?facilityType=AMENITIES | 정보형(비거래 POI) | 예약 없음(지도·연락처) | 맛집·전통시장·휴양림·충전소 |
| GOODS 스토어 | /user/product · productCategoryIdx(1,2,5,6,7) | 실물 커머스(배송) | 수량·배송지 | productOld 잔존, 다수 0원 |
| PACKAGE 패키지/번들 | productCategoryIdx=7 (단일 SKU로 위장) | 구성품 묶음 예약 | 대표일자 + 구성품 일정 | 번들 구조 부재, 평면 상품화 |
| GROUP 단체 | /user/groupReservation (B2G/B2B) | 견적·요청(RFQ) | 희망일·인원·예산 | 톤 이질('액티부키 X 놀고팜') |
| AUDIO 오디오가이드 | /user/audio-guide | 무료/디지털 이용권 | 지역·코스 단위 | 동선 분리, 미니사이트화 |
| WELLNESS 치유관광 | /user/jbwellnesstour · 5FPI 설문 | 예약 + 진단 연계 | 프로그램·회차 | 전북 한정, AI엔진 결합 |
모든 타입이 공유하는 core 컬럼은 단일 카드 시스템·검색 인덱스의 최소 계약이다. 타입별 속성은 product_attribute(product_id, key, value) EAV 또는 타입별 확장 테이블로 분리한다.
| 구분 | 필드 | 모든 타입 공통? | 비고 |
|---|---|---|---|
| 공통(core) | id, slug, title, product_type | O | slug = SEO/canonical 키 |
summary, hero_image, gallery[] | O | alt 필수(현 47% 누락 해결) | |
region_code(시도/시군구/읍면) | O | 법정동코드 기반, 지역 패싯 | |
provider_id | O | 우수체험관/입점사 FK | |
category_id | O | 통합 트리 단일 참조 | |
tags[] | O | 테마·계절·반려·접근성 | |
price_from, price_unit, currency | O | 0원 금지 검증, '가격문의' 별도 플래그 | |
fulfillment = INSTANT/REQUEST/INFO/SHIP | O | '바로결제'vs'전화문의' 누수 차단 핵심 | |
rating_avg, rating_count, status | O | 리뷰 마이그레이션 후 노출 | |
| EXPERIENCE | duration_min, session_times[], min/max_pax, indoor/outdoor | X | 회차·소요시간 |
| STAY | room_types[], checkin/out, bed_config, amenities[] | X | 객실 재고 달력 |
| CAMPING | site_type(글램핑/카라반/오토), pad_size, power, pet_zone | X | 사이트 단위 재고 |
| GOODS | sku_options[], weight, ship_fee, origin, storage(냉장/냉동) | X | 정육·특산품 콜드체인 |
| PACKAGE | components[](FK→product), bundle_price, savings | X | §5 번들 모델 |
| GROUP | rfq_form, capacity_range, budget_range, lead_days | X | 견적 워크플로 |
| WELLNESS | 5fpi_link, program_weeks, therapy_type | X | 치유농업 AI엔진 연계 |
도메인 분리가 아니라 이용 의도(여행 동사) 기준 1뎁스 + 타입 기준 2뎁스로 통합한다. 괄호는 현행 idx 매핑.
농촌여행 카탈로그 (root)
├─ 체험하기 (EXPERIENCE)
│ ├─ 영농·수확 ← experienceCategoryIdx=1
│ ├─ 자연·생태 ← 2
│ ├─ 문화·예술 ← 3
│ ├─ 힐링·레포츠 ← 4
│ ├─ 공예·요리 ← 5
│ └─ 기타 체험 ← 20
├─ 머무르기 (STAY)
│ ├─ 빌라형 ← accommodationCategoryIdx=2
│ ├─ 독채형 ← 3
│ └─ 촌캉스 ← 6
├─ 캠핑하기 (CAMPING)
│ ├─ 캠핑장 / 글램핑 / 카라반 / 야영장 / 수련원 / 기타 ← facilityCategoryIdx
├─ 둘러보기 (AMENITY · 비거래 POI)
│ ├─ 향토음식맛집 / 전통시장 / 휴양림 / 전기차충전소
├─ 사가기 (GOODS)
│ ├─ 특산품(1) / 기념품(2) / 정육(5) / 체험키트(6)
├─ 묶음여행 (PACKAGE) ← productCategoryIdx=7 재구조화
│ ├─ 체험+숙소 / 체험+특산품 / 가족형 / 당일형
├─ 단체로 (GROUP · RFQ)
│ ├─ 학교·교육 / 기업·모임 / 지자체 B2G
└─ 특화 (SPECIAL)
├─ 오디오가이드 (AUDIO)
└─ 치유관광·치유농업 (WELLNESS, 전북)
카테고리(1개 선택)와 직교하는 다대다 태그. 패싯 UI 필터 = DB 태그 namespace를 그대로 노출해 IA-검색 불일치(현 데스크탑 검색바 vs 모바일 아이콘 그리드)를 제거한다.
| 패싯(namespace) | 값 예시 | 적용 타입 | UI 컨트롤 |
|---|---|---|---|
| 지역 region | 경북·경산 / 전북·완주 / 전남·담양 | 전 타입 | 시도→시군구 드릴다운 |
| 테마 theme | 수확체험·딸기 / 만들기 / 할로윈 / 반려동반 / 가족 | 전 타입 | 칩 다중선택 |
| 인원 party | 1~2인 / 가족(3~5) / 소그룹(6~15) / 단체(16+) | 체험·숙소·캠핑·단체 | 인원 스텝퍼(검색바 연동) |
| 계절 season | 봄 / 여름 / 가을(수확 성수) / 겨울(촌캉스) | 체험·캠핑·패키지 | 토글 |
| 반려동물 pet | 동반가능 / 전용존 / 불가 | 숙소·캠핑·체험 | boolean |
| 접근성 a11y | 휠체어 / 무장애 / 주차 / 대중교통 | 전 타입 | boolean 그룹 |
| 이행 fulfillment | 바로결제(INSTANT) | / 가격·전화문의(REQUEST) | 거래 신뢰 정렬 가중치 |
패키지는 별도 상품 타입이 아니라 구성품을 참조하는 컨테이너 product. 구성품 가격 합 대비 절감액을 표기하고, 예약 시 자식 SKU의 재고를 동시 점유한다.
PRODUCT (type=PACKAGE) "완주 1박2일 딸기수확+촌캉스"
├─ bundle_price = 89,000 list_sum = 105,000 savings = 16,000
└─ PACKAGE_COMPONENT (다대다, 순서/필수여부)
├─ #1 EXPERIENCE 딸기수확체험(2인) required day=1
├─ #2 STAY 촌캉스 독채 1박 required day=1
└─ #3 GOODS 딸기잼 키트 optional add-on
예약 트랜잭션:
PACKAGE 결제 → child별 inventory_hold 발급 →
EXPERIENCE 회차 슬롯 -2, STAY 객실달력 -1박 →
하나라도 실패 시 전체 롤백(원자적)
/user/farm/excellentCompanyList의 업체 마스터를 provider로 승격해 모든 product가 단일 공급자 FK를 갖게 한다. 공급자는 PLP/PDP 신뢰 단위이자 정산·기부 답례품 입점 계약의 주체다.
PROVIDER (우수체험관/입점사)
id, name, region_code, biz_no,
is_verified(우수체험관 인증), payout_account,
donation_contract(지자체 답례품 계약 여부)
│ 1
│
│ N
PRODUCT (type ∈ 8종)
│ 0..N │ 0..N
PACKAGE_COMPONENT DONATION_REWARD_LINK
(번들 구성, §5) (체험/숙박권 → 답례품, 30%한도)
│
ORDER_ITEM ── ORDER ── REVIEW(rating_avg 집계 역연결)
| 관계 | 카디널리티 | 핵심 규칙 |
|---|---|---|
| provider → product | 1:N | 모든 SKU는 공급자 1개 필수, 미인증 공급자 상품은 검색 가중치 하향 |
| provider.is_verified | flag | 우수체험관 인증 = PDP 신뢰 배지 + 정렬 우대 |
| product ↔ tag | N:M | 패싯 검색 인덱스 소스 |
| product → donation_reward | 1:0..N | 기부 답례품화: 지자체 계약 + 기부액 30% 이내 + 서비스·체험 이용권 등록 |
4개 도메인 검색을 하나의 인덱스(예: products 컬렉션)로 통합. 홈 검색바의 지역·날짜·인원 3축이 그대로 패싯 쿼리 파라미터가 되어 데스크탑/모바일 멘탈모델을 일치시킨다.
product_type+통합 category+다대다 tag 단일 모델. 체험·숙소·캠핑·스토어가 한 검색바·한 장바구니·한 카드 시스템을 공유하고, 패키지 번들과 기부 답례품 연결(체험 바우처/숙박권)이 같은 product 그래프 위에서 성립한다.4개 도메인은 재고 단위(inventory unit)와 시간 단위(time grain)가 다르다. 엔진은 공통 Bookable 추상 위에 타입별 어댑터를 둔다.
| 타입 | 예약 단위 | 재고 키 | 가격 축 | 예시(놀고팜 실측) | 모드 |
|---|---|---|---|---|---|
| 체험 | 날짜 + 회차(슬롯) + 인원 | (상품, 날짜, 회차)별 잔여정원 | 성인/아동/단체, 주중/주말 | 경산 포도수확 체험 10:00·14:00 회차, 회당 정원 20 | 실시간확정 |
| 숙소 | 날짜범위(체크인~아웃) + 객실 | (객실타입, 1박 날짜)별 잔여 수 | 객실타입, 비수기/성수기, 주중/주말, 인원 추가 | 촌캉스 독채 1동, 8/1~8/3 (2박) | 실시간확정 |
| 캠핑 | 날짜범위 + 사이트(구획) | (사이트, 1박 날짜)별 점유 0/1 | 사이트등급(글램핑·카라반·오토), 성수기, 입실인원 | 글램핑 A-3 사이트, 8/15~8/16 | 실시간확정 / 일부 요청형 |
| 패키지 | 복합(체험+숙소+스토어 묶음) | 구성요소 재고의 AND 홀딩 | 묶음가(할인) 또는 구성요소 합산 | '1박2일 포도밭 가족' = 독채1박 + 수확체험2인 + 특산품 | 복합(전구성 홀딩) |
편의시설/우수체험관/스토어 productOld(0원)는 예약 대상이 아니거나 마이그레이션 미완이다. 스토어 실물상품은 별도 Orderable(배송형)로 분리하되 동일 결제·정산 인프라를 공유한다.
[Bookable] (추상) ├─ ExperienceBookable slot_grain = 회차(시각) stock = capacity-기반 ├─ StayBookable range_grain = 1박(날짜) stock = room_count-기반 ├─ CampingBookable range_grain = 1박(날짜) stock = site 0/1 점유 └─ PackageBookable composite[*Bookable] stock = 구성요소 AND [Orderable] (배송형, 재고 stock_qty) ← 스토어 특산품/정육/키트
supplier(공급자: 우수체험관/숙소주/캠핑장)
└─< product(상품, type, booking_mode, supplier_id)
├─< rate_plan(요금제: 성인/아동/객실타입/사이트등급, base_price)
│ └─< price_calendar(rate_plan_id, date, weekday_kind,
│ season, price, override)
├─< inventory_unit(객실/사이트/회차정의)
│ └─< availability(unit_id, date|slot, total, sold, held, blocked)
└─< option(옵션: BBQ세트/이불추가/장비대여, price, max_qty)
hold(가심사/홀딩: cart_id, availability_id, qty, status, expires_at) ← TTL 10분
└─1:1─ booking(주문: status, mode, total, voucher_id, payment_id)
└─< booking_item(product_id, unit, qty, unit_price, option_json)
└─1:1─ payment(pg, method, amount, status, pg_tid, refund_json)
└─< voucher(code, qr_payload, status, redeemed_at, redeemer)
settlement(정산: supplier_id, period, gross, fee, net, status)
└─< settlement_line(booking_id, gross, fee_rate, net)
availability(total, sold, held, blocked). 잔여 = total - sold - held - blocked. 체험은 회차당 total=정원, 숙소·캠핑은 1박 날짜당 total=객실수/사이트 1.blocked=total(노출만, 예약불가)로 등록 후 계약 완료 사이트부터 점진 개방.| 축 | 규칙 | 예시 |
|---|---|---|
| 인원 구분 | 성인/아동/유아, 구분별 단가 | 수확체험 성인 18,000 / 아동 12,000 / 36개월↓ 무료 |
| 주중/주말 | weekday_kind = 주중/금/주말, 캘린더 override | 독채 주중 150,000 / 금·토 220,000 |
| 비수기/성수기 | season 구간 테이블(지자체·상품별) | 7/15~8/15 성수기 +40% |
| 옵션 | 수량 가산, max_qty 제한, 재고 연동 가능 | BBQ세트 +25,000(최대1), 이불추가 +10,000/매 |
| 단체할인 | 인원 임계 자동 할인(단체예약 동선과 연결) | 20인 이상 1인당 -2,000(B2G/학교 단체) |
가격 계산은 서버 권위(server-authoritative). 클라이언트 표시가는 참고용이며, 홀딩·결제 시점에 price_calendar 재조회로 재계산해 가격 변조를 차단한다.
held += qty, expires_at = now+10분held -= qty 회수UPDATE ... SET held=held+:q WHERE total-sold-held-blocked >= :q 단일 원자 쿼리| 모드 | 흐름 | 적용 SKU | SLA |
|---|---|---|---|
| 실시간확정 | 홀딩 → 결제 → 즉시 확정 → 바우처 발급 | 재고 정형화된 숙소·캠핑·정원형 체험(기존 '바로결제') | 즉시 |
| 온라인 예약요청(승인형) | 홀딩 → 가결제(승인·미청구) → 공급자 승인 → 본청구·확정 / 거절 시 자동 취소·승인취소 | 일정 조율 필요·비정형 체험·일부 캠핑(기존 '전화문의') | 공급자 응답 24시간, 초과 시 자동취소+안내 |
'전화문의' 배지는 전량 제거하고 위 2모드로 매핑한다. 승인형도 통화 없이 사이트 내에서 가결제(PG 승인 후 capture 보류)로 처리해 통화 누수와 노쇼를 동시에 줄인다.
PaymentGateway 인터페이스: authorize/capture/cancel/partialRefund). 바이바로를 1차 어댑터로 두고 신규 간편결제를 동일 인터페이스로 추가해, SKU별 결제수단 차이를 엔진 상위에서 흡수.payment.status 전이만 허용(승인→매입→취소/부분환불).| 도메인 | 이용일 기준 취소 시점 | 환불율 | 노쇼 |
|---|---|---|---|
| 체험 | 7일 전까지 | 100% | 환불 0% |
| 체험 | 3~6일 전 | 70% | - |
| 체험 | 1~2일 전 / 당일 | 50% / 0% | 0% |
| 숙소·캠핑 | 5일 전까지 | 100% | 0% |
| 숙소·캠핑(성수기) | 5일 전까지 | 90% (성수기 가중) | 0% |
| 숙소·캠핑 | 2~4일 전 / 1일·당일 | 50% / 0% | 0% |
| 패키지 | 구성요소 중 가장 엄격한 정책 적용 | 최소 환불율 채택 | 0% |
부분환불: 인원 일부 취소(체험 4인 중 1인 취소)는 해당 인원 단가만 환불, 옵션은 옵션 정책 따름. 천재지변·공급자 귀책 취소는 정책 무관 100% + 패널티 면제(예외 플래그).
| 항목 | 정책 |
|---|---|
| 정산 주기 | 월 2회 (1~15일 이용분 → 익월 10일 / 16~말일 → 익월 25일), 이용완료(바우처 사용 또는 체크아웃) 건만 정산 대상 |
| 수수료 | 거래액 기준 플랫폼 수수료 8% (PG수수료 별도 차감), 단체예약 협의율 |
| 홀드백 | 환불·분쟁 대비 5%를 60일 보류 후 지급 |
| 정산 단위 | settlement_line(booking 단위 gross/fee/net) → 공급자별 settlement 집계, 명세서 발행 |
| 기부 바우처 | 바우처 결제건은 지자체 청구분과 분리 정산(공급주체=지자체 계약 기준) |
voucher.code(영숫자 12자) + 서명된 QR payload(booking_id·item·만료·HMAC) 발급. 1예약 다인원은 인원 수만큼 또는 단일 다회 사용 바우처 중 상품설정 따름.redeemed_at 기록(중복사용 차단). 오프라인 대비 코드 수기 입력 폴백.사용자 프론트(SPA) 예약엔진 재고DB PG(바이바로/간편) 공급자 │ 날짜·인원 선택 │ │ │ │ │ │──────────────>│ getAvailability──────────>│ 잔여 조회 │ │ │ │<─────────────캐시/DB 그리드─│ │ │ │ '예약' 클릭 │ │ │ │ │ │──────────────>│ createHold ─>│ UPDATE held+ WHERE 잔여>=q (원자) │ │ │ │<──ok/매진────│ │ │ │ │<─hold(TTL10m)─│ │ │ │ │ 결제수단 선택 │ confirmPrice >│ price_calendar 재계산(서버권위) │ │──────────────>│ pay ────────>│ authorize ─────────────────>│ │ │ │ │<──auth_ok(승인,Idempotency)─│ │ │ ┌─────────[ 실시간확정 ]──────────────────────────────────────────┐ │ │ │ │ capture ───────────────────>│ 매입 │ │ │ │ │ │ sold+=q, held-=q 바우처·QR 발급 │ │ │ │<─확정/바우처/QR──────────────────────────────────────────────────┘ │ │ └─────────[ 승인형(예약요청) ]───────────────────────────────────┐ │ │ │ notify ───────────────────────────────────────────>│승인/거절 │ │ 24h 내 승인 ─> capture·확정·바우처발급 │ │ │ │ 거절/타임아웃 ─> auth취소·held회수·안내 │<──┘ │ 현장 도착 │ QR 스캔(공급자) ─> verify(HMAC·상태) ─> redeemed_at │ │ (취소 시) │ cancel ─> 정책표 환불율 계산 ─> partialRefund/cancel ─>PG │
홀딩 TTL 만료·승인 타임아웃·결제 콜백 중복은 모두 스케줄러+멱등키로 자기치유(self-healing)하며, 어떤 경로에서도 오버부킹과 미회수 재고가 남지 않도록 재고 차감(held/sold)과 결제 상태를 단일 트랜잭션 경계 안에서 정합 유지한다.
| 지점 | 현재 상태 | 문제 | 목표 |
|---|---|---|---|
| 데스크탑 홈 | 지역/날짜/인원 검색바 | 카테고리·테마 패싯 없음, 결과가 카테고리별 분절 페이지로 흩어짐 | 5축 통합검색 1개 |
| 모바일 홈 | 아이콘 10개 그리드 | 검색바와 멘탈모델 불일치 - 같은 서비스가 기기마다 다르게 보임 | 동일 검색바 + 확장 패싯 |
| 결과 정렬 | 없음(기본 노출순) | 인기·거리·가격·평점으로 못 거름 | 4종 정렬 + 패싯 |
| 지도 | 없음 | "내 주변 농촌체험" 탐색 불가 | 지도-리스트 동기 탐색 |
| 자동완성 | 핫키워드 5개(경북·경산·만들기·할로윈·대구)만 정적 노출 | 오타·동의어·지역명 매칭 없음 | 자동완성 + 동적 핫키워드 |
| SEO 진입 | jsessionid URL, 프로그래매틱 랜딩 없음 | "경북 딸기따기" 검색 유입 0 | 지역×테마 랜딩 자동생성 |
| AI 추천 | 5FPI 치유 설문(별도 미니사이트) | 동선 이질적, 결과→예약 연결 끊김 | 통합 챗봇으로 흡수 |
홈의 모바일 아이콘 그리드를 폐기하고, 데스크탑·모바일 모두 동일한 검색바를 최상단에 둔다. 검색바는 5개 축(지역·날짜·인원·카테고리·테마)을 갖되, 모바일은 탭하면 풀스크린 시트로 펼쳐진다. 카테고리 아이콘은 검색바 아래 "빠른 진입 칩"으로 격하되어 보조 역할만 한다.
[ 어디로?(지역) | 언제?(날짜) | 누구와?(인원) | 무엇을?(카테고리) | [돋보기] ]
└ 펼침: 테마 패싯(딸기·할로윈·촌캉스·치유 …)
─ 빠른칩 ─ #딸기따기 #촌캉스 #글램핑 #특산품 #치유관광 #단체
| 축 | 입력 방식 | 데이터 소스(현 IA) | 예시 값 |
|---|---|---|---|
| 지역 | 자동완성(시/도→시군구) | 전국 행정구역 + 공급 밀집지 | 경북 경산, 전북 임실, 전남 담양 |
| 날짜 | 캘린더(단일/범위) | SKU 예약가능일 | 2026-07-05 ~ 07-06 |
| 인원 | 스텝퍼(성인/아동) | SKU 정원 | 성인 2, 아동 2 |
| 카테고리 | 다중선택 칩 | experienceCategoryIdx 등 | 체험·숙소·캠핑·스토어 |
| 테마 | 패싯 다중선택 | 태그(신규 구축) | 수확체험·반려동물·우천가능 |
현 카테고리 IA를 그대로 패싯으로 매핑하고, 신뢰도 문제(0.0 평점·전화문의 누수)를 필터로 정면 해결한다.
| 패싯 그룹 | 값(현 IA 매핑) | 타입 | 비고 |
|---|---|---|---|
| 대분류 | 체험 / 숙소 / 캠핑 / 편의시설 / 스토어 / 단체 / 치유 | 단일 탭 | 탭 전환 시 하위 패싯 동적 교체 |
| 체험 하위 | 영농수확(1)·자연생태(2)·문화예술(3)·힐링레포츠(4)·공예요리(5)·기타(20) | 다중 | experienceCategoryIdx |
| 숙소 하위 | 빌라형(2)·독채형(3)·촌캉스(6) | 다중 | accommodationCategoryIdx |
| 캠핑 하위 | 캠핑장·글램핑·카라반·야영장·수련원·기타 | 다중 | facilityCategoryIdx |
| 예약 방식 | 바로결제만 / 전화문의 포함 | 토글 | 기본값=바로결제만 - 전화누수 SKU 숨겨 트랜잭션 마켓처럼 보이게 |
| 신뢰 필터 | 리뷰 있는 곳만 / 평점 4.0+ | 토글 | 0.0(0) SKU 기본 후순위 |
| 가격 | 0~10만원+ 슬라이더 | 범위 | 0원(productOld 미마이그)은 "가격문의"로 라벨링, 정렬 제외 |
| 편의 | 주차·반려동물·우천가능·휠체어·실내 | 다중 | 속성 태깅 신규 |
| 날짜/인원 | 검색바와 동기화 | - | 잔여 정원 있는 SKU만 |
| 정렬 | 키 | 로직 | 주의(실측 데이터) |
|---|---|---|---|
| 인기순(기본) | popularity | 최근 30일 예약수×0.6 + 조회×0.2 + 리뷰수×0.2 | 바로결제·리뷰보유 SKU 자동 상위 - 디렉터리식 SKU 격하 |
| 거리순 | distance | 사용자 위치/지정지점 기준 haversine | 지도 탭과 공유 |
| 가격순 | price_asc | 실결제가 오름차순 | 0원/가격문의 SKU는 정렬 대상서 제외(맨 뒤 고정) |
| 평점순 | rating | 베이지안 평균(C=3.8, m=5) - 리뷰 적은 곳 과대평가 방지 | 0.0(0)은 "신규"로 라벨, 평점순서 제외 |
베이지안 평점: score = (m*C + n*avg) / (m + n) (m=가중 표본 5, C=전체평균 3.8). 리뷰 0개 SKU가 "평점 5.0"으로 왜곡 상위 노출되는 사고를 막는다.
리스트-지도 50:50 분할(데스크탑) / 리스트 상단 "지도로 보기" 토글(모바일). 지도 이동 시 뷰포트 내 결과만 동기 갱신("이 지역 재검색" 버튼). 캠핑 245p 공공데이터식 디렉터리가 오히려 지도에선 밀도 자산으로 전환된다.
시퀀스: 지도 탐색
사용자 → 지도 pan/zoom
→ viewport bbox(좌표) 전송
검색API → bbox 내 SKU + 클러스터(핀 묶음) 반환
프론트 → 핀 hover시 미니카드(썸네일·가격·평점·바로결제배지)
→ 핀 클릭 → 좌측 리스트 해당 카드로 스크롤+하이라이트
사용자 → "이 지역 재검색" → 패싯 유지한 채 bbox만 갱신
| 기능 | 동작 | 예시 |
|---|---|---|
| 자동완성 | 지역·SKU명·테마·우수체험관명 통합 제안(타입 표시) | "경산" → 지역 경북 경산 / 체험 경산 포도따기 / 업체 경산○○농원 |
| 오타·동의어 | 초성·동의어 사전 | "ㄸㄱ"→딸기, "촌캉스"="농촌+바캉스"=독채숙소 |
| 핫키워드(동적) | 현 정적 5개(경북·경산·만들기·할로윈·대구)를 실시간 검색량 기반으로 교체 + 시즌 큐레이션 | 6월: 매실·블루베리 / 10월: 할로윈·고구마 / 12월: 촌캉스·귤따기 |
| 최근/인기 | 최근 검색어 + 지역 인기 테마 | "임실 치즈체험" 재검색 1탭 |
현 jsessionid URL·canonical 부재로 검색유입이 0에 가깝다. "지역 × 테마" 조합을 정적 랜딩으로 자동 생성하여 롱테일 유입을 확보한다.
URL 설계
/travel/{지역} → 경북 농촌여행 (허브)
/travel/{지역}/{테마} → /travel/gyeongbuk/strawberry
/travel/theme/{테마} → 전국 딸기따기 체험
/stay/{지역}/{숙소유형} → /stay/jeonbuk/chonkangseu
페이지 = 통합검색의 프리필터된 결과 + 지역/테마 카피 + JSON-LD
| 요소 | 처리 |
|---|---|
| 제목 | 경북 경산 딸기따기 체험 예약 | 놀고팜 |
| JSON-LD | Product·Offer·AggregateRating·LocalBusiness·BreadcrumbList |
| canonical | 패싯 조합 정규화(정렬 파라미터 제외), self-canonical |
| 본문 | 지역 소개 + 대표 SKU 6개 + FAQ(JSON-LD FAQPage) + 내부링크(인접 지역/테마) |
| 생성 규모 | (공급 밀집 시군구 ~80) × (테마 ~12) = 약 900p 자동생성, 결과 0건 조합은 noindex |
웰로 매칭봇의 약점은 입력 affordance 부재(무엇을 말해야 할지 모름)다. 우리는 자유 텍스트가 아니라 구조화된 입력 칩(예산·일정·동행·관심)을 먼저 제시하고, 그 위에 자유 대화를 얹는다. 결과는 추상 추천이 아니라 예약 가능한 실물 SKU 카드로 끝난다(검색·재고와 직결). 5FPI 치유농업 설문 엔진을 이 챗봇의 "치유 모드"로 흡수한다.
대화→예약 시퀀스
1) 진입: "AI 여행 플래너" (칩 4종 먼저 노출, 자유입력은 보조)
2) 사용자: [가족·아동] [1박2일] [~20만] [수확] + "경북에서 딸기"
3) 봇: 의도 파싱 → 통합검색 API 호출(지역=경북, 테마=딸기·수확, 인원=가족, 박=1, 예산필터)
4) 봇: 일정 제안
· 오전: 경산○○농원 딸기따기(성인 1.5만, ★4.6, 바로결제)
· 오후: 임실 치즈만들기(2만, ★4.4)
· 숙박: 촌캉스 독채(12만, ★4.7)
· 답례품 크로스셀: "이 지역 고향사랑기부 시 딸기잼 답례품" (USP)
5) 사용자: "딸기 말고 포도" → 봇: 해당 항목만 교체(재검색)
6) "전체 장바구니 담기" → 통합 결제(단일 세션/장바구니)
| 항목 | 웰로 매칭봇 | 놀고팜 AI 플래너 |
|---|---|---|
| 입력 | 자유 텍스트(막막함) | 칩 4종 우선 + 자유입력 보조 |
| 출력 | 기부 사업 매칭(추상) | 예약가능 실물 SKU 일정표 |
| 전환 | 결과→행동 단절 | 장바구니 1탭 → 통합결제 |
| 자산 | - | 5FPI 치유엔진 + 실물 공급 흡수 |
| 크로스셀 | - | 고향사랑기부 답례품 동선 연결 |
SearchableItem(통합 인덱스)
├─ id, type(체험|숙소|캠핑|편의|스토어|치유)
├─ title, thumb, region_sido, region_sigungu, geo(lat,lng)
├─ category_idx(원 IA 키), theme_tags[](신규)
├─ price, price_type(바로결제|전화|가격문의) ← 누수 SKU 식별
├─ rating_avg, rating_count(0이면 신규 라벨)
├─ amenities[](주차·반려·우천·실내)
├─ available_dates[], capacity
└─ donation_linked(bool) ← 답례품 USP 플래그
│
▼ 색인(검색엔진: 자동완성·패싯·지오·정렬)
SearchQuery{region,date,pax,categories[],themes[],facets,sort,bbox}
│
▼
AIPlannerSession{budget,nights,companion,interests[],messages[]}
└─ 동일 SearchQuery로 변환 → 동일 결과 파이프라인 재사용
핵심: AI 챗봇·지도·PLP·SEO 랜딩이 모두 하나의 SearchQuery → SearchableItem 인덱스를 공유한다. 별도 미니사이트(치유·단체·오디오)도 같은 인덱스에 type만 다르게 적재하여 톤·동선 이질감을 제거한다.
원칙: 실제 예약/구매 완료 건만 리뷰 가능(verified purchase only). 별점은 거래 데이터와 1:1로 묶이며, 미거래 SKU에는 별점 위젯 대신 대체 신뢰 신호를 노출한다. 가짜 '0.0' 표기를 화면에서 영구 추방한다.
| 현 문제(실측) | 해결책 | 노출 정책 |
|---|---|---|
| '0.0(0)' 만연 - 사회적 증거 0 | 리뷰 0건이면 별점 위젯 자체를 렌더링하지 않음. 대신 '신규 등록' / '예약 N건' / 인증 배지 노출 | 별점=null → 리뷰 준비중 칩 + 우수체험관 인증 배지 우선 |
| 전화문의로 거래 누수, 리뷰 수집 불가 | 전화 SKU도 '예약확정 후 SMS 리뷰요청'으로 verified 리뷰 수집(콜→예약대장 매칭) | 전화 SKU는 별점 대신 전화예약 배지 + 후기 텍스트만 |
| 캠핑 245p 공공데이터식 무가격·무리뷰 디렉터리 | 고캠핑 집계분은 외부정보 라벨 분리, 자체 예약가능분만 별점·가격 노출 | 외부집계 카드엔 별점 미표기 + '공식 예약 연결 예정' 표기 |
| 리뷰 데이터 미마이그레이션 | 초기 부트스트랩: 운영진 모니터링 체험 후기 + 우수체험관 기존 방문객 SMS 회수 캠페인(인당 3천원 적립) | 시드 리뷰는 체험단 라벨 명시(자연 리뷰와 구분) |
공급 주체는 우수체험관/농가/캠핑장/스토어 셀러. 공급자 어드민에서 상품등록-재고-캘린더-정산-문의를 한 곳에서 처리한다. 단체예약(B2G/B2B)은 별도 견적·계약 워크플로로 분리한다.
| 단계 | 내용 | 검증/SLA |
|---|---|---|
| 1. 가입신청 | 사업자번호·농가구분·계좌·정산담당 | 사업자 진위 API(국세청), 1영업일 |
| 2. 자격심사 | 우수체험관 지정서/보험가입증/시설사진 | 운영진 수동 심사, 2~3영업일 |
| 3. 상품등록 | 카테고리·가격·정원·소요시간·환불규정·사진(통일 16:9 카드) | 슬롭 배너 반려, 가이드 템플릿 강제 |
| 4. 결제연동 | PG 하위몰 등록(에스크로), 정산계좌 검증 | '바로결제' 전환 - 전화누수 차단 |
| 5. 오픈 | NEW 배지 90일, 노출 가중치 부여 | 첫 거래 후 리뷰요청 자동화 |
| 항목 | 정책 | 비고 |
|---|---|---|
| 정산주기 | 이용완료일 기준 주정산(매주 수요일) / 신규 90일은 격주 | 이용일+환불기간(7일) 경과분만 |
| 플랫폼 수수료 | 체험/숙소/캠핑 8~12%, 스토어 10~15%, 단체예약 협의(5~8%) | 우수체험관/BEST 등급 -2%p 우대 |
| PG·결제대행 | 카드 약 2.0~2.8% 별도 차감 | 에스크로 거래 |
| 세금 | 공급가/부가세 분리, 간이·면세 농가 구분, 사업소득 3.3% 원천(개인) | 전자세금계산서 자동발행 |
| 기부 답례품 연계 | 지자체 계약 SKU는 지자체 정산 라인 별도(공급주체=지자체) | 답례품 기부액 30% 한도 검증 |
정산 시퀀스 이용완료 → [환불대기 7일] → 정산확정 → 수수료·PG·원천 차감 → 주간배치(수) → 농가계좌 입금 → 세금계산서 발행 → 어드민 내역 반영
학교·기관·기업 단체(견학·워크숍·체험학습)는 즉시결제가 아닌 견적→문의→계약→정산 흐름. '액티부키 X 놀고팜' 톤을 메인 IA에 흡수하되 전용 동선 유지.
| 단계 | 고객(학교·기관) | 공급/운영 |
|---|---|---|
| 1. 문의 | 인원·날짜·예산·대상(초·중·고/기관) | 리드 자동 라우팅(지역·정원 매칭) |
| 2. 견적 | 맞춤 패키지 + 단가표 수신 | 다중 농가 묶음 견적, 버스·식사 옵션 |
| 3. 계약 | 전자계약서·공문(품의용 견적서 PDF) | 계약금/잔금 분할, 세금계산서 |
| 4. 운영 | 참가자 명단·안전동의 수합 | 인솔·보험·우천대안 관리 |
| 5. 정산/사후 | 잔금 결제·이용확인서 | 단체 전용 수수료 정산, 후기 회수 |
| 등급 | 기준 | 혜택 |
|---|---|---|
| BEST | 평점 4.5↑ · 리뷰 30↑ · 노쇼 2%↓ · 응답률 95%↑ | 수수료 -2%p, 상단노출 가중, BEST 배지 |
| 우수 | 평점 4.2↑ · 리뷰 10↑ · 취소율 5%↓ | 검색 가중 +, 격주→주정산 승격 |
| 일반 | 기본 운영 기준 충족 | 표준 정책 |
| 경고/제재 | 노쇼·취소·신고 누적, 평점 3.0↓ | 노출 하향, 재심사·노출중지 |
품질 점수(QS) = 평점(40%) + 응답률·속도(20%) + 정시이행/노쇼역(20%)
+ 리뷰량·사진비율(10%) + 인증·수상(10%)
현 productCategoryIdx 5종(특산품1/기념품2/정육5/체험키트6/패키지7)을 유지하되, '공급주체' 축(일반셀러 vs 농가직거래)과 '배송유형' 축을 직교(orthogonal) 속성으로 분리한다. 카테고리는 탐색용, 배송/공급은 SKU 속성용.
| 카테고리 | 대표 SKU 예시 | 기본 배송유형 | 옵션 축 | 0원/레거시 리스크 |
|---|---|---|---|---|
| 특산품(1) | 영주 사과 5kg, 의성 마늘 1접, 순창 고추장 2kg | 택배 / 산지직송 | 중량·수량·등급(특/상) | 높음 — productOld 다수 |
| 정육(5) | 횡성 한우 1+ 등심 300g, 양념 LA갈비 1kg | 신선냉장(콜드체인) | 부위·중량·냉장/냉동 | 높음 — 가격 변동성 큼 |
| 체험키트(6) | 치즈만들기 키트(2인), 메주 담그기 세트 | 택배 | 인원·구성품 | 중간 |
| 기념품(2) | 지역 굿즈, 전통주잔 세트, 오디오가이드 연계 엽서 | 택배 | 색상·구성 | 중간 |
| 패키지(7) | 특산품+체험바우처 묶음, 명절 선물세트 | 혼합(택배+바우처) | 구성 선택 | 높음 — 가상상품 혼재 |
| 농가직거래(축) | 우수체험관 농가가 직접 등록한 제철 농산물 | 산지직송 위주 | 예약수확·정기배송 | 신규 — 클린 데이터 |
레거시를 자동 노출 차단부터 한 뒤, SKU 단위로 분류·정상화·폐기한다. 0원은 미완 데이터이지 무료가 아니므로, 검수 전까지 결제 진입을 막는다.
[마이그레이션 파이프라인] productOld (레거시 N건) ├─ STEP0 분류: price==0 / 전화문의배지 / 이미지없음 / 평점0.0 플래그 ├─ STEP1 격리: status=DRAFT 강제, PLP/검색 색인 제외 (noindex) ├─ STEP2 매핑: old.fields → new SKU 스키마 (단위·중량·옵션 파싱) ├─ STEP3 가격검수: 0원 → 공급가 입력 필수 (셀러/MD 2단 승인) ├─ STEP4 승인: status=ACTIVE 전환 (이미지 alt·재고·배송정책 충족 시만) └─ STEP5 폐기: 90일 미검수 → ARCHIVED + 301 redirect(유사 SKU)
| 케이스 | 판정 규칙 | 처리 | 목표 |
|---|---|---|---|
| price=0 & 재고 있음 | 셀러 활성 + 단종 아님 | 가격 입력 요청 알림 → DRAFT 유지 | 정상화 후 복귀 |
| price=0 & 셀러 비활성 | 최근 180일 로그인/주문 없음 | ARCHIVED + 301 | 폐기 |
| '전화문의' 배지 SKU | 온라인 결제 미설정 | 결제설정 강제 온보딩 / 미설정 시 비노출 | 전화 누수 차단 |
| 평점 0.0(0) | 리뷰 0건 | 'NEW' 배지로 치환, 별 0개 비노출 | 사회적 증거 0 인상 제거 |
| 이미지 alt 누락 | alt 빈값/누락 | SKU명+카테고리 자동 생성 후 셀러 검수 | 접근성·SEO |
0원 노출 가드: 애플리케이션 레벨에서 price <= 0 && status==ACTIVE는 배포 차단(불변식). 0원은 오직 DRAFT에서만 허용.
핵심은 SKU = 재고의 단일 진실원. 스토어 판매도, 답례품 제공도, 패키지 구성도 모두 같은 SKU의 재고를 차감한다. Product(전시) ≠ SKU(재고) 분리가 이중재고 방지의 토대.
[ERD 핵심]
Seller(농가/업체, excellentCompany 연계)
1─* Product (전시단위: 제목/설명/이미지/카테고리)
1─* Sku (옵션조합: 사과5kg특, price, weight)
1─1 Inventory (qty_on_hand, qty_reserved, safety_stock)
*─* Channel ← SKU가 어느 채널에 노출되나
├ STORE (스토어 판매)
├ REWARD (기부 답례품 카탈로그)
└ PACKAGE_ITEM (패키지 구성품)
Reservation(여행예약: 체험/숙소/캠핑) ─┐
Sku ──────────────────────────────────┼→ CartItem (단일 장바구니)
DonationOrder ─────────────────────────┘
| 엔티티 | 키 필드 | 불변식 |
|---|---|---|
| Sku | sku_code, price(>0), unit, weight_g, supply_type | 가용재고 = on_hand - reserved - safety |
| Inventory | qty_on_hand, qty_reserved | 예약/주문/답례 모두 reserved 경유(낙관적 락) |
| Channel | sku_id, channel_type, channel_price | 채널별 가격은 가능, 재고는 공유 불가능(단일) |
| 배송유형 | 리드타임 | 포장/온도 | 비용 정책 | 합배송 |
|---|---|---|---|---|
| 택배(상온) | D+1~2 | 상온 박스 | 3,000원 / 3만↑ 무료 | 셀러 동일 시 합배송 |
| 산지직송 | D+2~5(예약수확 시 가변) | 농가 직포장 | 셀러별 개별, 도서산간 할증 | 셀러 분리배송(합배송 불가) |
| 신선냉장(콜드체인) | D+1~2(요일 지정) | 아이스팩+스티로폼, 냉장/냉동 분리 | 4,000원~, 냉동 추가 | 상온과 합배송 불가 |
장바구니는 배송그룹(shipment group) 단위로 자동 분할: (셀러 × 배송유형 × 온도대)가 그룹 키. 산지직송 정육과 택배 특산품을 한 카트에 담으면 배송비·도착일이 그룹별로 표시된다.
| 흐름 | 상태머신 | 신선식품 특례 |
|---|---|---|
| 주문 | PENDING→PAID→PREPARING→SHIPPED→DELIVERED | 예약수확 SKU는 PAID→BACKORDER(수확일 대기) |
| 교환 | REQUESTED→APPROVED→PICKUP→RESHIP | 파손/오배송만, 사진 필수 |
| 반품 | REQUESTED→APPROVED→RETURNED→REFUNDED | 신선·정육 단순변심 청약철회 제한(전상법 17조2 예외 고지) |
반품 정책을 SKU 속성 return_policy로 명시(상온=7일 단순변심 가능 / 신선·정육=품질하자만). PDP·결제·주문완료 3곳에서 동일 문구 노출(분쟁 예방).
독점 자산인 전국 농가 공급량을 지역(17개 시도) × 제철(월) 2축으로 큐레이션. 홈 핫키워드(경북/경산/만들기)와 검색 IA에 직결.
| 월 | 제철 큐레이션 슬롯 | 연계 동선 |
|---|---|---|
| 5~6월 | 완숙토마토·매실·마늘(의성) | 매실청 담그기 체험키트 크로스셀 |
| 9~10월 | 햇사과(영주)·송이·햅쌀 | 수확체험 예약 + 특산품 묶음 패키지 |
| 12~1월 | 한우 명절세트·곶감(상주) | 고향사랑기부 답례품 크로스셀 |
큐레이션은 region_tag + season_month[] SKU 태그로 구동, MD가 슬롯만 편성(수동 상품 나열 금지 → 자동 충원).
| 항목 | 스토어(STORE) | 답례품(REWARD) | 공유 여부 |
|---|---|---|---|
| 재고(Inventory) | 동일 SKU의 단일 qty_on_hand에서 reserved 차감 | 공유(단일) | |
| 가격 | 판매가 25,000원 | 답례 포인트 환산(기부액 30% 이내) | 분리 |
| 공급주체 | 셀러/농가 | 지자체(입점계약+상품등록 필수) | 분리 |
| 정산 | 셀러 정산 | 지자체 정산, 수수료 5~10% | 분리 |
| 노출 조건 | 전국 | 해당 지자체 답례품 등록 승인 시만 | 분리 |
[이중재고 방지 시퀀스 — 동시 주문 경합]
STORE 주문 ┐
├→ reserveStock(sku=APPLE5KG, qty=1) ← 단일 원장 낙관적 락(version)
REWARD 답례 ┘ ├ 성공: reserved+=1, 잔여 검사
└ 실패(version 충돌/재고부족): 재시도 or OUT_OF_STOCK
확정: SHIPPED 시 on_hand-=, reserved-= (양 채널 공통)
분리 케이스: 답례품 전용 SKU(지자체 한정 굿즈, 지역사랑상품권)는 Channel=REWARD 단독으로 두고 STORE 미노출. 공유 케이스: 농산물·정육·체험바우처는 양 채널 동시. 재고 단일 원장이라 한쪽이 팔리면 즉시 반영.
예약(체험/숙소/캠핑, 시간·재고 슬롯)과 실물상품(SKU)은 성격이 다르나 하나의 CartItem 추상으로 담는다. 결제는 단일, 이행(fulfillment)은 라인별 분기.
| 카트 라인 타입 | 재고 모델 | 결제 후 이행 | 취소/환불 규칙 |
|---|---|---|---|
| 실물상품(SKU) | 수량 재고 | 배송 그룹 생성 | 배송 전 취소·청약철회 |
| 체험/숙소/캠핑 예약 | 날짜·정원 슬롯 | 예약확정·바우처 발급 | 예약일 기준 취소수수료 |
| 체험바우처(답례 연계) | 발급 수량 | 바우처 코드(놀고팜 재고 연결) | 유효기간·미사용 환불 |
| 패키지 | 구성품 각각 차감 | 혼합 이행(택배+예약) | 구성 단위 부분취소 |
크로스셀: 체험 예약 PDP 우측 sticky 패널에 '해당 농가 특산품' 노출 → 한 카트에 담아 단일 결제. 반대로 특산품 구매 동선에서 고향사랑기부 크로스셀(개인·본인주소지 외·연 2,000만 한도 고지)을 띄워 답례품으로 체험 바우처를 회수하게 한다.
experience/accommodation 재고를 지자체 답례품으로 한 번 더 노출하고, 발급된 바우처를 기존 예약 엔진의 reservation에 0원 차감 결제로 흘려보내는 것이다.| 항목 | 제약 | 설계 반영 |
|---|---|---|
| 답례품 한도 | 기부액의 30% 이내 (10만원 기부 → 3만원 한도) | 바우처 액면을 min(상품가, 기부액×0.3)로 캡, 초과분은 자부담 결제 |
| 공급 주체 | 답례품 공급주체는 지자체 (민간 직접 판매 불가) | 놀고팜 업체→지자체 답례품 협약→상품등록. 우리는 예약·정산 위탁사 포지션 |
| 기부 주체 | 개인만, 본인 주소지 지자체 기부 불가 | 주소 검증 후 거주 지자체 답례품 자동 숨김 |
| 연 한도 | 2025년부터 연 2,000만원 | 기부액 입력 시 누적 한도 가드 |
| 세액공제 | 10만원 이하 전액, 초과분 16.5%, 10년 이월 | 크로스셀 후크에 실시간 공제액 계산기 |
| 답례품 종류 | '서비스·체험 이용권', '지역사랑상품권' 허용 | 체험/숙박/캠핑 바우처가 정확히 이 카테고리에 합법 적재 |
| 정산 | 고향사랑e음 API, 지자체별 계약, 수수료 5~10% | 지자체 정산 ↔ 업체 정산 2단 분리 |
donation ──┬─< voucher >──┬── reservation (0원 차감)
donor_id │ face_value │ product_idx (experience/accom/facility)
lguz_idx ─┤ cap=amt*0.3 │ pay_voucher + pay_self(초과분)
amount │ state └── usage_log (예약차감/취소복원)
e음_txn │ ISSUED→RESERVED→REDEEMED→EXPIRED
│
lg_contract(지자체 입점계약) ──< reward_product(답례품 등록)
lguz_idx reward_idx ── maps → product_idx(놀고팜 재고)
fee_rate(5~10%) face_value, region_lock
region_bundle ──< reward_product // (이 지역 기부→이 지역 체험)
region_code experience set
핵심: reward_product.maps→product_idx 한 줄이 USP의 전부다. 답례품 등록은 지자체 명의지만 실재고 포인터는 놀고팜 product/experience를 가리켜, 별도 재고 이중관리가 없다.
[기부자] [놀고팜] [고향사랑e음] [지자체] [예약엔진] │ 기부10만+답례품선택 │ │ │ ├──────────────>│ 기부요청 │ │ │ ├──────────────>│ 결제승인 │ │ │<──── e음_txn ─┤ │ │ ├── 한도검증 face=min(3만,상품가) │ │ │ voucher.ISSUED(QR발급) │ │<── 바우처 ─────┤ │ │ │ (예약 시점) │ │ │ ├─ 체험예약 선택 │ │ │ │ ├── voucher.RESERVED ──────────────>│ 예약hold │ │ pay_voucher=3만 / pay_self=차액 │ │ │<───────── 예약확정 ───────────────┤ │ │ voucher.REDEEMED(체험완료 후) │ │ ├── 정산: 지자체←수수료 / 업체←체험비 │
[PDP/장바구니] 특산품 5만원 담음 │ "이 지역 5만 기부 시 실부담 8,250원 + 답례품 1.5만 바우처" ├─ 기부 후크 클릭 ─> 주소검증(본인지자체 제외) │ 기부5만 → 공제 4.175만 / 답례 1.5만 ├─ 같은 장바구니에서 기부+구매 동시 결제(단일 세션) └─ 답례 바우처 즉시 재투입 → 추가 체험 예약(객단가 ↑)
| 단계 | 자금 흐름 | 비고 |
|---|---|---|
| 1. 기부금 | 기부자 → 고향사랑e음 → 지자체 기금 | 놀고팜 미경유(법적 분리) |
| 2. 답례품 대금 | 지자체 기금 → 답례품 정산 → 놀고팜(위탁) → 업체 | 수수료 5~10% 지자체 계약율 적용 |
| 3. 자부담 차액 | 기부자 → 놀고팜 PG → 업체 | 바우처 캡 초과분(예: 5만 체험 - 3만 바우처 = 2만) |
| 4. 취소·환불 | 예약 취소 → voucher.RESERVED→ISSUED 복원, 자부담만 PG 환불 | 바우처 액면은 현금 환급 불가(상품권 룰) |
| 리스크 | 영향 | 완화책 |
|---|---|---|
| 지자체 입점계약 지연 | 답례품 등록 불가 = USP 미가동 | 전북(치유관광 기반) 1~2개 지자체 파일럿 선행, 템플릿 계약서 |
| 30% 한도 오계산 | 법 위반·답례품 환수 | 서버단 cap=amt*0.3 하드가드, 초과는 자부담 강제 |
| 바우처 현금화 악용 | 상품권 부정유통 | QR 1회성·예약귀속·환불 시 현금불가, 본인인증 차감 |
| e음 API 정산 불일치 | 대사(reconciliation) 오류 | e음_txn 키로 일일 자동대사, 미스매치 보류큐 |
| 본인 주소지 기부 | 무효 기부 | 주소검증 후 해당 지자체 답례품·기부 버튼 숨김 |
| 재고 0원/전화문의 SKU 혼입 | 바우처 예약 불가 | 답례품 매핑은 '바로결제' 가능 + 가격>0 SKU만 허용 |
| 역량 | 웰로·위기브 | 놀고팜 |
|---|---|---|
| 기부 정산 레이어 | 보유 | 동등 확보 가능(e음 API) |
| 실물 체험·숙박 재고 | 없음 (기부 전용) | 체험6·숙소3·캠핑5·특산품 SKU 독점 보유 |
| 실시간 예약·차감 엔진 | 없음 | '바로결제' 트랜잭션 이미 가동 |
| 지자체 업체 마스터 | 없음 | 우수체험관·치유관광 협약 기반 |
| 구매→기부 크로스셀 동선 | 커머스 트래픽 없음 | 농촌여행 예약 트래픽이 본체 |
결론: 기부 플랫폼은 우리의 예약 재고를 답례품화할 수 없지만, 우리는 그들의 정산 레이어를 표준 API로 흡수한다. 해자는 "기부+예약+정산을 단일 세션에 닫는 유일한 사업자"라는 비대칭에 있다.
PRODUCT 테이블 + type 판별자로 통합해 파편화를 해소, (2) 모든 판매 가능 상품이 INVENTORY/AVAILABILITY에 묶여 '전화문의' 누수를 차단, (3) VOUCHER·SETTLEMENT·USER·CART를 기부(GIFT/DONATION) 도메인과 공유해 답례품 양방향 연계를 가능케 하는 것.
[USER]──┐ (회원: 여행자=기부자 단일계정)
│
├──< [CART] >── cart_item ── (PRODUCT_OPTION | STORE_PRODUCT | DONATION)
│ └ 단일 장바구니에 체험·숙소·특산품·기부 혼재
│
[SUPPLIER]──< [PRODUCT] >──< [PRODUCT_OPTION] >──< [INVENTORY/AVAILABILITY]
우수체험관 │ type= │ (날짜·회차·정원·객실)
/농가 │ 체험/숙소/캠핑/편의/패키지 │
/지자체직영 │ ↓
│ [BOOKING]──< [ORDER] >── [PAYMENT]
│ │ status └─< [REFUND]
│ │ 인원/voucher_id
│ ├── [REVIEW] (예약검증: booking_id 필수)
│ └── [VOUCHER] ←──┐ 기부 답례품 발급
│ │
├── [STORE_PRODUCT]──< [SHIPMENT] │
│ 특산품/정육/키트/기념품 │
│ │
└──< product_tag >── [REGION] / [THEME] │
│
[GROUP_RESERVATION] (B2G/B2B 단체) ──── 견적·정산 ───────┐ │
│ │
══════════ 기부 도메인 연결 ══════════ │ │
[LOCAL_GOV]──< [GIFT_CATALOG] >── voucher_template ─────┘ │
지자체 (답례품 등록: 체험권/숙박권) │
│ │
└──< [DONATION] >──< [GIFT] >── 발급 ──> [VOUCHER] ──┘
고향사랑e음 (기부액 30% 이내)
│
[SETTLEMENT] ── 정산대상: SUPPLIER(체험/상품 매출) | LOCAL_GOV(기부 답례품 원가/수수료)
현행은 experienceCategoryIdx, accommodationCategoryIdx, facilityCategoryIdx, productCategoryIdx가 각각 다른 테이블/URL(/user/experience, /user/accommodation, /user/facility, /user/product)에 흩어져 검색·장바구니·정산이 분리됨. 단일 PRODUCT.type + 정규화 카테고리로 통합한다.
| 현행(파편) | PRODUCT.type | category(정규화 enum) | 전용 속성 위치 |
|---|---|---|---|
| experienceCategoryIdx 1~5,20 | EXPERIENCE | 영농수확/자연생태/문화예술/힐링레포츠/공예요리/기타 | option(회차·소요시간) |
| accommodationCategoryIdx 2,3,6 | STAY | 빌라형/독채형/촌캉스 | inventory(객실·체크인) |
| facilityType=CAMPING | CAMPING | 캠핑장/글램핑/카라반/야영장/수련원 | inventory(사이트·박) |
| facilityType=AMENITIES | AMENITY | 맛집/전통시장/휴양림/충전소 | POI(예약불가·정보형) |
| productCategoryIdx 7(패키지) | PACKAGE | 체험+숙소+특산품 번들 | package_item(구성 FK) |
| productCategoryIdx 1,2,5,6 + productOld | STORE_PRODUCT(별도) | 특산품/기념품/정육/체험키트 | shipment(배송) |
마이그레이션: productOld 레거시와 '0원' SKU는 status=DRAFT로 격리, 가격·재고 검증 통과분만 ACTIVE 승격. AMENITY는 bookable=false로 두어 평점 0.0 오염을 PLP에서 분리.
| SUPPLIER (공급자 마스터 / 우수체험관·농가·지자체직영) | 타입 | 비고 |
|---|---|---|
| supplier_id (PK) | bigint | 우수체험관 = excellentCompany 통합 |
| name / business_no | varchar | 사업자번호(정산 KYC) |
| type | enum | FARM / EXCELLENT_CENTER / GOV_DIRECT |
| region_id (FK) | bigint | → REGION |
| settlement_account | varchar(enc) | 정산 계좌(암호화) |
| commission_rate | decimal | 플랫폼 수수료 % (정산 기준) |
| gov_contract_id (FK,null) | bigint | → LOCAL_GOV 입점계약(답례품화 필수) |
| PRODUCT (통합 상품) | 타입 | 비고 |
|---|---|---|
| product_id (PK) | bigint | |
| supplier_id (FK) | bigint | → SUPPLIER |
| type | enum | EXPERIENCE/STAY/CAMPING/AMENITY/PACKAGE |
| category | enum | 위 정규화 카테고리 |
| title / summary / thumbnail | varchar | 통일 카드용 16:9 단일 썸네일 강제(AI슬롭 배너 금지) |
| bookable | bool | false면 정보형 POI(전화문의 SKU 박멸) |
| base_price / rating_avg / review_cnt | decimal/int | 비정규화 캐시 |
| status | enum | DRAFT/ACTIVE/PAUSED/CLOSED |
| jsonld_cache | jsonb | Product/Offer 구조화데이터 |
| PRODUCT_OPTION (옵션/요금제) | 타입 | 비고 |
|---|---|---|
| option_id (PK) / product_id (FK) | bigint | |
| name | varchar | 예: '성인 1인', '4인 글램핑 1박' |
| price / min_qty / max_qty | decimal/int | 인원·수량 제약 |
| duration_min / session_type | int/enum | 체험 소요시간·회차형 여부 |
| INVENTORY / AVAILABILITY (날짜·회차·정원·객실) | 타입 | 비고 |
|---|---|---|
| avail_id (PK) / option_id (FK) | bigint | |
| date / session_no | date/int | 회차(체험), 박단위(숙소·캠핑) |
| capacity / booked / remaining | int | remaining≤0이면 매진(낙관락+행락) |
| room_no / site_no (null) | varchar | 객실/캠핑사이트 식별 |
| price_override | decimal | 성수기·주말 가변가 |
| BOOKING (예약) | 타입 | 비고 |
|---|---|---|
| booking_id (PK) | bigint | |
| user_id (FK) / avail_id (FK) | bigint | → USER, AVAILABILITY |
| order_id (FK,null) | bigint | 유상 예약 시 → ORDER |
| voucher_id (FK,null) | bigint | 기부 답례품 바우처 사용 예약 |
| headcount / qty | int | 인원/수량 |
| status | enum | PENDING/CONFIRMED/USED/NO_SHOW/CANCELLED |
| visit_date / checkin / checkout | date |
| ORDER / PAYMENT / REFUND | 타입 | 비고 |
|---|---|---|
| order_id (PK) / user_id (FK) | bigint | 장바구니 다건 결제 묶음 |
| ORDER.total / status | decimal/enum | PAID/PARTIAL_REFUND/REFUNDED |
| PAYMENT.pg_tid / method / paid_at | varchar | PG 실결제(바로결제 전면화) |
| REFUND.amount / reason / refunded_at | decimal | 취소수수료 정책 연계 |
| VOUCHER (바우처 / 기부 답례품 연계) | 타입 | 비고 |
|---|---|---|
| voucher_id (PK) | bigint | |
| gift_id (FK,null) | bigint | → GIFT(기부 답례품 발급분) |
| product_id (FK) | bigint | 교환 가능 체험/숙박권 |
| code / face_value | varchar/decimal | 고유코드·권면가 |
| status / issued_at / expires_at / redeemed_at | enum/ts | ISSUED/REDEEMED/EXPIRED |
| local_gov_id (FK) | bigint | 발급 주체 지자체(법: 공급주체=지자체) |
| REVIEW · GROUP_RESERVATION · STORE/SHIPMENT · 태그 · SETTLEMENT | 핵심 컬럼 | 비고 |
|---|---|---|
| REVIEW | review_id, booking_id(FK,필수), product_id, rating, body, photo[] | booking_id 검증 → 미구매 0.0 평점 차단 |
| GROUP_RESERVATION | group_id, user_id, org_name, type(SCHOOL/B2B/B2G), headcount, requested_date, quote_amount, status | 견적→승인→정산. 단체 톤 통합 |
| STORE_PRODUCT | store_product_id, supplier_id, category(특산품/정육/키트), price, stock | 0원/productOld 정리 대상 |
| SHIPMENT | shipment_id, order_id(FK), courier, tracking_no, status | 실물배송(체험과 분리 흐름) |
| REGION | region_id, sido, sigungu, gov_id(FK) | 경북/경산 등 핫키워드 연계 |
| THEME | theme_id, name(할로윈/만들기/촌캉스), slug | product_tag M:N |
| SETTLEMENT | settlement_id, target_type(SUPPLIER/LOCAL_GOV), period, gross, commission, refund, net, status | 공급자 매출 + 지자체 답례품 정산 단일 테이블 |
GIFT→VOUCHER 발급→BOOKING.voucher_id로 체험·숙박 사용DONATION 크로스셀SUPPLIER.gov_contract_id·GIFT_CATALOG로 입점target_type로 공급자/지자체 정산 일원화MVP는 "비로그인 전과정 탐색 → 결제 직전 로그인 → 일반/지정 기부 + 답례품/체험 바우처 결제 → e음 영수증"의 단일 동선을 닫는 것이 목표다. 정산 자동화, 커뮤니티 작성, 출석 리워드 교환 등은 P1 이후로 분리한다.
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| MEM-01 | 이메일/소셜 회원가입 | 이메일 + 카카오/네이버 OAuth. 만 14세 이상 확인, 약관·개인정보 동의 분리 수집 | P0·Must | 개인만 가입(법령), 사업자 제외 |
| MEM-02 | 간편 로그인/세션 | JWT + refresh 토큰. jsessionid URL 노출 제거, 서버세션→토큰 전환 | P0·Must | 레거시 서버세션 폐기 |
| MEM-03 | 본인확인(실명/주소지) | e음/PASS 본인인증으로 실명·주소지 확보. 본인 주소지 지자체 기부 차단 판정 근거 | P0·Must | 제도 필수, 기부 직전 1회 |
| MEM-04 | 비로그인 탐색 보장 | 기부·체험·답례품 전 페이지를 로그인 없이 열람·장바구니 담기 가능. 로그인 게이트는 결제/접수 직전만 | P0·Must | USP·전환율 핵심 |
| MEM-05 | 비밀번호 재설정 | 이메일 인증 링크 재설정, 만료 30분, 토큰 1회용 | P0·Must | ISMS-P 요건 |
| MEM-06 | 회원 탈퇴/개인정보 파기 | 탈퇴 즉시 비식별, 기부·세액공제 법정 보관분은 분리보관 후 보존기간 경과 파기 | P1·Should | 세법 보관의무 충돌 처리 |
| MEM-07 | 2단계 인증(2FA) | OTP/문자 2차 인증 옵션, 고액 기부 시 강제 | P2·Could | 보안 등급 상향 |
| MEM-08 | 레거시 계정 마이그레이션 | 아이러브고향/놀고팜 기존 회원 통합. 중복 이메일 병합, 기부·예약 이력 승계 | P1·Should | 2도메인 통합 1회성 배치 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| DON-01 | 일반기부 접수 | 지자체 선택→기부금액 입력→답례품 선택(선택)→e음 접수. 연 한도 2,000만원 누적 검증 | P0·Must | e음 API 경유 접수 |
| DON-02 | 지정기부 상세 | 제8조의2 사업별 페이지: 모금목표·누적모금액·달성률%·참여 N명·사용처 명세·마감일 | P0·Must | 기부깊이 90 핵심 |
| DON-03 | 모금률 게이지 컴포넌트 | 달성률 실시간 게이지, 목표 대비 %·잔여액·D-day 표시. 카드/상세 공용 | P0·Must | 공용 컴포넌트 |
| DON-04 | 주소지 기부 차단 | 본인확인 주소지와 동일 지자체 선택 시 접수 차단 + 사유 안내 | P0·Must | 법령 위반 방지 |
| DON-05 | 답례품 30%룰 검증 | 선택 답례품 가격 ≤ 기부액×30% 실시간 검증. 미달 시 최소 기부금 자동 산정·안내 | P0·Must | 답례품가가 최소기부 결정 |
| DON-06 | 지정기부 진행현황 업데이트 | 지자체가 사용처 집행 내역·사진을 타임라인 게시, 기부자에게 푸시 | P1·Should | 위기브 벤치마크 |
| DON-07 | 정기기부(약정) | 월 정액 자동기부 약정, 연 한도 내 분할 접수 | P2·Could | PG 빌링키 필요 |
| DON-08 | 기부 취소/환불 | 접수 후 영수증 발급 전 취소 가능, e음 상태 동기화 | P1·Should | 영수증 후 취소 불가 |
| DON-09 | 지정기부 사업 관리(지자체) | 지자체 운영자가 사업 등록·목표·사용처 입력하는 어드민 | P1·Should | 243곳 입점 운영 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| GFT-01 | 계층 분류 카탈로그 | 지자체·카테고리(농수산물/가공/공산품/농촌체험 바우처·숙박) 분류코드 트리 | P0·Must | USP: 체험 바우처 연결 |
| GFT-02 | 다중 필터·정렬 | 지역·가격대·카테고리·재고·인기순 동시 필터. URL 쿼리 동기화 | P0·Must | 기부깊이 지표 |
| GFT-03 | 답례품 상세 | 좌측 스크롤 콘텐츠 + 우측 sticky 선택 패널. 옵션·재고·배송정보·공급주체(지자체) | P0·Must | 0원가격 데이터 정제 선행 |
| GFT-04 | 재고/품절 관리 | 실물재고 연동, 품절 시 선택 차단. 놀고팜 실물공급 재고 동기화 | P0·Must | 레거시 0원·무재고 정리 |
| GFT-05 | 체험 바우처 답례품 | 체험/숙박/캠핑을 답례품으로 발급, 발급 후 예약 모듈로 연결(바우처 코드) | P0·Must | 복제불가 단일 동선 |
| GFT-06 | '바로결제' 배지 | 실물재고 즉시구매 상품에 배지 표기, 기부 없이도 구매 가능 동선 | P1·Should | 놀고팜 자산 활용 |
| GFT-07 | 답례품 후기 연결 | 수령 후 별점·리뷰 작성, 상세에 리뷰 카드 노출 | P1·Should | 평점0 만연 개선 |
| GFT-08 | AI 답례품 추천 | 기부지역·관심사 기반 추천 캐러셀 | P3·Won't | 데이터 축적 후 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| RSV-01 | 상품 카탈로그 | 체험(6하위)/숙소/캠핑(5하위)/우수체험관/치유관광 분류. 가격·리뷰 표기 필수 | P0·Must | 캠핑 245p 무가격 정제 |
| RSV-02 | 날짜·인원 가용성 조회 | 캘린더 기반 잔여 슬롯 조회, 마감 슬롯 비활성 | P0·Must | 실물공급 연동 |
| RSV-03 | 예약 신청·확정 | 날짜·인원·옵션 선택→결제→확정. 바우처 답례품 코드로도 예약 가능 | P0·Must | GFT-05 연계 |
| RSV-04 | 예약 변경/취소 | 취소 정책별 환불율 자동 계산, 일정 변경 | P0·Must | PAY 모듈 연동 |
| RSV-05 | 상세 sticky 예약 패널 | 좌측 콘텐츠 + 우측 sticky 예약 패널(날짜·인원·가격·CTA) | P0·Must | 공용 레이아웃 |
| RSV-06 | 단체예약 견적 | 인원 임계 초과 시 견적 요청 폼·운영자 회신 워크플로 | P2·Could | 레거시 단체예약 자산 |
| RSV-07 | 오디오가이드/치유관광 연동 | 현장 오디오가이드·치유 프로그램 콘텐츠 연결 | P3·Won't | 자산 존재, 후순위 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| TAX-01 | 인터랙티브 계산 위젯 | 기부액 입력→환급액 즉시 계산. 10만원 이하 전액(100/110 소득세+지방세=실질 100%), 초과분 16.5% | P0·Must | 공용 컴포넌트 |
| TAX-02 | 한도·이월 안내 | 연 2,000만원 한도, 미공제분 10년 이월 자동 표시 | P0·Must | 2025.1.1 개정 반영 |
| TAX-03 | 기부 플로우 내 임베드 | 기부 금액 입력 단계에 위젯 임베드, 답례품 30%룰과 동시 안내 | P0·Must | DON-05 동시 노출 |
| TAX-04 | 예시 시나리오 프리셋 | 10만/30만/100만원 버튼 프리셋으로 환급액 비교 표시 | P1·Should | 전환 촉진 |
| TAX-05 | 연말정산 영수증 안내 | e음 발급 세액공제 영수증 다운로드 경로·홈택스 연계 안내 | P1·Should | 발급은 e음 경유 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| SCH-01 | 통합 검색바 | 단일 GNB 검색으로 기부사업·답례품·체험·콘텐츠 동시 검색. 외부 떠넘김 0건 | P0·Must | 정보구조 88+ 핵심 |
| SCH-02 | 타입별 결과 탭 | 전체/기부/답례품/여행/콘텐츠 탭 분리, 각 결과 카드 통일 | P0·Must | 일관 카드 위계 |
| SCH-03 | 지역 기반 필터 | 243개 지자체·시도 단위 지역 패싯 필터 | P0·Must | 지역 핵심축 |
| SCH-04 | 자동완성·오타교정 | 지자체명·상품명 자동완성, 인기 검색어 | P1·Should | 검색 품질 |
| SCH-05 | 검색 결과 SEO | 슬러그--UUID URL, canonical/JSON-LD, productOld 잔존 제거 | P1·Should | 기술 85+ 지표 |
| SCH-06 | 최근 본/저장 검색 | 최근 조회·찜한 항목, 검색 저장 | P2·Could | 리텐션 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| CMS-01 | 아티클 발행 | 농촌여행/지역/제도(세액공제·지정기부) 아티클 CMS, 카드 일관 위계 | P0·Must | 콘텐츠 80+ 토대 |
| CMS-02 | 동네소식 피드 | 지자체별 소식·공지 애그리게이션 피드. 아이고 '팝업존' 플레이스홀더 제거 | P1·Should | 레거시 라이브 잔재 정리 |
| CMS-03 | 축제 애그리게이터 | 지역 축제 일정 수집·캘린더·지도 노출, 체험상품 연결 | P1·Should | 리텐션 USP |
| CMS-04 | 후기 커뮤니티 | 기부/체험 후기 작성·사진·별점, 피드 노출 | P1·Should | 평점0 개선 |
| CMS-05 | 댓글·좋아요 | 아티클·후기 댓글·반응 | P2·Could | 커뮤니티 활성 |
| CMS-06 | 신고·모더레이션 | 부적절 게시물 신고, 운영자 숨김/삭제 큐 | P1·Should | UGC 운영 필수 |
| CMS-07 | 콘텐츠-상품 연결 | 아티클 본문에서 관련 기부사업·체험·답례품 인라인 카드 삽입 | P2·Could | 전환 동선 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| ATT-01 | 출석체크 모듈 | 일일 출석 버튼, 연속 출석 스트릭 카운트. 공용 컴포넌트 | P1·Should | 리텐션 핵심 |
| ATT-02 | 포인트 적립 | 출석·후기·기부 행동별 포인트 적립 규칙 엔진 | P1·Should | 정책표 필요 |
| ATT-03 | 포인트 사용/교환 | 적립 포인트로 답례품 할인·체험 쿠폰 교환 | P2·Could | PAY 연동 |
| ATT-04 | 리워드 내역 | 적립·사용·소멸 이력 조회, 만료 안내 | P2·Could | 마이페이지 연계 |
| ATT-05 | 출석 보상 추첨/배지 | 스트릭 달성 배지·럭키드로우 게이미피케이션 | P3·Won't | 후순위 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| PAY-01 | 통합 장바구니 | 기부+답례품+체험을 단일 장바구니에 혼합 담기, 단일 세션 | P0·Must | 3분할 폐기, 통합 동선 |
| PAY-02 | PG 결제 | 카드·간편결제 연동, 결제 직전 로그인 게이트. 영수증·주문번호 발급 | P0·Must | ISMS-P 결제보안 |
| PAY-03 | 기부 접수 분기 | 장바구니 내 기부분은 e음 접수 경유, 답례품/체험은 PG 직결제 분기 처리 | P0·Must | 공공·민간 트랜잭션 분리 |
| PAY-04 | 기부영수증 발급 | e음 연동 세액공제 영수증 발급·상태 동기화 | P0·Must | 공공시스템 경유 |
| PAY-05 | 환불 처리 | 예약취소·답례품 반품 환불, 부분환불·환불율 계산 | P0·Must | RSV/GFT 연동 |
| PAY-06 | 지자체 정산 집계 | 지자체별 기부·답례품·수수료(5~10%) 자동 집계·정산 리포트 | P1·Should | 243곳 개별 수수료 |
| PAY-07 | 공급사 정산 | 놀고팜 실물공급사·체험사업자 정산 명세 | P1·Should | 실물공급 매출 |
| PAY-08 | 결제 실패/멱등 처리 | 중복결제 방지 멱등키, 실패 재시도·미결제 자동 만료 | P0·Must | 결제 안정성 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| NOTI-01 | 트랜잭션 알림 | 기부 접수·결제완료·영수증 발급·예약확정 이메일/SMS 발송 | P0·Must | 거래 필수 통지 |
| NOTI-02 | 인앱 알림센터 | 알림 목록·읽음 처리, 마이페이지 진입 | P1·Should | 리텐션 |
| NOTI-03 | 카카오 알림톡 | 알림톡 채널 연동, 발송 실패 시 SMS 대체 | P1·Should | 도달률 개선 |
| NOTI-04 | 지정기부 진행 알림 | 참여 사업 사용처 업데이트·목표 달성 푸시 | P1·Should | DON-06 연계 |
| NOTI-05 | 알림 수신 설정 | 채널별·유형별 수신 동의/거부, 마케팅 별도 동의 | P0·Must | 정보통신망법 |
| NOTI-06 | 리마인더 | 장바구니 미결제·예약 임박·세액공제 마감 리마인더 | P2·Could | 전환 회수 |
| ID | 기능 | 설명 | 우선순위 | 비고 |
|---|---|---|---|---|
| MYP-01 | 기부 내역 | 일반/지정 기부 이력·금액·영수증 다운로드, 연 누적·한도 잔여 표시 | P0·Must | 한도 추적 핵심 |
| MYP-02 | 주문/예약 내역 | 답례품 주문·배송 추적, 체험 예약·바우처 코드 상태 | P0·Must | 전 거래 통합 |
| MYP-03 | 세액공제 대시보드 | 올해 기부 환급 예상액 집계, 영수증 일괄 다운로드 | P0·Must | TAX 연계 |
| MYP-04 | 회원정보 관리 | 프로필·주소지·결제수단·약관 동의 이력 관리 | P0·Must | 주소지=기부 차단 근거 |
| MYP-05 | 찜/저장 | 관심 답례품·체험·기부사업 찜 목록 | P1·Should | 리텐션 |
| MYP-06 | 내 후기·포인트 | 작성 후기 관리, 포인트 잔액·내역 | P1·Should | ATT/CMS 연계 |
| MYP-07 | 알림 설정 진입 | NOTI 수신 설정 화면 연결 | P1·Should | NOTI-05 연계 |
| 우선순위 | 의미 | FR 수 | 대표 모듈 |
|---|---|---|---|
| P0·Must (MVP) | 출시 필수, 단일 기부·결제 동선 완결 | 41 | 회원·기부·답례품·결제·세액공제 |
| P1·Should | MVP 직후 4~8주, 운영·리텐션 강화 | 30 | 정산·커뮤니티·출석·알림 확장 |
| P2·Could | 여력 시, 부가 가치 | 12 | 포인트 교환·단체예약·콘텐츠 연결 |
| P3·Won't (이번 제외) | 백로그, 데이터 축적 후 | 6 | AI추천·게이미피케이션·오디오가이드 |
각 FR은 7장 비기능 요구사항(성능 TTFB<100ms, 접근성 alt 0누락, 보안 ISMS-P)과 함께 충족되어야 완료로 간주한다. P0 41개가 닫히면 평점 목표 86.2의 정보구조·기부깊이 축이 확보된다.
┌───────────────┐
│ LOCAL_GOV │ 멀티테넌트 루트 (243곳)
│ (지자체/테넌트)│
└──────┬────────┘
┌───────────────┬────────────┼───────────────┬──────────────┐
│1:N │1:N │1:N │1:N │1:N
┌────▼─────┐ ┌─────▼──────┐ ┌───▼──────────┐ ┌──▼─────────┐ ┌──▼──────┐
│ GIFT │ │ DONATION_ │ │ EXPERIENCE / │ │ CONTENT │ │RECEIPT_ │
│(답례품) │ │ CAMPAIGN │ │ ACCOMMODATION│ │(아티클/소식 │ │ POLICY │
│categoryCd│ │(지정기부) │ │ / FACILITY │ │ /축제) │ │(정산조건)│
└────┬─────┘ └─────┬──────┘ └───┬──────────┘ └────────────┘ └─────────┘
│N:1 │ │N:1
┌────▼─────┐ │ ┌────▼────────┐
│ CATEGORY │◄────────┘ │ PRODUCT │ (예약/스토어 판매단위)
│(계층트리) │ (캠페인도 분류) │ +바로결제배지 │
└──────────┘ └────┬────────┘
│N:1 (선택)
┌──────────────────────────────────────┼───────────────────────────────┐
│ │ │
┌──▼──────┐ ┌──────────┐ 1:N ┌──────▼──────┐ 1:N ┌────────────┐ │
│ USER │──────────────────────► │ ORDER │ ─────► │ ORDER_LINE │───┘
│(개인회원)│ │ CART │◄────────│ (통합주문) │ │ line_type: │
└──┬──────┘ │(통합장바구니)│ 1:1 └──────┬──────┘ │ DONATION / │
│1:N └──────────┘ │1:1 │ RESERVATION│
│ ┌──────────────┬───────────────┤ │ / PRODUCT │
│ │1:N │1:N │1:1 └─────┬──────┘
┌──▼────┐ │ ┌────▼─────┐ ┌─────▼──────┐ │
│ POINT │ │ │ DONATION │ │ PAYMENT │ │1:1 (line_type=DONATION)
│(적립금)│ │ │(기부원장) │ │(PG/e음 정산)│ ┌────▼──────┐
└───────┘ │ │ e음연동키 │ └─────┬──────┘ │ DONATION │
│ │ 세액공제 │ │1:1 (DONATION) │ (기부원장) │
┌─────────▼──┐ └────┬─────┘ ┌─────▼──────┐ └────┬──────┘
│ ATTENDANCE │ │1:1 │ RECEIPT │ │1:1
│ (출석체크) │ ┌────▼─────┐ │(기부금영수증│ ┌────▼──────┐
└────────────┘ │GIFT(답례품)│ │ e음 발급) │ │RESERVATION│
└──────────┘ └────────────┘ │(예약-라인별)│
┌────────────┐ ┌──────────┐ └───────────┘
│ COMMENT │ │ REVIEW │ (CONTENT/EXPERIENCE/GIFT에 polymorphic 연결)
│(소식 댓글) │ │(별점·후기)│ target_type + target_id
└────────────┘ └──────────┘
주요 13개 엔티티의 대표 컬럼만 발췌. 모든 PK는 uuid(URL은 슬러그--UUID 패턴), 모든 테이블에 created_at/updated_at 공통. FK는 _id 접미사로 표기.
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | uuid | PK |
email / phone | varchar | 로그인 식별, e음 본인확인 연계 |
name | varchar | 실명(기부 영수증용) |
resident_region_code | varchar(5) | 본인 주소지 지자체 코드 - 기부 시 동일 지자체 차단(법령) |
annual_donation_sum | int | 당해연도 누적 기부액, 한도 2,000만원 검증 |
point_balance | int | POINT 집계 캐시 |
marketing_agreed | bool | 비로그인 탐색 허용, 결제 직전만 가입 유도 |
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | uuid | PK |
region_code | varchar(5) | 행안부 법정동 코드(테넌트 키) |
name | varchar | 예: "전남 담양군" |
contract_status | enum | 입점계약: 대기/활성/해지(243곳 개별) |
commission_rate | decimal | 수수료 5~10% (정산 산식 입력값) |
eum_org_id | varchar | 고향사랑e음 기관 연동 ID |
brand_color / logo_url | varchar | 테넌트 브랜딩(지자체관) |
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | uuid | PK |
order_line_id | uuid | FK, line_type=DONATION 라인 1:1 |
local_gov_id | uuid | FK, 기부 대상 지자체 |
donation_type | enum | GENERAL(일반) / DESIGNATED(지정, 제8조의2) |
campaign_id | uuid | FK nullable, 지정기부 시 캠페인 연결 |
amount | int | 기부금액(답례품가의 ÷0.3 이상) |
eum_transaction_key | varchar | e음 접수번호 - 공공시스템 경유 필수 |
tax_deduction_amount | int | 세액공제액(10만↓ 전액, 초과 16.5%) |
gift_id | uuid | FK nullable, 선택한 답례품 |
status | enum | 접수/본인확인/완료/취소 |
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | uuid | PK |
local_gov_id | uuid | FK (테넌트) |
category_id | uuid | FK, 통합 분류 트리 |
title | varchar | 예: "담양 죽녹원 야간 경관조명" |
goal_amount | int | 목표 모금액 |
raised_amount | int | 현재 모금액(게이지 표시) |
participant_count | int | 참여 N명 |
fund_usage | text/json | 사용처 명세(항목별 배분) |
start_at / end_at | timestamp | 모금 기간 |
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | uuid | PK |
local_gov_id | uuid | FK, 공급주체=지자체(법령) |
category_id | uuid | FK, 계층 categoryCode 트리 |
name | varchar | 예: "담양 대통밥 체험 바우처 2인" |
price | int | 답례품 가격 |
min_donation_amount | int | price ÷ 0.3 (30%룰, 최소 기부금) |
gift_kind | enum | 물품 / 바우처(농촌체험) / 숙박 - USP |
linked_product_id | uuid | FK nullable, 놀고팜 실물재고·바로결제 연결 |
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | uuid | PK |
parent_id | uuid | FK self, 계층(adjacency list) |
code | varchar | categoryCode 정규 코드(예: GIFT.FOOD.RICE) |
path | ltree/varchar | materialized path(빠른 하위 조회) |
domain | enum | GIFT / TRAVEL / CONTENT - 단일 트리에서 도메인 구분 |
depth | int | 다중필터 UI 레벨 |
| 컬럼 | 타입 | 비고 |
|---|---|---|
ORDER.id | uuid | PK, 하나의 결제 단위 |
ORDER.user_id | uuid | FK |
ORDER.total_amount | int | 라인 합계 |
ORDER_LINE.order_id | uuid | FK |
ORDER_LINE.line_type | enum | DONATION / RESERVATION / PRODUCT - 정산·영수증 분기 키 |
ORDER_LINE.ref_id | uuid | DONATION/RESERVATION/PRODUCT 대상 ID |
ORDER_LINE.amount | int | 라인 금액 |
ORDER_LINE.settlement_target | enum | EUM(공공) / PG_DIRECT(예약·스토어) - 정산 경로 분리 |
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | uuid | PK |
order_id | uuid | FK 1:1 |
method | enum | 카드/간편결제/계좌이체 |
pg_provider | varchar | 예약·스토어 결제 PG사 |
eum_settlement_ref | varchar | 기부 라인은 e음 정산 경유(직접 정산 불가) |
status | enum | 대기/승인/부분취소/취소 |
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | uuid | PK |
donation_id | uuid | FK 1:1 |
eum_receipt_no | varchar | e음(행안부) 발급번호 - 우리 시스템은 발급 주체 아님 |
deduction_amount | int | 세액공제 확정액 |
carryover_amount | int | 미공제 이월액(최대 10년) |
issued_at | timestamp | 발급일 |
| 엔티티 | 대표 컬럼 | 비고 |
|---|---|---|
| REVIEW | target_type+target_id, rating(1~5), order_line_id | 실구매 검증 후기(평점 0 만연 해소), polymorphic |
| CONTENT | type(아티클/소식/축제), local_gov_id nullable, festival_start_at | 축제 애그리게이터·동네소식 |
| COMMENT | content_id, user_id, parent_id | 소식 댓글(트리) |
| ATTENDANCE | user_id, checked_date(unique), streak_count | 출석체크 모듈, 일 1회 |
| POINT | user_id, amount(±), reason, balance_after | 적립/사용 원장(출석·후기 보상) |
| CART | user_id, line_type, ref_id, qty | 기부·예약·스토어 단일 장바구니 |
parent_id + path(materialized path)로 무한 계층, domain(GIFT/TRAVEL/CONTENT)으로 영역 구분categoryCode와 여행 카테고리가 같은 트리·같은 필터 UI 공유 → 다중필터 일관local_gov_id FK 보유local_gov_id 필터 강제(Row-Level 격리)contract_status)·수수료(commission_rate)·e음 ID를 테넌트별 관리settlement_target=EUMsettlement_target=PG_DIRECT| 규칙 | 적용 위치 | 근거 |
|---|---|---|
| 기부자 본인 주소지 지자체 차단 | DONATION insert 시 user.resident_region_code ≠ local_gov.region_code | 법령(주소지 외 기부) |
| 연 한도 2,000만원 | user.annual_donation_sum + amount ≤ 20,000,000 | 2025.1.1~ |
| 답례품 30%룰 | gift.price ≤ donation.amount × 0.3 (= min_donation_amount 강제) | 답례품가가 최소 기부금 결정 |
| 지정기부=캠페인 필수 | donation_type=DESIGNATED ⟹ campaign_id NOT NULL | 제8조의2 |
| 답례품 공급주체 | gift.local_gov_id = donation.local_gov_id | 공급주체=지자체 |
| 후기 작성 자격 | REVIEW는 status=완료 ORDER_LINE 보유자만 | 평점 신뢰 회복 |
URL 식별자는 전 엔티티 slug--uuid(예: /gift/damyang-bamboo-rice--a1b2…)로 통일, jsessionid·productOld 잔재 제거 및 canonical/JSON-LD 매핑의 기준 키로 사용한다.
KLID)은 기부접수·본인확인·세액공제 영수증의 단일 법정 원장이다. 우리 플랫폼은 기부 행위 자체를 절대 자체 DB로 확정하지 않는다. 모든 기부는 e음 API를 경유해 지자체 기금으로 귀속되고, 우리는 탐색·상담·UX·답례품/체험 커머스를 담당하는 프런트엔드 겸 답례품 공급망 역할로 책임 경계를 명확히 분리한다. 핵심 원칙: 기부금은 우리 매출이 아니다. 답례품·체험 예약 마진과 입점 수수료만 우리 매출이다.기능을 책임 주체별로 분리한다. 법적 효력이 발생하는 영역(기부접수/본인확인/영수증/세액공제)은 전량 e음 경유, 사용자 경험·상품·커머스는 우리가 소유한다.
| 기능 | 처리 주체 | 비고 |
|---|---|---|
| 기부 접수·확정(기부번호 발번) | e음 경유(필수) | 우리 DB는 pending까지만, 확정은 e음 응답으로 |
| 본인확인(실명·주소지 검증) | e음 경유(필수) | 주소지 외 기부 룰 검증은 e음이 최종 판정 |
| 세액공제 영수증·연말정산(홈택스/연말정산 간소화) | e음 경유(필수) | 우리는 발급 사실만 표시, 원본은 국세청 연계 |
| 지정기부 모금액·달성률·목표 데이터 | e음 조회 + 우리 캐시 | 표시는 우리 UI, 수치 원천은 e음(TTL 캐시) |
| 답례품 카탈로그·재고·선택 | 우리 소유 | 공급주체는 법적으로 지자체, 운영은 우리 |
| 농촌체험 바우처·숙박 예약(USP) | 우리 소유 | 놀고팜 실물재고/바로결제 연결 |
| 회원·세션·장바구니·검색·콘텐츠 | 우리 소유 | 단일 GNB/세션, 외부 떠넘김 0건 |
[정상 플로우: 기부 + 답례품 선택 + 체험 바우처] 사용자 우리 플랫폼(BFF/주문서비스) e음 API(KLID) 지자체 기금/PG │ │ │ │ │ 1.기부지자체·금액·답례품 선택(비로그인 탐색 OK) │ │ │─────────────────────▶│ │ │ │ │ 2.룰 사전검증(주소지 외/한도/30%룰) │ │ │ - 클라 즉시 + 서버 재검증 │ │ │ 3.로그인/본인확인(결제 직전 1회) │ │ │─────────────────────▶│ 4.본인확인 요청(CI/주소) │ │ │ │───────────────────────────▶│ 5.실명+주소지 판정 │ │ │◀───────────────────────────│ (주소지 외 OK?) │ │ │ 6.기부 접수요청(idempotencyKey, 멱등) │ │ │───────────────────────────▶│ 7.기부번호 발번 │ │ │ │ → 지자체 기금 귀속│ │ │◀───────────────────────────│ 8.기부확정+영수증ID│ │ │ 9.우리 주문 confirm │ │ │ │ (답례품/체험 = 우리 매출 라인 분리 기록) │ │ │ 10.답례품 결제/체험 바우처 발급(우리 PG)─────────▶│ │◀─────────────────────│ 11.완료(기부영수증+주문번호 동시 표시) │ │ │ │ │ [보상 트랜잭션] 7~10 사이 실패 시: - e음 기부 확정 후 우리 confirm 실패 → e음 기부는 유효, 주문만 재시도 큐 - 답례품 결제 실패 → 기부는 살리고 답례품만 '미수령/재선택' 상태로 분리 - 기부 접수 실패(8 NACK) → 답례품 결제 미실행, 주문 전체 void
핵심: 기부 확정(8단계)이 트랜잭션 경계의 기준점이다. 답례품·체험은 기부 확정 이후에만 결제를 태워 "돈은 빠졌는데 기부는 안 된" 상황을 원천 차단한다.
법령상 개인 본인만, 본인 주소지 외 지자체에만 기부 가능. 검증은 2단계로 한다.
| 검증 항목 | 우리 사전검증 | e음 최종판정 |
|---|---|---|
| 실명/본인 여부 | 본인인증(PASS/간편인증) 통과만 확인 | CI 기준 최종 |
| 주소지 외 여부 | 회원 주소 캐시로 즉시 차단(UX) | 주민등록 주소 기준 최종 |
| 연 2,000만원 한도 | 우리 누적 추정치 경고 | 전국 합산 한도 최종 |
| 답례품 30%룰 | 답례품가 ≤ 기부액×30% 강제 | 접수 시 재검증 |
본인인증 방식은 e음 표준 연계 방식을 따른다(간편인증/공동인증서 등). 우리는 인증 결과 토큰만 보관하고 주민번호 평문은 저장하지 않는다.
한 번의 주문에서 자금 흐름이 둘로 갈린다. 회계·세무·정산 라인을 물리적으로 분리한다.
주문 1건에 order_id 하나, 그 아래 donation_line(e음 기부번호 연결)과 commerce_line(답례품/체험, 우리 매출)을 별 테이블로 둔다. 세금계산서·정산·환불 정책이 라인별로 완전히 다르므로 절대 한 금액으로 합산 기록하지 않는다.
| 항목 | 처리 |
|---|---|
| 기부금 영수증 | e음 발급(전자기부금영수증). 우리는 영수증ID·발급상태만 미러링, 원본 다운로드는 e음/홈택스 링크로 위임 |
| 세액공제 계산 위젯 | 우리 UI 인터랙티브 계산기: 10만원 이하 전액(실질 100%), 초과분 16.5%, 미공제 10년 이월 시각화. 법정 수치는 e음/국세청 기준 고지, 우리 계산은 참고용 명시 |
| 연말정산 간소화 | e음→국세청 연계로 자동 반영. 우리는 "간소화 자동조회 대상" 안내만, 별도 자료 발급 책임 없음 |
| 답례품·체험 결제 증빙 | 우리 PG 영수증/현금영수증(기부영수증과 별개). 30%룰상 답례품가는 세액공제 대상 아님을 UI에 명시 |
전국 243개 지자체와 개별 입점 계약. 수수료 5~10% 구간을 지자체별로 다르게 설정·정산할 수 있는 데이터 모델이 필요하다.
ERD (입점·수수료 핵심) municipality (지자체 243) ├─ muni_id (PK) region_code name └─ status: contracted | pending | suspended partner_contract (입점 계약, muni_id 1:N 가능 - 갱신 이력) ├─ contract_id (PK) muni_id (FK) ├─ fee_rate (DECIMAL 5~10%) # 수수료율 ├─ fee_base: gift_only | gift+exp # 수수료 부과 대상(답례품만/체험포함) ├─ settle_cycle: monthly|biweekly ├─ valid_from / valid_to └─ contract_doc_id # 전자계약 원본 gift_catalog (답례품, muni_id별) ├─ gift_id (PK) muni_id (FK) price category_code └─ supply_source: nolgofarm_stock | local_supplier settlement (정산, 월 마감) ├─ settle_id muni_id period ├─ donation_count / gift_amount / exp_amount ├─ fee_amount = base × fee_rate └─ payout_to_muni / payout_to_us
| 지자체 예시 | 수수료율 | 부과 대상 | 정산주기 |
|---|---|---|---|
| 전북 OO군(체험형 다수) | 7% | 답례품+체험 | 월 정산 |
| 경북 OO시(농산물 위주) | 10% | 답례품만 | 월 정산 |
| 강원 OO군(초기 입점 우대) | 5% | 답례품만 | 격주 |
수수료는 기부금이 아니라 답례품·체험 공급액 기준으로 산정(기부금은 전액 지자체 귀속이므로 우리가 떼지 않음). fee_base 플래그로 체험 매출을 수수료 대상에 포함할지 계약별 토글.
외부 공공 API는 우리 통제 밖이다. "기부는 됐는데 화면엔 실패", "돈은 빠졌는데 기부 안 됨"을 모두 막는다.
idempotencyKey(주문UUID 기반) 부여. 동일 키 재시도 시 e음/우리 모두 중복 발번 금지. 타임아웃 후 무조건 재조회(상태 확인)부터.donation_line 대사(reconciliation). 불일치 건 알림 + 수동 처리 큐.| 장애 상황 | 우리 처리 | 사용자 영향 |
|---|---|---|
| 본인확인 timeout | 재조회 후 미확정 시 재시도 유도 | 결제 미진행(안전) |
| 기부접수 응답 불명 | 조회 API로 발번 확인 후 분기 | 중복기부 0 |
| 기부확정 후 우리 confirm 실패 | outbox 재처리, 주문 자동 복구 | 영수증 정상, 답례품 지연 안내 |
| 답례품 PG 실패 | 기부 유지, 답례품만 재선택 | 기부 효력 보존 |
| # | 확인 항목 | 왜 중요한가 |
|---|---|---|
| 1 | e음 API 연동 규격 - 동기/비동기 여부, 기부확정 콜백 제공 여부, 멱등키 지원 여부 | 6.2/6.7 트랜잭션 설계의 전제 |
| 2 | 민간 플랫폼이 e음 본인확인을 직접 호출 가능한지, 아니면 e음 화면으로 리다이렉트해야 하는지 | 6.3 인증 UX 형태 결정(임베드 vs 리다이렉트) |
| 3 | 지정기부 모금액/달성률 실시간 조회 API 제공 여부 및 갱신 주기 | 기부 깊이 90 목표의 모금률 게이지 정확도 |
| 4 | 전자기부금영수증 발급 시점·우리 미러링 허용 범위 | 6.5 영수증 표시 책임 경계 |
| 5 | 답례품 공급 정산 구조 - 지자체↔플랫폼 직접 정산인지 e음 경유인지 | 6.4/6.6 매출·정산 모델 |
| 6 | 수수료(5~10%) 부과 대상 - 답례품만인지 체험 포함 허용되는지(제도/계약 양면) | USP 수익화 가능성 판가름 |
| 7 | e음 정기점검·SLA·장애 통보 채널 | 6.7 가용성 설계 |
| 8 | 연 2,000만원 한도 전국합산 조회를 플랫폼이 받을 수 있는지(아니면 e음만 판정) | 6.3 사전검증 범위 |
| 9 | 현재 아이러브고향 기존 e음 연동 백엔드의 규격·인증서 재사용 가능 여부 | 레거시 자산 활용/마이그레이션 범위 |
기존 자산: 아이러브고향에 e음 연동 백엔드가 이미 존재하므로, 신규 구축이 아니라 규격 재확인 후 신플랫폼 BFF로 재배선하는 것이 합리적. #9가 1순위 확인 항목.
#F9AA24는 메인 컬러가 아닌 CTA 포인트 전용으로만 사용한다.레거시의 Pretendard 폰트 OTS 디코드 실패 이슈를 해결하기 위해, woff2 단일 포맷의 Pretendard Variable을 self-host한다. font-display: swap으로 FOIT를 방지하고, 시스템 폰트 폴백 스택을 지정해 폰트 로드 실패 시에도 한글 가독성을 보장한다. 숫자(기부액·달성률·세액공제)는 font-variant-numeric: tabular-nums로 자릿수 정렬한다.
@font-face {
font-family: 'Pretendard Variable';
src: url('/fonts/PretendardVariable.woff2') format('woff2-variations');
font-weight: 45 920; font-display: swap;
}
:root { --font-sans: 'Pretendard Variable', -apple-system, 'Apple SD Gothic Neo',
'Noto Sans KR', system-ui, sans-serif; }
타입스케일(모바일퍼스트 기준, px·weight·line-height·용도):
| 토큰 | size(px) | weight | line-height | 용도 |
|---|---|---|---|---|
display | 40 / 데스크탑 56 | 800 | 1.15 | 랜딩 히어로 타이틀 |
h1 | 32 / 40 | 700 | 1.25 | 페이지 단일 h1(상세 답례품·지정기부명) |
h2 | 24 / 28 | 700 | 1.3 | 섹션 제목(사용처 명세, 후기) |
h3 | 20 | 600 | 1.4 | 카드 제목, 위젯 헤더 |
body-lg | 17 | 400 | 1.6 | 아티클 본문 |
body | 15 | 400 | 1.6 | 기본 텍스트, 리스트 |
caption | 13 | 500 | 1.5 | 메타정보(참여 N명, 날짜) |
label | 12 | 600 | 1.4 | 배지(바로결제), 필터칩, 분류코드 |
num-emph | 28 | 800 | 1.2 | 강조 숫자(달성률 %, 세액공제액) — tabular-nums |
최소 본문 15px 이상 유지(접근성). 텍스트가 박힌 이미지는 사용 금지하고 모두 실제 텍스트로 렌더한다(레거시 '텍스트 박힌 이미지' 폐기).
두 서비스의 정체성을 색으로 구분한다. 기부 축(신뢰 톤, 블루)은 아이러브고향·고향사랑기부 흐름에, 체험 축(생기 톤, 그린)은 놀고팜·농촌여행 흐름에 적용한다. CTA·결제·강조 액션은 축과 무관하게 주황 포인트로 통일한다. 위기브 보라/민트는 모던 톤 참고용 액센트로 제한 사용한다.
donate-50 #EEF4FFdonate-100 #D6E4FFdonate-300 #7CA8F0donate-500 #2F6BE0 (기본)donate-600 #1F52BDdonate-700 #163E92donate-900 #0E2A66exp-50 #ECFBF2exp-100 #CFF3DEexp-300 #69CF95exp-500 #18A95B (기본)exp-600 #0F8C49exp-700 #0A6B38exp-900 #074A27cta-400 #FFC04D (hover)cta-500 #F9AA24 (메인 CTA)cta-600 #E08E00 (press)accent-violet #6C5CE7 (위기브 참고)accent-mint #00CEBA (위기브 참고)success #1B9E5A / bg #E7F7EEwarn #E6A100 / bg #FFF6E0danger #DC3545 / bg #FCEBECinfo #2F6BE0 / bg #EEF4FF중립 그레이스케일(텍스트·보더·배경 공통):
| 토큰 | hex | 용도 |
|---|---|---|
gray-0 | #FFFFFF | 표면/카드 배경 |
gray-50 | #F7F8FA | 페이지 배경, 스켈레톤 베이스 |
gray-100 | #EEF0F3 | 구분선 약, 칩 배경 |
gray-200 | #E1E4E9 | 보더 기본 |
gray-400 | #A6ADBA | placeholder, 비활성 |
gray-600 | #5B6473 | 보조 텍스트(caption) |
gray-800 | #2B313B | 본문 텍스트 |
gray-900 | #161A20 | 제목 텍스트 |
대비 검증(WCAG AA): gray-800(#2B313B) on gray-0 = 12.4:1, gray-600 on gray-0 = 5.0:1(본문 AA 통과). CTA 텍스트는 #F9AA24 위 흰 글씨가 대비 미달(약 1.9:1)이므로 주황 버튼의 라벨은 gray-900(#161A20)으로 지정(대비 약 9:1)한다. 동일 색만으로 정보 전달 금지 — 달성률·상태는 색+텍스트+아이콘 병행.
space-1 4 · space-2 8space-3 12 · space-4 16space-5 24 · space-6 32space-7 48 · space-8 64radius-sm 6 (칩·배지)radius-md 10 (버튼·인풋)radius-lg 16 (카드)radius-xl 24 (모달·시트)radius-full 9999 (아바타·게이지)shadow-sm 0 1 2 rgba(22,26,32,.06)shadow-md 0 4 12 rgba(22,26,32,.08)shadow-lg 0 12 28 rgba(22,26,32,.12)sm 640 (큰 모바일)md 768 (태블릿)lg 1024 (상세 2단 분기)xl 1280 (max-width 컨테이너)상세 페이지 레이아웃: lg(1024) 이상에서 좌측 스크롤 콘텐츠 + 우측 sticky 기부/예약 패널(top offset 24px) 2단 구성, 미만에서는 단일 컬럼 + 하단 고정 액션바(sticky bottom CTA).
| 컴포넌트 | 용도 | 상태(variants) | 접근성 규칙 |
|---|---|---|---|
| Button | 주 액션(기부하기·바로결제·예약), 보조·텍스트 버튼 | primary(주황,라벨 gray-900)/secondary(축 컬러 아웃라인)/ghost/destructive, hover·press·disabled·loading | 최소 터치 44×44px, :focus-visible 2px 외곽선, loading 시 aria-busy, 아이콘 단독 버튼은 aria-label |
| Card | 답례품·체험·숙소·아티클 목록 단위 | default/hover-elevate/selected, 축별 상단 라벨 컬러(기부=블루/체험=그린) | 전체 카드 클릭은 <a>로 래핑, 썸네일 alt 필수, 가격·리뷰수 실제 텍스트 |
| 모금률 게이지 | 지정기부 달성률 시각화(목표·현재 모금액·달성%·참여 N명) | 0~99%/100% 달성/초과달성, 막대형·원형 | role="progressbar" + aria-valuenow/min/max, 색만이 아닌 "62% 달성" 텍스트 병기, danger/success 색+라벨 |
| 세액공제 계산 위젯 | 기부액 입력→공제액 인터랙티브 산출(10만 이하 전액→16.5%, 30%룰, 연 2,000만 한도) | 입력중/결과표시/한도초과 경고/0원, 슬라이더+직접입력 | <label> 연결된 인풋, 결과는 aria-live="polite"로 안내, 키보드 조작 가능 슬라이더 |
| 별점 리뷰 카드 | 체험·숙소·답례품 후기(평점·작성자·날짜·본문·사진) | 평점 0~5(0.5 단위), 사진有/無, 더보기 접힘 | 별점은 aria-label="5점 만점에 4.5점", 레거시 '평점 0 만연' 대신 "리뷰 없음" 명시 표기 |
| 바로결제 배지 | 놀고팜 실물재고 즉시결제 가능 상품 식별(USP 동선) | 즉시결제/예약대기/품절 | 색+아이콘+텍스트("바로결제") 3중 표기, label 12px 600, 대비 AA |
| 출석체크 모듈 | 리텐션 — 일일 출석 적립(연속일·캘린더 그리드) | 출석완료/오늘/미래(비활성)/연속보상 | 버튼 44px, 상태를 색+체크아이콘+요일텍스트, 스크린리더용 날짜·상태 라벨 |
| 스켈레톤 | 로딩 중 콘텐츠 자리표시(CLS 방지) | 카드형/리스트형/상세형, shimmer 애니메이션 | 실제 콘텐츠와 동일 치수로 레이아웃 점프 방지, aria-hidden="true"+컨테이너 aria-busy, prefers-reduced-motion 시 shimmer 정지 |
<meta name="viewport" content="width=device-width, initial-scale=1"> — 레거시 줌차단(user-scalable=no, maximum-scale) 제거. 최대 200% 확대 가능.alt(답례품·체험 썸네일=상품명, 장식 이미지=alt=""). 목표 alt 누락 0건.h1 1개, 논리적 헤딩 위계, lang="ko", 키보드 포커스 가시화(:focus-visible), 폼 라벨 연결, 상태 변화 aria-live.디자이너 부재를 고려해 토큰을 코드 단일 출처로 운영한다. CSS Custom Properties(:root) 또는 Tailwind theme.extend에 위 토큰을 그대로 정의하고, 컴포넌트는 Storybook으로 카탈로그화해 상태·접근성을 회귀 검증한다.
| 모듈 | 핵심 기능 | 주 사용 역할 | 법령/신뢰 게이트 |
|---|---|---|---|
| 회원관리 | 개인회원 검색/상태(정상·휴면·정지·탈퇴), 본인확인 이력, 기부 한도(연 2,000만) 누적 조회, CI 중복 차단 | CS매니저 | 본인 주소지 기부 차단 플래그 |
| 지자체 입점/계약 | 243곳 입점 신청·계약·수수료(5~10%) 관리, 담당자 계정 발급, 정산주기 설정 | 제휴매니저 | 계약 미체결 지자체 상품 게시 불가 |
| 답례품 상품/재고 | 상품 등록·카테고리 분류코드, 재고(실물/바우처/숙박), 최소기부금 자동계산 | 지자체운영자 | 0원 가격·재고0 진열 차단, 30%룰 |
| 지정기부 캠페인 | 목표/모금/사용처 등록, 심사 워크플로(제8조의2), 달성률 게이지 데이터 | 지자체운영자+심사관 | 사용처 명세 미입력 시 공개 불가 |
| 농촌여행 상품·예약 | 체험/숙소/캠핑 상품, 예약 캘린더, 바로결제 트랜잭션, 바우처 교환 처리 | 놀고팜운영자 | 무가격·0리뷰 디렉터리 진열 차단 |
| 콘텐츠 CMS | 아티클/동네소식/축제 애그리게이터, AI 생성 큐레이션·승인 큐 | 에디터 | AI 콘텐츠 품질 게이트(미승인 게시 불가) |
| 주문/정산 | 기부·예약 주문 통합, 지자체별 정산 명세, 수수료 차감, 세액공제 영수증 상태 | 정산담당 | e음 영수증 정합성 검증 |
| CS/문의 | 1:1 문의·신고·환불 티켓, SLA 타이머, 매크로 답변 | CS매니저 | - |
| 프로모션/배너 | 배너·기획전·출석체크 보상, 노출 기간/타겟팅 | 마케터 | '팝업존' 플레이스홀더 라이브 차단 |
| 통계·대시보드 | 기부 KPI(총모금·세액공제액·달성률·재기부율), 지자체별/기간별 | 전체(읽기) | - |
| RBAC/권한 | 역할·권한 매핑, 데이터 스코프(지자체 단위), 감사 로그 | 슈퍼관리자 | 최소권한 원칙 |
| 감사/로그 | 전 모듈 변경 이력(누가/언제/무엇), 영수증 발급 추적, 보안 이벤트 | 슈퍼관리자 | ISMS-P 감사 추적 |
최소권한 원칙. 지자체운영자는 자기 지자체 데이터만(data scope = orgId) 접근. 슈퍼관리자만 RBAC·정산 확정 권한 보유.
| 역할 | 회원 | 상품/재고 | 지정기부 심사 | 정산 확정 | CMS 게시 | AI 승인 | RBAC | 데이터 스코프 |
|---|---|---|---|---|---|---|---|---|
| 슈퍼관리자 | 전체 | 전체 | O | O | O | O | O | 전체 |
| 운영총괄 | 조회/제재 | 전체 | O | 요청 | O | O | X | 전체 |
| 심사관 | 조회 | 조회 | O | X | X | 조회 | X | 전체 |
| 정산담당 | 조회 | X | X | O | X | X | X | 전체 |
| 지자체운영자 | X | 자기 org | 등록만 | 조회(자기) | X | X | X | orgId 한정 |
| 에디터 | X | X | X | X | 초안/발행요청 | 큐 검토 | X | CMS만 |
| 마케터 | 세그먼트 | 조회 | X | X | 배너만 | X | X | 프로모션 |
| CS매니저 | 조회/제재 | 조회 | X | 환불요청 | X | X | X | 전체(CS) |
| 놀고팜운영자 | X | 여행상품 | X | 조회(자기) | X | X | X | 여행 공급사 |
레거시 실패(0원 productOld, 캠핑 245p 무가격·0리뷰, 팝업존 플레이스홀더, 평점 0 만연)를 시스템 차원에서 봉쇄. 게시(publish) 시점에 발행 검증기가 차단 사유를 반환하면 상태는 BLOCKED로 떨어지고 절대 노출되지 않는다.
| 차단 룰 | 대상 | 조건 | 동작 | 해제 방법 |
|---|---|---|---|---|
| ZERO_PRICE | 답례품/여행상품 | 판매가 ≤ 0 또는 null | 게시 차단 | 유효 가격 입력 |
| ZERO_PROGRESS_DISPLAY | 지정기부 캠페인 | 달성률 0%인데 '인기/추천' 슬롯 배정 | 추천 슬롯 제외 | 일반 목록만 노출 허용 |
| NO_STOCK | 답례품(실물) | 재고 0이고 '품절표시' 미설정 | 목록 숨김 | 재고 입고 또는 품절배지 |
| NO_USAGE_SPEC | 지정기부 | 사용처 명세·목표금액 미입력 | 공개 차단 | 제8조의2 항목 완비 |
| RULE_30_VIOLATION | 답례품 | 답례품가 > 기부액 30% | 매칭 차단 | 최소기부금 상향 |
| PLACEHOLDER_LIVE | 배너/팝업 | 이미지/링크 비어있음 | 노출 차단 | 실제 소재 등록 |
| AI_NOT_APPROVED | AI 콘텐츠 | 승인 상태 ≠ APPROVED | 게시 차단 | 에디터 승인 |
| MISSING_ALT | 전 콘텐츠 | 대표 이미지 alt 누락 | 발행 경고+차단 | alt 입력(접근성) |
AI가 농촌여행/지역/제도 아티클·큐레이션 초안을 생성하되, 사람 승인 없이는 절대 게시 불가. 자동 품질 점수가 임계 미만이면 승인 큐에 도달조차 못하고 반려된다.
| 품질 지표 | 임계값 | 미달 시 |
|---|---|---|
| 중복 유사도 | < 0.85 | 자동 반려 |
| 사실 근거 링크 | 주장당 ≥ 1 | 승인 큐 보류 |
| 법령 수치 정확성 | 100% 일치 | 자동 차단 |
| 금칙어/과장 | 0건 | 하이라이트 표시 |
| alt·h1·길이 | 충족 | 발행 차단 |
Municipality(orgId PK, 명칭, 계약상태, 수수료율%, 정산주기)
│1 │1
│N 답례품 │N 지정기부
RewardItem(id PK, orgId FK, 분류코드, Campaign(id PK, orgId FK, 목표액,
판매가, 재고, 최소기부금, 모금액, 달성률%, 사용처명세,
상태[DRAFT|PUBLISHED|BLOCKED]) 심사상태[등록|심사중|승인|반려])
│ │
└──────────┐ ┌───────────┘
│N │N
Order(id PK, memberId FK, type[기부|예약],
금액, orgId FK, 결제상태, 영수증상태)
│1
│1 e음 연동
TaxReceipt(id PK, orderId FK, e음발급ID,
공제유형[전액|16.5%], 공제액, 정합성[OK|불일치])
│
Settlement(id PK, orgId FK, 기간, 총주문액,
수수료차감, 지급예정액, 상태[대기|확정|지급])
Member(id PK, CI, 주소지코드, 연누적기부액, 상태)
Content(id PK, type[아티클|소식|축제], origin[휴먼|AI],
품질점수, 승인상태, alt충족, 게시상태)
AuditLog(id PK, actorId, action, target, before/after, ts)
| KPI | 정의/산식 | 분해 축 | 목표 알림 |
|---|---|---|---|
| 총모금액 | 기간 내 기부 주문 합계 | 지자체/기간/지정vs일반 | 전월 대비 -10% 시 |
| 캠페인 달성률 | 모금액 / 목표액 × 100 | 캠페인별 | 마감 D-7 & 50% 미만 |
| 세액공제 발급액 | e음 영수증 공제액 합 | 전액(10만↓)/16.5% | 정합성 불일치 발생 즉시 |
| 답례품 전환율 | 기부완료 / 답례품 조회 | 분류코드별 | - |
| 바우처 교환율 | 여행 바우처 사용 / 발급 | 체험/숙박 | 미사용 만료 임박 |
| 재기부율 | 2회+ 기부자 / 전체 기부자 | 월 코호트 | - |
| AI 콘텐츠 승인율 | 승인 / AI 생성 | 주간 | <60% 시 모델 점검 |
| 차단 진열 건수 | BLOCKED 상태 상품/콘텐츠 | 차단 룰별 | 신뢰 모니터링 |
TaxReceipt에 e음발급ID 매핑, 정합성 자동 대사(불일치 시 정산 보류)| 단계 | 기간 | 산출물 | 완료 기준(DoD) |
|---|---|---|---|
| P0 기반 | 2주 | RBAC·감사로그·인증, 데이터 모델 마이그레이션 | 9개 역할 권한 매트릭스 동작, 모든 변경 감사 기록 |
| P1 핵심 | 4주 | 회원·답례품·지정기부·진열 차단 게이트 | 0원/30%룰/사용처 미입력 게시 100% 차단 |
| P2 거래 | 3주 | 주문·e음 영수증 대사·정산 | 영수증 정합성 자동 대사, 지자체별 정산 명세 생성 |
| P3 콘텐츠 | 3주 | CMS·AI 품질 게이트·승인 큐 | AI 미승인 게시 불가, 품질점수 미달 자동 반려 |
| P4 운영 | 2주 | 대시보드 KPI·CS·프로모션 | 기부 KPI 8종 실시간, 팝업존 플레이스홀더 차단 |
전 모듈 공통: 모바일에서도 검수 큐·CS 티켓 처리 가능한 반응형 백오피스. 표 기반 일괄 작업(다중선택 승인/반려/차단)으로 디자이너·기획자 없는 소수 운영 인력의 처리량 확보.
| 레이어 | 권고 기술 | 버전·구성 | 선택 근거 (대안 대비) |
|---|---|---|---|
| 프론트엔드 | Next.js + React + TypeScript | Next 14 App Router, React 18, TS 5 | 상세 페이지는 SSR/ISR로 TTFB·SEO 동시 확보(JSON-LD/canonical 서버 주입). 레거시 jQuery 3.x+서버렌더 완전 폐기. 모바일퍼스트 단일 반응형을 컴포넌트로 강제. |
| 렌더링 전략 | ISR + 부분 SSR | 답례품/상품 ISR revalidate 60s, 모금현황 SSR | 지자체 카탈로그(243곳)는 변경 빈도 낮아 ISR로 캐시 적중률 극대화. 모금액/달성률만 실시간. |
| 백엔드 (권고) | Kotlin + Spring Boot 3 | JDK 21(Virtual Thread), Spring Boot 3.3, Gradle | 고향사랑e음(행안부/KLID) 본인확인·기부접수·세액공제 영수증 연동은 PG·금융권 SOAP/XML·전자서명 생태계와 맞물리며, JVM 진영의 검증된 보안·트랜잭션 라이브러리(Spring Security, 전자서명 모듈)가 압도적으로 풍부. 세액공제 30%룰·2,000만 한도·10년 이월 같은 금액 정합성 로직은 강타입+트랜잭션 보장이 유리. |
| 백엔드 (대안) | Node + NestJS | Node 20, NestJS 10 | 프론트와 언어 통일(생산성)·BFF 구성엔 유리하나, 공공·결제 연동의 보안 감사·전자서명·정밀 금액연산에서 약점. BFF 한정으로만 부분 채택 가능(아래 9.3). |
| 주 DB | PostgreSQL 16 | RDS Multi-AZ, 읽기 복제 1대 | 기부 트랜잭션 ACID, JSONB(답례품 속성), citext·파티셔닝(연도별 기부내역). UUID PK로 슬러그--UUID URL 정책 직접 지원. |
| 검색 | OpenSearch 2.x | 3노드 클러스터(소형) | 답례품 계층 분류코드+다중필터+한글 형태소(Nori)·자동완성. PG full-text로 시작 후 데이터 증가 시 승격하는 단계적 도입 허용. |
| 캐시·세션 | Redis 7 | ElastiCache, AOF | 세션 저장소(jsessionid 제거의 핵심)·모금률 게이지 카운터·세액공제 위젯 결과 캐시·결제 멱등키. 피크 시즌 read 폭증 흡수. |
| 객체 스토리지 | Amazon S3 | 버킷 분리(public/private) | 답례품·체험·후기 이미지 원본. Pretendard 폰트 OTS 디코드 실패 자산을 정상 woff2로 교체·서빙. |
| CDN | CloudFront | OAC, Brotli, 이미지 최적화 | 정적·ISR 캐시 엣지 배포로 TTFB<100ms 달성의 1차 수단. next/image + AVIF/WebP로 LCP 개선. |
| 결제 PG | 토스페이먼츠 또는 NHN KCP | 결제창 + 정산 API | 놀고팜 '바로결제'(실물·체험 즉시결제) 동선. 지자체 수수료 5~10% 정산 리포트 연동. |
| 간편인증 | 본인확인 PASS(통신 3사) + 카카오/네이버 로그인 | NICE/KCB 본인인증 | 기부는 개인·실명·본인 주소지 외 제약상 본인확인 필수. 단 탐색 전과정 비로그인, 로그인·인증은 결제 직전에만 트리거. |
┌─────────────────────────────┐
사용자(모바일퍼스트) │ CloudFront (CDN, TLS1.3) │
───────────────────▶│ WAF / OWASP 룰 / 봇 차단 │
└───────────────┬─────────────┘
정적·ISR 캐시 ┌──────────┴──────────┐ /api/*
┌───────────▶│ Next.js (SSR/ISR) │───────┐
│ │ next/image, JSON-LD │ │ (BFF, 인증 토큰)
│ └─────────────────────┘ ▼
┌─────┴─────┐ ┌───────────────────────┐
│ S3 │◀── 이미지/폰트(woff2) ────│ ALB (Multi-AZ) │
│ 원본 자산 │ └──────────┬────────────┘
└───────────┘ ▼
┌──────────────────────────────────────┐
│ Spring Boot 3 (모듈러 모놀리스) │
│ ├ donation (기부·한도·세액공제 30%룰) │
│ ├ catalog (답례품·상품·분류코드) │
│ ├ booking (체험·숙박·바로결제) │
│ ├ search (OpenSearch 색인/질의) │
│ ├ content (아티클·후기·출석체크) │
│ └ identity (세션·간편인증·권한) │
└──┬─────────┬─────────┬─────────┬───────┘
▼ ▼ ▼ ▼
┌──────────┐ ┌───────┐ ┌────────┐ ┌──────────┐
│PostgreSQL│ │ Redis │ │OpenSrch│ │외부 연동 │
│Multi-AZ │ │세션/캐시│ │검색색인 │ │e음/PG/PASS│
│+읽기복제 │ └───────┘ └────────┘ └──────────┘
└──────────┘
외부 연동: 고향사랑e음(본인확인·기부접수·세액공제 영수증) / PG(결제·정산) / 간편인증(PASS·카카오)
관측: OpenTelemetry → Prometheus + Grafana + Loki / Sentry(FE·BE)
| 기준 | 모듈러 모놀리스 (권고) | 마이크로서비스 (비권고) |
|---|---|---|
| 운영 복잡도 | 단일 배포·단일 로그·로컬 트랜잭션 | 분산 트랜잭션(Saga)·서비스 메시 운영부채 |
| 조직 적합성 | 디자이너·기획자 없는 소규모 팀에 최적 | 팀당 서비스 소유 전제 — 인력 부족 |
| 금액 정합성 | 기부+장바구니+결제 단일 DB 트랜잭션 | 서비스 간 정합성 보장 비용 큼 |
| 피크 대응 | 스테이트리스 → 수평 확장으로 충분 | 세밀하나 과한 정교함 |
| 이행성 | 모듈 경계 보존 → 추후 분리 용이 | - |
BFF는 Next.js Route Handler가 담당(인증 토큰 핸들링·응답 조합). 별도 Node/NestJS BFF는 도입하지 않아 운영 단순성을 지킨다.
| 분류 | 지표 | 목표(SLO) | 달성 수단 |
|---|---|---|---|
| 성능 | TTFB | < 100ms (캐시 적중) | CloudFront 엣지 캐시 + ISR + Redis |
| LCP | < 2.5s (모바일 4G) | next/image AVIF, 폰트 woff2 preload, 스켈레톤 | |
| CLS / INP | CLS < 0.1 / INP < 200ms | 스켈레톤·이미지 width/height 고정으로 레이아웃 점프 제거 | |
| 가용성 | 월 가용성 | 99.9% (월 다운 43분 이내) | ALB+ASG Multi-AZ, RDS Multi-AZ 자동 페일오버, 무중단 배포 |
| 확장성 | 피크 처리량 | 평시 대비 10배(연말 세액공제 마감·기부 시즌) | 스테이트리스 앱 HPA 오토스케일, Redis 캐시, 읽기복제 분산, 큐(SQS)로 e음 연동 비동기 흡수 |
| 동시 결제 | 피크 500 TPS | 결제 멱등키(Redis), PG 비동기 콜백, 재고 락 최소화 | |
| 보안 | 인증·세션 | jsessionid URL 노출 0건 | URL rewrite 세션ID 폐기 → HttpOnly·Secure·SameSite 쿠키 + Redis 세션, 토큰 회전 |
| 표준 준수 | ISMS-P / ISO 27001 대응 | 개인정보 암호화(AES-256, 전송 TLS1.3), 접근통제·감사로그, 망분리 검토 | |
| 웹 취약점 | OWASP Top 10 | WAF 룰셋, CSP 헤더, CSRF 토큰, SQLi(파라미터 바인딩)·XSS 자동 이스케이프, 의존성 SCA | |
| 개인정보 | 최소수집·법령 준수 | 기부 본인확인 데이터는 e음 경유 처리, 주민번호 미저장(CI/DI만), 결제정보 PG 토큰화 | |
| 관측성 | 분산 추적 | p95 지연 추적 100% | OpenTelemetry 계측 → Tempo/Jaeger, traceId 전구간 전파 |
| 로그·메트릭 | 중앙 집계 | Prometheus(메트릭)+Loki(로그)+Grafana 대시보드, 골든 시그널 | |
| 에러·알림 | 탐지 < 1분 | Sentry(FE/BE) + Alertmanager → Slack, SLO 번레이트 경보 | |
| 접근성·SEO | 마크업 정합 | h1 1개, alt 누락 0, lang=ko | CI 린트(axe-core, html-validate), 이미지 alt 필수 검증 |
| 구조화 데이터 | canonical·JSON-LD 100% | SSR에서 Product/Article/Organization 스키마 주입, sitemap 자동 생성 |
productOld·jsessionid 파라미터 완전 제거, /{slug}--{uuid} 패턴 + canonical 강제.font-display: swap + preload.참고: 검색(OpenSearch)·결제·인증 같은 외부 의존은 장애 격리를 위해 서킷 브레이커(Resilience4j)와 폴백(검색 다운 시 PG full-text 폴백)을 적용한다.
마이그레이션 대상을 이관(carry-over), 정제(cleanse), 폐기(retire)로 분류한다. 잘못된 데이터를 그대로 신규로 옮기면 신규 플랫폼이 레거시의 신뢰 문제를 상속하므로, 추출 단계에서 게이트를 건다.
| 영역 | 현 상태(레거시) | 판정 | 신규 처리 |
|---|---|---|---|
| 회원/세션 | jQuery 3.x + 서버세션 jsessionid URL 노출 | 정제 | HttpOnly 쿠키/JWT 세션으로 재발급, URL에서 세션ID 제거 |
| 스토어 상품 | productOld 테이블 잔존, 0원 가격 상품 라이브 | 정제·폐기 | productOld 폐기, 0원·null 가격 상품 UNPUBLISHED 격리 후 검수 |
| 캠핑 카탈로그 | 245p 무가격·0리뷰 디렉터리, 평점 0 만연 | 정제 | 가격 없는 항목 비공개, 평점 0은 '리뷰 없음'으로 표기(별 0개 노출 금지) |
| 폰트/렌더 | Pretendard OTS 디코드 실패(woff2 깨짐) | 폐기 | Pretendard Variable woff2로 교체, font-display:swap |
| 아이고 홈 | '팝업존' 플레이스홀더가 프로덕션 라이브 | 차단(P0) | 레거시에서 즉시 제거, 신규는 실데이터 모금 캐러셀로 대체 |
| 모바일 | 분기형(m. 별도 템플릿) | 폐기 | 모바일퍼스트 단일 반응형으로 통합, 분기 라우팅 제거 |
| e음 연동 백엔드 | 기부접수·본인확인·세액공제 영수증 API(아이러브고향) | 이관(무변경) | 그대로 프록시 승계, 엔드포인트·인증키 유지 |
| '바로결제' 트랜잭션 | 놀고팜 실물 PG 결제 일부 운영 | 이관 | 주문/결제 원장 무손실 이전, 진행 중 주문은 레거시에서 종결 |
아래 4건은 신규 오픈을 기다리지 않고 레거시 프로덕션에서 먼저 수정/차단한다. 잠재 기부자·예약자에게 노출되는 동안 발생하는 신뢰 손실이 비용보다 크기 때문이다.
| # | 버그 | 증상 | 즉시 조치 | 리드타임 |
|---|---|---|---|---|
| P0-1 | 0원 가격 상품 | 스토어/답례품에 '0원' 결제 가능 항목 노출 | 가격 ≤ 0 또는 null 인 SKU 전수 WHERE price<=0 비공개 처리, 결제 API에 가격 검증 추가 | 즉시(1일) |
| P0-2 | productOld 잔존 | 구 상품 테이블이 검색/리스트에 섞여 중복·유령 상품 | productOld 참조 라우트 차단, 신규 product 단일 소스로 강제 | 2일 |
| P0-3 | 팝업존 플레이스홀더 | 아이고 홈 메인 영역에 더미 콘텐츠 라이브 | 해당 위젯 즉시 숨김 또는 실데이터 모금 현황으로 교체 | 즉시(0.5일) |
| P0-4 | Pretendard OTS 실패 | 본문 폰트 깨짐/시스템폰트 폴백, 위계 붕괴 | woff2 정상본 재배포, OTS 깨진 파일 제거 | 1일 |
P0 차단은 신규 빌드와 병행 가능한 독립 작업이다. 레거시 코드 동결(freeze) 전 마지막 핫픽스로 처리하고, 이후 레거시는 읽기 위주 유지보수 모드로 전환한다.
추출(Extract)→정제·변환(Transform)→적재(Load) 3단계. 핵심 변환은 정수 PK → 슬러그--UUID 매핑, 레거시 ID → 신규 ID 매핑 테이블 영구 보존(301 리다이렉트·외부 참조 복원에 사용)이다.
| 도메인 | 원본 | 레코드 규모(추정) | 변환 규칙 | 검증(완료 기준) |
|---|---|---|---|---|
| 회원 | 레거시 user(2도메인 분리) | 통합 단일 계정 | 이메일/CI 기준 중복 병합, 비밀번호 해시 그대로 이전(불가 시 재설정 유도), 동의이력 승계 | 중복 0건, 로그인 성공률 ≥ 99% |
| 상품(예약/스토어) | product (+productOld 제외) | 체험6·숙소·캠핑5·스토어·우수체험관 | productOld 전량 제외, 0원 제외, 슬러그--UUID 부여, 카테고리 분류코드 재매핑 | 가격 누락 0건, 카테고리 미분류 0건 |
| 답례품 | 지자체 답례품 카탈로그 | 지자체별 N(243곳 일부) | 계층 분류코드 부여, 30%룰 검증(답례품가 ≤ 기부액×0.3), 공급주체=지자체 명시 | 30%룰 위반 0건, 공급지자체 매핑 100% |
| 기부 이력 | e음 연동 donation | 누적 기부 트랜잭션 | 원장 무변경 이전, e음 접수번호·영수증 키 보존, 지정기부(제8조의2) 플래그 보존 | 금액 합계 일치(원 단위), 영수증 조회 100% |
| 예약/주문 | reservation/order, '바로결제' PG | 예약·실물주문 | 상태머신 재매핑(대기/확정/취소/환불), PG 거래ID 보존 | 금액·상태 정합 100%, 미정산 0건 |
| 콘텐츠/후기 | article·review·notice | 아티클·후기·공지 | 평점 0 → '리뷰없음' 정규화, 이미지 경로 CDN 재배치, alt 결손 보강 | 깨진 이미지 0건, alt 누락 0건 |
레거시 ID 매핑 테이블(영구 보존) ┌──────────────┬───────────────┬──────────────────────────────┬─────────┐ │ legacy_domain│ legacy_id │ new_uuid │ slug │ ├──────────────┼───────────────┼──────────────────────────────┼─────────┤ │ nolgofarm │ product/1024 │ 7f3a...e21 │ 곡성-딸기체험 │ │ ilovegohyang │ donation/55012│ a1c9...09b │ - │ │ ilovegohyangai│ rec/88 │ (폐기, AI추천 신규 재생성) │ - │ └──────────────┴───────────────┴──────────────────────────────┴─────────┘ 용도: ① 301 리다이렉트 소스 ② 외부 백링크/검색엔진 인덱스 복원 ③ 기부영수증 역추적
예약(nolgofarm)·기부(ilovegohyang)·AI추천(ilovegohyangai.org) 3분할을 폐기하고 단일 도메인·단일 GNB·단일 세션·단일 장바구니·단일 검색으로 흡수한다. AI추천은 별도 도메인을 두지 않고 신규 플랫폼 내 추천 모듈로 내재화한다. 코드 내부의 toNolgofarm()·toGohyang() 같은 도메인 간 점프 라우팅은 내부 경로로 흡수해 외부 떠넘김(redirect to other domain)을 0건으로 만든다.
| 레거시 도메인 | 역할 | 통합 후 경로 | 리다이렉트 |
|---|---|---|---|
| nolgofarm.com | 농촌여행 예약/스토어 | 신규 단일 도메인의 /experiences, /store | 301(canonical 단일 도메인) |
| ilovegohyang.nolgofarm.com | 고향사랑기부 | /donation, /rewards | 301 |
| ilovegohyangai.org | AI 추천(별도 도메인) | 내부 추천 모듈 /recommend 흡수, 도메인 폐기 | 301 → 홈/추천 |
<link rel="canonical"> 단일 도메인 지정, jsessionid 등 세션 파라미터를 URL에서 완전 제거.Product/Event/Offer/BreadcrumbList) 구조화 데이터 부여, <html lang="ko">, 페이지당 h1 1개.sitemap.xml 제출 + 구 도메인 sitemap에 리다이렉트 적용, Search Console 주소 변경 신고로 인덱스 이전 가속.빅뱅 전환을 피하고, 신규 플랫폼이 레거시를 화면 단위로 '조여 가며(strangle)' 트래픽을 흡수한다. 리버스 프록시(엣지 라우터)가 경로별로 신규/레거시를 분기하고, 비율을 점진 상향한다.
[사용자/검색봇]
│
[엣지 리버스 프록시] ← 경로/비율 기반 라우팅, 즉시 롤백 스위치
├── /donation/** → 신규(병행 검증 후 100%)
├── /experiences/* → 신규
├── /store/** → 신규 (P0 정제 완료분만)
├── /e음-callback/* → 레거시 백엔드 그대로 프록시(변경금지)
└── /legacy/** → 레거시(잔여 트래픽, 점차 0으로)
| 단계 | 기간 | 범위 | 트래픽 배분 | 완료 게이트(Exit) |
|---|---|---|---|---|
| 0. 동결·차단 | 1주 | P0 4건 레거시 핫픽스, 레거시 코드 freeze | 레거시 100% | P0 0건, 매핑 테이블 1차 완성 |
| 1. 섀도 마이그레이션 | 2주 | ETL 리허설(읽기 전용), 데이터 정합 대사 | 레거시 100% | 금액 합계 일치, 검증 쿼리 전부 통과 |
| 2. 카나리 | 1~2주 | 저위험 화면(콘텐츠/아티클/상세) 신규 노출 | 신규 5→25% | 오류율 < 0.5%, TTFB < 100ms, CLS 안정 |
| 3. 기부 동선 전환 | 2주 | 기부/답례품/세액공제 위젯, e음 콜백 병행 | 신규 50% | 영수증 발급 100%, 30%룰 위반 0 |
| 4. 예약/결제 전환 | 2주 | 예약·'바로결제'·장바구니 통합 | 신규 80% | 결제 성공률 ≥ 레거시, 미정산 0 |
| 5. 전면 컷오버 | 1주 | 레거시 읽기전용, 301 전면 적용 | 신규 100% | 404 0건, 구 도메인 인덱스 이전 시작 |
| 6. 레거시 폐기 | 전환 +90일 | 레거시 인프라 회수(리다이렉트만 잔존) | - | 리다이렉트 외 레거시 호출 0 |
| 리스크 | 영향 | 발생 가능성 | 대응 |
|---|---|---|---|
| e음 연동 콜백/인증키 도메인 불일치 | 기부 접수·영수증 발급 중단(법적·신뢰 직결) | 중 | 전환 전 e음 측 신규 도메인 화이트리스트 등록·샌드박스 검증, 콜백은 단계 6까지 레거시 경유 유지 |
| 기부/결제 이중 기록 | 중복 청구·정산 오류 | 중 | 금전 SoT 단일화, 멱등키(idempotency key) 적용, 일 단위 금액 대사 |
| 0원·productOld 잔재가 신규로 유입 | 신뢰훼손 재발, 결제 사고 | 중 | ETL 추출 게이트(price>0, productOld 제외)와 적재 후 검증 쿼리 이중 차단 |
| SEO 순위 하락 | 유입 감소 | 중 | 1:1 301 전수 매핑, canonical/sitemap/JSON-LD, Search Console 주소 변경, 404 0건 모니터링 |
| 구 슬러그/백링크 깨짐 | 외부 유입 404 | 높음 | 매핑 테이블 기반 리다이렉트를 단계 6 이후에도 무기한 유지 |
| 회원 비밀번호 해시 비호환 | 로그인 실패 | 낮음 | 해시 알고리즘 호환 검토, 불가 시 첫 로그인 시 무중단 재해싱 또는 재설정 유도 |
| 243 지자체 정산/수수료 매핑 누락 | 정산 분쟁 | 낮음 | 입점 계약·수수료율(5~10%) 키 매핑 테이블화, 전환 전 지자체 확인 회신 수취 |
| 전환 중 장애·트래픽 급증 | 일시 접속 저하 | 낮음 | 엣지 비율 점진 상향, 즉시 롤백 스위치, 저트래픽 시간대 전환 |
jsessionid URL 노출 0, alt 누락 0, h1 1개/페이지, lang=ko, JSON-LD/canonical 적용, TTFB < 100ms.stage-gate 방식. 5개 병행 트랙(기반·기부·여행·콘텐츠·Admin)이 동시 진행되며, 트랙별 의존성은 표의 '의존성' 열로 통제.| 단계 | 기간(주) | 스프린트 | 한 줄 목표 | 진입 KPI 게이트(통과 기준) |
|---|---|---|---|---|
| P0 긴급 안정화 + 도메인 결정 | 3주(W1-3) | S0 | 치명 버그 제거 + 단일 도메인 확정 | 도메인 1개 확정·DNS 전환 완료, 0원가격·jsessionid·팝업존 플레이스홀더 라이브 0건, Pretendard OTS 디코드 실패 해소, Lighthouse 접근성 70+ |
| P1 기부 깊이 + 차별 동선 | 7주(W4-10) | S1-S3 | 기부 깊이 90 + 답례품↔체험 연결 | 세액공제 위젯·모금률 게이지·다중필터 라이브, 비로그인 전과정 탐색 100%, e음 연동 결제 성공률 98%+, 기부 깊이 내부평점 88+ |
| P2 콘텐츠 · 리텐션 | 8주(W11-18) | S4-S7 | 콘텐츠·리텐션 80 + 통합 88 | 아티클 30편+·축제 애그리게이터·출석체크·후기 커뮤니티 라이브, 통합 점수 88+, 주간 재방문율(WAU/MAU) 25%+ |
| P3 고도화 | 10주(W19-28) | S8-S13 | 총점 86.2 달성 + 운영 자동화 | 목표 프로파일 전 영역 충족, 입점 지자체 50곳+, 결제 전환율 P1 대비 +20%, ISMS-P 준비 점검 통과 |
slug--UUID, canonical/JSON-LD, lang=ko| 스프린트 | 트랙 | 마일스톤 | 산출물 | 의존성 | Exit criteria |
|---|---|---|---|---|---|
| S0 (W1-3) | 기반 | M0.1 도메인 통합 결정 | 단일 도메인 확정(nolgofarm.com 권장), ilovegohyang.*·ilovegohyangai.org 301 리다이렉트 맵, DNS·SSL 전환 | 없음(최우선) | 3도메인→1도메인, 외부 떠넘김 0건, 리다이렉트 404 0건 |
| 기반 | M0.2 치명 버그 박멸 | 스토어 productOld·0원가격 제거, jsessionid/URL 세션 제거, 팝업존 플레이스홀더 제거, Pretendard Variable 폰트 정상화(OTS 해소) | M0.1 | 0원상품 0건, 줌차단 해제, 폰트 렌더 100% | |
| 기부 | M0.3 e음 연동 점검 | 기존 아이러브고향 e음 백엔드 헬스체크, 결제·영수증 경로 회귀 테스트 | 없음 | 기존 기부 트랜잭션 무중단 |
P0 KPI 게이트 미통과 시 P1 착수 보류. 도메인 결정은 SEO 자산·브랜드·검색 노출을 고려한 단일 의사결정으로, 이후 모든 트랙의 선행 의존성.
| 스프린트 | 트랙 | 마일스톤 | 산출물 | 의존성 | Exit criteria |
|---|---|---|---|---|---|
| S1 (W4-5) | 기반 | M1.1 디자인시스템 v1 | 2축 팔레트(기부 신뢰톤/체험 생기톤), 주황 #F9AA24 CTA, 공용 컴포넌트(모금률 게이지·세액공제 위젯·별점카드·바로결제 배지·스켈레톤) | M0.2 | CLS<0.1, 컴포넌트 8종 스토리북 등록 |
| 기반 | M1.2 통합 셸 | 단일 GNB/세션/장바구니/검색, 모바일퍼스트 단일 반응형 | M0.1 | 예약+기부 1세션 1카트, 분기형 모바일 폐기 | |
| S2 (W6-7) | 기부 | M1.3 답례품 카탈로그 | 계층 분류코드 + 다중필터(지역·가격·카테고리·답례품유형), 답례품 가격→최소 기부금 자동 산정(30%룰) | M1.1 | 필터 4축, 30%룰 검증 100% |
| 기부 | M1.4 세액공제 위젯 | 인터랙티브 계산기(10만 전액 100%→초과 16.5%, 연 2,000만 한도, 10년 이월 안내) | M1.1 | 법령 케이스 자동 테스트 통과 | |
| S3 (W8-10) | 기부 | M1.5 지정기부 + 비로그인 동선 | 모금액/달성률%/목표/참여N명/사용처 명세, 좌측 스크롤+우측 sticky 패널, 비로그인 전과정 탐색(로그인=결제 직전만) | M1.3, M1.4 | 비로그인 탐색 100%, 모금 게이지 실시간 |
| 여행 | M1.6 답례품↔체험 연결(USP) | 농촌체험 바우처/숙박을 답례품 카탈로그에 연결, 놀고팜 실물재고+바로결제 단일 동선 | M1.5, M1.2 | 바우처 발급→체험 예약 E2E 성공 |
| 스프린트 | 트랙 | 마일스톤 | 산출물 | 의존성 | Exit criteria |
|---|---|---|---|---|---|
| S4 (W11-12) | 콘텐츠 | M2.1 아티클 엔진 | 농촌여행/지역/제도 아티클 CMS, JSON-LD Article, 초기 30편 | M1.1 | 아티클 30편 발행, 검색 인덱싱 |
| S5 (W13-14) | 콘텐츠 | M2.2 축제 애그리게이터 + 동네소식 | 지역 축제 수집·노출, 동네소식 피드 | M2.1 | 축제 데이터 50건+ 자동 갱신 |
| S6 (W15-16) | 콘텐츠 | M2.3 출석체크 + 후기 커뮤니티 | 출석체크 모듈(리텐션), 후기/리뷰 작성·노출, 평점 0 만연 해소 | M1.2 | 출석 연속 7일 기능, 신규 리뷰 수집 |
| S7 (W17-18) | 여행 | M2.4 체험 디렉터리 정비 | 캠핑 245p 무가격·0리뷰 디렉터리에 가격·리뷰·스켈레톤 채움, 6하위 체험 분류 | M2.3 | 무가격 페이지 0건, 리뷰 커버리지 60%+ |
| 스프린트 | 트랙 | 마일스톤 | 산출물 | 의존성 | Exit criteria |
|---|---|---|---|---|---|
| S8-9 (W19-22) | Admin | M3.1 지자체 운영 콘솔 | 243곳 입점 워크플로(개별 계약·수수료 5~10%), 답례품 카탈로그 셀프 운영, 정산 | M1.3 | 입점 지자체 50곳+ 온보딩 |
| S10-11 (W23-26) | 기반 | M3.2 성능·SEO·접근성 풀튠 | TTFB<100ms, alt 0누락, h1 1개, canonical/JSON-LD 전면, 줌해제, 텍스트 박힌 이미지→실제 텍스트 | 전 트랙 | Lighthouse 접근성 85+, 기술 85+ |
| S12-13 (W27-28) | 기반/Admin | M3.3 보안·관측·전환 최적화 | ISMS-P급 보안 점검, 모니터링/로그, 결제 퍼널 A/B, 개인화 추천 | M3.1, M3.2 | 총점 86.2, 전환율 P1 대비 +20% |
임계 경로(Critical Path): M0.1 도메인결정 ─▶ M1.2 통합셸 ─▶ M1.3 답례품 ─▶ M1.5 지정기부 ─▶ M1.6 USP연결 ─▶ M3.1 입점콘솔 ─▶ M3.3 최종 병행 가능(임계 경로 외): 콘텐츠 트랙(M2.1~2.3) … M1.1 이후 독립 진행 성능/접근성 풀튠(M3.2) … 전 트랙 산출물 위에서 마감 게이트: [P0게이트] [P1게이트] [P2게이트] [P3 최종게이트] 주차: W3 ──────── W10 ──────────── W18 ──────────── W28
병목 1순위는 e음 API 연동(공공 시스템 경유, 본인확인·영수증)과 지자체 개별 입점 계약(243곳)이며, 둘 다 외부 일정 의존이므로 P1·P3 게이트 통과 시점의 최대 리스크 요인. 입점 계약은 P1과 병행해 영업 트랙으로 선행 착수 권장.
| 단계 | 기간 | 누적 | 핵심 산출물 | 마일스톤 |
|---|---|---|---|---|
| P0 발견·설계 | 1개월 | M1 | IA 확정, 디자인시스템(Pretendard Variable) 토큰, ERD/API 명세, e음 연동 스펙 | 착수 승인 |
| P1 MVP 구축 | 4개월 | M5 | 단일 GNB/세션/장바구니, 기부 깊이(계산위젯·지정기부·게이지), e음 연동, 답례품 카탈로그, 모바일퍼스트 반응형 | MVP 베타 오픈 |
| P2 정식 확장 | 4개월 | M9 | 콘텐츠·커뮤니티, 답례품↔농촌체험 바우처 연동, AI 추천, 전 지자체 확장, 성능/접근성 최적화(TTFB·CLS·alt) | 정식 런칭 |
| P3 안정화(선택) | +2개월 | M11 | 성수기 부하대응, 데이터 기반 개선, A/B | 하드닝 |
가정: 인력 적시 확보·요구사항 동결 전제. e음 API 연동 승인 지연 시 P1이 0.5~1개월 슬립할 수 있음(외부 의존 리스크).
| 롤 | P0(1mo) | P1 MVP(4mo) | P2 정식(4mo) | Person-Month |
|---|---|---|---|---|
| PM/PO | 1.0 | 1.0 | 1.0 | 9.0 |
| 백엔드 | 1.0 | 2.0 | 2.0 | 17.0 |
| 프론트 | 0.5 | 2.0 | 2.0 | 16.5 |
| 디자이너 | 1.0 | 1.0 | 0.5 | 7.0 |
| QA | 0.0 | 1.0 | 1.0 | 8.0 |
| 데브옵스 | 0.5 | 1.0 | 0.5 | 6.5 |
| 데이터/AI | 0.5 | 1.0 | 1.0 | 8.5 |
| 합계(FTE) | 4.5 | 9.0 | 8.0 | 72.5 |
가정: FTE 1.0=풀타임. 액티부키는 현재 디자이너·기획자 부재 → 디자이너/PM은 P0~P1 외부 또는 신규 채용으로 충당 권장. 데이터/AI는 추천·검색·콘텐츠 자동화 겸임. 피크 동시 투입 최대 9~10명(P1).
| 롤 | 월 단가(블렌디드, 가정) | P-M | 소계(중앙값) |
|---|---|---|---|
| PM/PO | ₩750만~900만 | 9.0 | 약 ₩7,400만 |
| 백엔드 | ₩750만~1,000만 | 17.0 | 약 ₩1억4,900만 |
| 프론트 | ₩700만~900만 | 16.5 | 약 ₩1억3,200만 |
| 디자이너 | ₩600만~800만 | 7.0 | 약 ₩4,900만 |
| QA | ₩500만~650만 | 8.0 | 약 ₩4,600만 |
| 데브옵스 | ₩800만~1,000만 | 6.5 | 약 ₩5,900만 |
| 데이터/AI | ₩850만~1,100만 | 8.5 | 약 ₩8,300만 |
| 합계 | - | 72.5 | 약 ₩5.3억 |
가정: 간접비(사무·관리)는 블렌디드 단가에 포함. 예비비 10~15% 별도 권장. 정부 R&D/지역 매칭 활용 시 실부담 절감 가능(미반영).
| 항목 | 구성(가정) | 초기(MAU 3만) | 성장기(MAU 30만) |
|---|---|---|---|
| 컴퓨트 | 앱서버 컨테이너 2~3대→오토스케일 | ₩30만~60만 | ₩200만~400만 |
| DB | Managed PostgreSQL(HA), 리드레플리카 | ₩20만~40만 | ₩150만~300만 |
| 검색 | OpenSearch/Elastic(답례품·체험 다중필터) | ₩15만~30만 | ₩80만~150만 |
| 캐시 | Redis(세션·게이지·재고) | ₩10만~20만 | ₩50만~100만 |
| 스토리지 | 오브젝트(이미지·문서), 백업 | ₩5만~10만 | ₩30만~60만 |
| CDN | 정적·이미지 배포(TTFB<100ms) | ₩10만~30만 | ₩80만~200만 |
| 트래픽/네트워크 | 아웃바운드·LB | ₩10만~20만 | ₩60만~150만 |
| 모니터링/로그 | APM·로그(ISMS-P 보존) | ₩10만~30만 | ₩50만~120만 |
| AI/추천 API | 추천·콘텐츠 생성 토큰 | ₩10만~30만 | ₩80만~250만 |
| 알림(메일/SMS) | 본인확인·영수증·알림 | ₩10만~20만 | ₩40만~100만 |
| 월 합계 | PG 수수료 제외 | ₩130만~290만 | ₩820만~1,830만 |
PG/결제 수수료(거래액 비례, 별도): 예약·스토어 카드결제 약 2.0~2.8%. 기부는 고향사랑e음 공공시스템 경유 → 일반 PG와 구조 상이, 지자체 입점 수수료 5~10%는 정산 수익구조 항목(인프라 아님). 가정: 월 거래액 1억 시 카드 PG 약 ₩200만~280만 발생.
| 영역 | 권장 | 근거 |
|---|---|---|
| 코어 백엔드·e음 연동 | 내재화 | 도메인 핵심·보안(ISMS-P)·장기 유지보수, 지자체 확장 반복 |
| 프론트 SPA·디자인시스템 | 내재화(+초기 외주 보강) | 일관 컴포넌트 자산화, 반복 페이지 다수 |
| 초기 디자인 시안·아트워크 | 하이브리드 | 디자이너 부재 → P0 외주로 시스템 정립 후 내재 운영 |
| QA 자동화 | 내재화 | 회귀 테스트 반복 가치, AI로 케이스 생성 |
| 인프라/데브옵스 | 내재화(파트타임) | 0.5 FTE로 충분, 매니지드 서비스 활용 |
종합 가정: 본 추정의 절감 수치는 내부 검증 전 가설이며, P0 종료 시 실제 속도(velocity) 측정으로 재산정 권장. 과도한 정밀치로 해석하지 말 것.
각 에이전트는 독립 git worktree와 전용 컨텍스트(담당 디렉터리·스킬셋)를 갖는다. PM-오케스트레이터만 전체 리포를 보며 통합·중재한다.
R=실행, A=최종책임, C=협의, I=통보. H=휴먼 PM.
| 작업 영역 | R(실행) | A(책임) | 핵심 산출물 | 선행 의존 |
|---|---|---|---|---|
| 디자인 토큰·컴포넌트 | A2 | A1 | tokens.css, Storybook 12종 | 없음(최우선) |
| 도메인 모델·OpenAPI | A3 | A1 | openapi.yaml v1, ERD | 없음(최우선) |
| DB 통합 스키마 | A5 | A3 | schema.sql, 마이그레이션 맵 | OpenAPI 확정 |
| 세액공제/30%룰 엔진 | A3 | H | calc 모듈+테스트벡터 | 법령 검수(H) |
| e음 API 어댑터 | A6 | H | e음 게이트웨이, 영수증 플로우 | e음 키 발급(H) |
| 프론트 화면(상세/리스트) | A4 | A1 | SPA 라우트 24종 | A2 토큰+A3 API |
| 콘텐츠·아티클·alt | A7 | A1 | 아티클 40편, alt 100% | 반독립(A2 카드만) |
| QA·품질게이트 | A8 | A1 | E2E·Lighthouse 리포트 | 각 PR 단위 |
| CI/CD·보안 | A9 | H | 파이프라인, ISMS-P 체크리스트 | 없음(병행) |
| 구분 | 작업 | 이유 |
|---|---|---|
| 직렬(필수 선행) | ① 디자인 토큰 동결 → ② OpenAPI/ERD 동결 → ③ 화면·통합 구현 | 토큰·계약이 모든 하위 작업의 입력. 미동결 시 재작업 폭증 |
| 직렬(법적/외부) | e음 키 발급 → 어댑터 → 결제 직전 로그인 플로우 | 공공 시스템 경유는 비가역, 외부 일정 종속 |
| 병렬 가능 | A2 컴포넌트 / A7 콘텐츠·아티클 / A9 CI·보안 / A5 데이터 정제 | 공유 계약만 참조하면 상호 무간섭. 워크트리 격리로 동시 진행 |
| 병렬 가능 | 토큰 동결 후: A4 화면 24종을 라우트 단위로 분할 동시 구현 | 컴포넌트 계약 고정 후 화면은 독립 |
| ID | 작업 | R | 선행 | 유형 | 휴먼 게이트 |
|---|---|---|---|---|---|
| W1.1 | 2축 팔레트·타입스케일 토큰 확정 | A2 | - | 직렬 | HITL-1 톤 승인 |
| W1.2 | 공용 컴포넌트 12종(게이지·세액위젯 등) | A2 | W1.1 | 병렬 | - |
| W2.1 | 통합 도메인 모델·ERD | A3 | - | 직렬 | HITL-2 스키마 리뷰 |
| W2.2 | OpenAPI v1(장바구니/검색/주문 단일) | A3 | W2.1 | 직렬 | - |
| W2.3 | 세액공제+30%룰 계산엔진+테스트벡터 | A3 | W2.2 | 병렬 | HITL-3 법령검수 |
| W3.1 | productOld/0원/jsessionid 정제 | A5 | W2.1 | 병렬 | - |
| W3.2 | 슬러그--UUID URL 맵 + 301 리다이렉트 | A5 | W3.1 | 병렬 | HITL-4 URL 보존검수 |
| W3.3 | 답례품 계층 분류코드 + 다중필터 인덱스 | A5 | W3.1 | 병렬 | - |
| W4.1 | e음 API 어댑터(접수·본인확인·영수증) | A6 | W2.2 | 병렬 | HITL-5 키발급·계약 |
| W4.2 | 지정기부 모금액/달성률/사용처 동기화 | A6 | W4.1 | 병렬 | - |
| W5.1 | 단일 GNB/세션(JWT)/반응형 셸 | A4 | W1.2,W2.2 | 직렬 | - |
| W5.2 | 상세(좌스크롤+우sticky) 예약/기부 통합 | A4 | W5.1 | 병렬 | HITL-6 핵심동선 UX |
| W5.3 | 비로그인 전과정 탐색·결제직전 로그인 | A4 | W5.1 | 병렬 | - |
| W5.4 | 답례품→농촌체험 바우처/숙박 연결(USP) | A4 | W3.3,W4.2 | 병렬 | HITL-6 |
| W6.1 | 아티클 40편·축제 애그리게이터·출석체크 | A7 | W1.2 | 병렬 | HITL-7 콘텐츠 팩트체크 |
| W6.2 | alt 0누락·박힌이미지→텍스트 전환 | A7 | - | 병렬 | - |
| W7.1 | CI/CD·TTFB<100ms·ISMS-P 보안 | A9 | - | 병렬 | HITL-8 보안승인 |
| W7.2 | E2E·Lighthouse·접근성 회귀 게이트 | A8 | 각 PR | 병렬 | - |
| W8.0 | 통합·머지·릴리스(86.2점 검증) | A1 | 전체 | 직렬 | HITL-9 출시승인 |
핸드오프는 코드가 아니라 계약(contract)으로 전달한다. 계약 동결 후에만 하위 에이전트가 병렬 착수한다.
[동결순서 1] A2 → 전원 : tokens.css + Storybook (디자인 계약) [동결순서 2] A3 → A4,A5,A6: openapi.yaml + ERD (데이터/API 계약) [통합지점 1] A2⊕A4 : 컴포넌트 prop 시그니처 (Storybook 스냅샷 일치) [통합지점 2] A3⊕A5 : 마이그레이션 후 스키마 = OpenAPI 모델 정합 [통합지점 3] A6⊕A3⊕A4 : e음 영수증 ↔ 주문 ↔ 세액위젯 값 일치 (E2E) [통합지점 4] A4⊕A7 : alt/JSON-LD 슬롯 채움 (Lighthouse SEO/A11y) [최종통합] A1 : 워크트리 머지 → 통합 브랜치 → 회귀 게이트
AI가 자율 진행하되, 비가역·법적·브랜드 정체성 지점에서만 휴먼 PM(david)이 승인한다. 게이트 통과 전 다운스트림 머지 금지.
| 게이트 | 지점 | 판단 대상 | 차단 효과 |
|---|---|---|---|
| HITL-1 | 디자인 톤 동결 | 기부 신뢰톤 vs 체험 생기톤 균형, CTA #F9AA24 위치 | 전 컴포넌트 재작업 방지 |
| HITL-3 | 세액·30%룰 검수 | 10만 전액/16.5%/10년이월, 답례품 30% 한도 계산 정확성 | 법적 오류·환불 리스크 |
| HITL-5 | e음 연동 승인 | API 키·본인확인 플로우, 243지자체 계약 범위 | 공공 시스템 사고 |
| HITL-4 | URL 보존 | 301 맵 누락 시 SEO·기존 유입 손실 | 유기 트래픽 보호 |
| HITL-8 | 보안 승인 | ISMS-P급, 개인정보·결제 PG 격리 | 침해·인증 리스크 |
| HITL-9 | 출시 승인 | 목표 86.2점 달성 리포트 최종 확인 | 프로덕션 릴리스 게이트 |
A8/A9가 운영하는 머지 차단 규칙. 하나라도 실패 시 PR 머지 불가.
{id,title,html} 계약을 준수해 충돌 없이 생성되고, 상위 오케스트레이터가 <h2> 래핑·중복 제거·톤 정합으로 통합했다.이는 디자이너·기획자가 없는 액티부키가 동일 패턴으로 실제 개발도 수행 가능함을 입증한다. 기획서 13섹션 = 구현 9에이전트로 1:1 대응되며, 본 문서의 병렬 집필에서 검증된 핸드오프(계약 우선)·HITL(팩트체크)·품질게이트(스키마 검증) 구조를 그대로 코드 생산에 이식하면 된다. 방법론의 자기증명(self-evidence): 읽고 있는 이 산출물이 곧 작동 증거다.