---
title: "작업보고 — 어드민 콘솔 v0.1 (애널리틱스 + CS 확장)"
category: "workreport"
document_type: "작업보고"
source_status: "generated"
knowledge_group: "03_history"
priority: "High"
purpose: "마스터 전용 어드민 콘솔 v0.1 구현 기록. 운영 분석(애널리틱스) 프로토타입 → 사장님 지적(어드민=CS 수단, 기능 전무)을 수용해 CS 도구(유저 리스트·플랜 부여/박탈/조정·코칭 회 토큰 보정·컴플레인 보드·인앱 문의·AI 1차 분류)로 확장. service_role admin Worker 경유 구조, chat-proxy/admin-analytics Worker 실배포, support_ticket 마이그레이션. 대화-지적-수용-보완 과정과 MCP 5화면 검증·의사결정 5요소 포함."
read_when: ["어드민콘솔","애널리틱스","CS","유저관리","컴플레인","베타준비","최신상태복구"]
updated: "2026-06-06"
work_timestamp: "20260606_204500"
context: "달록본레포CC (D:\\dallog\\dallog_git) — 어드민 콘솔 v0.1 구현 스레드. PR#39·#40 main 머지."
source_of_truth: "https://dallog-tools.hansbridge.co.kr/knowledge/"
---

# 작업보고 — 어드민 콘솔 v0.1 (애널리틱스 + CS 확장)

> 베타배포 전 **운영자가 베타 데이터를 분석하고 고객을 응대(CS)** 할 수 있어야 한다는 요구에서 출발. 운영 분석 대시보드(애널리틱스)로 시작해, 사장님 지적을 수용해 **CS 도구**까지 한 번에 확장한 v0.1 기록이다.

