Appearance
프론티아 글로벌 — 가입·온보딩 & 글로벌 토대 PRD
글로벌 출시의 첫 진입 경험(설치→로그인→가입→온보딩) 과 그 과정에서 확정되는 유저·콘텐츠의 마켓/언어/타임존 데이터 토대를 함께 다룬다. 유저가 처음 앱을 켜는 순간부터 데이터가 어떻게 정해지고 고정되는지를 흐름 순서로 정의한다. 다른 글로벌 PRD(탐색·플레이 / 창작·발행 / 결제·정산 / 운영·어드민 / UI 현지화)가 여기서 정한 마켓·언어·타임존 값과 공용 기능을 가져다 쓴다.
Status: draft Created: 2026-07-03 Last updated: 2026-07-03 대상 표면: 앱 / 웹 / 어드민 (가입 화면 + 백엔드 데이터 토대)
이 문서의 표기
- 마켓: 세계를 나눈 지역 단위. 유저·콘텐츠가 어디에 속하는지의 기준이며 독립 테이블/설정으로 둔다.
- 콘텐츠 마켓(7개, 자기 언어 콘텐츠 있음): NA(북미 = 미국·캐나다, 영어) · JP(일본, 일본어) · KR(한국, 한국어) · TW(대만·홍콩·마카오, 번체) · LATAM(중남미 스페인어권, 스페인어) · BR(브라질, 포르투갈어) · ID(인도네시아, 인니어).
- 매핑되지 않은 나머지 모든 국가(태국·베트남 등)는 NA로 매핑된다 — 별도 'ROW/기타 지역' 마켓을 두지 않고, 그 국가 유저의 마켓 = NA(영어 콘텐츠 노출). 유저 국가 원값은 따로 보존해 분석·향후 마켓 승격에 쓴다.
- 국가↔마켓 매핑은
country-market-mapping.md참조.
- 언어 코드 — 두 축이 별개다:
- UI 언어 8종: ko(한국어) · en(영어) · ja(일본어) · zh-Hant(번체 중국어) · es(스페인어) · pt(포르투갈어) · id(인니어) · th(태국어). 마켓과 무관(기기/브라우저 디폴트·변경 가능). UI 현지화 소관.
- 콘텐츠 언어 7종: en · ja · ko · zh-Hant · es · pt · id. 콘텐츠 마켓과 1:1이며 프롬프트·생성에만 쓴다. 태국어는 콘텐츠 마켓이 없어 UI 언어로만 존재(콘텐츠 언어 아님). 베트남어는 수요가 약해 UI 언어에서도 제외.
- 노출 규칙(문서 전체 기준): 유저는 자기 마켓 콘텐츠를 본다. 마켓에 매핑되지 않은 국가의 유저는 마켓이 NA라 자연히 NA(영어) 콘텐츠를 본다.
- 되돌리기 비용 등급(R): R1=쉬움(노출/UI) · R2=중간(재판정·재시딩) · R3=비쌈(스키마·데이터 재이전).
- 표시 약속:
검토 필요=아직 정해지지 않음(§7) ·후속=출시 후 디테일 패스 · 🎨 디자인 필요=신규 유저 대면 화면.
Reversal Risk Summary
| 레이어 | R등급 | 점검 초점 |
|---|---|---|
| 정책 / 규칙 | R3 | 마켓 경계(국가↔마켓 매핑)·가입 시 고정·기존 유저 마켓 정책은 출시 후 되돌리기 비쌈 |
| 데이터 / 백엔드 | R3 | 국가·마켓·언어·타임존·콘텐츠 마켓/언어의 저장 단위와 판정 로직은 전 글로벌 PRD의 토대 → 출시 전 픽스 필수 |
| 유저 대면 화면 | R2 | 로그인 화면 provider 노출·생년월일/성인 게이트·생년월일 수정 유도 화면은 신규 |
| 문구 / 시각 표현 | R1 | 문구는 언어별 리소스(UI 현지화 소관)라 조정 쉬움 |
1. 목표 및 배경
1.1 목표
- 프론티아를 한국 밖으로 확장해 사용자 층을 넓히는 것이 이 글로벌 이니셔티브의 목적이다(전체 그림은 출시 계획 문서). 이 PRD는 그 확장의 첫 진입 경험(설치→로그인→가입→온보딩)과 데이터 토대를 맡는다 — 유저가 처음 앱을 켜는 순간부터 어느 마켓·언어·타임존에 속하는지 정해지고 고정되게 한다.
1.2 배경 (현황)
- 프론티아는 현재 한국 전용이다 — 유저에 국가 개념이 없고(전원 한국 가정), 에피소드·노출·언어가 전부 한국 기준이며, 로그인·가입·연령 확인 경험도 한국 전용으로 짜여 있다.
- 글로벌 노출·언어·결제·분석이 전부 "유저·콘텐츠가 어느 마켓·언어인지"를 전제한다. 그 필드와 판정이 없으므로, 확장의 맨 앞에 이 토대가 온다.
- 국가별 DB 분리 없이 하나의 유저풀 + 마켓 필터로 가는 방식은 단일 한국 법인으로 글로벌을 운영하는 유사 서비스에서 검증돼 있다.
1.3 접근
- 국가별 DB 분리 없이 하나의 유저풀로 가고, 노출은 마켓 필터로 가른다.
- 마켓은 독립 테이블/설정이다 → 주요 국가를 마켓에 매핑하고 나머지 국가는 NA로 매핑한다(별도 'ROW' 마켓 없음, 매핑 안 된 국가 유저의 마켓 = NA·영어 노출). 마켓 추가·국가 재배치·특정 국가의 새 마켓 승격이 데이터 이전 없이 된다. 유저에는 유저 국가와 그로부터 파생한 마켓을 둘 다 저장한다(마켓만 저장하면 분석을 국가 단위로 못 쪼개고, 승격 시 재파생도 못 함).
- 유저의 국가·마켓·타임존을 가입 시 판정·고정하고(언어는 기본값만 정하고 유저가 바꿀 수 있음), 기존 유저는 소급 채운다.
- 콘텐츠(에피소드·소울)에도 마켓·언어를 각각 한 개씩 붙인다.
- 공용 기능(마켓 필터·언어 결정·마켓 대표 타임존)을 한 곳에서만 정의해 다른 PRD가 가져다 쓰게 한다.
2. 타깃 사용자
2.1 주요 사용자
- 신규 글로벌 유저 — 가입 시 국가·마켓·타임존이 자동 판정된다(비가시).
- 기존 유저 — 소급 백필 대상(전원 한국 유지).
- CS / 어드민 — 오판정·이주 유저를 수동 교정(이력 로깅).
2.2 핵심 시나리오
- 미국 유저가 로그인 화면에서 Google·Apple을 본다 → 가입 시 IP로 미국 감지 → 유저 국가=미국, 마켓=NA, 언어 기본값=en, 타임존=미국 시간대로 자동 고정.
- 브라질 유저가 가입 → 유저 국가=브라질, 마켓=BR, 언어 기본값=pt.
- 나이지리아 유저가 가입 → 유저 국가=나이지리아(매핑 안 된 국가) → 마켓=NA → 노출은 NA(영어). (유저 국가=나이지리아는 원값으로 보존.)
- 기존 한국 유저 → 백필로 유저 국가=한국, 언어=ko, 기존 에피소드·소울 마켓=KR/언어=ko.
- 해외 유저가 성인 콘텐츠 접근 시 → 만 18세 이상이면 "18세 이상이 맞습니까?" 팝업, 만 18세 미만이면 차단 + 생년월일 수정 유도. (한국 유저는 기존 본인인증 기반 성인 인증을 그대로 탄다 — 성인 기준 만 19세 연 나이.)
3. 핵심 기능 요구사항
유저가 앱을 처음 켜는 순간부터 데이터가 고정되기까지의 흐름 순서로 정리한다(§3.1 설치→§3.2 가입→§3.3 가입 이후). 이어서 라이프사이클 표(§3.4), 콘텐츠 필드(§3.5), 공용 기능(§3.6), 백필(§3.7), 어드민(§3.8).
3.1 설치·첫 실행 (비로그인)
로그인 화면 — 소셜 로그인 provider 노출
동작: 로그인 화면은 감지된 국가(앱·웹 모두 IP)에 따라 1차 노출 provider를 다르게 보여준다.
감지 국가 1차 노출 provider 한국 Google · Apple · Kakao 일본 · 대만 Google · Apple · LINE 그 외(미국·캐나다·홍콩·나머지 세계) Google · Apple 비즈니스 룰:
- "다른 방식으로 로그인" 진입점을 둬서 1차에 없는 나머지 provider를 펼친다 → 모든 provider가 항상 도달 가능(예: 한국 카카오 계정 유저가 해외에서도 로그인·복구). 국가 구분은 1차 노출 순위일 뿐 완전 숨김이 아니다.
- provider 노출 기준 국가는 가입 전 감지값이다. 어떤 provider로 로그인하든 유저 국가 최종 판정은 provider와 독립이다.
🎨 디자인 필요(신규): ①국가별 1차 provider 로그인 화면 ②**"다른 방식으로 로그인" 버튼과 눌러서 펼쳐지는 화면**.
비로그인 노출·표시 (가입 판정과 동일 소스)
- 동작: 아직 유저가 없어 아무 값도 저장하지 않는다. 단 판정에 쓰는 소스는 §3.2 가입 판정과 동일해야 한다:
- 콘텐츠 노출 마켓: 앱·웹 모두 IP (매핑 없거나 IP 판정 실패 시 NA)
- 표시 언어: 앱=기기 언어 / 웹=브라우저 언어 (지원 밖이면 en)
- 표시 시각: 앱=기기 타임존 / 웹=브라우저 타임존
- 비즈니스 룰: 이 값들은 노출·표시용이며 유저에 고정되지 않는다 — 고정은 가입 시점에만.
3.2 가입 시점 — 판정·고정 (비가시)
국가·마켓·언어·타임존 자동 판정
- 동작: 유저는 국가·언어·타임존을 선택하지 않는다(셀렉터 UI 없음). 가입 시 자동 판정된다.
- 판정 기준(소스 우선순위):
- 유저 국가 — 앱·웹 공통으로 IP geo 하나로 판정한다(스토어 국가는 유저 국가 판정에 쓰지 않는다). IP 판정이 실패할 때만 폴백(기기/브라우저 지역 → 최종 NA). (스토어 국가는 인앱 결제 가격 결정에만 쓰이는 별도 값 — payments·§6 UL 참조.)
- 마켓 — 유저 국가를 국가↔마켓 매핑 테이블에 넣어 파생. 매핑된 7개 마켓 중 하나이거나, 매핑 안 된 국가는 NA.
- 언어 기본값 — 앱: 기기 언어. 웹: 브라우저 언어. (지원 8종 밖이면 en.) 유저가 나중에 바꿀 수 있다(§3.3).
- 타임존 — 기기 타임존(앱=OS, 웹=브라우저), IANA 문자열 그대로.
- 비즈니스 룰:
- 판정 실패 시: 마켓은 감지 국가의 마켓(국가 불명이거나 매핑 없으면 NA), 타임존은 유저 국가 대표 타임존 → 최종 NA(미국) 대표 타임존.
- 유저 국가는 원값 그대로 저장한다(분석 진실값).
생년월일·연령·성인 게이트
목적: 해외에 본인인증 수단이 없는 상태에서 미성년 보호를 달성한다. 한국은 기존 본인인증 기반 성인 인증을 그대로 쓰고, 해외는 자기확인으로 대체한다.
가입 공통 동작:
- 가입 시 생년월일 수집 — 카카오 가입자는 카카오 제공값(고정, 유저 수정 불가), 그 외 provider(구글·애플·라인)는 자기보고(직접입력, 이후 수정 가능). 휴대폰/본인인증 없이. 만 14세 미만 가입 차단(한국·해외 공통).
성인 게이트 = 한국 / 한국 외 두 갈래: 한국과 해외는 성인 기준 나이도, 인증 방법도 다르다.
항목 한국(KR 마켓) — 기존 유지 한국 외(비-KR 마켓) — 신규 성인 기준 나이 만 19세(연 나이 기준) — 청소년보호법상 청소년은 만 19세 미만이되 만 19세가 되는 해의 1월 1일부터 성인으로 본다(생일 안 지나도 그 해에 만 19세면 성인) 만 18세(엄격 만나이) — 18번째 생일이 오늘이거나 지나야 성인(출생연도만 아니라 생일까지) 판정 방식 올해 연도 − 출생 연도 ≥ 19 오늘 날짜 − 생년월일 ≥ 만 18년 판정 근거값 본인인증으로 확인된 실제 나이 유저가 자기보고한 생년월일 인증 방법 기존 본인인증 기반 성인 인증 플로우 그대로 유지(실제 나이 확인) — 신규 개발 없음 성인 콘텐츠 접근 시 "18세 이상이 맞습니까?" 자기확인 팝업(본인인증 아님) → 동의 시 성인 확인. 진입점은 계정 설정 인증 지속성 기존 방식 그대로 계정 단위·1회·유효기간 없음(지속) 본인인증 모달 뜸(한국 기존) 안 뜸 기준 미달 시 기존 한국 성인 인증 실패 처리 성인 콘텐츠 차단(자기확인 팝업 미노출) + 생년월일 수정 유도(아래). 생년월일이 하한이며 자기확인으로 못 덮는다 - 생년월일 수정 유도 플로우 🎨(비-KR, 신규): 만 18세 미만이 성인 콘텐츠에 접근하면 "18세 미만은 인증할 수 없어요. 잘못 입력했다면 생년월일을 수정하고 다시 시도해주세요. [생년월일 변경하러 가기]" → 생년월일을 고치면 다시 판정. (영구 잠금 아님, 그러나 기록이 18+로 바뀌어야 통과.)
근거: 한국은 이미 본인인증 인프라와 청소년보호법상 연령 확인 의무가 있어 기존 성인 인증(만 19세)을 유지한다. 해외는 본인인증 수단이 없고, 우리 콘텐츠 수위(성인 암시, 노골적 아님)에선 타깃 국가 전부 자기확인만으로 법적 충분하다. 두 경우 모두 실질 구속력은 국가법이 아니라 앱스토어 연령등급이다(§7). 해외에서 생년월일이 미성년을 가리키는데 체크박스로 덮는 설계는 "고의적 외면"으로 방어 불가라 채택하지 않는다.
무료재화
- 동작: 본 PRD는 무료재화 판정에 쓰는 마켓 값만 제공한다. 실제 지급·노출 규칙(웰컴스타 기기 기준 지급, 비-KR 무료 스타 탭 미노출)은 결제·정산 PRD가 소유한다.
약관·동의 캡처
- 목적: 글로벌 유저에게 언어별 약관을 제시하고, 개정·재동의를 판정할 수 있게 동의를 기록한다.
- 동작:
- 문서 세트: 이용약관 · 개인정보처리방침 · 청소년보호정책.
- 에디션 2종: 한국판 / 글로벌판. 글로벌판은 하나의 약관 본문을 8개 언어로 번역하고, 지역별 차이는 짧은 지역 부록으로 붙인다(국가판을 따로 만들지 않음). 준거법 = 한국법 기본, 구속 언어 = 한국어 우선, 미·캐 유저 부록에 개별 중재·집단소송 포기. 마켓 기준 노출 — KR 마켓 → 한국판, 그 외 → 글로벌판. (상세 구조는 법무 검토용 메모.)
- 동의 시점: 가입 시 캡처.
- 버전: 동의 레코드에 (동의한 문서/에디션, 버전, 동의 시각)을 남긴다. 약관 내용·버전 기준은 프론트(웹뷰 서빙)이고 서버는 스탬프만 한다. 저장 버전 < 현재 버전이면 프론트가 재동의를 띄운다.
- 비즈니스 룰: 에디션은 문서 참조로 모델링해 "국가"를 별도 컬럼으로 박지 않는다. 약관 본문·준거법·번역은 정책·현지화 트랙(글로벌판 준거법·구조는 §7).
3.3 가입 이후 — 고정·변경
- 국가·마켓·타임존 = 셀프 변경 불가(서버 강제). CS/어드민 수동 변경만 + 변경 이력 로깅.
- 언어 = 셀프 변경 가능 — 기기/브라우저 언어는 기본값일 뿐, 유저가 설정에서 바꾼다(변경 가능 규칙·저장은 본 PRD). 언어는 UI 표시에만 영향(노출 마켓 격리와 무관). 변경 화면(계정 설정 내 언어 선택 UI)은 UI 현지화 PRD 소관.
- 생년월일 = 직접 입력한 경우 셀프 변경 가능. 본인인증·OAuth 소스로 받아온 경우(주로 한국)는 잠금. 해외는 OAuth에서 받아오는 게 없어 전부 변경 가능.
3.4 데이터 라이프사이클
유저 데이터
| 데이터 | 언제 생기나 | 무엇 기준으로 | 픽스·변경 규칙 | 비로그인 |
|---|---|---|---|---|
| 유저 국가 | 가입 시 | 앱·웹 모두 IP → (IP 실패 시)기기/브라우저 지역 → NA | 고정, 셀프 변경 불가, CS/어드민만 | 저장 안 함(노출 판정만 즉석) |
| 마켓 | 가입 시(국가에서 파생) | 국가↔마켓 매핑 테이블 | 고정, 셀프 변경 불가 | 저장 안 함(노출용 즉석) |
| 언어 | 가입 시 기본값 | 앱=기기 언어 / 웹=브라우저 언어(8종 밖 en) | 기본값일 뿐 설정에서 변경 가능 | 저장 안 함(표시만) |
| 타임존 | 가입 시 | 기기 타임존(IANA) | 고정, 셀프 변경 불가, 폴백 국가 대표tz→NA(미국) 대표tz | 저장 안 함(표시만) |
| 생년월일 | 가입 시 | 자기신고 | 직접 입력=변경 가능, 인증·OAuth 소스=잠금 | — |
콘텐츠(에피소드·소울) 데이터
| 데이터 | 언제 생기나 | 무엇 기준으로 | 픽스·변경 규칙 | 비로그인 |
|---|---|---|---|---|
| 마켓 (한 개) | Draft 생성 시 본인 마켓 → 발행 시 확정 | 디렉터 본인 마켓 그대로 저장(매핑 없는 국가면 마켓=NA). 전원 고정·조정 불가 | 발행 후 변경 불가 | 해당 없음 |
| 언어 (한 개) | Draft 생성 시 마켓 대표언어 → 발행 시 확정 | 그 마켓의 대표 언어로 자동(프롬프트 분기용). 편집 UI 없음 | 발행 후 변경 불가 | 해당 없음 |
콘텐츠 마켓·언어의 입력·검증·발행 UI·권한은 창작·발행 PRD 소관. 본 PRD는 필드가 무엇이고 언제 고정되는지(표)와 스키마·백필만.
3.5 콘텐츠 마켓·언어 필드
- 에피소드·소울 각각에 마켓 한 개 + 언어 한 개. 마켓 = 발행자 본인 마켓 고정, 언어 = 그 마켓의 대표 언어로 자동(1:1 — NA=en·JP=ja·KR=ko·TW=zh-Hant·LATAM=es·BR=pt·ID=id).
- 한 콘텐츠는 한 마켓에만 속한다. 다른 마켓·언어 콘텐츠는 그 마켓 계정에서 직접 발행한다(창작·발행).
- 콘텐츠 마켓은 발행자 본인 마켓(7개 중 하나)이며, 매핑 안 된 국가의 발행자는 마켓=NA다(유저와 동일 — 별도 ROW 값 없음).
- 기존 한국 에피소드·소울은 마켓=KR·언어=ko로 백필.
3.6 공용 기능 (다른 PRD가 소비)
한 곳에서만 정의한다(중복 구현 금지).
- 마켓 노출 필터 — 콘텐츠/노출 목록을 유저 마켓 기준으로 거른다(매핑 없는 국가 유저는 마켓이 NA라 NA를 본다 — 별도 처리 아님). 탐색·플레이 / 운영·어드민이 호출.
- 언어 두 축 — UI 표시 언어 = 유저 언어(UI 현지화가 소비). 생성·프롬프트 언어 = 콘텐츠(에피소드·소울) 언어(플레이·채팅·창작·발행이 소비). 둘은 별개다.
- 마켓 대표 타임존 — 마켓마다 대표 타임존을 하나씩 정의한다(운영·어드민의 팝업·배너·푸시 공통 시간을 각 마켓 로컬 시각으로 변환하는 데 씀). 콘텐츠 마켓 대표 타임존: KR=서울 · JP=도쿄 · TW=타이베이 · NA=뉴욕(동부) · BR=상파울루 · ID=자카르타 · LATAM=멕시코시티. NA는 시간대가 여러 개라 대표 하나(뉴욕/동부)로 근사한다(매핑 안 된 국가 유저도 NA 대표 타임존을 따른다).
타임존 호출부 마이그레이션
원칙: 경계 계산만 필요하고 UI에 안 보이는 건 한국 시간(KST) 고정 유지, 유저에게 시각으로 보이는 것만 유저 타임존.
- 유지(KST 고정): 친밀도(Bond) 일일 한도 · 채팅 선톡 자격/일일 한도 · 일일미션 리셋 등 내부 경계 계산 — 유저에게 시각으로 노출되지 않으므로 KST 그대로. (일일미션은 비-KR 무료재화 게이트로 보상이 막히지만, 경계 계산 자체는 다른 일일 로직과 동일하게 KST 유지.)
- 유저 타임존으로 전환(현실시간 표시·주입): ①채팅/플레이 프롬프트에 넣는 "현재 현실 시각" ②UI에 보이는 시각(댓글 작성 시간·에피소드 업데이트 시간 등). 이건 유저에게 시각으로 보이므로 유저 타임존으로 변환.
3.7 기존 유저 백필
- 기존 유저 마켓 = 전원 KR 유지(측정 결과 비-KR 코호트 극소수). 기존 언어=ko, 기존 에피소드·소울 마켓=KR/언어=ko.
- 기존 유저 유저 국가 = 전부 한국으로 채운다(기존 유저는 사실상 전원 국내라 소급 IP 판정이 불필요하고, 과거 접속 IP도 소급 확보 불가 — 지연 보정·재파생은 하지 않는다).
3.8 어드민
유저 국가/마켓/타임존 수동 변경
- 특정 유저의 유저 국가/마켓/언어/타임존을 수정. 권한 = CS/어드민. 변경 이력 로깅 필수.
마켓 테이블 · 국가 매핑 관리
- 콘텐츠 마켓 7개를 정의하고, 국가↔마켓 매핑(country-market-mapping.md)·각 마켓의 대표 타임존을 관리한다. 주요 국가를 마켓에 매핑하고 나머지 국가는 NA로 매핑한다(별도 ROW 마켓 없음). 매핑 안 됐던 국가에 콘텐츠가 생기면 그 국가를 새 마켓으로 승격한다(매핑 변경 + 해당 국가 유저 마켓 재파생, 데이터 이전 없음).
- 국가↔마켓 매핑에는 국가 대표 타임존(타임존 폴백용)도 둔다.
- 마켓 전체 켜기/끄기·전체 차단 스위치는 두지 않는다.
3.9 Scope
포함 (In scope)
- 로그인 화면 provider 노출 + "다른 방식으로 로그인" 폴백(디자인).
- 가입 시 국가·마켓·타임존 판정·고정, 언어 기본값, 생년월일·연령·성인 게이트(한국=만 19세 본인인증 기존 유지 / 해외=만 18세 자기확인·생년월일 수정 유도), 약관 동의 캡처.
- 셀프 변경 규칙(국가·마켓·타임존 잠금 / 언어·직접입력 생년월일 변경 가능) + CS/어드민 수동 변경·이력.
- 유저·콘텐츠 데이터 라이프사이클·스키마, 마켓(콘텐츠 7개, 매핑 없는 국가는 NA)·국가↔마켓 매핑, 기존 유저·콘텐츠 백필.
- 공용 기능(마켓 필터·언어 두 축·마켓 대표 타임존) + 타임존 호출부 마이그레이션.
- 마켓 테이블·국가 매핑 관리(매핑·대표 타임존).
제외 (Out of scope) — 인접 문서 경계
| 항목 | 소관 |
|---|---|
| 콘텐츠 마켓·언어 발행 시 확정·검증·발행 스냅샷 쓰기 | 창작·발행 |
| 탐색·발견 마켓 필터 적용·딥링크 접근 차단·프로필 노출 규칙 | 탐색·플레이 |
| 마켓별 큐레이션·공지·팝업·푸시·유저 관리 도구 | 운영·어드민 |
| 결제 국가·통화 저장·가격 표시·"무료 스타" 탭 노출·정산 | 결제·정산 |
| UI 텍스트·약관 번역 리소스 | UI 현지화 |
| 약관 본문·글로벌판 준거법·연령/국외이전 정책 | 정책 트랙 |
| 유저 셀프 국가/마켓 변경 UI·NA로 매핑된 국가의 새 마켓 승격·추가 언어(프랑스어 UI·힌디·아랍어 등) | 2차 |
4. 에러 처리 및 예외 상황
| 상황 | 처리 방향 |
|---|---|
| IP·기기/브라우저 전부 판정 실패 | 마켓=NA(앱·웹 동일) |
| 매핑되지 않은 국가 유저 | 마켓=NA → NA(영어)로 노출(에러 아님) |
| 기기 언어가 지원 8종 밖 | 언어 기본값 en |
| 기기 타임존 미확보 | 유저 국가 대표 타임존 → NA(미국) 대표 타임존 |
| 기존 유저 유저 국가 단서 0 | 한국으로 채움 |
| 해외 유저 만 18세 미만이 성인 콘텐츠 접근 | 차단 + 생년월일 수정 유도(자기확인 팝업 미노출) |
| CS 변경 동시 충돌 | 마지막 변경 우선 + 이력 양쪽 기록 |
5. 데이터 분석
글로벌 계측은 별도 문서 없이 각 PRD 이벤트에 마켓/언어 속성을 붙인다. 여기서 공통 속성 규칙을 한 번 정의한다.
- 유저 공통 속성:
user_market·user_language·user_country. - 콘텐츠 실린 이벤트:
episode_market·episode_language(또는soul_*). - 가입 판정 결과·유저 마켓 수동 변경·언어 변경을 이벤트로 남긴다.
- 컨벤션은 event-docs.frontia.dev(snake_case, 동사_명사).
6. Ubiquitous Language
이 표가 마켓/국가/언어/타임존 용어의 정의 원본이다. 다른 PRD는 필요한 항목을 한 줄로 요약해 인라인한다.
| Term | Korean | Definition | Do Not Confuse With |
|---|---|---|---|
| Market | 마켓 | 국가에서 매핑되는 콘텐츠 격리 단위(7개: NA·JP·KR·TW·LATAM·BR·ID). 매핑 안 된 국가는 NA로 매핑(별도 ROW 없음). 언어와 무관 | User Country(국가 단위 원값) |
| User Country | 유저 국가 | 유저의 국가 원값. 가입 시 IP로 판정(앱·웹 공통). 마켓의 소스이자 분석·마켓 승격의 근거로 원값 보존 | Store Country(가격 전용) |
| Store Country | 스토어 국가 | 앱스토어 계정 국가. 인앱 결제 가격 결정에만 쓰는 별도 값(payments 소관). 유저 국가 판정에는 쓰지 않음 | User Country(IP 기반) |
| Language | 언어 | 마켓과 무관. 두 축이 별개 — 유저 UI 언어(8종, UI 표시, 기기·브라우저 디폴트·변경 가능) / 콘텐츠 언어(7종, 에피소드·소울, 생성·프롬프트 기준). th는 UI 언어로만 존재(vi는 UI에서도 제외) | Market(마켓) |
| User Timezone | 유저 타임존 | 현실시간 표시·주입 기준(IANA). 가입 시 기기에서 확정 | Market Timezone(마켓 대표) |
| Market Timezone | 마켓 대표 타임존 | 마켓마다 하나 정한 대표 시간대. 팝업·배너·푸시 공통 시간을 마켓 로컬 시각으로 변환 | User Timezone(유저 개인) |
7. 검토 필요 (미결정 항목)
- [ ] 약관 법무 사인오프 — 2에디션·한국법 기본·한국어 우선·지역 부록 구조는 법무 검토용 메모(
terms-legal-review-memo.md)에 정리. 최종 본문 작성·검토는 법무. (담당: 정책/법무) - [ ] 앱스토어 연령등급 설정 — 성인 게이트의 실질 구속력. Apple 새 18+ 등급(2026-01-31 적용)·Google IARC를 마켓별로 정확히 설정. (담당: PM/운영)
- [ ] 홍콩 성인 콘텐츠 진입 경고 페이지 — 홍콩은 음란물 조례상 Class II(indecent) 콘텐츠에 법정 경고 진입 페이지가 필요할 수 있음. (담당: 정책/법무)
- [ ] GeoIP 서비스 선택 — 웹 IP 판정 의존성. (담당: 엔지니어)
외부 grounding 필요 (구현 시 코드에서 확인)
- 한국 시간 고정 위치 중 "현실시간 표시·주입"에 해당하는 지점만 유저 타임존으로 전환(경계 계산은 KST 유지).
- 서버측 IP geo(GeoIP) 판정 경로를 앱·웹 가입 흐름 양쪽에 확보(유저 국가 판정 소스). 스토어 국가는 유저 국가와 분리돼 인앱 결제 가격에만 쓴다(payments 소관).
부록: 메타 정보
Required artifacts
- Spec — N/A(백엔드 중심).
- Design (🎨) — 로그인 화면 provider 노출 · "다른 방식으로 로그인" · 생년월일·성인 자기확인 팝업 · 만 18세 미만 생년월일 수정 유도 화면. (설정 언어 변경 UI는 UI 현지화 PRD Design 소관.) 어드민(유저 수동 변경·마켓 테이블)은 백엔드 직접 구현.
- Migration plan — 본문 §3.7에 포함(기존 유저·콘텐츠 전원 KR 백필). 별도 파일 아님.
Size & Risks
- Size: L / Confidence: medium — 신규 스키마 + 판정 + 마켓·국가 매핑 + 백필 + 공용 기능 + 타임존 마이그레이션 + 온보딩 신규 화면.
- 위험: ①타임존 마이그레이션 대상(현실시간만) 오분류 ②국가↔마켓 매핑 오설계 ③온보딩 마찰로 가입 전환 하락.
- 의존: UI 현지화(약관·문구, 8개 언어). 결제·정산(무료 스타 탭·결제 국가). GeoIP(미정).
References
- 코드 근거(As-is): frontia-api Payment에 스토어/국가 컬럼 없음(결제 검증 DTO에만 비영속). User에 role/국가/언어/타임존 필드 없음.
- 성인 게이트 근거(해외): 타깃 5개국(미국·캐나다·일본·대만·홍콩) + 라틴·동남아 전부 성년 18세, suggestive 콘텐츠엔 자기확인으로 법적 충분. 생년월일 하한은 고의적 외면 회피(FTC·ICO·EFF). 실질 구속=앱스토어 연령등급.
- 성인 게이트 근거(한국): 청소년보호법 제2조 — 청소년=만 19세 미만이되 만 19세 되는 해 1월 1일부터 성인(연 나이). 판매·제공자 연령 확인 의무 → 기존 본인인증 기반 성인 인증 유지. (국가법령정보센터 청소년보호법.)
- 국가↔마켓 매핑: country-market-mapping.md. (게임 서버 리전 분류를 참고하되 1차는 7 콘텐츠 마켓 + 나머지 국가 NA 매핑으로 단순화.)
- 결정 로그 원문: CLAUDE.md §8.