정영길

제품 하나를 끝까지 만들고,
현장에서 터진 문제를 원인까지 찾아 고치는
풀스택 개발자입니다.

프론트엔드 3년을 거쳐, 공장에 설치되는 검사 장비의 운영 대시보드를 맡았습니다.
웹 개발자가 없던 초기에는 신규 제품을 풀스택으로 단독 개발했고,
디스크가 차서 멈추던 700GB 테이블과 현장 장애를 직접 해결했습니다.

신규 제품 풀스택 단독 개발 · 700GB 테이블 구조 개선 · 부팅·실시간 연결 장애 원인 규명
younggil94@naver.com GitHub 기술 블로그

경력 요약

프론트엔드 3년을 거쳐, 지금은 화면부터 API·데이터·배포까지 한 제품의 전 구간을 맡고 있는 풀스택 개발자입니다. 현재는 고객사 현장(온프레미스)에 설치되어 24시간 돌아가는 산업용 검사 장비의 운영 대시보드를 개발하고 있습니다.

경력 5년 3개월 (2020.11 ~ 재직 중)
핵심 역량 대용량 테이블 파티셔닝 · 운영 DB 마이그레이션 · 온프레미스 K8s 배포 운영 · 무중단 장애 원인 분석
대표 지표 700GB · 12개 테이블 무중단 파티셔닝 · 3억 2,804만 행 COUNT(*) 87초 제거 · 설치 파일 93% 감소(150MB→10.9MB) · E2E 40개/9분 43초 · PR 작성 5분→30초
주요 기술 React · TypeScript  /  NestJS · Prisma · PostgreSQL  /  Kubernetes · Helm · ArgoCD
기록 기술 블로그 11편

전 구간을 끝까지 책임집니다. 웹 개발자가 없는 팀에 합류해 신규 제품을 풀스택으로 단독 개발했습니다. 백엔드 API와 화면 전체를 설계·구현하고, 고객사로 나가는 배포 구성까지 직접 다룹니다.

반복 비용은 코드가 아니라 구조로 없앱니다. 하루 16만 건이 적재되며 디스크가 차면 장비가 멈추던 12개 테이블(약 700GB)을 DELETE 기반 정리에서 RANGE 파티셔닝 + DROP PARTITION 구조로 전환했습니다(기본 키 전면 재설계). RENAME swap + 최근 N일치만 이관으로 쪼개 라인이 쉬는 틈에 배포해 가동 중단 0분으로 끝냈고, 정리 작업은 수동 10~30분 → 스케줄러 자동이 됐습니다.

증상이 아니라 원인을 찾습니다. 재현되지 않는 장애는 조건을 하나씩 통제하며 범위를 좁힙니다. 부팅을 막던 3억 2,804만 행 COUNT(*)(87,371ms)를 제거했고, 하나의 증상 뒤에 있던 서로 무관한 원인 3건을 각각 규명했습니다 — 그중 공용 훅 한 곳을 고치자 같은 함정의 폴링 6개가 전부 보호됐습니다. 고칠 때는 재발 시 확인할 진단 수단을 함께 배포합니다.

프론트엔드 3년의 기준을 유지합니다. CI가 없던 프론트엔드에 목을 쓰지 않는 E2E를 붙여, 푸시마다 테스트 40개 · 고객사 5곳 · 9분 43초가 돌게 했습니다. 그 외 공통 컴포넌트 표준화, 서버/클라이언트 상태 분리, 렌더링 전략 구분, 하루 1.8만 건 화면의 가상 리스트 전환이 주로 다룬 주제입니다.

해결한 문제는 배경과 검토한 선택지, 그중 무엇을 왜 택했는지까지 정리해 글로 남깁니다.

기술적 역량

Backend & Data

NestJS Node.js TypeScript Prisma PostgreSQL Redis Stream REST API SSE Socket.IO

운영 DB의 파티셔닝, 인덱스, 마이그레이션 이관 작업을 직접 수행했습니다.

Infra & DevOps

Docker Kubernetes Helm ArgoCD Bitbucket Pipelines GitOps

제품이 고객사 현장의 Kubernetes 환경에 설치되는 구조라, Helm 차트가 곧 각 사이트의 구성입니다. 차트 작성, ArgoCD 등록, 서버 리소스 조정, 빌드·배포 파이프라인 구성을 직접 했습니다.

Frontend

React Next.js TypeScript React Query Zustand Tailwind CSS Storybook React Native

React 기반 화면을 3년간 담당했고, 공통 컴포넌트 표준화와 대용량 목록 가상화, 권한 기반 화면 제어를 직접 구현했습니다.

Sub & Tools

Go (Wails) WPF / C# Claude Code Jira/Slack/Git Figma

현장 PC용 데스크톱 앱을 Go(Wails)로 재작성했고, Claude Code 커맨드로 리뷰·PR 작업을 자동화했습니다.

대표 성과

Aivex에서 맡았던 작업 다섯 가지입니다. 각 항목의 배경과 검토한 선택지, 무엇을 왜 택했는지는 기술 블로그에 정리해 두었습니다.