## 목차
- [0. 문서 정보](#0-문서-정보)
- [용어 병기](#용어-병기-개발어휘--한국어)
- [1. 작업 배경](#1-작업-배경)
- [2. 대화 흐름 — 제안·지적·수용·보완](#2-대화-흐름--제안지적수용보완)
- [3. 구현 범위](#3-구현-범위)
- [4. 수정·신규 파일](#4-수정신규-파일)
- [5. Worker 배포 · SQL 적용](#5-worker-배포--sql-적용)
- [6. MCP 브라우징 검증 (스크린샷)](#6-mcp-브라우징-검증-스크린샷)
- [7. 의사결정 5요소](#7-의사결정-5요소)
- [8. 미해결 · 후속](#8-미해결--후속)

---

## 0. 문서 정보
- 작업일: 2026-06-06
- 브랜치/머지: `feature/admin-analytics-prototype`(PR#39) · `feature/admin-cs`(PR#40) → main
- 핵심 커밋: `a7284a7`(애널리틱스) · `abc9430`(chat-proxy GEMINI_MODEL) · `b932760`(CS 확장)
- 배포: admin-analytics Worker·chat-proxy Worker 실배포 완료(아래 §5)

## 용어 병기 (개발어휘 / 한국어)
| 개발어휘 | 한국어 | 해설 |
|---|---|---|
| service_role | 서비스 롤 키 | 행 단위 접근제한(RLS)을 우회해 전체 사용자 데이터를 다루는 마스터 키. 브라우저에 절대 노출 금지 |
| Worker | 워커(백엔드) | Cloudflare에서 도는 서버 코드. 민감 키를 브라우저 대신 여기서만 사용 |
| RLS | 행 단위 접근제한 | "내 데이터는 나만" DB가 강제하는 보안 규칙 |
| entitlement | 사용권(잔여 회) | 사용자가 AI 코칭을 몇 회 더 쓸 수 있는지 |
| ticket | 문의 티켓 | 사용자가 보낸 컴플레인 1건 |
| 1차 자동분류 | 키워드 분류 스텁 | LLM 대신 키워드로 카테고리·우선순위를 임시 추정(후속 AI 고도화) |

---

## 1. 작업 배경

베타배포(프로젝트 Phase 1) 전에 **운영자가 베타 데이터를 분석**할 도구가 없으면 베타의 목적(측정)이 무산된다는 판단으로 어드민-애널리틱스를 먼저 제안·구현했다. 이어 사장님이 **"어드민의 기능이 거의 전무하다. 어드민은 CS 역할을 하는 수단"** 이라고 지적하며 CS 기능 일습을 요구해, 같은 콘솔에 CS 도구를 확장했다.

> 비개발자용 해설: 어드민(관리자 화면)은 ① 베타 데이터로 의사결정하는 "분석실"이자 ② 고객을 응대하는 "CS 창구"다. 이번에 둘 다 깔았다. 단, 전체 사용자 데이터를 다루는 일은 보안상 별도 백엔드(Worker)가 처리한다.

---

## 2. 대화 흐름 — 제안·지적·수용·보완

| 단계 | 내용 |
|---|---|
| 제안 | 베타 전 어드민-애널리틱스 필수 → 프로토타입 선제 구현(샘플 즉시, Worker 연결 시 실집계) |
| 수용 | 사장님 "애널리틱스는 괜찮다" |
| 지적 | "어드민 기능이 전무. CS 수단인데 유저 리스트업·플랜 조정·토큰 보정·컴플레인 보드(+인앱 문의·AI 자동분류)는 있어야" |
| 구조 결정 | "별도 어드민 레포 불필요 → 단일 레포 + /admin + service_role Worker. 배포만 분할" (사장님 확정) |
| 보완 구현 | 유저 관리·플랜/토큰 조치·컴플레인 보드·인앱 문의·1차 자동분류 일괄 구현 |
| CF 세팅 | 사장님이 Worker 시크릿 등록 → 점검 중 ① admin Worker 실코드 미배포(405) ② chat-proxy GEMINI_MODEL 미인식 발견 |
| 배포 처리 | 터미널 wrangler 인증 확인 → admin-analytics·chat-proxy **실배포 완료**(CC가 직접 수행) |

> 사용자가 보면 되는 결론: "분석만 되고 관리는 안 된다"는 지적을 받아, 같은 화면에서 **유저를 보고·플랜을 바꾸고·토큰을 보정하고·문의를 처리**하는 CS 기능까지 채웠다.

---

## 3. 구현 범위

### 3-1. 애널리틱스(운영 분석)
- KPI(가입자·코치 사용자·총 요청·누적 원가·실패율) + 전환 퍼널 + 원가 추이(7일) + 플랜 분포 + 질문유형 + 가드레일 + 품질·리텐션
- 샘플 즉시 표시 → service_role Worker 연결 시 실집계 자동 전환(출처 뱃지 투명 표기)

### 3-2. CS 도구
| 기능 | 내용 |
|---|---|
| 유저 리스트업 | 전체 가입자(이메일·닉네임·핸들·플랜·잔여·가입일) 리스트·검색 |
| 플랜 부여/박탈/조정 | 드롭다운으로 등급 변경 → 구독·사용권 재설정(service_role) |
| 토큰(코칭 회) 보정 | 특정 이슈(오류·보상)로 회 수 임의 +/- 보정, 사유·감사로그 기록 |
| 컴플레인 보드 | 고객문의 전수 + 상태(신규/진행중/해결/종료) 변경 + AI 1차 분류 표기 + **날짜·시간 정렬·기간 필터**(PR#41) |
| 인앱 문의 | 사용자 `/support`에서 유형+내용 제출, 내 문의 내역, 사이드바 진입점 |
| AI 자동분류 | 제출 시 키워드 1차 분류(카테고리·우선순위·요약). 후속 LLM 분류·자동해결로 고도화 |

---

## 4. 수정·신규 파일

**신규**
- `migrations/2026-06-06_admin_cs.sql` — support_ticket(고객문의) + admin_action_log(감사로그) + RLS
- `src/pages/Admin.tsx` — 마스터 전용 탭 셸(애널리틱스/유저/컴플레인)
- `src/components/admin/{AnalyticsTab,UsersTab,ComplaintsTab}.tsx`
- `src/lib/admin/{analytics,api}.ts` — Worker 클라이언트(샘플 폴백)
- `src/pages/Support.tsx` · `src/lib/support.ts` — 인앱 문의 + 1차 분류
- `workers/admin-analytics/{index.js,wrangler.toml}` — 집계+CS service_role Worker

**수정**
- `src/App.tsx`(라우트 /admin·/support) · `src/components/Layout.tsx`(사이드바 진입점)
- `src/pages/admin.css`(탭·테이블·모달·보드·폼 스타일)
- `workers/chat-proxy/{index.js,wrangler.toml}` — GEMINI_MODEL 인식 + 기본 모델 gemini-2.5-flash

**삭제**: `src/pages/AdminAnalytics.tsx`(Admin.tsx 탭 구조로 대체)

---

## 5. Worker 배포 · SQL 적용

| 항목 | 상태 |
|---|---|
| admin-analytics Worker | ✅ **실배포 완료** (`npx wrangler deploy`). 토큰 없는 GET → 401 = 실코드 확인 |
| chat-proxy Worker | ✅ **재배포 완료**. 기본 모델 `gemini-2.5-flash` 반영(BRIEF 변수는 별도 brief-proxy 워커 소관) |
| service_role 키 | [환경변수 등록됨] — Worker secret, 코드·문서 미기록 |
| support_ticket 마이그레이션 | ⏳ **사용자 적용 대기** — Supabase SQL Editor 에 `migrations/2026-06-06_admin_cs.sql` 적용 필요(적용 전 컴플레인/인앱 문의는 빈 결과) |

> 비개발자용 해설: AI 서버·집계 서버는 켰다(배포 완료). 고객문의를 담을 "표(테이블)" 하나만 사장님이 Supabase에 한 번 만들어주시면(SQL 붙여넣기) 문의 기능이 실제로 돈다.

---

## 6. MCP 브라우징 검증 (스크린샷)

테스트: 로컬 dev(localhost:5173) + 마스터 세션, 데스크탑 1440×900, 콘솔 앱오류 0. 현재 자동화 브라우저는 **로컬 마스터 세션(실 OAuth 아님)** 이라 Worker에 토큰이 안 실려 401→샘플로 폴백한다(설계대로). **실제 운영자가 dallog.kr에서 구글 로그인 시 실데이터로 전환**된다.

| 검증 | 결과 | 화면 |
|---|---|---|
| 애널리틱스 탭(탭 구조·KPI·차트) | PASS | <a href="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-01-analytics-tab.png"><img src="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-01-analytics-tab.png" width="150"></a> |
| 유저 탭(리스트·플랜뱃지·잔여) | PASS | <a href="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-02-users-tab.png"><img src="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-02-users-tab.png" width="150"></a> |
| 유저 관리 모달(플랜/토큰 조치) | PASS | <a href="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-03-user-manage-modal.png"><img src="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-03-user-manage-modal.png" width="150"></a> |
| 컴플레인 보드(필터·AI분류·상태) | PASS | <a href="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-04-complaints-tab.png"><img src="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-04-complaints-tab.png" width="150"></a> |
| 인앱 문의 폼(/support) | PASS | <a href="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-05-support-form.png"><img src="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-05-support-form.png" width="150"></a> |
| 컴플레인 필터(상태·기간·정렬) | PASS | <a href="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-06-complaints-filters.png"><img src="pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-06-complaints-filters.png" width="150"></a> |

### 6-1. 유저 관리
![그림. 유저 관리 모달 — 플랜 등급 드롭다운(부여·박탈·조정)과 코칭 회(토큰) 보정 입력](pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-03-user-manage-modal.png)

### 6-2. 컴플레인 보드
![그림. 컴플레인 보드 — 상태 필터칩, 우선순위·AI 카테고리 뱃지, 상태 변경 버튼](pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-04-complaints-tab.png)

### 6-3. 인앱 문의
![그림. 사용자 인앱 문의 폼(/support) — 유형 선택 + 내용 + 내 문의 내역](pacelog-archive/pages/02-workreport/assets-20260606_204500_admin_cs/cs-05-support-form.png)

---

## 7. 의사결정 5요소

### 결정 A — 어드민 = 단일 레포 + /admin + service_role Worker
- **선택**: 본레포에 마스터 전용 /admin + 집계/CS는 admin Worker(service_role)로 분리 배포.
- **배제**: 별도 어드민 레포(인증·디자인·배포 중복).
- **이유**: 인증·Supabase·디자인 재사용, 프로토타입 속도, 유지보수 단순. 보안 경계는 "키를 Worker에만".
- **사용자 정서**: "별도 레포 불필요. 배포만 분할" 직감과 일치, 즉시 확정.
- **재검토**: 보안 강화 필요 시 admin 프론트를 별도 서브도메인으로 분리(정식 단계).

### 결정 B — CS 쓰기는 service_role Worker 경유(프론트 직접 금지)
- **선택**: 유저 전수 조회·플랜/토큰 변경·문의 상태변경은 모두 Worker가 service_role로 수행.
- **배제**: 프론트에서 직접 RLS 우회(불가·위험) / service_role 프론트 노출(절대 금지).
- **이유**: RLS가 본인 데이터만 허용 → 운영 작업은 검증된 백엔드에서만. 키 노출 0.
- **재검토**: 없음(보안 원칙).

### 결정 C — chat-proxy 기본 모델 gemini-2.5-flash 상향
- **선택**: 기본 모델을 flash-lite → gemini-2.5-flash(사장님 지정 GEMINI_MODEL 반영).
- **배제**: flash-lite 유지(decision_log #2 비용방어 기본값).
- **이유**: 사장님이 GEMINI_MODEL=gemini-2.5-flash 등록 → 의도 반영. 코드가 GEMINI_MODEL도 인식하도록 수정 + wrangler.toml 진본화.
- **재검토**: 원가·품질 측정 후 모델 재조정(애널리틱스 원가 추이로 판단).

### 결정 D — AI 자동분류는 1차 키워드 스텁부터
- **선택**: 제출 시 키워드 기반 카테고리·우선순위·요약 임시 저장(ai_*).
- **배제**: 처음부터 LLM 분류(범위 과다) / 분류 없음(보드 가독성 저하).
- **이유**: 구조(ai_* 컬럼)를 먼저 확정해 보드를 굴리고, 후속에서 chat-proxy 연동으로 동일 구조에 LLM 분류·자동해결을 끼운다.
- **재검토**: 베타 문의량·정확도 보고 LLM 분류 전환.

---

## 8. 미해결 · 후속

- **support_ticket 마이그레이션 적용**(사용자) → 컴플레인/인앱 문의 실동작.
- **실데이터 라이브 검증** — 운영자 구글 로그인(ccy8215@gmail.com, OWNER_EMAILS 등재됨) 상태에서 /admin → 실집계·실유저·실문의 확인.
- **AI 자동분류 고도화** — 키워드 스텁 → LLM 분류·자동해결(chat-proxy 연동).
- **퍼널 중간단계·가드레일·리텐션 계측** — 현재 0/근사, 이벤트 로깅 추가 필요(Phase1 측정).
- **개인정보 확장 수집**(생일·성별 등) — 동의 기반 수집 후 유저 테이블 컬럼 확장(마케팅·이벤트 활용).
- 보완점은 사장님이 화면을 보고 지시 → 반영.
