경력기술서

인호준 dlsghwns12@gmail.com · github.com/hojunin

맡았던 일 중 직접 판단하고 결정한 비중이 큰 프로젝트를 골라, 무엇이 문제였고 왜 그 방법을 택했는지 중심으로 적었습니다. 전체 경력 요약은 이력서에 있습니다.

주요 프로젝트

크로스플랫폼 상품 어드민

무신사 · 2026.01 ~ 현재
역할
상품 등록·수정 폼 설계, 일괄 처리, BFF
기술
Next.js, React Hook Form, Zod, TanStack Query, tRPC

배경 · 문제

무신사·29CM·조조타운·티몰글로벌·무신사차이나 5개 플랫폼과 14개 판매지역에 걸쳐, 파트너와 운영자가 한 곳에서 상품을 등록·수정·검수하는 통합 어드민을 만드는 프로젝트입니다.

상품 하나에 붙는 필드가 200여 개인데, 어떤 섹션이 보이고 무엇이 필수인지는 판매할 플랫폼과 카테고리, 상품 유형에 따라 전부 달라집니다. 플랫폼이 추가될 때마다 폼을 다시 짜는 구조라면 유지할 수 없었습니다. 여기에 파트너가 수천 건을 한 번에 올리고 고치는 엑셀 일괄 작업까지 같은 제품에서 받아야 했습니다.

접근 · 해결

폼을 40여 개 섹션으로 나누고, 섹션마다 Zod 스키마와 기본값을 정의해 하나의 폼 스키마로 조립했습니다. 섹션 사이에 걸친 규칙(예를 들어 특정 플랫폼을 선택하면 그 플랫폼 전용 섹션들이 필수가 되는)은 스키마의 크로스필드 검증으로 한곳에 모았습니다. 화면 쪽은 섹션 레지스트리 하나가 등록·수정·조회 세 화면의 순서·노출·검증 전략을 결정하는 단일 진실이라, 플랫폼이 추가되면 스키마와 레지스트리 항목을 늘리는 것으로 끝납니다.

엑셀 일괄 처리의 원칙은 "이 작업을 하는 사람은 조금 기다려도 되지만, 그 때문에 다른 사용자의 화면이 느려지면 안 된다"였습니다. 상품을 반영하는 API가 한 번에 한 건씩만 처리할 수 있어서, 수천 행을 그대로 흘려보내면 그 부담을 화면을 서빙하는 서버가 함께 떠안는 구조였습니다.

그래서 파싱과 1차 검증을 브라우저에서 끝내 잘못된 파일이 서버까지 가지 않게 했고, 전송은 일정 크기로 쪼개 동시 2건까지만 보내도록 제한했습니다. 실제 반영은 여러 건을 병렬로 처리하는 별도 서버에 묶음 단위로 넘겨, 화면을 담당하는 쪽이 오래 붙잡히지 않게 했습니다. 재시도해도 같은 행이 두 번 반영되지 않도록 행마다 고유 키를 부여했습니다.

결과

플랫폼과 판매지역이 늘어도 폼 구조를 바꾸지 않고 스키마 확장으로 흡수할 수 있게 됐습니다.

이 제품을 만들며 내린 기술 결정 중 가장 큰 것이 BFF 도입이었고, 별도 프로젝트로 아래에 정리했습니다.

BFF 도입: 기술 선택과 운영 설계

무신사 · 2026.02 ~ 현재
역할
기술 선택 의사결정자 · 성능 검증 · 장애 대응 설계
기술
Next.js API Routes, tRPC, Zod, k6, Datadog

배경 · 문제

기존 파트너 플랫폼은 Backend가 Public API를 만들어 주고 프론트엔드는 클라이언트만 담당하는 구조였습니다. 크로스플랫폼 상품 어드민에서는 Backend가 도메인별 Internal API만 제공하기로 하면서, 프론트엔드 팀이 상품·재고·정산 API를 직접 조합하는 서버를 만들고 배포하고 운영해야 하는 상황이 됐습니다.

백엔드 지원 없이 프론트엔드 엔지니어가 감당할 수 있는 수준으로 운영 복잡도를 낮추는 것이 조건이었습니다.

접근 · 해결

기술을 고르기 전에 BFF의 책임 범위부터 정의했습니다. API 조합·데이터 변환·에러 처리·입력 검증은 하고, DB 직접 접근·트랜잭션·데이터 영속화는 하지 않는다. 그렇게 정리하니 모든 작업이 I/O 바운드였고, "프레임워크 성능은 선택 기준이 아닐 것"이라는 가설이 나왔습니다.

