demo-firm-memory walkthrough — 자기 데이터로 자기 AI 학습 검증
위상: ADR 0015 "Tenant 격리 AI 학습" 의 production 동작 검증 가이드. 합성 부트스트랩 (scripts/seed-synthetic-firm-memory.ts) 이 시드한 demo-firm-memory tenant 를 영구 dev 자산으로 운영. e2e spec (e2e/synthetic-firm-memory-production-walkthrough.spec.ts) 이 V2 RelatedMemoriesPanel + AiPrefillCard 가시성 회귀 가드.
무엇
production Firebase 의 demo-firm-memory tenant 에 5 Pack × 4 시나리오 = 20 합성 사건 + 40 legacyDocs (scanned 20 + authored 20) + 45 refinementFeedback 이 영구 시드되어 있다. 이 tenant 의 owner 권한을 가진 dev 계정 으로 로그인하면 production V2 Vector Search · 학습 루프 · panel UI 가시성을 직접 시각/자동 검증 가능.
사용 시나리오:
- 신규 V2 검색 ranking 알고리즘 변경 시 회귀 검증
- AiPrefillCard / RelatedMemoriesPanel UI 변경 시 가시성 보존 확인
- 학습 루프 (refinementFeedback → exemplar selection) 시각 데모
emulator 한계 회피 목적: emulator 의 Firestore Vector Search 비활성으로 V2 panel 의 실 hits 검증 불가 → production firestore 의 격리된 demo tenant 사용.
dev 계정
email: dev-walkthrough@demo-firm-memory.neohollo.test
uid: dev-walkthrough-demo
tenant: demo-firm-memory
role: owner
- email 도메인 prefix
@demo-firm-memory.neohollo.test로 식별 명확 - tenant 단일 한정 (demo-firm-memory) — 다른 tenant 가입 없음 → cross-pollution 차단
- password 는 시드 스크립트가
E2E_DEMO_WALKTHROUGH_PASSWORDenv var 에서 읽음. 미설정 시 default 적용 (scripts/seed-demo-walkthrough-account.ts참조). dev 환경 한정 — 외부 노출 시 즉시 reset (Firebase 콘솔 또는 admin SDK) - Custom Auth claims: 시드 시
setCustomUserClaims(uid, { tenantId, role })호출 필수.getServerSession의 tenantId 결정 source 가 ID token claim 이라 누락 시 layout 가드 → /onboarding redirect
시드 / 회수
# dev 계정 + member 시드 (이미 1회 적용됨, 재실행은 idempotent)
NODE_PATH=apps/web/node_modules pnpm exec tsx \
scripts/seed-demo-walkthrough-account.ts --apply
# 회수 (실수로 시드된 경우 또는 영구 종료 시)
NODE_PATH=apps/web/node_modules pnpm exec tsx \
scripts/seed-demo-walkthrough-account.ts --revoke
합성 데이터 자체 (cases / legacy / feedbacks) 는 seed-synthetic-firm-memory.ts 가 관리:
# demo-firm-memory tenant 재시드 (force)
NODE_PATH=apps/web/node_modules pnpm exec tsx \
scripts/seed-synthetic-firm-memory.ts --apply --force --tenant=demo-firm-memory
사용법
1) production 배포 URL 직접 (가장 단순)
main 브랜치는 Firebase App Hosting 자동 배포. production URL 에 incognito 브라우저 로 진입 후 dev 계정 credentials 로 로그인.
production URL 은 Firebase 콘솔 → App Hosting → backend neohollo-pro 의 hosted URL 확인.
2) 로컬 production 향 dev server
기존 emulator 향 dev server (port 3000) 는 그대로 유지하고 별도 터미널에서:
NEXT_PUBLIC_USE_EMULATOR=false pnpm dev --filter=@neohollo/web -- -p 3002
http://localhost:3002 incognito 진입.
시각 검증 포인트
| 페이지 | 기대 |
|---|---|
/dashboard | demo tenant 통계 카드 — 사건 20건 / 회수율 분포 / 만족도 차트 |
/legacy | 사무실 기억 40건 list (debt/divorce/부동산/상속/계약 5종 cluster) |
/cases | 종결 사건 20건 list, recoveryType 컬럼 14종 분포 |
/cases/case-debt-04 | 사이드바 RelatedMemoriesPanel 에 같은 cluster (debt) hits N건 가시 — 의미 매칭 |
/cases/case-divorce-01 | 같은 panel 에 divorce cluster hits 우세 |
/cases/new | AiPrefillCard mount + 자유 텍스트 입력 → AI 추정 (silent RAG hits 가 prompt 강화) |
/cases/{id}/documents/{docId} (서류 편집) | InPlatformDocEditor 사이드바 RelatedMemoriesPanel + RelatedPrecedentsPanel + firmHistoryCount chip ("사무실 학습 N건") |
V2 검증 (이미 검증된 결과)
PR #1661 의 production findRelatedMemoriesV2Impl 시뮬:
| 시나리오 | precision@5 |
|---|---|
| 신규 debt 사건 | 1.00 |
| 신규 divorce 사건 | 0.80 |
| 신규 명도 사건 | 0.40 (cluster size 4 max=0.80) |
| 신규 유류분 사건 | 0.80 |
| 신규 부당이득 사건 | 0.60 |
| overall | 0.72 |
e2e 회귀 가드
e2e/synthetic-firm-memory-production-walkthrough.spec.ts 가 production 향 dev server 또는 배포 URL 통해 자동 walkthrough. 35.4초 PASS 검증됨 (PR #1665).
E2E_BASE_URL=https://pro.neohollo.com \
E2E_DEMO_WALKTHROUGH_PASSWORD=<password> \
E2E_APPCHECK_DEBUG_TOKEN=<uuid> \
./apps/web/node_modules/.bin/playwright test \
synthetic-firm-memory-production-walkthrough --reporter=list
필수 환경변수 3종:
E2E_BASE_URL— production URLE2E_DEMO_WALKTHROUGH_PASSWORD— dev 계정 passwordE2E_APPCHECK_DEBUG_TOKEN— Firebase App Check debug token (콘솔에 등록된 UUID)
App Check 우회 흐름:
- production 의 App Check enforcement 는 정당한 보안 layer. 사용자 본인 사용에는 영향 없으나 자동화는 token 발급 불가
- spec 이
page.addInitScript로self.FIREBASE_APPCHECK_DEBUG_TOKEN을 page load 전 inject → Firebase SDK 가 provider 무관 debug 모드 우선 적용 - token 은 환경변수로만 받음 (코드/문서/repo 에 노출 X). 발급은 Firebase 콘솔 → App Check → 본 앱 → "Manage debug tokens"
read-only 검증:
- 기존 시드 사건 (case-debt-04) 상세 진입 → RelatedMemoriesPanel hits ≥ 1
- /legacy list 합성 데이터 가시
- /cases/new AiPrefillCard mount
금지 (production tenant 누적 방지):
- 신규 사건 등록 (cases/new 의 finalize)
- 신규 legacyDoc 업로드
- finalize-document 호출 (refinementFeedback 변경)
안전 규칙
- ✅ dev 계정 = demo-firm-memory tenant 만 접근. 다른 tenant 시도 시 차단
- ✅ 시드 데이터 (cases / legacy / feedback) 는
--force재시드로 idempotent 회복 - ✅ 사용자 본인 production 사무소와 완전 분리 (별도 incognito + 별도 계정)
- ⚠️ password 는 dev 환경 한정. 외부 노출 시 Firebase 콘솔에서 즉시 reset
- ⚠️ e2e spec 이 mutation 동작 (사건 등록 등) 추가 시 누적 위험 — read-only 가드 강제
회수 절차 (영구 종료 시)
# 1. dev 계정 + member 회수
NODE_PATH=apps/web/node_modules pnpm exec tsx \
scripts/seed-demo-walkthrough-account.ts --revoke
# 2. (선택) 합성 데이터 cleanup — 별도 scripts/cleanup-synthetic-firm-memory.ts
# 현재 미구현. 필요 시 직접 Firestore 콘솔에서 tenants/demo-firm-memory 삭제
# 또는 cleanup 스크립트 추가 후속 PR.