700GB

RANGE 파티셔닝으로 전환한 운영 테이블 12개
상위 3개가 각 ~250GB · 무중단 전환

3.28억 행

부팅을 막던 COUNT(*)가 읽던 행 수
87,371ms 소요 → 제거 후 정상 기동

93%

데스크톱 앱 설치 파일 감소 150MB → 10.9MB
약 1/14 · 단일 exe 배포

40개

푸시마다 도는 E2E 테스트 고객사 5곳
9분 43초 · 목 없이 실제 백엔드

11편

재직 중 작성한 기술 블로그 글
위 성과 전부가 글로 공개됨

Database

디스크가 차서 멈추던 장비

하루 16만 건이 쌓여 디스크가 차면 저장이 실패하고 장비가 멈췄습니다. 대량 DELETE는 VACUUM 부하로 오히려 write를 지연시켜 배제하고, 12개 테이블 약 700GB(상위 3개가 각 ~250GB)를 RANGE 파티셔닝으로 전환했습니다. 250GB를 전부 복사하는 대신 RENAME swap + 최근 N일치만 이관하고 테이블별로 트랜잭션을 쪼개, 라인이 쉬는 틈에 나눠 배포해 비가동 시간 없이 끝냈습니다. 정리 작업은 수동 10~30분 → DROP PARTITION 스케줄러 자동으로 바뀌었습니다.

📝 디스크가 꽉 차서 멈춘 검사 장비 — 대용량 테이블 파티셔닝 삽질기
Incident

연결이 끊긴 채 복구되지 않던 장애

장비를 재부팅해도 연결 끊김 표시가 사라지지 않고 브라우저 새로고침에만 복구됐습니다. 폴링 영구 정지 / heartbeat 미도달 / 재연결 취소 조건 — 서로 무관한 원인 3건을 각각 규명했습니다. 재귀 setTimeout을 finally로 옮겨 공용 훅 한 곳을 고치자 같은 함정에 걸려 있던 폴링 6개가 전부 보호됐고, heartbeat 10초 · watchdog 30초(3회 미수신) 기준으로 half-open을 감지하도록 바꿨습니다. 재발 시 쓸 진단 로그 수집도 함께 배포했습니다.

📝 연결은 살아있는데 데이터가 안 온다 — 새로고침해야만 복구되던 SSE 고치기
Architecture

데스크톱 앱 150MB → 10.9MB

웹 화면 하나를 띄우기만 하는 앱이 Chromium을 통째로 번들링해 150MB(157,664,256B)였습니다. Chromium 취약점이 나올 때마다 앱을 다시 빌드해야 하는, 엔진 수명주기를 앱이 떠안는 구조였습니다. OS에 이미 있는 웹뷰를 빌려 쓰는 Go/Wails로 재작성해 10.9MB(11,517,440B) 단일 exe가 됐습니다 — 93% 감소, 약 1/14. 빌드·설치 파일 생성·릴리스도 자동화해 버전 태그 push만으로 배포됩니다.

📝 웹 화면 하나 띄우자고 150MB를 깔고 있었다 — Electron 래퍼를 Go로 갈아엎기
Ownership

신규 제품 풀스택 단독 개발

실장비도 데이터도 확정 기획서도 없이 시작한 신규 제품에서 백엔드 API와 화면 전체를 단독 개발했습니다. 백로그는 Epic 5 / Story 35 / Task 71 — 총 113건. 초반 스프린트에 담긴 건 만들 것이 아니라 알아낼 것이라 16 → 6 → 9 → 14 → 25건으로 뒤로 갈수록 무거워졌고, 격일 스크럼 23회와 6명 참석 리뷰 4회로 변경 주기를 따라갔습니다. 장비 동작을 모사하는 Mock 서버로 실장비 없이 인터페이스를 확정했습니다.

📝 센서도 기획서도 없이 킥오프했다 — 불확실한 프로젝트를 다섯 스프린트로 굴린 기록
Testing

목을 쓰지 않는 E2E — 고객사 5곳 화면을 푸시마다 검증

프론트엔드에는 CI 자체가 없어, 고객사별로 다른 화면 조합이 깨져도 배포 전에 알 방법이 없었습니다. 목을 쓰지 않고 실제 백엔드에 검사를 주입해 전역 집계까지 확인하는 E2E를 붙였습니다. 다만 모든 테스트가 하나의 백엔드를 공유해 병렬 실행 시 결과가 오염됐고 — 4회 중 2회 실패 — 병렬로 버는 시간은 10초 남짓이었습니다. 10초를 아끼자고 CI 게이트의 신뢰도를 바꿀 이유가 없어 워커를 1개로 고정했습니다. 지금은 푸시마다 테스트 40개 · 고객사 5곳(A 9 / B 6 / C 9 / D 8 / E 5) · 9분 43초가 돌고, 인증 → 잔여 페이지 정리 → 백엔드 설정 정합화 setup 3단계가 매 실행 앞단에서 스스로를 복구합니다. 남은 과제는 재시도로 덮인 플레이키 2건과, 직렬 10분이라 아직 머지 게이트로 걸지 못한 점입니다.

