---
title: "작업보고 — 코치노트 AI RC2 spec05 플랜·구독·사용량(코칭 회) 차감 구조"
category: "workreport"
document_type: "작업보고"
source_status: "generated"
knowledge_group: "03_history"
priority: "High"
purpose: "코치노트 AI RC2 5/6(spec_rc2_05_plan_billing + 05a_plan_admin) 구현 기록. 차감 단위를 방→턴(회) 비율로 번복(decision_log #16)한 플랜행정 구조 — 플랜표·구독·entitlement·방카운터·차감 RPC + TS helper. SQL 적용·검증 완료. 화면 wiring은 spec06. 다음 작업자가 사용량·차감 구조와 spec06 연결 지점을 이어받기 위한 기록."
read_when: ["코치노트AI","플랜·과금·사용량","최신상태복구","후속작업·우선순위"]
updated: "2026-06-06"
work_timestamp: "20260606_181206"
context: "달록본레포CC (D:\\dallog\\dallog_git)"
source_of_truth: "https://dallog-tools.hansbridge.co.kr/knowledge/"
---

# 작업보고 — 코치노트 AI RC2 spec05 (플랜·구독·사용량 차감 구조)

> **AI 코칭권/회 차감 구조 · 플랜(구독/이용 등급) · OWNER/BETA/VIP 등급 · 결제 Phase 분리** 구현 기록(6개 중 5/6).
> 핵심: 차감 단위를 방(대화방)에서 **턴(=회) 비율**로 번복(decision_log #16). "사용자는 토큰이 아니라 AI 코칭 경험(회)을 산다."

## 목차
- [0. 요약](#0-요약) · [1. 작업 배경](#1-작업-배경) · [2. 적용 기준](#2-적용-기준) · [3. 구현 범위](#3-구현-범위)
- [4. 수정·생성 파일](#4-수정생성-파일) · [5. SQL 적용·결과](#5-sql-적용결과) · [6. 빌드·검증](#6-빌드검증)
- [7. 명세 대비 완료 여부](#7-명세-대비-완료-여부) · [8. 미구현·보류](#8-미구현보류) · [9. 발견 이슈](#9-발견-이슈)
- [10. 후속 작업](#10-후속-작업) · [11. 의사결정·사용자 의도](#11-의사결정사용자-의도) · [12. 최종 판단](#12-최종-판단) · [부록. 용어 병기](#부록-용어-병기)

---

## 0. 요약

코치노트 AI의 **플랜·과금 행정(AI Credit Governance)** 구조를 구현했다. 차감 단위를 턴(회) 비율로 바꾸고(방 단위 폐기), 플랜 정책표·구독·잔여 회 장부·방 카운터·원자적 차감 RPC + TS helper를 만들었다. SQL은 사장님 수동 적용·검증 완료(PASS). 실제 화면 표시·차감 호출 연결(wiring)은 spec06으로 이관(착수 전 컨펌).

## 1. 작업 배경

달록은 메인사업(팩토핀)이 아닌 서브파이프라인이라 수익화 전 비용 누수에 민감하다("돈 한 푼 벌기 전에 비용이 터진다"). 동시에 사용량을 숨기고 소진 후 결제 유도하는 방식이 아니라 **실시간 잔여량을 보여주는 친절한 제공자 정책**을 원했다(decision_log #7). 차감 모델은 직전 라운드에서 "방 단위 → 턴 비율"로 번복됐다(#16) — 단발 질문 한 번에 무료 체험이 통째 증발하는 체감 불공정("당했다")을 없애 유료 전환 퍼널을 보호하려는 의도.

## 2. 적용 기준

| 구분 | 내용 |
|---|---|
| 명세 | spec_rc2_05(원본) + spec_rc2_05a §A 정정문(A-1~A-8) **대체 적용**, §A 밖은 원문 유지 |
| 결정로그 | #16(차감 방→턴 번복) / #4(연장 결제 Phase 분리) / #3(플랜·가격) |
| 사용자 지침(착수 전 컨펌) | 분리 2테이블(구독/entitlement) · helper만 준비(chatApi 연결은 spec06) |
| 비용 산정 | spec05a §2.1 단일 기준(10턴 10.6원/20턴 30.3원/30턴 59.1원/3단계 월최대 2,660원). GPT 토큰 시뮬값 혼용 금지 |
| 금지 | 결제 PG 실연동·결제창 UI·spec06 선구현·storageGate 임의 활성화·spec01~04 재설계·BETA/VIP 제공량 임의 확정·SQL 자동적용 |

## 3. 구현 범위

차감 모델 확정: 1턴(질문+답변 1쌍)=1회, 정상 1회 차감, **응답 실패 무차감**, 연장 할증 회(1단계 2회·2/3단계 3회, 결제 Phase 전용·방당 2회), 잔여량 정수 "회"로만 관리·표시, 토큰 기준 사용자 차감 없음(이중장부).

| 구분 | 구현 내용 | 객체 | 상태 |
|---|---|---|---|
| 플랜 정책표 | 가격·코칭권·월제공회·턴캡·턴당차감 단일 출처(7행 시드) | coach_plan_catalog | 완료 |
| 결제/연장 설정 | 결제 Phase(beta/billing)·할증률·연장 한도 설정값 | coach_billing_setting | 완료 |
| 구독(자격) | 플랜·주기·해지·예약 다운그레이드 | coach_subscription | 완료 |
| 사용량 장부 | 이번 주기 부여/사용/잔여 회(=granted−used) | coach_entitlement | 완료 |
| 방별 카운터 | 방 턴 게이지·연장 방당한도(storageGate 독립) | coach_thread_usage | 완료 |
| plan_type 확장 | CHECK 4종 → owner/beta/vip 포함 7종(ALTER) | request_log·conversation | 완료 |
| 턴 차감기 | 정상 1회/연장 할증/owner 무차감 계측, 원자적 | coach_consume_turn | 완료 |
| 구독·사용량 RPC | ensure·reset_cycle·get_entitlement·change_plan·cancel·usage_summary | DB RPC 6 | 완료 |
| TS helper | 조회·차감·환산·Phase 판정·OWNER 분석 | coachChat/ 5파일 | 완료 |
| chatApi 차감 연결 | (의도적 제외) | — | 이관(spec06) |

## 4. 수정·생성 파일

| 파일 | 변경 |
|---|---|
| migrations/2026-06-07_coachchat_plan_billing.sql (+_GUIDE.html) | 신규 — 테이블5·ALTER·RPC7, 이중발행 가이드 |
| src/lib/coachChat/types.ts | 수정 — PlanType owner/beta/vip + Plan·Subscription·Entitlement·ConsumeTurnResult·BillingSetting(추가만) |
| src/lib/coachChat/{planCatalog,billingPhase,subscription,entitlement,usageReport}.ts | 신규 — helper 5 |
| docs/go_work/{handoff_spec05_to_spec06, kb_patch_prep_spec05, worklog_spec05_plan_billing}.md | 신규 — 인계·KB패치·작업보고(본레포 산출물) |

## 5. SQL 적용·결과

SQL **있음** (`migrations/2026-06-07_coachchat_plan_billing.sql`). **사장님 수동 적용 완료(2026-06-06), 1회성 검증 결과 공유.**

| 검증 항목 | 결과 | 근거 |
|---|---|---|
| 플랜표 7행 시드 | **PASS** | free/tier1~3 수치 정확, owner/beta/vip 제공량·가격 NULL(미확정), beta/vip is_measurement_excluded=true |
| plan_type CHECK 7종 확장 | **PASS** | log·conv 제약 모두 free/tier1/tier2/tier3/owner/beta/vip |
| owner 등급 부여(service_role) | **PASS** | 사용자 `ab1970be-…` owner INSERT Success |
| coach_get_entitlement() SQL Editor | **PASS(의도된 빈 결과)** | SQL Editor는 auth.uid()=NULL → "No rows returned"가 정상. 앱/가장(假裝) 세션에서 행 반환 |

> SQL Editor에서 사용자 기준 RPC가 빈 결과를 내는 것은 버그가 아니라 미로그인 가드(설계). 실제 동작은 인증 세션 또는 `set_config('request.jwt.claims',…)+SET LOCAL ROLE authenticated` 가장 스니펫으로 확인.

## 6. 빌드·검증

- **`npm run build`(tsc+vite): PASS** (타입 오류 0, 청크 경고는 기존 무관).
- **차감 로직 시뮬레이션 28/28 PASS**(RPC 계산식 1:1 미러, 로컬 Supabase 미연결 대체): 시드 정합성, 무료30/1단계600/2단계900/3단계1350 소진, 응답 실패 무차감, 연장 할증 2/3회, 베타 연장 비활성·무료 연장 거부, 연장 방당한도 20턴, 업그레이드 차액 700, OWNER 무제한+계측, BETA/VIP 분리, 주기 리셋 분기. 검증 후 임시 스크립트 삭제.
- **MCP 브라우징/화면 검증: N/A** — UI는 spec06 단계(이번은 helper·구조까지).

## 7. 명세 대비 완료 여부

| 명세 요구 | 여부 | 근거 |
|---|---|---|
| 제공량·가격·턴캡(05a §2.1) | PASS | plan_catalog 시드(검증 PASS) |
| 턴 비율 차감·응답 실패 무차감(§A-2/#16) | PASS | consume_turn |
| 잔여 "회" 정수·코칭권=구매묶음(§3·§5) | PASS | granted−used / formatRemaining |
| 턴캡 경고(강제차단 아님)(§A-3) | PASS(데이터) | turn_cap 제공, 모달은 spec06 |
| 연장 할증 0.1코칭권/턴·설정값(§A-4) | PASS | billing_setting + RPC 환산 |
| 연장 방당 2회·무료 불가·베타 비활성 | PASS | 설정값 + is_purchasable 가드 |
| 소진 잔여<1(§A-5) | PASS | is_exhausted |
| 업그레이드 즉시 차액(§A-6)·다운/해지(§2.6) | PASS | change_plan·cancel·reset |
| 월 리셋(§2.2) | PASS | reset_cycle_if_due |
| OWNER 무제한+계측+기간별(§7) | PASS | owner 시드 + usage_summary |
| BETA/VIP 구조만·미확정(§8) | PASS | plan_type + NULL 보류 |
| 가격 2버전·웹유도 히든(§1.2) | PARTIAL | web/store_price 컬럼 준비, 쇼핑 UI는 spec06 |
| Phase 분기(§3·§4) | PASS | billing_phase 설정값 |
| spec06 표시용 데이터(§14) | PASS | get_entitlement·usage_summary·planCatalog |
| 결제 PG 실연동 / 프론트 UX | N/A | 수익화 Phase / spec06 |

## 8. 미구현·보류

| 항목 | 상태 | 이유 |
|---|---|---|
| chatApi 차감 wiring·쇼핑 페이지·웹결제 히든 컨테이너 | 이관 | spec06(사장님 컨펌) |
| BETA/VIP 제공량·기간 | 미확정 | 재시뮬레이션 전 임의 확정 금지(이월 컨펌 ⓐⓑ) |
| store_price_krw | NULL | 스토어 정책 검토 후 |
| 결제 PG 실연동 | 설계상 미구현 | 베타엔 결제 없음=설계 의도(수익화 Phase) |

> 작업자 편의 축소 항목 없음. 위는 모두 명세가 명시적으로 후속/범위 외로 둔 것.

## 9. 발견 이슈

- **[해결] 무료 사용자 연장 거부 누락(DB 가드 버그).** 초기 consume_turn 연장 가드가 "월제공/코칭권 NULL일 때만" 거부 → 값 있는 무료가 연장 통과(명세 §A-4 위배). "구매 가능 유료(is_purchasable) 또는 무제한(owner)만 허용"으로 수정, SQL·GUIDE·시뮬 반영, 재검증 28/28 PASS. **검증이 실제로 버그를 잡은 사례.**

## 10. 후속 작업

1. **spec_rc2_06_frontend_ux** — 사용량 노출("AI 코칭 N회 남음")·캡 모달·소진 UX·플랜 쇼핑·OWNER 패널 + **consume_turn 호출 wiring(응답 성공 직후)**. 연결 지점 = handoff_spec05_to_spec06 §7.
2. **결제 Phase 전환** — billing_setting.billing_phase=billing으로 변경(설정값) → 연장 할증·결제 활성.
3. **BETA/VIP 확정** — 재시뮬레이션(05a §8 전제) 후 catalog 값 주입.
4. **KB 업로드** — dallogkb_summary 패치(kb_patch_prep_spec05): "가격·플랜"·"사용량·소진 UX" 단락을 턴 비율/회 단위로 교체(RC2 전체 완료 후 일괄).

## 11. 의사결정·사용자 의도

**결정 #16 차감 단위 방→턴 비율 (5요소)**
- 선택된 안: 턴 비율 차감(1턴=1/턴캡 코칭권, 정수 회 관리). 연장 할증 0.1코칭권/턴(설정값).
- 배제된 안: 방 단위 차감(첫 메시지 시 1방), 토큰 기준 사용자 차감(이중장부 위배), 연장 5턴=1코칭권(4~6배 과도).
- 선택 이유: 방 단위는 실사용량과 괴리·역진성. 턴 비율은 한계원가 비례로 공정·예측가능. 턴캡이 방당 상한을 고정해 차감 단위를 바꿔도 방당 최대 원가 불변(운영 리스크 0, UX만 개선).
- 사용자 의견·정서: "체감 단위와 실제 비용이 따로 노는" 구조를 불편해함. 사용량 표시는 친절·직관적이어야 한다는 #7 기조 연장. 운영 리스크는 턴캡이 막아주니 UX를 사용자 친화로 가져가도 손해 없음에 안심.
- 재검토 조건: 베타 실측에서 턴당 실제 원가가 캡 가정과 크게 어긋나거나 할증률이 손해/반발 유발 시. 할증률·턴캡은 설정값이라 코드 변경 없이 조정.

**보존할 사용자 의도(축소 금지)**
- 친절한 제공자 정책 — 사용량을 구석에 작게 숨기면 의도 위반(spec06 주의).
- 손실방어 1번 원칙 — 출혈 도박 금지. 무료 평생 1회성, BETA/VIP 호의도 시뮬레이션으로 결정.
- 빼앗기 프레임 회피 — 캡/소진/할증 문구는 자연스러운 종료 프레임("이 코칭이 마무리됐다 / 새 대화로 잇겠다").
- 설정값화 = 락인 아닌 기본값 선택, 베타 실측 후 조정.

## 12. 최종 판단

- spec05 작업 단위는 **완료**(구현·빌드·시뮬·SQL 적용·문서). 단 helper→화면 wiring은 spec06.
- Phase0 채팅 가동의 토대. 사용량 표시·차감 호출 완결은 spec06에서.
- 사용자 확인 필요(이월): BETA/VIP 제공량·스토어가·웹결제 노출 시점.

## 부록. 용어 병기

Plan(구독/이용 등급) · Entitlement(사용권·이번 주기 부여 권한) · Usage·coaching turn(사용량·코칭 1회=질문+답변 1쌍) · credit(코칭권=쇼핑 구매 묶음) · turn cap(방당 턴 상한) · extension surcharge(연장 할증) · billing phase(결제 단계 beta/billing) · thread(대화방·세션) · storageGate(저장 활성화 게이트) · RLS(행 수준 보안=본인만) · RPC(DB 서버 측 계산 함수) · price_version(단가 버전).
