PetAI WBS 4.0 백엔드·데이터·보안

목표: 로컬 핵심 플레이를 침범하지 않고, 업데이트·날씨·알림·백업·제한된 친구 기능·구매 복원·분석에 필요한 최소 서버만 제공한다.
주 책임: Backend
협업: Unity, Product, Privacy, DevOps, QA
핵심 원칙: optional backend, data minimization, explicit consent

1. 서버 도입 원칙

  • Boot→Home→Template Dialogue→Shared Play→Result→Memory→Save→Restart는 네트워크 없이 동작한다.
  • 서버 장애는 핵심 플레이를 차단하지 않는다.
  • 대화 원문과 장기 기억은 서버에 저장하지 않는다.
  • 동의 없는 정확한 GPS, Health 원시값, 연락처와 광고 식별자는 payload에서 제외한다.
  • 날씨 조회는 사용자가 명시적으로 동의한 경우에만 현재 정밀 GPS를 받을 수 있으며, 날씨 응답을 만든 뒤 정밀 좌표를 저장·분석·공유하지 않는다.
  • 서버는 로컬 관계 수치와 보상의 권위를 가지지 않는다.
  • 친구 기능 장애는 친구 목록·방 방문·스티커만 막고, 홈·관계·공동 플레이·추억은 계속 동작한다.
  • 친구 관계는 수락형이며, 연락처 전체 수집·자동 친구 추가·공개 검색을 하지 않는다.
  • 각 API는 timeout, cache, stale, signature, rollback, opt-out을 정의한다.

2. 작업분해구조

WBS 작업 상태 선행 산출물 수용 기준
4.1.1 API 공통 규약 READY 기능 범위 version/error/retry/idempotency OpenAPI lint
4.1.2 Auth 경계 OPEN 백업 정책 install/account option ADR anonymous path 분리
4.1.3 SNS identity 연결 OPEN provider·탈퇴 정책 provider subject→opaque UID, token 폐기 규칙 raw provider token 저장 0건
4.1.4 Friend graph OPEN auth request/accept/remove/block state machine 수락 전 room 접근 0건
4.1.5 Room snapshot delivery OPEN room public schema allowlisted snapshot/version/cache 대화·기억·정밀 위치 포함 0건
4.1.6 Sticker reaction OPEN friend graph approved sticker/revoke/visibility free text·image·URL payload reject
4.1.7 Social safety OPEN policy report/block/audit retention 차단 뒤 조회·반응 0건
4.1.8 Tutorial/profile sync OPEN account policy current step/completed/character ID/user nickname/character nickname/first meeting/starter grant migration 기기 이전 뒤 도입 반복·중복 시작 지급 0건
4.2.1 Content manifest CONDITIONAL local bundle version/hash/signature/minApp 변조 차단
4.2.2 Bundle delivery CONDITIONAL manifest CDN/object URL/rollback 이전 bundle 유지
4.3.1 GPS weather proxy READY consent UX·provider 결정 current coordinate→weather grid, consent receipt, cache/source, coordinate discard provider 장애·권한 거절 시 수동 도시 fallback
4.4.1 Push registration CONDITIONAL consent UX opaque token/topic opt-out 즉시 반영
4.4.2 Notification schedule CONDITIONAL event catalog type/window/quiet hours 게임 없이 압박 금지
4.5.1 Progress backup CONDITIONAL account·crypto allowlist payload/version local authority 유지
4.5.2 Restore CONDITIONAL backup inspect/preview/confirm silent overwrite 0건
4.5.3 Purchase entitlement OPEN BM policy product/transaction/restore idempotency 중복 지급·관계·능력치 판매 0건
4.6.1 Analytics ingest CONDITIONAL consent policy event allowlist forbidden field reject
4.6.2 Retention/delete CONDITIONAL legal/product TTL/delete job/export deletion audit
4.7.1 Rate/abuse limits P2 endpoint spec per-endpoint limits 핵심 local play 무관
4.8.1 Monitoring P2 deployment SLO/error budget 원문 없는 alert

3. 전송 허용·금지