📝 끝까지 자동인 배포에 검증 한 칸 넣기 — 목을 쓰지 않는 E2E

경력 사항

Aivex

현재

Fullstack Engineer

2026.03 - 재직 중

공장에 설치되는 검사 장비의 운영 대시보드 개발 (기존 제품 + 신규 제품). 고객사 현장에 직접 설치되는 온프레미스 환경
프론트엔드(React) · 백엔드(NestJS/Prisma/PostgreSQL) · 현장 PC용 데스크톱 앱(Go) · 배포(Helm/ArgoCD) 담당
웹 개발자가 없는 상태에서 합류해 기능 개발과 현장 장애 대응을 수행

React TypeScript NestJS Prisma PostgreSQL Redis Stream SSE Go (Wails) Docker Kubernetes Helm ArgoCD

신규 제품 풀스택 단독 개발 — 백로그 113건 · 5개 스프린트로 전 구간 완료

  • 백엔드 API 전체 신규 작성 — 도메인별로 책임 경계를 나눠 설계해, 기획이 자주 바뀌어도 변경 범위를 한 영역 안에 가둠. 기획이 계속 움직여 격일 스크럼으로 주기를 맞추고, 이해한 내용을 문서로 되돌려 팀에 검증받으며 진행
  • 장비 이벤트를 Redis Stream으로 수신·처리, 최신 상태는 메모리 캐시로 조회. 장비마다 다른 통신 규격을 하나의 인터페이스로 감싸는 추상화 계층 작성
  • 동시 유입 시 같은 데이터가 두 번 저장되고 주문 상태가 어긋나던 문제를 DB 락으로 처리 순서를 강제해 해소
  • 수십만 건 규모 이력의 엑셀 다운로드를 스트리밍 방식으로 구현 — 조회 기간이 길어져도 서버 메모리 사용량이 일정하게 유지
  • 화면 전체 구현 — 측정값 추이 차트 대시보드, 단계별 장비 초기 설정 마법사, 실시간 현황 패널, 주문 생성·조회, 권한 제어
  • 공통 기반 작성 — 전역 알림 토스트, 저장 전 이탈 방지 훅, 화면 밖으로 밀려나지 않는 모달 레이아웃, API 타임아웃·중복 요청 제거
  • 스프린트별 처리량은 16 → 6 → 9 → 14 → 25건. 초반이 얇은 건 담긴 게 만들 것이 아니라 알아낼 것이었기 때문 — 그때 정해진 것들이 마지막 스프린트에 25건을 담을 수 있게 함. 격일 스크럼 23회, 6명 참석 스프린트 리뷰 4회로 타 직군과 주기를 맞춤
  • 매뉴얼에도 고객사 담당자에게도 없던 답을 현장 작업자 유선 문의로 확보. 가장 정확한 정보원은 문서가 아니라 장비를 매일 쓰는 사용자였음
  • 5개 스프린트 동안 실장비·데이터·확정 기획서 없이 진행. 백로그를 Epic 5 / Story 35 / Task 71 — 총 113건으로 세우고, 할 일을 기능이 아니라 함께 맞춰야 할 상대(디자이너 / 판정 모듈 담당 / 제어 모듈 담당) 기준으로 분해. 장비 동작을 모사하는 Mock 서버를 만들어 말이 아닌 실제 데이터로 인터페이스를 조율

🚀 Impact: 장비 연동을 제외한 화면·API·데이터·인터페이스 검증까지 완료

📝 센서도 기획서도 없이 킥오프했다 — 불확실한 프로젝트를 다섯 스프린트로 굴린 기록

대용량 테이블 파티셔닝 전환 (700GB · 12개) — 무중단 · 정리 작업 수동 10~30분 → 스케줄러 자동

  • 검사 한 건이 이미지 메타·ROI·시퀀스 등 여러 행을 파생시켜 하루 약 16만 건이 적재. 디스크가 차면 저장이 실패하고 24시간 돌아가는 공장의 장비가 정지
  • 대량 DELETE는 VACUUM 부하가 디스크를 붙잡아 신규 write를 지연시켜 배제. 삭제 시간대 분산도 "한가한 새벽"이 없는 24시간 공장이라 기각
  • 12개 테이블 · 약 700GB를 PARTITION BY RANGE(created_at)로 전환 — 파티션 키를 포함하도록 기본 키 전면 재설계, 단일 행 보장이 깨지는 자리는 쓰기 로직을 updateMany → 0건이면 create로 교체. 부담이 상위 3개 테이블(각 ~250GB)에 몰려 있다는 점이 "최근 N일만 이관" 설계의 단서가 됨
  • 250GB를 전부 복사하는 대신 RENAME swap + 최근 N일치만 이관. 수백 GB 복사를 한 트랜잭션에 묶었다 막판에 깨지면 전부 롤백되므로 테이블별 개별 트랜잭션으로 분리 — 실패한 테이블만 TRUNCATE 후 재시도. ALTER SEQUENCE ... OWNED BY 이관까지 챙겨 swap 후 id 연속성 보존
  • 점검 창을 따로 잡는 대신 점심·휴식 등 라인이 멈추는 틈마다 테이블을 하나씩 전환하고, DB 구조 변경이 끝난 뒤 파티션 인지 코드를 배포하는 2단 분리로 진행 — 비가동 시간을 따로 잡지 않고 무중단으로 완료. swap 직후에는 매번 EXPLAIN ANALYZE로 partition pruning 작동을 확인한 뒤 트래픽 재개
  • 보관 기간만 설정하면 새 파티션 생성·만료 파티션 DROP을 자동 수행하는 스케줄러를 애플리케이션 안에 직접 구현 (pg_partman 대신 — 운영 제약과 로그·모니터링 가시성 때문. 되돌릴 수 없는 작업이라 단위 테스트 동반)
  • 고객사마다 DB 상태가 달라 현재 상태를 스스로 판별해 분기하는 스크립트로 prisma db push 운영을 prisma migrate 이력 체계로 이관. 기존 마이그레이션 4개를 통합본 1개로 정리하고, 이력 자체가 없는 DB는 전체 baseline 마킹으로 처리

