Firebase 초기화 헬스체크 운영 가이드 (ADR 0029)
2026-04-29 ops 콘솔 KPI=0 silent failure 사고 후 수립된 fail-loud 정책의 운영 측 가이드. CLAUDE.md "Firebase 초기화 fail-loud" 섹션 + ADR 0029 가 정책 SSoT, 본 문서는 일상 모니터링·복구 절차.
1. 정책 요지
환경변수 미설정 → fallback 빈 객체 export 금지 → 즉시 throw.
-
금지 패턴:
export const adminDb = app ? getFirestore(app) : ({} as ReturnType<typeof getFirestore>)— fallback cast 금지if (!adminDb || typeof (adminDb as { collection?: unknown }).collection !== "function") return;— v9 modular SDK 인스턴스에.collection없으므로 항상 가드 통과 못 함- silent return / silent skip 가드 일반
-
권장 패턴:
throw new Error("Firebase 미초기화: <env keys>")즉시 발화 (apps/web/lib/firebase/admin.ts참고)- 무결성 확인이 꼭 필요하면
isFirebaseReady()단일 SSoT ("app" in instancestable API)
2. 회귀 가드
apps/ops/__tests__/firebase-init.test.ts— env 미설정 시 import throwapps/web/__tests__/firebase-init.test.ts— 동일
PR 머지 시 두 테스트 통과 확인. 우회 추가 코드 없음.
3. 일상 모니터링
3.1 매일 06:00 KST (배포 직후)
- ops 콘솔 dashboard 접속
- KPI 카드 4종 (테넌트 수·활성 사용자·사건 수·회수 합계) 모두 정상 표시 확인
- 이상 신호:
- 모든 카드 0 표시 (테넌트 0건이 아닌 경우) → 즉시 §4 절차
- 일부 카드만 0 표시 → 도메인별 헬스체크 (§5)
3.2 자동화 모니터링 (TODO — 후속 ship)
- Cloud Logging: "Firebase 미초기화: NEXT_PUBLIC_FIREBASE_*" 에러 count
- Sentry alert: 동일 에러 메시지 임계값 → 즉시 알림
현재는 수동 점검 + Firebase Console 로그. 자동화 alert 는 후속 PR 에서.
4. 사고 대응 절차 (KPI 모두 0)
Step 1: 환경변수 검증
# apps/ops 의 NEXT_PUBLIC_FIREBASE_* 환경변수 누락 여부
firebase apphosting:backends:get ops --project <projectId>
또는 App Hosting 콘솔에서 backend 환경변수 확인:
NEXT_PUBLIC_FIREBASE_API_KEYNEXT_PUBLIC_FIREBASE_AUTH_DOMAINNEXT_PUBLIC_FIREBASE_PROJECT_IDNEXT_PUBLIC_FIREBASE_STORAGE_BUCKETNEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_IDNEXT_PUBLIC_FIREBASE_APP_ID
Step 2: 로그 확인
Cloud Logging 에서 ops backend 로그 검색:
severity >= ERRORtextPayload =~ "Firebase 미초기화"
→ 발화 시점·인스턴스 식별. ADR 0029 정책상 반드시 throw 발화 가 정상.
Step 3: 만약 throw 안 발화하는데 KPI 0 이면 → silent failure 재발
즉시 ADR 0029 정책 위반 점검:
# v9 호환 가드 패턴 grep
grep -rn "typeof.*\.collection.*!== *\"function\"" apps/ops/ apps/web/
grep -rn "{}\\s*as.*\\(Firestore\\|Auth\\|FirebaseApp\\)" apps/ops/ apps/web/
→ 발견 시 isFirebaseReady() 로 교체 PR 즉시 작성. 사고 보고서 ADR cross-link.
Step 4: 복구
- Step 1 에서 환경변수 누락 → App Hosting 콘솔 또는
apphosting.yaml에 추가 → redeploy - Step 3 에서 v8 호환 가드 발견 → 즉시 PR 작성 → 머지 → redeploy
5. 도메인별 헬스체크
5.1 시나리오 페이지 (ADR 0028)
/scenarios접속 → 임의 도메인 카드 (예:auth/RecordConsentsScenarioCard) 클릭- 테스트 tenant 선택 → Run
- 결과 패널에 성공/실패 + Firestore write 요약 표시 → 정상
- 0건 표시·에러 메시지 없음 → silent skip 의심 → §4 Step 3
5.2 tenants 페이지
/tenants접속 → 테넌트 목록 표시- 0건이지만 actually 테넌트 존재 → silent failure → §4
5.3 public-rag 페이지
/public-rag접속 →publicDocumentscount 표시- 0건이지만 production 에 데이터 있음 → silent failure → §4
6. 회귀 방지 코드 작성 시 체크리스트
- Firebase init 진입점에 fallback cast
({} as Firestore)없는가? - env 미설정 시
throw new Error()발화하는가? - 가드 추가 시 (1) fallback 자체를 막는가? (2) 가드 통과 후 호출이 실제 동작하는가 emulator 로 1회 검증?
-
isFirebaseReady()외 변형 init 검사 만들지 않았나? - LLM 코드 hedging 패턴 ("그럴듯한 방어 가드", "환경변수 미설정 시 fallback", "typeof 검사") 없는가?
7. 후속 회의 — UX 두 번째 안전망
ADR 0029 후속 의제: /meeting 빈 상태 vs 실패 상태 UI 패턴 통일 tier=B (2026-05-13 데드라인, P4 디자이너 주도).
- C-7: 빈/실패 4-state 디자인 시스템
- C-8: 카피 SSoT
- C-9: SystemStatusBadge
- C-10: 에러 토스트 hook
→ 사용자 화면에 "이상하다" 신호 가 도달해야 silent failure 의 두 번째 안전망 완성.