가설을 실측으로 검증했습니다. NestJS·Fastify·Next.js에 동일한 tRPC procedure를 올려 k6로 3단계 부하를 돌린 결과, 경부하에서 프레임워크 간 차이는 0.02ms 미만이었고 고부하에서는 프레임워크가 아니라 비즈니스 로직 복잡도가 성능을 좌우했습니다.

그 위에서 서버 프레임워크 3종 × 통신 프로토콜 3종의 6개 조합을 비교했습니다. NestJS 계열은 DI·데코레이터·모듈 시스템이 DB와 트랜잭션을 가진 서버를 전제한 설계라 BFF에는 과했고, GraphQL은 클라이언트가 어드민 하나뿐이라 스키마·리졸버·Codegen 관리 비용만 남았습니다. Fastify+tRPC는 안정적이었지만 I/O 바운드 작업에서 별도 서버 인프라 비용을 정당화하기 어려웠습니다.

결과

Next.js API Routes + tRPC를 채택하고 의사결정 기록(ADR)으로 남겼습니다. 별도 Pod·배포 파이프라인·모니터링 대상을 추가하지 않고 배포 단위 1개를 유지했고, Codegen 없이 라우터에서 React 컴포넌트까지 하나의 타입 시스템으로 이어졌습니다.

부하테스트로 기준 부하의 10배까지 Error Rate 0%, P50 49ms·P95 177ms(통과 기준 100ms·300ms)를 확인했습니다. 라우터·스키마·비즈니스 로직은 Next.js에 의존하지 않게 설계해(전송 계층도 표준 fetch 어댑터), 부하가 커지면 독립 서버로 떼어낼 수 있는 경로를 남겼습니다. 다만 인증 컨텍스트를 만드는 지점은 Next 어댑터에 붙어 있어, 실제로 분리하려면 그 부분을 갈아끼워야 합니다.

프론트엔드 아키텍처 설계와 Architecture Keeper

무신사 · 2025.02 ~ 2025.12
역할
아키텍처 설계 · 표준 문서화 · AI 리뷰 봇 구현
기술
Turborepo, TanStack Query, Zod, GitHub Actions, Gemini CLI

배경 · 문제

무신사 파트너와 29CM Connect 두 조직이 합쳐진 신설 팀이었습니다. 양쪽의 개발 표준이 서로 달랐고, 여러 조직의 여러 애플리케이션에서 쓰일 모듈을 어떻게 설계할지에 대한 합의된 기준이 없었습니다.

접근 · 해결

Api → Service → Feature → App 4계층과 단방향 데이터 흐름을 정의하고, 레이어별 책임·안티패턴을 각각 문서로 명문화했습니다. "폴더 구조만 보고도 아키텍처를 유추할 수 있어야 한다"는 원칙으로 구조와 문서를 일치시켰습니다. Service Layer 존치처럼 의견이 갈린 안건은 찬성·반대·중립을 모두 기록하는 방식으로 합의했습니다.

설계가 문서에만 남으면 지켜지지 않는다고 봤습니다. type check나 lint로는 "feature에서 api를 직접 호출하지 않는다" 같은 규칙을 검사할 수 없고, 아키텍처에 익숙한 소수가 매번 수동 리뷰로 잡는 방식은 지속 가능하지 않았습니다. 규칙을 AI 룰 파일로 옮겨 에디터와 CI가 같은 기준을 보게 하고, CI에서 이를 검사하는 봇을 만들었습니다.

공식 예제는 GitHub MCP를 붙여 AI가 API를 직접 호출하게 하는데, 대용량 PR에서 토큰이 폭증했습니다. 필요한 데이터를 미리 추출해 넘기고 AI는 분석만 하도록 역할을 분리했습니다. AI 응답을 그대로 믿지 않도록 타입가드로 검증하고, 모든 단계를 실패 허용으로 두어 AI 리뷰가 CI를 막지 않게 했습니다.

결과

변경된 레이어를 감지해 병렬로 리뷰하고 PR에 라인 단위 코멘트를 남기는 봇이 CI에 자리 잡았습니다. 아키텍처 문서 → AI 룰 → CI 검증이 하나로 이어져, 소수에게 몰려 있던 리뷰 부하가 분산됐습니다.