🚀 Impact: 정리 작업이 10~30분 + 운영자 직접 실행에서 즉시 완료 + 스케줄러 자동 처리로 변경. 전환 전 구간 공장 가동 중단 0분

📝 디스크가 꽉 차서 멈춘 검사 장비 — 대용량 테이블 파티셔닝 삽질기 📝 고객사마다 제각각인 운영 DB를 prisma db push에서 migrate로 옮기기

SSE 실시간 연결 끊김 장애 수정 — 원인 3건 규명 · 훅 1곳 수정으로 폴링 6개 동시 보호

  • 장비를 재부팅해도 연결 끊김 표시가 사라지지 않고 브라우저 새로고침에만 복구되던 문제. 하나의 증상 뒤에 서로 무관한 원인 3건
  • ① 재귀 setTimeout 폴링이 콜백 reject 시 다음 실행을 예약하지 않아 영구 정지. 백엔드만 재시작되면 새로고침 전까지 상태 조회 0건 → finally로 옮겨 해소. 공용 훅 한 곳을 고치자 같은 함정에 걸려 있던 폴링 6개가 전부 보호됨 (비전 모듈 5초·모션 컨트롤러 3초 폴링 포함 — 내가 확인한 건 2개였고 나머지 4개는 덤)
  • ② heartbeat의 data가 빈 문자열이라 NestJS가 data: 라인을 생략했고, SSE 규격상 브라우저가 이벤트를 디스패치하지 않아 리스너가 한 번도 호출되지 않음. watchdog이 그동안 재고 있던 건 연결 상태가 아니라 "업무 이벤트 30초 부재" → 설비가 조용한 시간대마다 정상 연결을 30초마다 강제 재연결. 전송 형식 수정으로 오탐 제거 (heartbeat 10초 · watchdog 30초 = 3회 연속 미수신 기준)
  • ③ 데이터 수신 시 재연결 예약을 조건 없이 취소해, 버퍼에 남아 있던 이벤트 1건에 예약이 취소되며 복구가 최대 30초 지연 → 연결이 살아 있을 때만 취소하도록 조건 보정. 덤으로 watchdog 경로는 이미 30초를 기다린 뒤인데 기본 재연결 지연 3초가 또 붙던 것도 제거
  • 재발 시 근거로 쓸 진단 로그 수집 기능 신설. 중복 억제가 없으면 부하를 만들고, 억제를 넣으니 이번엔 필요한 로그를 삼키던 문제까지 이어서 수정

🚀 Impact: 새로고침 없이 자동 복구되도록 수정, 재발 시 확인할 진단 경로 확보

📝 연결은 살아있는데 데이터가 안 온다 — 새로고침해야만 복구되던 SSE 고치기

장비 기동 실패 원인 추적 — 3억 2,804만 행 COUNT(*) 87초 제거로 정상 기동

  • 한동안 쓰지 않던 장비가 다시 켜지지 않는 장애. 재실행·재설치로는 재현되지 않음
  • 설정 파일을 하나씩, 다시 항목을 하나씩 바꿔가며 원인을 데이터 보관 설정으로 좁힘
  • 파티셔닝 배포 두 달 뒤, 처음으로 만료 파티션이 생긴 순간 그것도 하필 가장 무거운 이미지 메타 테이블에서 터짐. 정리 작업이 파티션 테이블을 순회하는 구조라 88초짜리 조회가 반복되며 부팅을 끝내지 못한 채 파드가 종료
  • 삭제 대상 선정 후 다음 로그까지 87,371ms(약 88초)간 완전한 침묵. 밖에서 보면 멈춘 것과 구분되지 않음. 범인은 만료 파티션을 DROP하기 전 행 수를 세던 COUNT(*) — rows: 328,040,507. 로그에 건수를 찍으려고 넣은 한 줄이 부팅 경로를 막고 있었고, 동작에 쓰이지 않아 제거
  • 원인을 다 파악하기 전에도 진행 상황을 계속 공유하고, 정식 배포 전까지는 코드 변경 없이 설정 값만 바꿔 우회하도록 현장에 안내. 수정 배포 시점은 내 준비가 아니라 공장 라인이 쉬는 시간에 맞춰 조율
  • 기능 테스트는 통과했는데 운영에서 터진 유형. 개발 환경 파티션엔 몇천 건뿐이라 COUNT(*)가 눈 깜짝할 새 끝났고, 같은 코드가 운영에선 3억 2,804만 행을 읽음. 5자릿수 데이터량 차이는 5자릿수 지연으로 돌아온다는 것 — 이후 리뷰에서 전체 스캔·반복문 내 쿼리는 운영 데이터량을 대입해 읽는 기준을 세움

