pharmacy-pos-qr-system/docs/user-identity-merge.md
thug0bin 2625430ca5 fix: 마이페이지 카카오 로그인 시 계정 머지(연동) 누락 수정
- _handle_mypage_kakao_callback()에서 link_kakao_identity() 호출 추가
- 키오스크(번호) → 알림톡 → 카카오 로그인 시 자동 머지
- "고객" 이름 → 카카오 실명으로 자동 업데이트
- 케이스별 시나리오 문서 추가 (docs/user-identity-merge.md)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 17:25:46 +09:00

5.5 KiB

사용자 계정 연동(머지) 시나리오

개요

청춘약국 마일리지 시스템은 두 가지 경로로 사용자가 생성됩니다:

  1. 전화번호 경로 — 키오스크에서 번호 입력, 회원가입 폼
  2. 카카오 경로 — QR 스캔 후 카카오 로그인

한 고객이 두 경로를 모두 사용할 수 있으므로, 전화번호 기반 유저에 카카오 계정을 연동(머지) 하는 로직이 필요합니다.


데이터 구조

users 테이블
├── id (PK)
├── nickname    ← 키오스크 신규: "고객" / 카카오 연동 후: 실명
├── phone       ← 전화번호 (유니크 키)
├── mileage_balance
└── ...

customer_identities 테이블
├── user_id (FK → users.id)
├── provider = 'kakao'
└── provider_user_id = 카카오 ID

핵심 원칙: phone이 유저의 기본 식별자. 카카오는 부가 연동.


시나리오별 동작

시나리오 1: 키오스크만 사용하는 고객 (가장 흔함)

1회차: 키오스크 → 010-1234-5678 입력
  → get_or_create_user("01012345678", "고객")
  → users: {id: 100, nickname: "고객", phone: "01012345678", balance: 0}
  → 500P 적립 → balance: 500

2회차: 키오스크 → 같은 번호
  → get_or_create_user → 기존 user_id=100 반환
  → 300P 적립 → balance: 800

5회차까지: 전부 user_id=100에 누적

결과: 한 유저에 전부 쌓임. 문제없음.


시나리오 2: 키오스크 N회 → 알림톡 → 카카오 연동 (핵심 플로우)

[키오스크 5회 적립] → user_id=100, balance=2,000P, nickname="고객"

[알림톡 수신] → "적립 내역 확인" 버튼 탭
  → https://mile.0bin.in/my-page?phone=01012345678
  → 마이페이지 표시 (잔액 2,000P, 거래 5건)

[카카오 로그인 버튼 클릭]
  → _handle_mypage_kakao_callback() 실행
  → find_user_by_kakao_id(kakao_id) → 없음
  → 카카오에서 전화번호 "01012345678" 수신
  → phone으로 users 조회 → user_id=100 발견
  → link_kakao_identity(100, kakao_id, ...) ← 여기서 머지!
  → nickname "고객" → 카카오 실명 "김철수"로 업데이트
  → /my-page?phone=01012345678 리다이렉트

결과:

  • user_id=100에 카카오 계정 연결됨
  • 기존 5건의 적립 내역 그대로 유지
  • 이름 "고객" → "김철수"로 업데이트
  • 다음부터 QR 스캔으로도 같은 계정으로 적립

시나리오 3: QR 스캔(카카오) 먼저 → 키오스크 사용

[QR 스캔 + 카카오 로그인]
  → 카카오에서 phone "01012345678" + kakao_id 수신
  → get_or_create_user("01012345678", "김철수")
  → user_id=100 생성 (phone + kakao 동시에 연결)
  → 500P 적립

[이후 키오스크 사용] → 010-1234-5678 입력
  → get_or_create_user → 같은 phone → user_id=100 반환
  → 300P 적립 → balance: 800

결과: 처음부터 phone + kakao가 연결되어 있으므로 머지 불필요.


시나리오 4: 이미 카카오 연동된 유저가 다시 카카오 로그인

[카카오 로그인 (마이페이지)]
  → find_user_by_kakao_id(kakao_id) → user_id=100 발견
  → 이미 연결됨 → 마이페이지로 리다이렉트

결과: 중복 연동 방지. link_kakao_identity()도 내부적으로 중복 INSERT 방지.


시나리오 5: 카카오에 전화번호가 없는 경우

[카카오 로그인 (마이페이지)]
  → find_user_by_kakao_id → 없음
  → kakao_phone = None (카카오 설정에서 전화번호 미등록)
  → 에러: "카카오 계정에 전화번호 정보가 없습니다"

결과: 연동 불가. 카카오 설정에서 전화번호 등록 안내.


시나리오 6: 알림톡에서 바로 my-page 접근 (카카오 로그인 없이)

[알림톡 수신] → "적립 내역 확인" 버튼
  → https://mile.0bin.in/my-page?phone=01012345678
  → 전화번호로 직접 조회 → 마이페이지 표시
  → 카카오 연동 없이 내역만 확인

결과: 열람만 가능. 카카오 연동은 카카오 로그인 버튼을 눌러야 진행.


연동 시점 정리

진입 경로 link_kakao_identity 호출 비고
QR 스캔 → 카카오 로그인 → 적립 O claim 플로우에서 자동 연동
키오스크 → 번호 입력 → 적립 X 전화번호만 있음
마이페이지 → 카카오 로그인 O (신규!) _handle_mypage_kakao_callback에서 머지
알림톡 → 마이페이지 (번호 직접) X 카카오 로그인 안 함

이름 업데이트 규칙

현재 이름 카카오 이름 결과
"고객" "김철수" → "김철수" (업데이트)
"고객" "고객" or 없음 → "고객" (유지)
"김철수" (기존 실명) "김영희" → "김철수" (기존 유지, 덮어쓰지 않음)

원칙: "고객"(키오스크 기본값)인 경우에만 카카오 실명으로 업데이트. 이미 실명이 있으면 유지.


관련 코드

함수 파일:라인 역할
get_or_create_user() app.py:372 전화번호로 유저 조회/생성
link_kakao_identity() app.py:485 카카오 계정을 유저에 연결
find_user_by_kakao_id() app.py:519 카카오 ID로 유저 조회
_handle_mypage_kakao_callback() app.py:793 마이페이지 카카오 콜백 (머지 포함)
api_kiosk_claim() app.py:1986 키오스크 적립 + 알림톡 발송