ADR 0038 — ops v2 운영 콘솔 정보 아키텍처
날짜: 2026-05-07
상태: Accepted
Tier: A (Architecture · 운영 콘솔)
적용 범위: apps/ops 전체 — 사이드바 정보 아키텍처, 시나리오 페이지 routing, 신설 페이지 (운영 가시성·도구·시스템) 의 통합 설계.
결정문
apps/ops 의 평면 메뉴 구조를 5 그룹 정보 아키텍처 (운영·검증·콘텐츠·도구·시스템) 로 재편하고, 시나리오 페이지를 registry-driven subroute 로 마이그레이션하여 운영 효율성·확장성·테스트 안전망을 동시에 확보한다.
배경
apps/ops 는 너홀로프로 운영팀이 production 을 모니터링하고 새 기능을 검증하는 콘솔이다. 2026-04-29 ADR 0028 (비즈니스 로직 추출) 이후 시나리오 카드가 90+ 개로 늘었고, 페이지도 10 개 평면 구조로 성장했다. 다음 한계가 누적되었다.
- 평면 사이드바:
dashboard / tenants / scenarios / rag-eval / ai-quality / bot-runs / case-prefill / public-rag / public-rag/bulk가 모두 같은 층에 나열. 영역별 의도 (운영 vs 검증 vs 콘텐츠) 가 사이드바에 안 드러남. 새 페이지 추가할수록 인지부하 증가. - 시나리오 페이지 한 덩어리:
scenarios/page.tsx788줄, import 만 113줄. 카드 등록이 manual list, 단일 페이지라/scenarios/docs·/scenarios/portal같은 URL 공유·북마크 불가, 카드 메타 (4 메타 표준, ScenarioCardShell) 가 컴포넌트 내부에 갇혀 검색·필터·자동 회귀 검증에 활용 못 함. - 운영 가시성 0: 2026-05-03 production sweep 에서 functions 메모리 256MiB 부족·ADR 0002 좀비 함수가 gcloud CLI 1회로 발견된 사례. ops 안에 incident timeline·Functions health·Firestore index 누락 detector 가 없어 매주 외부 도구로 우회.
- 개발자 마찰 도구 0: 테스트 tenant 1클릭 시드 (
e2e/stress 시드는 users/{uid}.consents 까지 chain메모 반영), feature flags 토글, Cmd+K command palette, debug token 발급 같은 일상적 마찰을 줄이는 도구 부재. - 검증/모니터링 분리 흐림: scenarios (mutation 검증) · rag-eval (RAG 품질) · ai-quality (AI 응답) · bot-runs (자동 e2e) · case-prefill (프리필) 가 한 흐름이지만 평면 메뉴라 의도 안 보이고 신규 운영자가 학습 시 큰 헷갈림.
결정 — 5 그룹 정보 아키텍처
| 그룹 | 의도 | 페이지 |
|---|---|---|
| 🔭 운영 (Ops) | 우리가 보는 production 상태 | dashboard · tenants · incidents ⭐ · health ⭐ |
| 🧪 검증 (Verify) | 새 기능 안전망 — production tenant 영향 없이 시뮬레이션 | scenarios (subroute 화) · case-prefill · bot-runs · rag-eval · ai-quality · journey ⭐ |
| 📚 콘텐츠 (Content) | 우리가 채우는 데이터 | public-rag · public-rag/bulk · legal-news ⭐ · templates ⭐ |
| 🛠️ 도구 (Tools) | 마찰 줄이기 | command-palette (Cmd+K 전역) · tenant-fixture ⭐ · debug-tokens ⭐ · feature-flags ⭐ |
| ⚙️ 시스템 (System) | 정책·감사 | audit-log ⭐ · env ⭐ · members ⭐ |
⭐ = 본 ADR 로 신설. 기존 페이지는 모두 보존하되 그룹만 부여.
시나리오 콘솔 v2 — 핵심 변경
90 카드 단일 페이지 → registry-driven subroute. 4가지 변경:
1. registry 분리 (_lib/scenario-registry.ts)
각 카드별 _components/cards/<domain>/<Card>.tsx 옆에 <Card>.meta.ts 추가. zod 검증된 4 메타 (CLAUDE.md ScenarioCardShell 4 메타 표준 SSoT 와 동일):
// _components/cards/case-lifecycle/CreateCaseScenarioCard.meta.ts
export const meta = scenarioMetaSchema.parse({
key: "create-case",
domain: "case-lifecycle",
title: "사건 생성",
dataModel: "tenants/{tid}/cases/{caseId} ...",
businessLogic: "createCase (packages/business-logic/cases) ...",
meaning: "변호사 사건 등록 진입점. recoveryType·packType ...",
webMapping: "/cases/new → CaseCreateForm ...",
tags: ["mutation", "case", "core"],
});
scripts/build-scenario-registry.ts 가 fs scan → 자동 collect → registry 모듈 생성. 회귀 가드 = apps/ops/__tests__/scenario-registry-coverage.test.ts (모든 cards/**/*ScenarioCard.tsx ↔ *.meta.ts 1:1 검증).
2. 도메인 subroute
| URL | 의미 |
|---|---|
/scenarios | 인덱스 (도메인 그리드 + 검색 + 즐겨찾기) |
/scenarios/[domain] | 도메인 카드 그리드 (예: /scenarios/case-lifecycle) |
/scenarios/[domain]/[card] | 단독 시나리오 페이지 (URL 공유 가능, PR 리뷰 시 "이 시나리오 한 번 돌려봐" 가 링크로 됨) |
기존 scenarios/page.tsx 의 master-detail UX 는 /scenarios 인덱스에서 그대로 유지 — 점진 마이그레이션이라 회귀 위험 최소화.
3. 최근 실행 사이드 패널
모든 시나리오 mutation Server Action 이 tenants/{tid}/opsScenarioRuns/ 에 텔레메트리 append (이미 일부 카드는 진행 중). v2 사이드 패널이 최근 N 건 + 결과 enum + before/after diff 노출. 회귀 의심 시 즉시 재실행.
4. 즐겨찾기·태그 필터·키워드 검색
- localStorage
ops:scenarios:favorites에 카드 키 저장 → 인덱스 페이지 상단에 "즐겨찾기" 섹션 - 메타
tags배열로 필터 (예:mutation·read-only·core·learning·chain) - 키워드 검색은
title + meaning + dataModel토큰 매칭 (Fuse.js 같은 lib 도입 보류 — 단순 substring 으로 충분)
신설 페이지 명세
운영 (Ops)
incidents— Cloud Functions 에러 로그 timeline (gcloud Functions API → server fetch, 페이지당 limit 50, 1분 캐시) · Firestore index 누락 detector (collectionGroup 쿼리 실패 catch) · ADR 0029 fail-loud 미준수 신규 코드 검출 (정적 분석) · 5xx 비율health— Functions 메모리·CPU·콜드 스타트·Firestore latency p95 · embed-legacy-doc 실패율 (ADR 0015 학습 루프 건강도)
검증 (Verify)
journey—e2e/JOURNEY-MATRIX.md의 19 chain 을 ops 에서 직접 실행 + step-by-step 결과 노출. 기존scenarios/_components/cards/auto/ChainScenarioCard확장.
콘텐츠 (Content)
legal-news— ADR 0033 일간 법률 뉴스 검증 (현재 시나리오 카드만 있음 → 단독 페이지 승격)templates—public/docxTemplates/+tenants/{tid}/docxTemplates/공용 템플릿 관리 UI (지금은 Storage 콘솔 사용)
도구 (Tools)
command-palette(전역Cmd+K) —cmdklib (~5KB), 시나리오·페이지·테스트 tenant 즉시 jumptenant-fixture— "1클릭 시드" 버튼: owner + cases 5건 (Pack 1·2·3·4·5 각 1) + legacyDocuments 10건 + embedding + portal token +users/{uid}.consentschain 한 번에. 매 e2e 작업 시 시드 시간 0.debug-tokens— UUID/portal token 즉시 발급 (지금은 Server Action 직접 호출 우회)feature-flags—config/appMetadata.features.*트리 UI 토글. 지금은 Firestore 콘솔에서 직접 편집 → emulator/production 헷갈림. ops 에 토글 UI + 변경 audit log
시스템 (System)
audit-log— masterAdmin 행동 추적 (시나리오 실행·feature flag 변경·tenant fixture 시드)env— 환경변수·secret 상태 (값 마스킹 필수,apps/web/.env.example가 SSoT)members—masterAdmins/{email}화이트리스트 관리 (read-only 시작, write 는 차후 ADR)
위험·완화
| 위험 | 완화 |
|---|---|
| 시나리오 routing 마이그레이션이 기존 e2e 깨뜨림 | /scenarios 인덱스 페이지를 v1 처럼 master-detail UX 로 유지하며 subroute 점진 추가. 기존 e2e 그대로 통과 |
| 90 카드 registry 자동화 시 누락 카드 | apps/ops/__tests__/scenario-registry-coverage.test.ts 추가 — fs scan 으로 카드 컴포넌트 ↔ registry 1:1 검증 |
| Cloud Functions 로그 fetch 가 production cost 발생 | ops 에서는 read-only, 페이지당 limit 50, 1분 캐시. fetch 빈도 정량 모니터 |
Cmd+K palette cmdk lib 도입 | bundle 크기 ~5KB, ops 만 영향 (web 미영향). MIT 라이선스 |
| ADR 0028 패턴 위반 우려 | 모든 신설 mutation 은 packages/business-logic/<도메인>/ 추출 후 server action thin wrapper |
Non-goal
- web 앱 코드 수정 (의존 규칙 준수)
- Firestore rules 변경
- masterAdmin 인증 모델 변경 (
masterAdmins/{email}그대로) - 외부 의존성 신규 추가는
cmdk한 개로 제한
구현 순서 (PR 단위)
| PR | 산출물 | 예상 시간 |
|---|---|---|
| 1 | 본 ADR (doc-only) | 0:30 |
| 2 | AppSidebar 5 NavGroups + 신설 페이지 placeholder route + e2e | 1:30 |
| 3 | scenarios registry + meta 파일 batch 생성 (5 도메인) | 1:30 |
| 4 | scenarios/[domain] subroute + 단독 카드 페이지 + 검색·필터·즐겨찾기 | 1:30 |
| 5 | incidents + health 페이지 v1 | 1:30 |
| 6 | Cmd+K palette + tenant-fixture + feature-flags | 2:00 |
| 7 | audit-log + env + members | 1:00 |
| 8 | README/문서 갱신 + 자율 세션 메모 + 회귀 마지막 한바퀴 | 0:30 |
총 약 10시간. 보수 추정 6 PR · 도전 추정 8 PR.
측정 가능한 성공 지표
- ops 사이드바 클릭 수 group 별 분포 측정 가능 (텔레메트리 후속)
- 시나리오 단독 페이지 URL 공유 사용률 (PR 본문 링크 포함률)
- production sweep 빈도 vs 수동 gcloud 시간 (목표: 30초 이하)
- 매 e2e 작업 시드 준비 시간 (목표: tenant-fixture 후 5초 이하)
후속 과제
- 시나리오 텔레메트리 (
opsScenarioRuns/) 통합 — 일부 카드만 진행 중 - 시나리오 chain 시각화 (
journey페이지 v2) - feature-flags 변경 audit log + 자동 emulator/production 동기화
- members 화이트리스트 write UI (별도 ADR — 권한 위계 결정 필요)
- templates 페이지가 docx 미리보기 지원 (별도 ADR — docx-html 변환 결정 필요)
변경 이력
| 버전 | 날짜 | 변경 |
|---|---|---|
| 1.0 | 2026-05-07 | 초안 — ops 운영 콘솔 v2 정보 아키텍처 결정 |