🚀 Impact: 장비 정상 기동. 개발 환경 데이터 양으로는 드러나지 않는 종류의 문제를 코드 리뷰 확인 항목에 추가

📝 로그 한 줄 찍자고 3억 건을 세고 있었다 — 파티셔닝 배포 두 달 뒤의 청구서

현장 PC용 데스크톱 앱 재작성 — 설치 파일 150MB → 10.9MB (93% 감소)

  • 설치 파일 150MB(157,664,256B) — 웹 화면 하나를 띄우기만 하는 앱인데 Chromium을 통째로 번들링. 부속 DLL·pak 파일까지 같은 폴더에 함께 배포됐고, Chromium 취약점이 나올 때마다 앱을 다시 빌드해 재배포해야 하는 — 엔진 수명주기를 앱이 떠안는 구조
  • 그 엔진의 기능을 거의 쓰지 않아, OS에 이미 설치된 웹뷰를 빌려 쓰는 Go/Wails로 재작성 → 10.9MB(11,517,440B) 단일 exe — 93% 감소, 약 1/14. 앱이 하는 일은 전과 동일
  • 확대·새로고침·폴더 열기 버튼, 확대 배율 저장, 연결 상태 표시와 재시도 중단 조건 구현
  • 설치 관리자가 제거·업데이트 도중 공용 웹뷰 프로세스를 종료해 같은 PC의 다른 앱까지 꺼지던 문제 수정
  • 빌드·배포 파이프라인과 설치 파일 생성 자동화 — 버전 태그 push만으로 릴리스 생성. 150MB 폴더를 통째로 옮기며 어느 현장이 어느 버전인지 물어봐야 하던 배포가, 단일 파일이 되면서 내려받아 교체하는 흐름으로 정리됨

🚀 Impact: 설치 파일 150MB → 10.9MB, 단일 파일 배포로 전환. 브라우저 엔진 보안 업데이트는 OS가 처리

📝 웹 화면 하나 띄우자고 150MB를 깔고 있었다 — Electron 래퍼를 Go로 갈아엎기

온프레미스 K8s 배포 구성 및 서버 운영 — OOMKilled 반복 종료 해소 · Helm/ArgoCD 단독 관리

  • 제품이 고객사 공장의 Kubernetes 환경에 설치되어 나가는 구조라, Helm 차트가 각 사이트의 실제 구성. 차트 수정과 자동 배포 도구(ArgoCD) 등록을 직접 담당
  • 테스트에 필요하지만 어디에도 올라가 있지 않던 장비 동작 흉내용 목 서버의 배포 설정을 새로 작성해 개발·운영 환경에 배포
  • OOMKilled로 반복 재시작되던 백엔드 서버에 파드 리소스 limit/request 재조정 적용해 종료 해소
  • 자동 배포 실패 오류 수정, 환경별 실행 명령을 설정값으로 분리, 서버 사양에 맞춘 이미지 빌드

🚀 Impact: 고객사로 나가는 배포 구성을 직접 관리, 테스트용 서버를 자동 배포 대상에 편입, 반복되던 백엔드 서버 다운 해소

프론트엔드 E2E 테스트 파이프라인 구축 — 테스트 40개 · 고객사 5곳 · 9분 43초

  • 백엔드에는 CI가 있었지만 프론트엔드에는 CI 자체가 없었음. 고객사마다 화면 조합이 달라, 한 곳에 맞춘 변경이 다른 곳을 깨도 배포 전에 알 방법이 없던 상태
  • 목을 쓰지 않고 실제 백엔드에 검사를 주입해 결과표·검사 수량·불량 그래프 같은 전역 집계까지 확인하는 방식을 택함 — 목으로는 중복 집계 같은 실제 버그가 잡히지 않기 때문
  • 모든 테스트가 하나의 백엔드를 공유해 병렬 실행 시 서로의 결과를 오염 — 재봤더니 4회 중 2회 실패, 매번 다른 테스트가 깨짐. 병렬로 버는 시간은 43~49초 → 27~41초, 10초 남짓. 10초를 아끼자고 CI 게이트의 신뢰도를 바꿀 이유가 없어 워커를 1개로 고정 (describe.serial은 파일 내부만 보장해 불충분)
  • 매 실행 앞단에 setup 3단계를 직렬로 배치해 스스로를 복구하도록 구성 — 인증(6.4초) → 이전 실행의 잔여 페이지 정리(146ms) → 백엔드 설정 정합화(115ms)
  • 알람 로그 생성 API가 플래그 기본값 탓에 응답 전 외부 서버 업로드를 대기, CI에서 그 주소가 닿지 않아 네트워크 타임아웃까지 매달리며 훅 타임아웃 60초로 스펙이 통째로 죽던 문제를 규명·수정
  • 테스트 이름이 그대로 명세가 되도록 작성 — "주입한 검사가 결과표에 그대로 반영된다", "주입 건수가 검사 수량 Total/OK/NG에 반영된다" 등 목록만 훑어도 무엇을 보장하는지 읽힘

