🛡️ [코드변경사항 2026-08-18] 경영민감정보 클라이언트 사이드 가명화(Pseudonymization) 및 로컬 역매핑 적용
1. 개요 (Overview)
개정 목적 : 이력서 및 경력기술서 내 기업명, 연간 매출/실적 수치, 내부 시스템명 등 전/현 소속 기업의 경영민감정보(Business-Sensitive Info)가 외부 AI(Gemini API)로 전달될 때 발생하는 데이터 유출 리스크를 원천 차단.
적용 방식 :
[클라이언트 사이드] 가명화 처리 : 이력서 원문에서 기업명 → [회사A], 내부 시스템명 → [시스템A], 매출/수치 → [수치A] 식별 불가 토큰으로 변환.
[AI 전송] : 가명화된 텍스트만 Google Gemini API로 전송.
[AI 수신 & 역매핑] : AI 갭 분석 결과를 수신 후, 오직 사용자 로컬 브라우저에만 보관된 매핑 테이블을 참조하여 원문으로 역매핑 복원 및 화면 출력.
[디버그 코드 로그] : 개발자 도구(F12 / Console) 및 내부 파이프라인 상에 가명화, AI 전송, 역매핑 복원 과정 콘솔 로그 출력.
2. 주요 구현 코드 파일 (Implemented Source Files)
2.1. src/utils/pseudonymization.ts (신규 유틸리티)
주요 기능 :
pseudonymizeText(rawText): 정규표현식 기반으로 기업명, 시스템명, 수치/실적을 자동 탐지하여 가명 토큰 생성 및 매핑 테이블 수집.
depseudonymizeText(pseudonymizedText, mappingTable): 가명 토큰을 로컬 매핑 테이블의 원문으로 1:1 치환 복원.
depseudonymizeObject(obj, mappingTable): AI 응답 객체/배열 전체를 순회하며 가명 문자열을 일괄 복원.
콘솔 디버그 로그 : %c🛡️ [CareerFit Pseudonymization] 콘솔 그룹을 통해 원문, 가명화 전송 텍스트, 로컬 매핑 테이블 시각화 출력.
2.2. src/utils/gemini.ts (AI 매칭 파이프라인 연동)
localAnalyzeMatch(job, userResume):
AI 분석 요청 전 pseudonymizeText를 실행하여 가명화된 본문만 프롬프트에 담아 전송.
Gemini API 응답 수신 즉시 depseudonymizeObject를 호출하여 원문 역매핑 수행 후 리포트 반환.
2.3. src/components/AIMatchReport.tsx (보안 UI & 뱃지 적용)
프로필 헤더 보안 뱃지 영역에 🛡️ 클라이언트 가명화 (Pseudonymization) 뱃지 추가.
상단에 경영민감정보 원천 차단 안심 정보 안내 카드(Zero-Server Leak) 노출.
3. 검증 결과 및 실행 로그 (Execution Log & Verification)
3.1. 테스트 스크립트 실행 로그 (scratch/test-pseudonymization.cjs)
----------------------------------------
원문: A기업 ERP 고도화 프로젝트에서 연간 매출 120억 달성에 기여
가명화 텍스트: [회사A] [시스템A] 고도화 프로젝트에서 연간 매출 [수치A] 달성에 기여
매핑 테이블: { '[회사A]': 'A기업', '[시스템A]': 'ERP', '[수치A]': '120억' }
원문 복원: A기업 ERP 고도화 프로젝트에서 연간 매출 120억 달성에 기여
검증 결과: ✅ 성공 (Pass)
----------------------------------------
3.2. 브라우저 콘솔 로그 예시
🛡️ [CareerFit Pseudonymization] 클라이언트 사이드 가명화 처리
[원문 텍스트] A기업 ERP 고도화 프로젝트에서 연간 매출 120억 달성에 기여
[가명화 후 AI 전송 텍스트] [회사A] [시스템A] 고도화 프로젝트에서 연간 매출 [수치A] 달성에 기여
[로컬 매핑 테이블 (서버 미전송)] { "[회사A]": "A기업", "[시스템A]": "ERP", "[수치A]": "120억" }
🔄 [De-pseudonymization] 수신 결과 원문 복원 완료
[Gemini AI 수신 결과] { summary: "[회사A]의 [시스템A] 프로젝트 성과..." }
[역매핑 원문 복원 결과] { summary: "A기업의 ERP 프로젝트 성과..." }