유료 플랜 대비 약관 정비와 출시판 법률문서 v1 통일 — 초안 v1~v6 여섯 판·이중 시행에서 앱·서버·문서·랜딩이 같은 v1 한 판을 보게 (2026-09-15)
- 기간: 2026-09-15 하루 (세션 3개 —
019e6e30-4b0c-4c54-8313-bd1cdcee06a0유료 플랜 분석·v6 검토본·계약·v6 게시,e77bd906-a541-49ee-a2c6-7d462e3afb4f앱 v6 등재·출시판 v1 문안,c670ebdd-651b-44a5-975d-86592dfcc04fv0.19.4 반영). 오너 지시 원문: "너무 일 크게 벌리지 말고 꼭 필요한 것만" → "유료 결제 기능이 있다고 가정하고 미리 정비해 둬" → "유료 플랜까지 확정해서 약관 v1으로 통일, 출시 전 빠진 것 없는지 철저히 검증" → "최종 목표는 법률문서 최종판 완성까지, 앱 등록 등은 나중에" → "v0.19.4에 적용해야 하는 거 적용해줘". - 랜딩: 앱 PR #1681 →
release/v0.19.4e3789e74(마이그레이션20260916010100_consent_requirements_launch_v1, 큐 run 34975716750 Merge Check 통과). 앞서 앱 PR #1647 →release/v0.19.3f99223c3(v6 등재 — 출시판으로 대체됨). 문서 PR #106·#108·#109·#112·#114·#116(출시판 v1 게시, main070192f, Vercel Production 게시). 랜딩 Barbelic-landing PR #6 열림(앱 v0.19.4 Production 반영 뒤 병합). staging·Production 미반영(v0.19.4 승격 대기). - 설계서: 없음 — 계획은 이슈 #1640 본문(4 Phase, 예상 효과·개선사항 표, D1)과 09-15 18:14 댓글(출시판 v1 통일 4 Phase).
- 정본: 게시 문서
public/legal/terms-v1.html·privacy-v1.html·consent-sensitive-v1.html·consent-sharing-v1.html·consent-sharing-sensitive-v1.html·service-info.html·account/delete.html(문서 저장소 원문 = 앱public/legal/사본); 앱src/react/legalDocuments.ts(레지스트리 v1만), 서버onboarding_consent_requirements()(terms/privacy v1); 계약 유료 플랜 결제 전 고지·구독 관리; 대조표 출시판 법률문서 v1; 유료 검토본 review-2026-09-15-paid. - 도구: 문서·앱 양쪽
check-legal-documents.mjs+ 게시 기준점scripts/legal-publication.json(기준점이 없는 이력은 초안 — 게시본 불변 검사 제외), 앱sql:candidate·migrations:risk·schema:snapshot --reset·sql:extract·sql:check·db:model. - 게이트: 앱
npm run check(check:static, 2026-09-15 23:50 KST) 통과 — 법률문서 1판·6문서, 마이그레이션 236파일. 샌드박스 빈 DB에 마이그레이션 전체 재적용 →schema:snapshot --reset(23:58 KST) →sql:check원천 == 스냅샷 →db:model --check통과. 재생 DB 실측:onboarding_consent_requirements()= terms v1·privacy v1·sensitive_data_processing v1 필수, profile_sharing v1·sensitive_sharing v1 선택. 문서 저장소npm run check(법률문서 1판 완결, 내비 381경로) + 저장소 CI(scope·docs·verify) 통과. precheck 생략(오너 지시 09-15), QA2 부분 실행 없음(아래 남은 것). - 버그리포트: 없음.
- 계약: 유료 플랜 결제 전 고지·구독 관리(최소안: 결제 버튼 위 고지 한 화면 + 설정의 구독 관리 링크 + 구매 기록 두 열), 온보딩 화면 계약·온보딩 데이터 모델의 버전 서술 v1.
Phase 현황
| Phase | 내용 | 상태 |
|---|---|---|
| Phase 1 (유료 대비) | 결정값 표 — D1 앱 내 결제만, 스토어(Apple 3.1.2·Google Play)·국내 규정(전자상거래법·시행령 20조의2·신고 면제) 정리 | ✅ 이슈 댓글 |
| Phase 2 (유료 대비) | 약관 v6·처리방침 v6·운영 안내·결제 전 고지문 검토본 → 오너 지시로 v6 게시(공지 09-15·시행 10-15), 사업자 표시·전화 | ✅ docs PR #106·#109·#112·#114 |
| Phase 3 (유료 대비) | 앱 계약 — 최소안으로 축소(별도 표·서버 문·알림 흐름 삭제) | ✅ docs PR #108(+최소안 갱신) |
| Phase 1 (v1 통일) | 법 요건 대조표 + 출시판 v1 문안(약관·처리방침·동의문 3종·운영 안내) — 전화·호스팅 제공자·분쟁 처리·3영업일·구제 기관 보완 | ✅ docs PR #116 문안 |
| Phase 2 (v0.19.4 반영) | 앱: 사본 v1 한 벌(초안 삭제), 레지스트리 v1, 서버 요구 v1 마이그레이션, 게시 기준점 | ✅ 앱 PR #1681 e3789e74 |
| Phase 3 (v0.19.4 반영) | 문서·랜딩 정합 — 계정 삭제 안내·스토어 URL·계약 서술·데이터 모델 v1, 문서 사이트 게시, 랜딩 링크 | ✅ docs PR #116 병합·게시 · 랜딩 PR #6 열림 |
1. 배경
#1625(2026-09-15 낮)가 무료 서비스 전제로 약관·처리방침 v5와 동의 구조를 확정했다. 같은 날 오너가 유료 플랜 출시 계획을 알렸다 — 유료는 전자상거래법(계약 전 표시·청약철회·환급 기한·거래 기록 보존)·정기결제 고지 규정·앱 마켓 구독 정책이 새로 걸리는데 v5에는 유료 조항이 없고, 운영 안내에는 상호만 있었다(대표자·주소·전화·사업자등록번호·통신판매업 신고 표시 없음). 초안은 v1(7/18)부터 v6(9/15 게시, 10/15 시행)까지 여섯 판이 쌓여 "v5 시행 중 + v6 예정"인 이중 상태였고, 실제 회원은 없었다(운영 DB 16명 = 테스트 계정).
2. 문제 제기
유료 판매의 법적 근거가 문서에 없었다
약관 v5 제5조는 "현재 무료, 유료 도입 시 별도 안내"뿐. 계약 성립·가격 표시·자동 갱신 고지·청약철회 예외·환불·미성년자 결제 조항이 없고, 처리방침에 결제 정보 항목·보유 기간·앱 마켓의 지위가 없었다.
사업자 표시가 법이 요구하는 항목에 못 미쳤다
전자상거래법 10조(사이버몰 표시)·13조(신원 표시)가 요구하는 상호·대표자·주소·전화·사업자등록번호·통신판매업 신고번호(또는 면제)·호스팅 제공자 중 상호만 있었다.
출시 전 초안 여섯 판이 게시본으로 남아 있었다
동의 기록은 버전을 가리키므로 "게시본은 못 바꾼다"가 원칙인데, 실제 회원이 없는 초안까지 그 원칙에 묶여 앱 public/legal/에 17개 파일, 레지스트리 6판, 서버 요구 v5, 랜딩 링크 v4, 스토어 제출 문서 URL v3/v4가 제각각이었다. 문서·앱 검사(check-legal-documents.mjs)는 origin/main에 있는 버전 파일의 삭제·변경을 전부 거부해 초안 정리 자체가 막혔다.
3. 해결 방안
원칙 (오너 결정, 2026-09-15)
- D1 = 앱 내 결제만(iOS Apple 앱 내 결제·Android Google Play 결제, 웹 결제 없음, 환불·해지는 앱 마켓 절차 우선). 채택 — 첫 유료 출시의 환불·고지·심사 요건을 스토어 표준에 맞추는 것이 가장 단순.
- "꼭 필요한 것만": 별도 신청 기록 표·서버 문 2개·무료 체험 종료/가격 인상 알림 흐름은 기각. 남긴 것 = 결제 버튼 위 고지 한 화면, 설정의 구독 관리 링크, 구매 기록에 약관 버전·확인 시각 두 열.
- "약관 v1으로 통일": 초안 여섯 판을 이용약관 v1·개인정보처리방침 v1 한 판으로 통합, 공지·시행 = 게시일(30일 유예·종전판 부칙 없음). 기존 초안 동의자는 테스트 계정뿐이라 다음 로그인에 재동의.
접근
| 대안 | 판단 |
|---|---|
| 유료 조항을 v6로 얹고 v1~v5를 그대로 둔다 | 기각 — 이중 시행·여섯 판이 그대로 남고, 스토어 URL·랜딩·서버가 각각 다른 번호를 가리킨다 |
| 초안 전부를 출시판 v1 한 판으로 통합, 게시 기준점부터 불변 | 채택 — 회원 없는 출시 전이라 가능한 유일한 시점. 기준점(scripts/legal-publication.json) 이후는 종전대로 새 판만 추가 |
| 초안 파일을 남기고 옛 URL을 v1로 리다이렉트 | 기각 — 파일이 남아 있으면 검사·레지스트리·동의 기록이 계속 옛 판을 가리킬 수 있다. 외부 링크(스토어 콘솔·랜딩)는 v1로 직접 갱신 |
4. 적용한 내용
유료 대비 Phase 1~3 (이슈 댓글, docs PR #106·#108·#109·#112·#114)
결정값 표(결제 경로·구독 기본·결제 전 고지 항목·해지 접근·환불·유료 전환 동의·사업자 표시·거래 기록 보존·결제 정보 처리 범위·Apple/Google의 지위·미성년자·자리표시자). 약관 v6 = 제5조 "이용요금과 유료서비스" + 제5조의2(결제·자동 갱신) + 제5조의3(청약철회·환불·해지) 신설, 처리방침 v6 = 구독·결제 정보 행(5년/3년)·앱 마켓 결제 처리자·국외 이전. 사업자 표시 = 데커드 스튜디오(Studio Dekerd)·대표자 박주희·화성시 사업장 주소·사업자등록번호 510-23-12564·전화 070-8064-4121·통신판매업 신고 면제(직전 연도 거래 50회 미만). 계약 paid-plan-consent.md를 최소안으로.
출시판 v1 문안 (docs PR #116, docs/legal/review-2026-09-15-launch-v1/README.md)
법 요건 대조표(전자상거래법 10·12·13·17·18조, 시행령 20조의2, 개인정보 보호법 30조 기재 사항 21항목, 약관규제법, 앱 마켓 정책)로 빠진 항목을 채웠다 — 전화·호스팅 서비스 제공자(Supabase Pte. Ltd., Vercel Inc.), 불만 처리·분쟁 조정 기관(한국소비자원 1372, 전자문서·전자거래분쟁조정위원회 1661-5714), 운영자 직접 환불 3영업일, 권익침해 구제 기관 보강·행정심판 안내, 운영 안내의 옛 "무료·승인 없는 공개" 설명 교체. 앱이 실제로 쓰는 항목과 대조(푸시·분석·광고·위치 플러그인 없음 → 추가 수집 항목 없음). 문서 저장소 검사에 게시 기준점 도입.
v0.19.4 반영 (앱 PR #1681, 마이그레이션 20260916010100_consent_requirements_launch_v1)
public/legal/: 출시판 6문서로 교체,terms/privacy v2~v6삭제.account/delete.html링크 v1.legalDocuments.ts: 레지스트리 terms/privacy v1(시행 2026-09-15)만,CURRENT_LEGAL_DOCUMENT_VERSIONSv1,EXISTING_MEMBER_CONSENT_DEADLINE= 시행일(출시판에 유예가 없으므로 "나중에" 버튼이 열리지 않음 — 다음 판이 부칙으로 유예를 두면 그 날짜로).- 서버
onboarding_consent_requirements()terms/privacy v5 → v1(sql:candidate, 위험 분류 low, 함수 재발행만·원본 DML 없음).schema.sql·registry.json·db-objects.json재생. - 앱
check-legal-documents.mjs: 게시 기준점 — origin/main에scripts/legal-publication.json이 없으면 초안 이력이라 불변 검사를 건너뛰고, 있으면 종전대로. - 문서: 계정 삭제 안내 링크,
app-store-submission.md·android-release.md의 스토어 URL,paid-plan-consent.md·onboarding-props.md·onboarding-data-model.md(en·ko) 버전 서술 v1. 문서 사이트 Vercel Production 게시(수동vercel deploy --prod; Docs Deploy 워크플로는DOCS_DEPLOYMENT_ENABLED미설정으로 skipped). - 랜딩
src/content/links.tsv4 → v1(PR #6, 병합 대기).
주요 결정과 그 근거
- 서버 요구 v1 전환을 앱 사본과 같은 릴리스에 실었다: Deploy가 DB → 프론트 순이라 몇 분 동안 옛 번들은 같은 경로의 옛 초안 v1 파일을 열지만 가입은 막히지 않는다(경로
/legal/terms-v1.html이 옛 번들에도 등재돼 있음). 두 릴리스로 나누면 그 사이 신규 가입이 초안 v5로 기록된다. - 유료 이용 신청 기록을
user_consents에 넣지 않았다:apply_user_consents_v1은 서버 요구 목록의 종류만 받고, 요구 목록은 곧 가입 화면이라 유료 항목이 가입에 나타난다. 최소안대로 구매 기록의 두 열로. - 약관에 가격·플랜 이름을 적지 않고 "결제 화면·앱 마켓 상품 정보 기준"으로 두어 상품이 정해져도 재게시가 필요 없다.
작업 중 드러난 것
- 문서·앱 양쪽
check-legal-documents.mjs가 origin/main의 버전 파일 삭제·변경을 전부 거부해 초안 정리가 막혔다 → 게시 기준점 파일로 "초안 이력 / 게시 이력"을 나눴다(1회 예외가 아니라 구조). - 앱 v0.19.3에서 #1643이 법률 문서를 앱
public/legal/에서 직접 제공하게 바꿔, 게시 순서가 "문서 저장소 게시 → 사본을 복사한 앱 릴리스 → 서버 요구 전환"이 됐다. 문서 사이트 게시만으로는 앱이 새 판을 열지 못한다. - 샌드박스 재생 순서:
sql:candidate→migrations:risk --write <supabase/migrations/…>→migrations:renumber --base origin/release/vX.Y.Z→schema:snapshot --sandbox <dir> --reset→sql:extract→sql:check→db:model.ci-local.mjs가 퇴역해 샌드박스(config.toml + junction 3개 +.temp/postgres-version)는 손으로 만들었다. - QA2
scenarios/database/*22곳이 terms/privacy v4 동의로 온보딩을 완료하고profile-onboarding이 요구 목록 = v4를 단언한다 — v5(현재 main)에서도 맞지 않고 이 반영 뒤에는 v1 + sensitive_data_processing v1이 정답. QA2 핀은 #1659 릴리스 세션 담당이라 손대지 않고 이슈에 알렸다. - Docs Deploy 워크플로는
DOCS_DEPLOYMENT_ENABLED변수가 없어 main 푸시마다 skipped — 문서 사이트 게시는 여전히 수동vercel deploy --prod.
5. 적용 결과
| 항목 | 전 | 후 |
|---|---|---|
| 게시 문서 판 수 | 약관·처리방침 6판(v1~v6), 이중 시행(v5 중·v6 예정) | v1 한 판, 공지·시행 2026-09-15 |
| 유료 판매 조항 | 없음 | 약관 v1 제5조~제5조의3(계약·가격 표시·자동 갱신·청약철회 예외·환불·해지·미성년자), 처리방침 결제 정보·앱 마켓 결제 처리자 |
| 사업자 표시 | 상호만 | 상호·대표자·주소·전화·사업자등록번호·통신판매업 신고 면제·호스팅 제공자(약관 제1조·처리방침 제1항·운영 안내) |
| 서버 요구 동의 | terms/privacy v5 | terms/privacy v1(+ sensitive v1 필수, 공개 2종 선택 — 재생 DB 실측) |
| 앱·문서·랜딩·스토어 URL 정합 | 앱 6판·랜딩 v4·스토어 문서 v3/v4 | 전부 v1(랜딩은 PR #6 병합 뒤) |
| 문서 사이트 | v1~v6 초안 | 출시판 v1만(terms-v1 200·공지일 2026-09-15, terms-v6 404) |
| 검사 | 초안 삭제 불가 | 게시 기준점 이후만 불변 |
| 미검증 | — | staging·Production 반영(v0.19.4 승격 대기), QA2 레인 통과(단언이 v4), 옛 번들 창(몇 분)의 실제 동작 |
6. 이번 개선으로 향상된 것
- 유료 플랜을 팔기 시작할 때 문서 쪽에 더 할 일이 없다 — 상품 값은 결제 화면·앱 마켓에, 약관은 이미 유료 조항을 가진 v1.
- 법률문서가 한 판이라 "어느 판이 시행 중인가"를 앱·서버·문서·랜딩이 따로 기억하지 않는다. 다음 판부터는 새 파일·새 레지스트리 항목·새 서버 요구 한 세트로 끝난다.
- 게시본 불변 검사가 "출시 전 초안"과 "게시본"을 구조적으로 구분한다.
남은 것
- v0.19.4 승격 ①·②(릴리스 세션): staging Deploy 뒤
app.barbelic.com/legal/terms-v1.html이 출시판(공지일 2026-09-15 표기)을 여는지,terms-v6.html이 404인지, 신규 가입 요구 목록이 v1인지 확인. Production 반영 뒤 랜딩 PR #6 병합, 이슈[v0.19.4 반영완료]종결. - QA2 온보딩 단언(v4 → v1 + sensitive v1) — #1659 릴리스 세션 몫.
- 오너 손: App Store Connect·Play Console의 약관·처리방침 URL을
terms-v1·privacy-v1로(문서app-store-submission.md·android-release.md에 적힌 값). 통신판매업 신고는 유료 거래가 한 해 50회를 넘긴 다음 해 초에. - 사람이 판단할 것 4건(대조표 6절 — 통신판매업 신고 해석, 청약철회 예외의 결제 화면 확인, 만 19세 미만 법정대리인 동의 방식, 직접 환불 3영업일 범위)은 유료 기능 구현·출시 직전 변호사 검토 때 — 지금 할 일은 없다(2026-09-15 오너 질문에 답한 판단).