이 봇은 4개월을 운영하다 제 손으로 걷어냈습니다. 그사이 코딩 에이전트 쪽 생태계가 빠르게 정리되면서, 별도 CLI를 워크플로에 물려 프롬프트·응답 파싱·타입가드를 직접 관리하는 방식보다 표준화된 액션을 쓰는 편이 유지 비용이 낮아졌기 때문입니다. 만든 것에 애착을 두기보다 같은 목적을 더 싸게 달성하는 쪽으로 갈아타는 게 맞다고 판단했습니다.

3개월 뒤 회고에서 스스로 만든 구조의 문제를 찾았습니다. 백엔드 응답 스키마가 조금만 바뀌어도 3개 레이어를 함께 고쳐야 했고, Service Layer는 API 전달·정규화·UI용 데이터 생성이 뒤섞인 중간 계층이 돼 있었습니다. V2에서는 Service Layer 스키마가 바뀌는 기준을 "UI가 바뀌어야 할 때"로 잡아 Anti-Corruption Layer로 재정의하고, 오버헤드가 된 Entity를 폐지하고, 팀에 이미 있던 Swagger 기반 타입 생성 파이프라인으로 대체하는 방향을 도출했습니다. 이 V2 역시 문서와 AI 룰로 다시 반영했습니다.

자율형 프론트엔드 엔진: PRD에서 PR까지

무신사 · 2026.04 ~ 현재
역할
설계 · 구현 (단독)
기술
Tauri, Rust, React, Zustand, Vite, Claude Code CLI

배경 · 문제

PM이 PRD를 쓰고, 디자이너가 퍼블리싱하고, 프론트엔드 개발자가 PR을 올리는 생산 파이프라인에서 단계마다 사람이 같은 정보를 다시 옮겨 적고 있었습니다. PRD를 넣으면 퍼블리싱을 거쳐 PR 초안까지 만들어지는 도구를 만들기로 하고 설계와 구현을 맡았습니다.

접근 · 해결

가장 중요한 결정은 디자인 시스템을 카탈로그로 만든 것입니다. AI에게 "우리 디자인 시스템대로 그려라"라고 시키면, 매번 컴포넌트 코드를 뒤져 무엇이 있는지부터 파악해야 합니다. 느리고, 매번 다른 답이 나옵니다. 그래서 컴포넌트마다 어떤 상황에 쓰는 것인지와 사용 예시를 함께 담은 카탈로그를 정본으로 두고, AI가 화면을 그릴 때 탐색 대신 카탈로그에서 고르게 했습니다. "검색 결과를 보여줘야 한다 → 어떤 컴포넌트를 쓴다"가 즉시 결정됩니다.

카탈로그가 정본이 되려면 저장소마다 그것을 만들 수 있어야 합니다. 어떤 컴포넌트 패키지를 쓰는지, 토큰이 어디에 정의돼 있는지, Provider를 어떻게 감싸는지가 저장소마다 다릅니다. 이걸 자동으로 식별해 카탈로그를 생성하고, 결과를 워크스페이스 프로파일로 캐싱해 이후 단계는 참조만 하도록 만들었습니다.

프리뷰에서 만든 코드가 프로덕션에서 다르게 동작하지 않도록, 프리뷰 앱의 설정 파일(package.json·엔트리·전역 CSS·빌드 설정)을 매 실행마다 원본에서 다시 생성합니다. 작업 중 AI가 설정을 건드려도 다음 실행에서 복원됩니다.

PRD나 디자인이 바뀌었을 때 처음부터 다시 하지 않는 것도 설계 목표였습니다. 재실행하면 현재 코드베이스를 참조해 PR을 다시 만들기 때문에, 변경이 생겨도 퍼블리싱 단계는 다시 밟지 않습니다.

결과

아직 숫자로 증명할 단계는 아닙니다. 다만 PRD가 단순하고 화면 형태가 정형화된 백오피스 제품에서는 디자인 시스템대로 화면이 기민하게 만들어지는 것을 확인했습니다. PRD 분석부터 퍼블리싱까지 10분 안에 끝납니다. 현재도 개발 중입니다.

Bugzar: QA 리포트를 AI가 바로 읽는 형태로

개인 프로젝트 · 2026.07
역할
기획 · 설계 · 구현 (단독)
기술
TypeScript, React, MCP, Cloudflare Workers, R2, Workers AI
공개
Apache-2.0 · github.com/hojunin/bugzar · npm @bugzar/sdk, @bugzar/mcp

배경 · 문제

