윤정민 a9634b7229 Expand notification settings API with marketing consent
- NotificationKey에 predictionRemind·jjaekTalk 추가(마케팅은 opt-in 맵에서 제외)
- GET/POST/PATCH /user 응답에 notifications 맵과 marketingOptIn 포함 — 클라가 서버 설정을 읽을 수 있게 함
- updateMe에 marketingOptIn 처리 추가: 동의 시각은 서버 serverTimestamp로 기록, 철회 시 동의 이력 보존 (기존에는 미파싱으로 단독 PATCH가 400)
- updateNotifications가 전체 맵 재기록 대신 patch 키만 merge 기록하도록 변경(동시 토글 유실 방지)
- userService 테스트 8건 추가(허용/차단 키, boolean 검증, 동의 시각 기록·보존, 기본값)
- backend-writes.md §1.1에 새 쓰기 필드·규칙 반영
2026-07-23 17:19:00 +09:00
..

Panit 데이터 read/write 패턴 문서

Panit 야구앱의 Firebase(Firestore + RTDB) 데이터 접근 패턴 전수 조사 결과. 백엔드(mmday-firebase)와 Flutter 클라이언트(Panit)를 함께 추적했다.

문서 구성

문서 내용
data-lifecycle.md 각 데이터가 어떻게 생성되고 누가 읽는지 — 생성 주체·트리거·소비자 맵 (종합)
backend-writes.md 백엔드 모든 write 경로 (repository/trigger/scheduled/handler), 빈도·배치·핫문서·비용
backend-reads.md 백엔드 모든 read + 캐싱 3계층(MemCache/kboCache/scoreboardCache), N+1·인덱스
optimization-plan.md read/write 최적화 로드맵 — 영향도×리스크 우선순위, 권장 변경·검증 포인트
client-patterns.md 클라 접근 패턴(직접 Firestore/RTDB vs CF, 실시간 vs 단발, SWR). 위치: Panit/docs/data-patterns/client-patterns.md

개선 보고서 (Before → Fix → After)

실제 적용된 최적화의 변경 전/후를 커밋 diff 근거로 정리. (백엔드=opt/backend-rw, 클라=opt/client-rw 브랜치)

문서 내용
improvements-backend-writes.md W1·W2·W3·W4·W5+R6·W6·doc-drift 적용 결과
improvements-backend-reads.md R1·R4·R5·R7 적용 결과 + 보류 항목(R2·R3) 사유
improvements-client.md C1·C2·C3·C4 적용 결과. 위치: Panit/docs/data-patterns/improvements-client.md

핵심 결론 (3줄)

  1. 클라는 Firestore/RTDB를 직접 읽지 않는다fcmTokens write 1곳 외 전부 Cloud Functions HTTP 경유.
  2. 최대 비용: write=games 매일 월 전량 재기록 / read=dailyArchive 유저별 게임쿼리 중복 + getStats 무효화 후 voteHistory 풀스캔 / 클라=voteSummary 10초 폴링.
  3. 인덱스 누락 없음 — 복합 인덱스 3종 모두 쿼리와 일치.