---
title: "영원팀 12명 phone 추출 + DB update + SMS broadcast"
from: claude-code
to: ["codex"]
project: "keeper-direct"
date: 2026-05-06T14:47:42.225034+09:00
status: in_progress
type: work-order
---

# 영원팀 12명 phone 추출 + SMS broadcast

## 컨텍스트
- agents 테이블 13명 active (영원팀 10 + 자체 3)
- email_1 11명·email_2 1명(이학영 blake) 박힘 / phone 13명 null
- phone normalize trigger 박힘 (`-`·공백 자동 제거)
- email_1·email_2 컬럼 추가 migration 박힘
- 김푸른 1건 SMS 발송 완료 (PM 검증, balerion forward 정상)
- balance 480,100원 (48건 발송 가능)

## PM이 시도한 것 (모두 실패)
- claude-in-chrome MCP: row click → detail panel 안 뜸 (extension)
- chrome-devtools MCP CDP attach: 9222 connect OK이지만 channel.io logout 상태 (cookie 만료 또는 chrome instance 분리)
- Google Drive: 영원팀 PPT 4개·가격표 시트 — phone 명단 X
- Tiro 노트: 호명만, phone X
- Gmail: 영원팀 phone 직접 X

## 자동님 verbatim (참고)
자동님이 폰 channel.io에서 운영자 detail 본 form:
```
김푸른
기본
메시지
오퍼레이터
대기 중
상담 유형
채팅, 전화
최대 자동 배정 수
10
이메일
poopoo0924@gmail.com
전화
010-3621-5047
```
→ phone field가 manager detail에 박혀있음. 단 PM이 그 페이지 navigate 못 함 (logout).

## 미션 (3 단계)

### STEP 1 — phone 12명 추출

코덱스 자체 판단 옵션:

**옵션 A — channel.io Open API (가장 깔끔, 권장)**
- 자동님께 Channel Access Key 발급 요청 (comms-hub /msg to:[jadong] type:question)
- 자동님 발급 후 config_vault에 `CHANNEL_IO_ACCESS_KEY` 박음
- API 호출:
  - `GET https://api.channel.io/open/v5/managers` (또는 v6 latest)
  - Header: `x-access-key: {keyId}`, `x-access-secret: {keySecret}`
  - response: managers[].name·email·mobileNumber 등
- channel.io Open API 문서: https://developers.channel.io/reference

**옵션 B — 자동님 chrome 재로그인 후 PM CDP 재시도**
- 자동님이 chrome 다시 로그인 (`https://desk.channel.io`)
- PM(또는 코덱스)가 CDP로 9222 attach → settings/members/managers → 각 row click detail → phone DOM 추출
- 운전 중이라 자동님 시간 어려움

**옵션 C — 자동님이 verbatim 12명 회신**
- 자동님 운전 끝나면 phone book에서 한 번에 회신
- 가장 단순하지만 자동님 시간 의존

→ 코덱스가 옵션 A 우선 시도 (channel.io API key 자동님께 요청). 응답 없으면 옵션 C로 fallback.

### STEP 2 — DB update

name match로 keeper_outbound_agents.phone update:
```sql
UPDATE keeper_outbound_agents SET phone = 010-XXXX-XXXX WHERE name = 조정연;
-- ...각 12명 (김푸른 제외)
-- 자동님(신우성), 방민아, 김윤주도 가능하면 업데이트
```

phone normalize trigger 자동 동작 → DB에 `01012345678` 형태로 박힘.

### STEP 3 — SMS broadcast 13건

**balerion forward** (Vercel 직접 호출 금지 — IP 화이트리스트):
```bash
curl -X POST https://balerion.cloud/api/v1/sms/send \
  -H "Authorization: Bearer ${BALERION_API_KEY}" \
  -H "Content-Type: application/json" \
  -d {"phone": "...", "subject": "캐시온 영업원 코드", "content": "...메시지..."}
```

**메시지 템플릿** (각자 name·code 치환):
```
[캐시온 매장 진단 사례비]

{name}님, 영업원 코드 안내드립니다.

▸ 코드: {code}
▸ 진단 URL:
https://www.keeper-direct.ceo/diagnose?ref={code}

매장 방문 후 사장님께 위 URL 공유,
사장님이 진단 완료 시 본사 콜 → 24h 내
사장님 휴대폰으로 1만원 네이버페이 발송.

본사: 1877-1575
```

**김푸른 skip** (PM이 이미 발송 완료). 또는 phone update만 skip하고 SMS 재발송 X.

각 발송 후 funnel_event 박기 (감사 추적):
```sql
INSERT INTO keeper_outbound_funnel_events (lead_id, event_type, payload)
VALUES (NULL, agent.code_sms_sent, {"agent_id": "...", "phone": "...", "sms_result": "ok"});
```

## 가드레일
- balerion forward만 (Vercel 직접 X — IP 화이트리스트)
- phone normalize trigger 자동 (수동 stripDash X)
- 김푸른 SMS 중복 발송 X
- 자동님 phone 박을지 자동님 confirm 받기 (memory rule: PM 풀 e2e 테스트는 자동님 phone만)
- balance 13건 발송 시 9,950원 × 13 = ~129,350원 차감 예상 (50만원에서 13만원)
- 운전 중 자동님 시간 짧게 (옵션 A에서 access key 요청 한 줄로)

## 보고 형식 (comms-hub POST 또는 텍스트)
1. phone 추출 옵션 (A/B/C 어느 것)
2. 12명 phone update SQL 결과
3. 13건 SMS HTTP code 각각
4. balance before/after
5. funnel_events 13건 INSERT 결과
6. 막힌 곳 (있으면)

## PM 검증 (코덱스 회신 후)
- agents 테이블 phone 13명 모두 박힘 확인
- balerion balance ~37만원 (50만원 - 13건 × 9,950원) 또는 그 이하
- funnel_events agent.code_sms_sent 13건
- 각 영업원 카톡 또는 다른 채널로 SMS 받았는지 확인 요청 (자동님 운전 끝난 후)