🚀 Impact: CI 부재(default 자체가 없음) → 푸시마다 E2E 40개 · 고객사 5곳(A 9 / B 6 / C 9 / D 8 / E 5) · 9분 43초가 도는 상태로 전환. 남은 과제는 재시도로 덮인 플레이키 2건과, 직렬 10분이라 아직 머지 게이트로 걸지 못한 점

📝 끝까지 자동인 배포에 검증 한 칸 넣기 — 목을 쓰지 않는 E2E

기존 제품 기능 개발 및 유지보수 — 멈추던 운영 화면 복구, PR 작성 5분 → 30초

  • API 아키텍처를 GraphQL에서 REST로 전환 — 서버 처리와 화면 호출 코드를 양쪽 다 이관
  • 사용자 역할에 따라 화면 노출과 조작 권한을 나누는 역할 기반 접근 제어(RBAC) 도입
  • 하루 1.8만 건이 쌓이는 알림 이력 화면이 수만 행을 한 번에 DOM으로 렌더하느라 멈추던 문제를 가상 리스트(@tanstack/react-virtual)로 전환 — 수만 행 → 실제로 보이는 수십 행만 렌더. 방법 5가지·라이브러리 3가지를 비교해 효과가 가장 큰 것이 아니라 기존 코드와 사용 감각을 가장 적게 흔드는 것을 선택 (컬럼 정렬을 지키려 table-layout: fixed + spacer 행 방식 채택). "느리다"의 원인 절반은 렌더가 아니라 조회 방식이라, 하루 단위 + 시간대 필터로 조회도 함께 재설계
  • 장비 수동 조작 화면의 명령 종류 확장, 설정값 불일치 경고 기능, 작업 이력 조회, 데이터 미저장 오류 수정 등 현장 요청 대응
  • AI 코딩 도구에 팀 전용 커맨드를 만들어 코드 리뷰를 PR 이전 단계로 이동 — 브랜치 분석·본문 작성·리뷰어 지정·push를 손으로 하던 PR 1건 5분 → 명령 한 줄 + 승인 30초. 시간뿐 아니라 PR마다 들쑥날쑥하던 품질이 일정해진 것이 더 컸음. 모든 변경이 배포 전 최소 한 번 점검을 거치게 되면서 console.log 잔존, 이벤트 리스너 cleanup 누락(실시간 화면 메모리 누수), 중복 컴포넌트가 사전에 걸러짐. 삭제·민감 파일 수정을 막는 훅과 도메인 매뉴얼 자동 로딩 커맨드도 함께 구성

🚀 Impact: API 아키텍처 REST 이관 + RBAC 도입, 수만 행 렌더링으로 멈추던 운영 화면을 보이는 수십 행만 렌더하도록 복구, PR 작성 5분 → 30초 및 배포 전 AI 사전 리뷰 습관화

📝 하루 1.8만 건 알림 로그 테이블, 가상 리스트로 최적화 📝 Claude Code 커맨드로 개발 작업 효율 높이기 — 사전 코드 리뷰부터 컨텍스트 자동화까지

팀패스 (Team Pass)

Frontend Developer

2025.04 - 2025.12 (9개월)

화장품 제조 뷰티 플랫폼 '브래닛' 프론트엔드 개발
React 기반 화면 전 범위 담당
1~2주 단위 스프린트로 배포하며 공통 컴포넌트 정비와 결제 연동을 수행

React TypeScript React Query Zustand Tailwind CSS Storybook

공통 컴포넌트 정비 및 상태 관리 구조 정리 — 신규 화면 작업 시간 단축

  • 버튼·입력·팝업 등 공통 컴포넌트를 variant/size/disabled/loading 규격으로 표준화하고 Storybook으로 문서화
  • 전면 교체 대신 신규·수정 화면부터 적용해 레거시를 점진 전환 — 디자이너와 규격을 합의해 화면별 구현 편차를 줄임
  • 서버 데이터는 React Query로 캐싱·동기화, UI 상태는 화면 단위로 국소화, 비즈니스 로직은 Custom Hook으로 분리
  • AI 어시스턴트로 반복 레이아웃 초안을 생성하고 인터랙션·상태 케이스 중심으로 정교화

🚀 Impact: 공통 컴포넌트 재사용으로 신규 화면 작업 시간 단축, 상태 관리 책임 분리로 버그 원인 범위 축소

