상담원 화면 문구를 「원문 표시 · 저장 시 마스킹」 정책에 맞춘다 — 잠금 아이콘 「민감정보가 마스킹되었습니다」
장민석이 넘긴 일이다(2026-10-06). 서버·콜 미디에이터 쪽은 w8-screen-plain-storage-encrypt(장민석)에서 바꿨고, 프론트는 고치지 않았다(사용자 지시 — 프론트는 조서희 전담). 근거:
_project/decisions/326(비공개).
무엇이 바뀌었나
콜 미디에이터 0.2.14 부터 /ws 의 transcript.text 가 원문이다. masked 구간은 그대로 오고,
MaskedText 가 그 자리 글자를 <mark> 로 그리므로 화면은 「원문 + 개인정보 자리 강조」가 된다(코드 수정 없이 동작).
DB 저장 쪽은 지금처럼 마스킹본이다 — 지난 통화 보기(GET /hub/calls/{id}/transcript)는 여전히 마스킹본을 준다.
정할 것 — 문구가 옛 정책 그대로다
- 자막 잠금 아이콘 title·aria-label 「민감정보가 마스킹되었습니다」(
TranscriptPanel.tsx) — 원문이 보이는데 이 문구가 뜬다 MaskedText.tsx·maskSensitiveText.ts주석 「실서버는 원문을 절대 주지 않는다」.claude/rules/call.md §2- 문구를 바꿀지 그대로 둘지는 프론트 판단이다 — 「저장 시 마스킹됨」처럼 바꿀 수도 있다
2026-10-08 — 정성윤이 넘겨받아 했다
담당을 조서희 → 정성윤으로 옮겼다(CLAUDE.md §4 — 넘겨받았으면 적는다). apps/ 는 조서희 전담이지만
PM 지시로 가져왔다(§0 — 사용자 지시가 우선). 문구를 어떻게 쓸지는 프론트 판단이라 되돌리거나 다시 쓰셔도 된다.
들여다보니 문구만의 문제가 아니었다
실서버에서 실제로 무엇이 그려지는지 코드로 따라가 보니 두 가지가 갈렸다.
| 자리 | 실서버에서 | 판정 |
|---|---|---|
| 자물쇠 아이콘 「민감정보가 마스킹되었습니다」 | 안 뜬다 — piiMatches 는 !isCoreApiConfigured() 일 때만 찬다(mock 전용) |
문구만 고침 |
| 「⚠ 경고」 배지 | 뜬다 — hasAlert = item.masked.length > 0 이라 개인정보 구간이 있으면 무조건 |
실제 문제 |
.masked-span 빨간 강조 |
원문을 감싼다 — ***** 를 덮던 색인데 이제 번호 위에 얹힌다 |
실제 문제 |
뒤의 둘이 시연 영상 검토(2026-10-02) 지적 ③ 「⚠ 경고 배지가 고객의 개인정보 발화에 붙는다」의 정체다. 상담원 위반과 같은 빨간 배지가 고객이 번호를 불렀을 뿐인 줄에 붙고, 빨간 강조가 번호로 눈을 끌었다.
고친 것
- 「⚠ 경고」 → 「저장 시 가림」(
.alert-pill.is-mask, 중립 회색).title「저장·전송할 때 이 부분은 가려집니다」 .masked-span기본색을 중립 회색 + 점선 밑줄로 — 「저장할 때 가려질 자리」라는 뜻만 전한다. ⚠ mock 의.is-pii·.is-abuse는 「이미 가려진 자리」라 그대로 뒀다- 자물쇠
title·aria-label→ 「저장할 때 가려지는 부분입니다」 MaskedText.tsx주석 — 「실서버는 원문을 절대 주지 않는다」가 거짓이 됐다. SEC-1 이 왜 그대로 성립하는지로 다시 썼다maskSensitiveText.ts에 「mock 전용」 한 줄.claude/rules/call.md §2— 옛 문장은 긋고 새 규칙을 적었다(절대 원칙 8)
검증
tsc --noEmit 통과 · npm test 92건 통과(기존 87 + 새 5).
새 테스트 test/plainScreenCopy.test.tsx 는 소스를 직접 읽어 옛 문구가 되살아나는지 본다 —
손으로 적은 목록끼리 맞추면 또 갈라지기 때문이다(ai 쪽에서 09-22 에 실제로 겪었다).
⚠ 운영 화면에서 눈으로 보지는 않았다 — 배포 뒤 확인이 남는다.