데이터 기본 조건
app/content/schema version 허용 운영에 필요한 범위
coarse device/OS version 조건부 분석 동의, 소수 bucket
event ID와 result bucket 조건부 원문·정확 시각 제외 가능
city-level weather key 조건부 위치 권한 없이 수동 도시 fallback
current precise coordinate 조건부 GPS 날씨 동의가 있는 요청에서만 수신, weather grid 변환 뒤 로그·DB·분석 payload에서 제거
weather consent version·timestamp 조건부 동의·철회 감사와 서버 수락 판단에 필요한 최소값
signed content request 허용 개인정보 없음
관계 stage bucket 조건부 백업 또는 동의 분석만
opaque UID와 수락된 friend edge 조건부 친구 기능 동의·탈퇴·차단 처리 목적만
공개한 room snapshot 조건부 가구·복장·승인된 캐릭터 상태만 allowlist
승인 sticker ID와 반응 시각 bucket 조건부 친구 반응 표시·차단·신고 처리 목적만
SNS provider subject 조건부 opaque UID 연결 후 최소 보존, 원본 access token 저장 금지
tutorial step, character ID, 사용자·캐릭터 호칭, 첫 만남 시간, starter grant 상태 조건부 로그인 계정의 기기 이전·도입 반복·중복 시작 지급 방지 목적만
product ID와 정규화 transaction ID 조건부 구매 복원·환불·중복 지급 방지 목적만
대화 원문 금지 예외 없음
장기 기억 원문·embedding 금지 예외 없음
정밀 GPS·주소의 영구 저장, 이동 이력, 분석 전송 금지 날씨 1회 조회 뒤 즉시 폐기
Health 원시값 금지 MVP 제외
사용자 입력 자유문장 금지 분석·로그에서 제외
주소록·SNS 친구 목록 전체 금지 직접 UID·초대 링크·명시 수락만 허용
결제 수단 번호와 원본 영수증 전문 금지 플랫폼 결제·검증 서비스에 위임
로컬 파일 경로·stack trace 전체 금지 정규화 error code만

4. 친구 기능 서버 경계

친구 기능은 소셜 네트워크가 아니라, 서로 아는 사람이 캐릭터와 방을 제한적으로 공유하는 기능이다.

  • 친구 추가: SNS 연결, 초대 링크, UID 중 하나로 요청을 만들고 상대가 수락해야 한다.
  • 방 방문: 서버는 공개 허용한 room snapshot만 전달한다. 대화, 장기 기억, 관계 수치, 위치, 일정은 snapshot에 넣지 않는다.
  • 캐릭터 교류: 클라이언트가 승인된 interaction ID를 요청하고, 각 캐릭터의 공개 상태를 기준으로 미리 만든 연출을 재생한다. 서버가 AI 대화를 만들지 않는다.
  • 반응: 승인된 sticker ID만 저장한다. 자유 텍스트, 이미지, 링크, 파일 첨부는 API 수준에서 거절한다.
  • 안전: remove, block, report가 같은 우선순위로 제공된다. block 뒤에는 profile, snapshot, sticker, 초대 링크의 접근 권한을 즉시 철회한다.
  • 오프라인: 친구 기능은 unavailable 상태를 명확히 보여 주되, 로컬 게임 상태를 바꾸거나 저장을 실패시키지 않는다.

공개 방 상태의 기본값은 비공개다. 사용자는 친구별 또는 전체 친구에게 공개할 수 있으며, 공개를 끄면 CDN cache와 서버 원본의 철회 시점도 기록한다.

4. Content manifest contract

{
  "bundleId": "petai-content",
  "version": 12,
  "schemaVersion": 3,
  "minAppVersion": "0.1.0",
  "sha256": "hex",
  "signature": "base64",
  "downloadUrl": "https://...",
  "publishedAt": "ISO-8601"
}

클라이언트는 signature와 hash를 검증한 뒤 새 bundle을 staging에 풀고 runtime validator를 통과시킨다. 실패하면 현재 활성 bundle을 유지한다. 서버 응답이 없으면 설치 번들을 사용한다.

5. 날씨 실패 계약

상황 반환 클라이언트 처리
fresh cache cached state source와 age 기록
provider timeout stale cache stale 허용 범위 표시 없이 자연스럽게 사용
cache 없음 unknown 중립 환경·대사
위치 권한 거절·동의 철회 no-location 수동 도시 또는 unknown fallback
invalid city 또는 coordinate 400 normalized error 수동 도시 재선택
rate limit retry-after 즉시 반복 금지