레이아웃 시프트 최소화 및 전환 UX 안정화 — 로딩 중 오조작 감소

  • Skeleton/Placeholder 영역을 고정하고 높이·간격을 선확보해 렌더링 전후 레이아웃 변동을 최소화
  • 모달·탭·리스트 갱신 등 전환 구간 인터랙션을 재사용 가능한 패턴으로 정리

🚀 Impact: 로딩 중 화면이 밀려 잘못 클릭하는 문제 감소

구독 유료화 결제 연동 — 예외 케이스까지 처리한 결제 플로우 운영

  • 상품·상태 조회 → 결제 팝업 호출 → 결과 처리 → 서버 확인 요청 → 구독 상태 동기화까지 프론트엔드 구간 연결
  • 성공·실패·취소 등 결제 결과별 UX와 구독 상태 기반 접근 제어·노출 정책 정리

🚀 Impact: 결제 중단·실패·재시도 케이스까지 처리한 구독 결제 플로우 운영

케이브먼트 (Cavement)

Frontend Developer

2023.11 - 2025.04 (1년 6개월)

남성 미용의료 플랫폼 '미남이오' 앱/웹과 제모 탐색 서비스 '제모데이' 웹 개발
렌더링 전략 분리와 지도 UX 최적화를 중심으로 성능 개선
CodePush 기반 운영 대응 구조와 결제 연동을 함께 수행

Next.js React Native TypeScript

렌더링 전략 구분 및 캐싱 최적화 — 초기 로딩 시간 단축

  • 페이지 목적(SEO·개인화)과 데이터 변경 주기를 기준으로 정적 화면은 SSG/ISR, 개인화·권한 기반 영역은 SSR로 분리 적용
  • 자주 이동하는 페이지는 미리 불러두고, 이미지가 많은 화면은 화면에 들어올 때 불러오도록 변경
  • 같은 데이터를 여러 번 요청하지 않도록 캐싱하고 다시 불러오는 시점의 규칙을 정리

🚀 Impact: 초기 로딩 시간 단축 및 동일 데이터 중복 호출 감소

지도 탐색 화면 렌더링 최적화 — 깜빡임 제거, 재조회 호출 감소

  • 지도 이동·줌마다 자동 재조회가 발생해 깜빡임과 마커 중복 렌더링이 생기던 문제
  • 이동·줌이 끝난 뒤에만 요청하도록 지연 처리하고, “검색” 버튼을 눌렀을 때만 조회하도록 변경 (기획과 조회 시점 기준을 재합의)
  • 마커를 매번 다시 그리지 않고 바뀐 것만 추가·제거하도록 수정, 지도 렌더링 로직 분리

🚀 Impact: 지도 이동 시 발생하던 깜빡임 제거 및 재조회 호출 감소

펫피플 (Pet People)

Frontend Developer

2022.04 - 2023.03 (1년)

반려동물 플랫폼 '와요/펫플래닛'의 앱 및 내부 어드민 개발

React React Native JavaScript

앱 신규 기능 개발 — 탐색·예약·기록 3개 기능 추가

  • 지도 기반 장소 탐색 — 카테고리·마커 탐색 구성, 마커 선택에서 상세 이동까지 동선 정리
  • 숙소 예약 — 조건별 필터로 탐색 조건을 구성하고 탐색 → 상세 → 예약·문의(결제 포함) 흐름 구현
  • 단계 기반 기록 작성 — 앱 종료·백그라운드 전환에도 흐름이 끊기지 않도록 임시저장을 제공해 입력 유실 방지

🚀 Impact: 장소 탐색·숙소 예약·기록 작성 세 기능을 앱 기능 범위로 확장

휴라(Hura)

응용프로그래머

2020.11 - 2022.04 (1년 6개월)

