장단콩 보드게임 & 미니어처 게임 클럽

게임 플레이 통계 — 향후 트로피 연동 참고 문서

개요

일정(posts, type: "event")이 마감(closedAt 생성)될 때, 해당 일정의 games 배열에 담긴 보드게임별 플레이 횟수를 gamePlayStats 컬렉션에 집계한다. 이 문서는 데이터만 정리하며, 이 데이터를 사용하는 트로피는 아직 없다 — 이후 게임 관련 트로피(예: “특정 게임 10회 플레이”)를 추가할 때 참고한다.

데이터 모델

gamePlayStats/{bggId} 문서:

{
  name: "Catan",       // 마지막으로 집계된 시점의 게임 이름 (BGG 상세 API 응답 기준)
  playCount: 12        // 마감된 일정에 이 게임이 등록된 누적 횟수
}

집계 시점과 트리거

functions/index.jsonPostClosed (onDocumentWritten("posts/{postId}", ...)):

알고 있어야 할 제약

향후 트로피 연동 시 참고

트로피 정의는 functions/trophies.jscheck(ctx) => boolean 형태 순수 함수로 추가하는 기존 관례(docs/superpowers/specs/2026-07-15-trophy-system-design.md 참고)를 따른다.

예: “카탄 10회 플레이” 트로피를 추가한다면:

  1. gamePlayStats/{bggId} 문서 하나만 읽으면 판정 가능 (playCount >= 10) → 다른 트로피처럼 무거운 컬렉션 쿼리 불필요.
  2. 이 트로피는 개인(uid) 트로피가 아니라 클럽 전체 공용 이정표에 가깝다 — 기존 트로피들은 전부 users/{uid}.trophies에 개인별로 귀속되는데, 게임 플레이 횟수는 특정 유저 행동이 아니라 클럽 전체 활동의 누적이다. “누구에게 수여할지”를 먼저 설계해야 한다(예: 해당 일정 작성자에게? 참석자 전원에게? 아니면 유저 트로피가 아닌 클럽 전체 배지로?).
  3. onPostClosed 트리거 안에서 게임별 집계 직후 트로피 후보를 판정하도록 확장하거나, gamePlayStats 자체에 대한 별도 onDocumentWritten 트리거를 새로 만드는 두 가지 선택지가 있다 — 후자가 “게임 통계 갱신”과 “트로피 판정” 책임을 분리해 기존 관례(예: game_scoresonGameScoreUpdated)에 더 가깝다.