날씨 정확도를 게임 진행 조건으로 사용하지 않는다. 날씨 보상, 연속 기록, 관계 패널티를 만들지 않는다. GPS 날씨 조회는 foreground 또는 사용자가 허용한 제한적 background refresh에만 수행하며, 위치 이동 감시를 시작하지 않는다.

6. 백업 원칙

  • opt-in 이전 업로드 0건
  • allowlist field만 직렬화
  • 업로드 전 local schema와 backup payload schema를 분리
  • restore 전에 diff summary 제공
  • primary local save를 즉시 덮어쓰지 않고 import candidate로 검사
  • cloud가 최신이라는 이유만으로 자동 선택하지 않음
  • 대화 원문·로컬 memory body 제외
  • 계정 삭제 시 server copy 삭제와 local 유지 여부를 별도 선택

7. 분석 이벤트 최소안

이벤트 필수 field 금지 field
session_started app_version, day_bucket exact last seen
home_interaction target_type, result coordinates, free text
shared_play_completed content_id, outcome, duration_bucket raw input timeline
memory_opened source_type, age_bucket memory body
real_action_offered action_id, accepted user reason text
event_completed event_id, choice_id dialogue line
error_observed error_code, feature stack trace, file path

8. 장애와 SLO

  • manifest API P95 목표 500ms, timeout 2s
  • weather proxy P95 목표 1s, timeout 2s
  • analytics는 fire-and-forget queue, gameplay blocking 0ms
  • backup은 사용자 명시 action에서만 진행 상태 표시
  • 모든 retry는 exponential backoff와 jitter
  • signature·schema 오류는 retry보다 rollback 우선
  • backend 24시간 장애 중에도 Day 0~7 local content 완주

9. 완료 증거

  • OpenAPI와 schema validation
  • allowlist/denylist payload 자동 테스트
  • signature/hash tamper fixture
  • timeout·5xx·429·offline·stale cache 통합 테스트
  • consent off 상태 network capture 0건
  • delete/export/restore 사용자 여정
  • log sample의 원문·정확 위치·절대 경로 0건
  • backend 미실행 상태 Unity 핵심 플레이 회귀

10. 연결 문서


11. 2026-07-23 서버 범위 보완

WBS 서버 책임 허용 데이터 금지 데이터 완료 증거
4.9 OAuth 계정 연결 provider subject, account UID, consent OAuth access token 장기 보관, 대화 원문 provider별 unlink/delete/re-auth 테스트
4.10 푸시 발송 push token, category opt-in, quiet hours, deep link id 자유 대화 본문, 정밀 위치 category off 시 network/dispatch 0건
4.11 날씨 프록시 조회 순간의 최소 위치 또는 수동 도시, weather response 좌표 이력, 이동 경로, 친구 공유 권한 off/timeout 시 client fallback 계약
4.12 친구·방 snapshot UID, 요청/수락/차단, 공개 방 snapshot DM, 이미지, 자유 텍스트, private room data 수락 전·차단 후 접근 거부 테스트
4.13 결제 검증·복원 store transaction id, product id, entitlement 대화/건강/위치와 결합한 프로파일 restore/refund/duplicate transaction fixture
4.14 선택 백업 비민감 성장·소유·방·튜토리얼 요약 memory body, health raw, exact location export/delete/restore와 conflict 선택 여정

11.1 데이터 보존 원칙

  • 푸시 목적의 “미접속”은 재방문 정책에 필요한 coarse last-active bucket만 사용하며, 장기 행동 이력을 마케팅 프로필로 만들지 않는다.
  • 스트레스 회복 푸시는 기본값 또는 opt-in 여부를 제품에서 결정한 뒤에만 발송한다. 건강 데이터는 회복 판정의 서버 입력이 아니다.
  • 이벤트·상품·한정 정책의 기준 데이터는 versioned content manifest로 제공하고, 클라이언트는 오프라인 cache와 schema rollback을 가져야 한다.

자세한 데이터 구분과 사용자 흐름은 최종 기능 정의서를 따른다.