44 lines
1.8 KiB
Plaintext
44 lines
1.8 KiB
Plaintext
rules_version = '2';
|
|
// TriplePick Firestore 보안 규칙
|
|
// 모델: 공개 데이터(경기/AI예측/집계)는 읽기 허용, 모든 쓰기는 서버(Admin SDK·Cloud Functions)만.
|
|
// 유저 예측/구독/참여는 클라이언트 직접 접근 금지 → 콜러블 함수로만 처리(검증·집계·PII 보호).
|
|
service cloud.firestore {
|
|
match /databases/{database}/documents {
|
|
|
|
// ---- 공개 읽기 전용 (쓰기는 Admin SDK가 규칙 우회) ----
|
|
match /matches/{matchId} {
|
|
allow read: if true;
|
|
allow write: if false;
|
|
}
|
|
match /ai_predictions/{docId} {
|
|
allow read: if true;
|
|
allow write: if false;
|
|
}
|
|
match /crowd_stats/{matchId} {
|
|
allow read: if true; // 군중 분포(퍼센트, PII 없음)
|
|
allow write: if false; // submitPrediction 함수가 트랜잭션으로 증분
|
|
}
|
|
|
|
// ---- 비공개: 함수/Admin 전용 (클라이언트 직접 접근 전면 금지) ----
|
|
match /user_predictions/{docId} {
|
|
allow read, write: if false; // 제출/조회는 콜러블 함수로만, 이메일 등 PII 보호
|
|
}
|
|
match /notify_subscriptions/{docId} {
|
|
allow read, write: if false; // 결과 알림 구독 (Resend 발송용)
|
|
}
|
|
match /event_participation/{deviceId} {
|
|
allow read, write: if false; // R2 — 상금 챌린지 누적/자격
|
|
}
|
|
|
|
// 그 외 전부 차단
|
|
match /{document=**} {
|
|
allow read, write: if false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 참고: 클라이언트 직접 쓰기 방식을 택할 경우(함수 없이), user_predictions에
|
|
// create 검증 규칙(opens_at ≤ now < lock_at[=킥오프 정각], outcome ∈ {TEAM_A_WIN,DRAW,TEAM_B_WIN},
|
|
// score 0~9 정수, nickname 2~16자, docId == matchId+"_"+deviceId)을 넣어야 한다.
|
|
// 단 crowd_stats 원자적 증분과 PII 보호 때문에 콜러블 함수 방식을 권장한다(docs/BACKEND.md).
|