PRD: 공개 명함 공유와 NFC 진입

  • 상태: Implemented (2026-07-22 as-built 기준 소급 작성 — 이 문서가 기능 노드의 표본)
  • 작성자: / 리뷰어:
  • 관련 문서: frontmatter related: 참조

1. 배경과 문제 정의

물리 NFC 카드를 태그하거나 링크를 공유받은 사람이 명함을 보는 것이 서비스의 핵심 루프다. 그런데 ① 카카오톡·슬랙에 링크를 붙이면 미리보기(OG)가 안 떴고, ② 비공개·삭제된 명함의 개인정보가 공유 경로에 남을 위험이 있었고, ③ NFC 유입과 공유 유입을 분석에서 구분할 수 없었다.

2. 목표

  • 공개 명함 링크를 어디에 붙여도 이름·직함·회사가 담긴 미리보기가 뜬다.
  • 비공개·삭제·탈퇴 명함의 개인정보는 공유 응답·HTML·로그·캐시 어디에도 남지 않는다.
  • NFC 유입(source=nfc)과 공유 유입(source=share)이 분석에서 분리된다.

3. 비목표

  • 검색 엔진 공개(noindex 유지), 프로필 사진의 OG 노출, 외부 플랫폼이 이미 캐시한 미리보기의 강제 회수.

4. 직무별 관점

직무핵심 관심사·제약관련 문서
기획(기입 — 예: 공유가 신규 가입 루프의 시작이라는 가설)
디자인(기입 — 예: 비공개 화면의 익명 플레이스홀더)
FE크롤러와 브라우저가 같은 HTML을 받되 React는 브라우저에서만 실행. /assets/app.js·app.css 고정 엔트리가 배포 계약배포 계약
BE데이터 최소화 — OG 층에는 전화번호·이메일이 코드 경로에 아예 없게. 세 층 분리as-built, 세 층 구조

5. 시스템 흐름과 API 연결

라우팅·에러 분기까지 포함한 상세판: 시스템 전체 흐름

flowchart TD
  NFC["NFC 태그"] --> RESOLVE["GET /v1/public/nfc-tags/{token}"]
  RESOLVE -->|CONNECTED| CARD["GET /card/{slug}?source=nfc"]
  RESOLVE -->|CLAIMABLE·NEEDS_CONNECT| CONNECT["POST /v1/me/nfc-cards/connect"]
  CONNECT -->|성공| CARD
  SHARE_IN["공유 링크 /card/{slug}?source=share&v=n"] --> CARD

  CARD -->|같은 프로세스| PROJ["share-preview projection<br/>이름·직함·회사만"]
  CARD -->|크롤러| OG["OG 태그 → 미리보기"]
  CARD -->|브라우저| REACT["React 실행"]
  REACT --> FULL["GET /v1/public/business-cards/{slug}"]
  REACT --> EVENTS["POST /v1/analytics/events"]
  OG --> IMG["GET .../og-image?v=n<br/>PUBLIC 재확인 후 PNG"]
API역할맥락 문서
GET /v1/public/nfc-tags/{token}4상태 판정, visitId 멱등nfc-card
POST /v1/me/nfc-cards/connect선점+연결 원자 수행nfc-card
GET /card/{slug}상태별 OG HTMLpublic-card
GET /v1/public/business-cards/{slug}React 전체 데이터 + viewerpublic-card
GET /v1/public/business-cards/{slug}/og-imagePUBLIC 재확인 후 PNGpublic-card
POST /v1/analytics/events유입·행동 수집 (schema v2)analytics

6. 열린 질문

  • sharePreviewRevision 분리 (지금은 명함 version 재사용 — 무관한 수정에도 공유 URL의 v가 바뀜). as-built 제한 #4.
  • 명함별 공유 이미지의 다중 인스턴스 캐시(현 Caffeine 로컬).

7. 변경 이력

날짜변경 내용변경자
2026-07-24as-built 기준 소급 작성AI