호패
경력근거: Design and develop mobile products using React Native and TypeScript
※ 실제 산출물이 아닌 AI 예측 시안입니다.
호패의 이 포지션은 React Native·TypeScript 로 hConnect 모바일 제품을 end-to-end 로 소유하며, 다양한 국가·사용자 환경·인증 플로우에서 글로벌 신원확인 경험을 설계하는 프로덕트 엔지니어입니다. 국가·문서별 절차를 상태 머신으로 묶어 검증 결과에 따라 다음 단계를 정하는 이 데모는 그 핵심 역량(다국가 인증 플로우의 RN 구현·상태 관리·재시도 UX)을 정면으로 보여줍니다. 생체인증·문서 판독 알고리즘은 외부 검증 API 가 한다고 가정해 도메인 전문성을 과장하지 않고, 검증 결과를 받아 플로우를 운전하는 프로덕트 엔지니어링에 집중합니다. 결과를 다음 단계·재시도·안내로 잇는 사슬은 화면마다 흩뿌린 분기로는 그대로 만들 수 없습니다.
React Native·TypeScript 로 hConnect 모바일 제품을 문제 정의부터 운영까지 end-to-end 로 소유합니다. 인증 플로우 데모가 직접 정렬됩니다.
다양한 국가·사용자 환경·인증 플로우에서 글로벌 신원확인 모바일 경험을 설계합니다. 상태 머신 플로우가 환경과 정렬됩니다.
Claude Code·Codex 같은 AI 도구를 개발 워크플로우의 핵심으로 씁니다. 플로우 카피 생성이 비즈니스와 정렬됩니다.
신원확인 세션 이벤트(세션·국가·문서 유형·현재 단계·검증 API 결과·재시도 수)를 받아, 국가·문서별 절차를 정의한 상태 머신으로 다음 단계·재시도·종료를 결정합니다. 결정은 상태 머신 규칙이 정하고, LLM 은 사용자에게 보일 안내 문구(현지화 카피)만 생성합니다. 생체인증·문서 판독은 외부 검증 API 가 한다고 가정하며, 이 도구는 그 결과를 받아 모바일 플로우를 운전하는 프로덕트 엔지니어링을 보여줍니다.
호패 모바일 프로덕트 엔지니어입니다. 국가·문서마다 다른 검증 분기를 화면마다 흩뿌려 새 국가가 들어올 때마다 깨지던 일을, 한 상태 머신에서 다음 단계와 재시도를 정해 안정적으로 운전하고 싶은 사람입니다.
국가·문서별 절차를 하나의 상태 머신으로 묶고 국가·문서 마스터를 붙이면, (a) 검증 결과(통과·추가요청·실패)에 따른 다음 단계를 규칙으로 결정하고, (b) 안내 문구를 LLM 이 현지화해 생성하며, (c) 새 국가·문서가 들어와도 플로우가 끊기지 않습니다.
세션 이벤트를 받아 국가·문서별 상태 머신으로 다음 단계·재시도를 결정하고 React Native 화면으로 보여주는 동작하는 플로우입니다. 검증 결과는 외부 API 를 가정한 더미로 시작합니다.
다음 단계 결정을 상태 머신 명세의 정답 전이와 비교하고, 검토자 2명이 라벨링해 정확도와 일치도를 보여주는 화면입니다.
국가·문서별 완료율과 막힘 단계 분포를 누적 집계해 약점을 보여주는 화면입니다.
다음 단계 시나리오 12종(통과·추가요청·실패·재시도)을 넣으면, 결정과 안내 문구가 몇 초 안에 나오는 걸 시연합니다
일부러 만든 악성·결측 입력 30종(검증 결과 null·미등록 국가·국가 표기 흔들림)을 넣어도 출력 형식(스키마)이 한 번도 안 깨집니다
내가 만든 정답 40건 중 다음 단계 전이가 상태 머신 명세와 일치한 게 36건(약 90%)입니다. 단, 명세·데이터를 모두 작성자가 만든 합성 기준이라 '성능 검증'이 아니라 '데모 조건에서의 동작'임을 명시합니다
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 정확도는 호패의 실 검증 API·실 국가 절차와 실 검토자가 있어야 측정 가능합니다. 이 도구는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다
수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다
이 포트폴리오는 다국가·다문서 인증 플로우를 React Native 상태 머신으로 구현하는 프로덕트 엔지니어링을 보여줍니다. 생체인증·문서 판독·제재 스크리닝 같은 신원확인 알고리즘은 외부 검증 API 가 한다고 가정하며, 그 도메인 전문성을 주장하지 않습니다. 모르는 도메인 깊이는 면접에서 모른다고 말하는 편이 낫습니다
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 검증 결과 누락·미등록 국가·최대 재시도 경계 같은 결측·경계 케이스를 더미에 일부러 섞어, 쉬운 전이만 푸는 게 아님을 보여줍니다
다음 단계는 규칙이 정하고 LLM 은 안내 문구만 생성합니다. 문구가 과장·오해를 부르지 않게 금지 표현을 차단하고, 결정 자체는 LLM 이 바꾸지 못하게 막습니다
국가·문서 표기가 제각각입니다. 정규화로 같은 국가로 묶고, 못 묶은 건 추측하지 말고 '미매핑'으로 알립니다. 실제 도입 시 국가 절차·검증 API 응답은 더미와 다르므로 상태 머신과 전이 규칙을 다시 맞춰야 합니다(도입 단계 과제로 분리)
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
신원확인 세션 이벤트 로그. 상태 머신·전이 결정이 가장 먼저 질의하는 테이블입니다. 검증 결과 결측·미등록 국가·국가 표기 흔들림·최대 재시도 경계를 일부러 섞어, 쉬운 전이만 푸는 게 아님을 보여줍니다.
| event_id | session_id | country_raw | country_id | doc_type | current_step | api_result | retries | ts |
|---|---|---|---|---|---|---|---|---|
| ev_001 | s_01 | 대한민국 | c_kr | id_card | doc_upload | ok | 0 | 2026-03-04T09:00 |
| ev_002 | s_01 | 대한민국 | c_kr | id_card | liveness | fail | 3 | 2026-03-04T09:02 |
| ev_003 | s_02 | 미국 | c_us | passport | doc_upload | need_more | 1 | 2026-03-04T10:00 |
| ev_004 | s_02 | 미국 | c_us | passport | review | — | 0 | 2026-03-04T10:05 |
| ev_005 | s_03 | 신규국가X | — | driver | doc_upload | ok | 0 | 2026-03-04T11:00 |
아래 Zod 스키마에 맞는 신원확인 세션 이벤트 60행 JSON 배열로 생성합니다. 국가 6~8개, 문서(passport/id_card/driver)·단계(doc_upload/liveness/review)·결과(ok/need_more/fail) 분포, 정상 흐름 위주에 막힘·재시도를 섞습니다.
{"type":"object","properties":{"event_id":{"type":"string"},"session_id":{"type":"string"},"country_raw":{"type":"string"},"country_id":{"type":["string","null"]},"doc_type":{"type":"string","enum":["passport","id_card","driver"]},"current_step":{"type":"string","enum":["doc_upload","liveness","review"]},"api_result":{"type":["string","null"],"enum":["ok","need_more","fail"]},"retries":{"type":"integer"},"ts":{"type":"string"}},"required":["event_id","session_id","country_raw","country_id","doc_type","current_step","api_result","retries","ts"]}
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(쉬운 전이만 푸는 함정 회피): (1) 같은 국가의 표기 별칭('대한민국'/'대한 민국', '미국'/'미 국'처럼 country_master 로 정규화돼야 함) 3건 이상, (2) 미등록 국가(country_id=null) 2건, (3) 결측: api_result 가 null 인 행 1~2건, (4) 경계값 최대 재시도(fail + retries 3 이상)·추가요청(need_more) 각 2건, (5) 한 세션이 doc_upload→liveness→review 로 이어지는 다단 흐름 2~3건. JSON 배열만.{"type":"object","properties":{"event_id":{"type":"string"},"session_id":{"type":"string"},"country_raw":{"type":"string"},"country_id":{"type":["string","null"]},"doc_type":{"type":"string","enum":["passport","id_card","driver"]},"current_step":{"type":"string","enum":["doc_upload","liveness","review"]},"api_result":{"type":["string","null"],"enum":["ok","need_more","fail"]},"retries":{"type":"integer"},"ts":{"type":"string"}},"required":["event_id","session_id","country_raw","country_id","doc_type","current_step","api_result","retries","ts"]}| React Native | 다국가 인증 플로우 모바일 화면(단계·재시도·상태) 구현입니다 |
| TypeScript | 상태 머신·전이 규칙·출력 스키마(Zod)의 구현 언어입니다 |
| Go | 검증 API·세션 이벤트 백엔드 연동을 가정합니다 |
| Zod | 이벤트 입력과 LLM 출력(안내 문구)의 런타임 형식 검증입니다 |
| 상태 머신 | 국가·문서별 단계·전이를 선언적으로 정의하는 핵심 모델입니다 |
| Claude | 사용자 안내 문구를 국가별로 현지화 생성하는 AI 도구입니다 |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차(전이가 맞았는지 확인)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(국가별 완료율 추이)로 진행합니다.
세션 이벤트 1건의 다음 단계 결정 카드. 결정·조건 요인·안내 문구를 한 스키마로 담아 플로우 화면에 씁니다. 결정은 상태 머신 규칙이 정하고 안내 문구만 LLM 이 생성합니다.
{"type":"object","properties":{"session_id":{"type":"string"},"country_id":{"type":["string","null"]},"decision":{"type":"string","enum":["proceed_next","request_more_doc","retry","complete","reject","hold"]},"factors":{"type":"array","items":{"type":"string","enum":["result_ok","need_more","max_retries","unmapped_country","missing_result"]}},"user_message":{"type":"string","minLength":10},"reason":{"type":"string","minLength":20},"evidence":{"type":"string","minLength":8},"hedge":{"type":["string","null"]}},"required":["session_id","country_id","decision","factors","user_message","reason","evidence","hedge"]}[
{
"input_ref": "ev_002 (대한민국 liveness 실패·재시도 3회)",
"output": {
"session_id": "s_01",
"country_id": "c_kr",
"decision": "reject",
"factors": [
"max_retries"
],
"user_message": "본인 확인을 여러 번 시도했지만 완료하지 못했습니다. 잠시 후 다시 시도하거나 다른 신분증으로 진행해 주세요.",
"reason": "liveness 단계에서 검증 실패가 이어지고 재시도가 3회로 한도에 도달해 상태 머신이 종료(거부)로 전이합니다.",
"evidence": "current_step=liveness, api_result=fail, retries=3",
"hedge": null
}
},
{
"input_ref": "ev_003 (미국 passport 추가요청)",
"output": {
"session_id": "s_02",
"country_id": "c_us",
"decision": "request_more_doc",
"factors": [
"need_more"
],
"user_message": "추가 서류가 필요합니다. 여권 정보 페이지를 다시 또렷하게 촬영해 올려 주세요.",
"reason": "검증 API 가 추가요청을 반환해 상태 머신이 서류 추가 단계로 전이합니다.",
"evidence": "api_result=need_more, current_step=doc_upload",
"hedge": null
}
},
{
"input_ref": "ev_004 (미국 review 결과 결측)",
"output": {
"session_id": "s_02",
"country_id": "c_us",
"decision": "hold",
"factors": [
"missing_result"
],
"user_message": "확인을 진행하고 있습니다. 잠시만 기다려 주세요.",
"reason": "검증 결과가 비어 있어 다음 단계를 단정하지 않고 대기로 둡니다. 결과 수신 후 재평가가 필요합니다.",
"evidence": "current_step=review, api_result=null",
"hedge": "결과 결측이라 통과·실패를 단정하지 않습니다"
}
},
{
"input_ref": "ev_005 (미등록 국가)",
"output": {
"session_id": "s_03",
"country_id": null,
"decision": "hold",
"factors": [
"unmapped_country"
],
"user_message": "현재 지역의 신원확인 절차를 준비 중입니다. 잠시 후 다시 시도해 주세요.",
"reason": "국가가 상태 머신 마스터에 없어 절차를 단정하지 않습니다. 국가 절차 등록 후 재평가가 필요합니다.",
"evidence": "country_id=null, api_result=ok",
"hedge": "미등록 국가라 다음 단계는 추정하지 않습니다"
}
}
][자동 검증] 1. Zod parse 로 출력 형식(필드·enum)이 스키마를 통과하는지 확인합니다. 2. decision 이 상태 머신 명세의 정답 전이와 일치하는지 봅니다(결과·단계·재시도는 결정적 규칙). 3. evidence 가 입력 이벤트의 실제 값 인용인지 토큰 매칭으로 확인합니다. 4. api_result 가 null 이거나 국가가 미매핑이면 hold 로 두고 단정을 막으며, user_message 의 금지·과장 표현을 차단합니다. [수동 검증] 1. 검토자 2명이 비동기로 다음 단계 전이를 라벨링해 정확도와 bootstrap Cohen's κ(두 사람 일치가 우연 이상인 정도, 0~1) 하한 0.6 이상을 봅니다. 2. 전체의 5% 를 사람이 직접 점검합니다.