전파 탐지 장비의 모니터링 프로그램 개발 (WPF/C#)

WPF

전파 탐지 장비 모니터링 화면 개발 — 운영자의 상태 파악 속도 개선

  • 장비에서 계속 전달되는 전파 데이터를 받아 화면에 실시간으로 표시하는 모니터링 UI 구현
  • 운영자가 값을 빠르게 읽을 수 있도록 대시보드·그래프·상태 표시 중심으로 화면 구성 및 사용자 흐름 정리

🚀 Impact: 실시간 모니터링 환경에서 운영자가 상태를 파악하는 속도를 개선

Writing

업무에서 실제로 겪은 문제를 배경 · 검토한 선택지 · 결정 근거 · 결과 순으로 정리해 공개하고 있습니다. · velog.io/@yg1110

운영 데이터베이스

멈추면 안 되는 DB의 구조를 바꾼 작업

  • 디스크가 꽉 차서 멈춘 검사 장비 — 대용량 테이블 파티셔닝 삽질기

    2026.06

    지우는 방식 대신 테이블을 쪼개는 구조를 택한 이유와, 장비를 세우지 않고 바꾼 절차

  • 고객사마다 제각각인 운영 DB를 prisma db push에서 migrate로 옮기기

    2026.06

    고객사마다 상태가 다른 운영 DB에 변경 이력 관리 체계를 도입한 방법

  • 로그 한 줄 찍자고 3억 건을 세고 있었다 — 파티셔닝 배포 두 달 뒤의 청구서

    2026.08

    로그에 건수를 찍으려던 쿼리가 3억 건을 세느라 장비 기동을 막던 장애의 추적 과정

실시간 · 성능

느리거나 멈추던 것들을 고친 작업

  • 연결은 살아있는데 데이터가 안 온다 — 새로고침해야만 복구되던 SSE 고치기

    2026.08

    하나의 연결 끊김 증상 뒤에 있던 서로 무관한 원인 3건을 분리해 수정한 과정

  • 하루 1.8만 건 알림 로그 테이블, 가상 리스트로 최적화

    2026.06

    수만 행을 그리다 멈추는 표를 고치며 방법 5가지·라이브러리 3가지를 비교한 기준

  • 웹 화면 하나 띄우자고 150MB를 깔고 있었다 — Electron 래퍼를 Go로 갈아엎기

    2026.08

    데스크톱 앱을 다시 만들며 따진 용량과 통제력의 트레이드오프

일하는 방식

프로젝트 진행 방식과 개발 프로세스

  • 센서도 기획서도 없이 킥오프했다 — 불확실한 프로젝트를 다섯 스프린트로 굴린 기록

    2026.08

    실제 장비와 기획서 없이 5개 스프린트를 진행하며 팀과 맞춰간 방식

  • Claude Code 커맨드로 개발 작업 효율 높이기 — 사전 코드 리뷰부터 컨텍스트 자동화까지

    2026.06

    AI 코딩 도구에 팀 전용 명령을 만들어 리뷰·PR 작업을 자동화한 구성

  • 물어보던 사람에서, 먼저 제안하는 사람으로 — 풀스택 수습 3개월

    2026.06

    풀스택 수습 3개월 회고

  • 프론트엔드 3년차, 풀스택으로 첫 걸음을 뗀 1.5개월

    2026.06

    풀스택 전향 후 첫 1.5개월 회고

사이드 프로젝트

프로젝트 태그

  • 완료 최소 기능 제품을 완성해 실제 사용 가능한 프로젝트
  • 진행중 개발·기능 추가가 계속 진행 중인 프로젝트
  • 중단 우선순위·방향 조정 등으로 개발을 중단한 프로젝트

Loopin

완료

2026.07

Source Code

습관·루틴을 매일 체크하고 연속 기록(streak)을 쌓는 PWA. 습관 기록은 기기 로컬에 저장하고, 올린 인증만 공개 피드로 공유. Service Worker와 Web Push로 체크 알림을 발송

React 19 Vite PWA (Workbox) Web Push Supabase Expo / React Native

Bookorry

완료

2026.03

Source Code

초대코드와 닉네임만으로 참여할 수 있는 소규모 독서 모임용 소셜 기록 앱. 독후감 공유와 헬스·식단 등 일상 루틴 인증을 그룹 피드로 함께 확인

Next.js 16 Supabase TypeScript Tailwind CSS

ClipStack

완료

2026.03

Source Code

복사한 텍스트를 자동으로 기록하고 전역 단축키(⌘+Shift+V)로 빠르게 접근할 수 있는 macOS용 클립보드 히스토리 매니저

Electron

Sprintlog

완료

2026.03

Source Code

OKR 관리와 일일 업무기록을 한 곳에서 관리하는 생산성 앱

React 19 Supabase

JobLens

완료

2026.02

Source Code

사람인·잡코리아 채용공고를 수집하고, 스코어링 엔진으로 추천/보류/제외를 판단한 뒤 이메일 알림을 발송하는 개인용 의사결정 지원 시스템

Python FastAPI pytesseract (OCR) Spring Boot PostgreSQL

TubeSync

중단

2026.02

Source Code

실시간으로 유튜브 영상을 함께 보면서 채팅/목록 관리를 할 수 있는 실시간 워치파티 서비스

React 18 Socket.IO NestJS Docker Compose

Wardrobe

중단

2026.01

Source Code

옷을 등록하고, 코디를 만들고, 세탁을 추적하는 모든 것이 한 곳에서 할 수 있는 서비스

React 18 Supabase

RMancer

완료

2026.01

Source Code

인바디·1RM·운동목표를 바탕으로 사용자에게 최적화된 운동 루틴을 추천해주는 서비스

Next.js 16 NestJS 11 PostgreSQL Docker Compose

SnipSnip

완료

2024.11

Source Code

북마크를 폴더로 분류하고 드래그 앤 드롭으로 정리할 수 있는 개인 북마크 관리 서비스

Next.js 14 NestJS 10 MySQL Docker

학력 및 수료

  • 한밭대학교
    컴퓨터공학 학사
    2013.03 - 2019.02
  • 삼성 청년 SW 아카데미 (SSAFY)
    SW 개발자 과정 수료
    2019.06 - 2020.06

자격증

  • 정보처리기사
    2019.08.16
  • 네트워크관리사 2급
    2019.05.21
© Younggil Jeong. All rights reserved.