버그 리포트의 비용은 양쪽에 나뉘어 있습니다. QA는 본 것을 말로 옮겨야 하고, 받는 개발자는 그 말을 읽고 같은 상황을 다시 만들어야 합니다. 이 과정에서 정보가 새고, "제 환경에서는 재현이 안 됩니다"로 되돌아옵니다.

AI 에이전트에게 버그를 맡길 때는 이 손실이 더 커집니다. 에이전트가 받는 것은 결국 사람이 요약한 텍스트라, 실제로 무엇이 실패했는지는 여전히 빠져 있습니다. 기록하는 쪽은 말로 설명하지 않고, 고치는 쪽은 재현하지 않아도 되게 만드는 것이 목표였습니다.

접근 · 해결

구조는 세 부분입니다. 기록(SDK) → 하나의 리포트 파일 → 소비(사람의 뷰어 / 에이전트의 MCP), 그리고 선택적으로 공유·발행(Worker)입니다.

기록. React 앱에 컴포넌트 하나를 붙이면 브라우저 API를 감싸 DOM 변화, 콘솔 에러(스택 포함), 네트워크 요청, Web Vitals, 시스템 정보를 하나의 타임라인으로 모으고, 여기서 재현 절차를 자동으로 합성합니다. 사람이 "이렇게 하면 됩니다"를 적는 대신 실제로 일어난 순서를 그대로 씁니다.

산출물을 서버가 아니라 파일로 뒀습니다. 결과는 자기완결형 HTML 하나라 계정도 네트워크도 없이 더블클릭으로 재생됩니다. 사내 도구가 "우리 서버에 올려야만 쓸 수 있다"는 이유로 안 쓰이는 걸 여러 번 봤기 때문에, 백엔드는 있으면 좋은 것이지 전제가 아니게 만들었습니다.

같은 파일을 사람과 에이전트가 함께 읽습니다. 뷰어는 사람이 보고, 같은 리포트를 MCP 서버가 읽어 에이전트에게 도구로 제공합니다. 리포트를 열고 재현 절차·콘솔 에러·실패한 요청을 질의하고, 특정 요청의 헤더와 본문까지 꺼내 볼 수 있습니다. 정적인 텍스트를 붙여넣는 대신 에이전트가 필요한 것을 직접 골라 가져가는 형태입니다. 포맷을 두 벌 만들지 않고 하나로 맞춘 것이 이 설계의 핵심입니다.

공유와 이슈 발행은 선택입니다. Cloudflare Worker가 리포트를 오브젝트 스토리지에 올려 공유 링크를 만들고, Workers AI로 초안을 만들어 클릭 한 번으로 Jira에 발행합니다. 여기서 AI는 마지막 단계에만 씁니다. 수집과 재현 절차 합성은 결정론적으로 처리해 모델이 실패해도 리포트 자체는 성립하게 했습니다.

다른 사람의 화면을 통째로 기록하는 도구라 안전장치를 함께 넣었습니다. LLM에 보내기 전 개인정보를 걸러내고, 허용한 헤더만 통과시킵니다. 페이지 안의 텍스트는 신뢰할 수 없는 입력으로 취급해 프롬프트를 덮어쓰지 못하도록 방어했고, 이슈 발행용 인증 토큰은 서버 세션에만 두어 브라우저로 내려가지 않게 했습니다.

결과

Apache-2.0으로 공개하고 npm에 배포했습니다. 모노레포 6개 패키지, TypeScript 약 2만 4천 줄, 테스트 74개이며, PR마다 프로덕션과 분리된 프리뷰 환경으로 배포되도록 CI를 구성했습니다.

SEO 개선으로 검색 유입 확대

겟차 · 2022 ~ 2023
역할
SEO 기법 적용 및 사이트맵 자동화

배경 · 문제

차량 정보 콘텐츠가 계속 쌓이는 서비스인데도 검색 색인 생성량이 6천 건 수준에 머물러, 만들어 둔 콘텐츠 대부분이 검색에서 발견되지 않고 있었습니다.

접근 · 해결

콘텐츠가 늘어날 때마다 사람이 대응하는 방식으로는 따라갈 수 없다고 보고, 사이트맵 업데이트를 자동화하고 캐노니컬 태그를 적용해 색인 대상 자체를 넓혔습니다.

색인이 된 뒤에는 검색 결과에서 눈에 띄어야 클릭으로 이어지므로, 콘텐츠별 다이나믹 메타태그를 적용하고 리치 텍스트 스키마를 붙였습니다.

결과

색인 생성량이 6천 건에서 7~8만 건으로 10배 이상 늘었고, 검색 노출수와 클릭수가 2~3배 증가했습니다. 스키마가 적용된 문서는 3만 건 이상 발생했습니다.

그 외 경력

무신사

2024.05 ~ 현재
  • 무신사·29CM·조조타운·티몰글로벌·무신사차이나 5개 플랫폼과 14개 판매지역을 다루는 통합 상품 어드민 개발
  • 디자인 변경이 수작업 없이 코드에 반영되도록, Figma Variables를 Tailwind 테마와 Ant Design 테마로 동시 변환하는 Figma 플러그인 개발
  • AI 기반 PR 생성 커맨드와 문서 작성 자동화를 만들어 팀에 확산. 스펙 주도 개발 도구를 실제 페이지 개발에 적용하는 PoC를 수행하고 결과를 사내에 공유
  • 카탈로그 어드민(표준 옵션·표준 카테고리·오퍼레이션 툴), 상품 카탈로그 통합(OCMP), 29CM 큐레이터, 마케팅 구좌 관리 시스템 개발
  • 신설 팀의 그라운드 룰을 코드리뷰 컨벤션·브랜치 전략·문서화 체계·회고 주기·공수 산정 기준까지 아젠다로 정리하고 데일리에서 하나씩 합의. 온보딩 가이드와 3단계 온보딩 미션을 설계해 멘토 역할 수행
  • 경력 프론트엔드 개발자 채용에 기술 면접관으로 참여. 지원자 이력서를 분해해 항목별 시간 배분·핵심 질문·꼬리질문·기대 답변을 갖춘 구조화 면접 질문지를 직접 설계
  • 상품 상세 페이지를 새 아키텍처로 전환, AppleCare+ 같은 무형상품 판매와 속성 피커 UI 설계, 아이폰 사전판매 대기열 개발 (29CM 카탈로그팀)
  • 테스트 코드가 없던 조직에서 크로스팀 Testing Working Group을 발족. 레이어별 테스트 기법을 매핑하고 학습 자료를 작성해 직접 스터디 진행 (29CM)

겟차

2022.03 ~ 2023.07
  • 현대캐피탈 라이브쇼 개발. iOS에서만 영상이 네이티브 풀스크린으로 재생되면서 라이브커머스의 핵심인 채팅·구매 UI가 가려지는 문제가 있었습니다. 앱·웹뷰·브릿지 라이브러리·솔루션사 제품까지 다섯 레이어를 전수 조사해 react-native-webview가 JS에서 받은 설정값을 iOS 네이티브로 전달하지 않는 것을 확인했습니다. 첫 방송이 다음 날이라 네이티브 레벨에서 먼저 우회 조치하고, 이후 라이브러리 코드를 분석해 근본 원인을 고친 PR을 업스트림에 올려 머지(react-native-webview#2548). 제 문제만 고치지 않으려고 WKWebView 공식 문서를 확인해 함께 누락돼 있던 설정까지 포함했습니다.
  • JSDoc·Redux에서 TypeScript·React Query로의 마이그레이션 주도. Best Practice 문서화와 보일러플레이트 스니펫 제작까지 병행
  • Sentry 기반 에러 추적 환경을 구축하고 로깅 커스텀 모듈을 제작해 팀에 전파
  • WebView와 Web 간 통신 규칙을 정리해, 규칙 불일치와 하위호환성으로 인한 통신 불능 문제를 해결
  • 팀 깃 정책을 도입하고 GitHub Actions로 CI를 자동화
  • SDU(Server Driven UI) 기반 광고 플랫폼 화면과 이벤트 트래킹 구현

스코어본

2021.06 ~ 2022.01
  • 스포츠 종합정보 앱의 프론트엔드 리뉴얼을 1인 개발. 프로젝트 생성부터 1.0 릴리즈까지 (React Native · TypeScript)
  • 아토믹 디자인 패턴으로 컴포넌트를 설계해 재사용성 확보

한국스마트인증

2020.08 ~ 2021.05
  • 블록체인 기반 익명 의사결정 서비스 Abowa의 프론트엔드 개발 (React Native · TypeScript)
  • 그룹·멤버·활동 관리 어드민 페이지 제작 (React Native for Web)
  • 구독·결제·인보이스 발행 웹 페이지와 백엔드 결제 기능 개발