← 웹 이력서
⌘P → 대상 "PDF로 저장"
김태영
Backend Engineer · 포트폴리오
프로필 사진
배포 파이프라인 개선 (SWING) 2026
백엔드·인프라
FE·BE·배치 3개 GitHub Actions 워크플로우가 서로를 모른 채 도는 구조에서 생기는 무중단 위협을 위험도별로 분석하고, 워크플로우 통합·자동 롤백·차등 캐시로 잡았습니다.
무중단 위협7개 분석배포 실패ECS 자동 롤백캐시 전략파일 특성별 차등
문제정의
  • packages/types를 건드리면 FE·BE 워크플로우가 동시에 떴고, 빨리 끝나는 FE(3~5분)가 구 BE(10~25분)를 호출해 404·undefined가 났습니다.
  • 마이그레이션은 성공했는데 ECS 배포가 실패하면, 새 스키마를 구 코드가 만났습니다.
  • CloudFront 전체 무효화는 글로벌 엣지로 최대 15분 전파돼, 그동안 신·구 번들이 혼재했습니다.
  • 배포 실패 시 직전 Task Definition으로 자동 복구하는 로직이 없어 콘솔에서 손으로 되돌려야 했습니다.
문제해결
  • 분리돼 있던 3개 워크플로우를 하나로 합치고 job 의존성으로 배포 순서(BE → FE)를 강제했습니다.
  • 배포 실패 시 직전 ECS Task Definition으로 자동 롤백하도록 만들고, continue-on-error의 outcome/conclusion 차이를 이용해 실패를 정확히 감지했습니다.
  • CloudFront 캐시를 파일 특성별로 나눠, 해시 에셋은 1년 immutable·index.html은 no-cache로 두고 선별 무효화했습니다.
  • 마이그레이션에서 DROP을 금지하고 ADD-only로 두어 롤백 시 구 코드 크래시 위험을 줄였습니다(근본책 아닌 완충재로 한정).
통합 워크플로 — BE→FE 순서를 job 의존성으로 강제
통합 워크플로 — BE→FE 순서를 job 의존성으로 강제
CloudFront 차등 캐시 — 해시 immutable · index.html no-cache
CloudFront 차등 캐시 — 해시 immutable · index.html no-cache
결과
  • packages 변경 시 FE가 구 BE를 호출하던 레이스 컨디션을 없앴습니다.
  • 배포가 실패해도 직전 안정 버전으로 자동 복구되게 했습니다.
  • 해시 에셋 영구 캐시·index.html no-cache로 캐시 전파 지연을 없애 배포 즉시 반영되게 했습니다.
실제 실행 — Detect → Backend → Batch·Frontend 순서 강제
실제 실행 — Detect → Backend → Batch·Frontend 순서 강제
↗ 블로그 · 배포 파이프라인 개선 시리즈
GitHub Actions · AWS ECS · CloudFront · Docker
LLM 구조화 추출 (SWING) 2026
백엔드·풀스택
장문 공고·문서 PDF를 LLM으로 파싱해 등록 폼을 자동으로 채우는 기능입니다. 핵심은 추출이 아니라, 모델이 뱉은 JSON을 검증 없이 저장하지 않는 설계였습니다 — 형식은 스키마로 강제하고, 값은 화이트리스트·길이 제한으로 거르고, 신뢰도는 등급으로 표시해 사람이 마지막에 확인하게 했습니다.
컨텍스트장문 PDF 50~100p출력 안정responseSchema 강제프로바이더Strategy로 교체 가능
문제정의
  • 정부지원사업 공고는 50~100페이지 PDF가 흔해, 사용자가 사업명·주관기관·접수기간·예산을 손으로 옮겨 적었고 누락·오입력이 잦았습니다.
  • LLM은 그럴듯한 JSON을 잘 뱉지만, 가끔 코드펜스·설명을 붙여 파싱을 깼고, 형식이 맞아도 값(분류·길이)이 틀린 답을 자신 있게 내놓았습니다.
  • 검증 없이 모델 출력을 DB에 넣으면 모델의 헛소리가 그대로 데이터가 됐습니다.
  • 소스가 URL·파일·텍스트로 갈렸고, 운영 인증을 API Key에서 서비스 계정으로 옮길 필요도 있었습니다.
문제해결
  • 장문 공고를 통째로 넣기 위해 1M 토큰 컨텍스트의 Gemini를 채택하되, IAiProvider 인터페이스(Strategy)로 추상화해 환경변수 하나로 프로바이더를 교체하도록 했습니다.
  • JSON을 프롬프트로 부탁하는 대신 responseMimeType·responseSchema로 출력 구조를 API 제약으로 강제해 파싱 실패를 사실상 없앴습니다.
  • 열거형은 화이트리스트로 받아 모델이 없는 값을 지어내면 ETC로 폴백하고, varchar 필드는 서비스 레이어에서 truncate해 저장 에러를 막았습니다.
  • 핵심 5필드 추출 여부로 confidence(high/medium/low)를 매기고, 추출 결과를 곧장 저장하지 않고 편집 가능한 폼에 prefill해 사람이 확인 후 등록하게 했습니다.
  • URL은 HEAD로 타입을 보고 PDF/HTML을 분기, 파일은 S3 버퍼를 base64로, 텍스트는 길이 제한으로 전처리한 뒤 같은 추출 경로로 모았습니다.
AI 구조화 추출 — 소스 분기·프로바이더 추상화·신뢰 방어, 그리고 Vertex 마이그레이션
AI 구조화 추출 — 소스 분기·프로바이더 추상화·신뢰 방어, 그리고 Vertex 마이그레이션
결과
  • 스키마 강제로 JSON 파싱 실패가 사실상 사라졌고, 화이트리스트·truncate로 모델 오류가 저장 에러로 번지지 않게 했습니다.
  • AI를 최종 권위가 아니라 빈 칸을 채우는 보조로 두어, confidence 배지와 편집 가능한 prefill로 사람이 마지막에 검증하게 했습니다.
  • 모델을 인터페이스 뒤로 숨긴 덕에, AI Studio SDK(API Key)에서 Vertex AI SDK(서비스 계정)로의 전환을 프로바이더 구현 파일 교체만으로 끝냈습니다.
↗ 블로그 · AI가 채운 칸을 그대로 믿지 않는다
NestJS · Gemini · Vertex AI · AWS S3 · TypeScript · React
투자일임 수수료 정산·청구 (160) 2025.02 – 2025.04
백엔드·기획
IPO 청약–매도 일임의 운용 보수를 정산·청구하는 시스템입니다. 수수료 정책을 성과보수에서 건당 정액으로 바꾸면서 기존·신규 정책을 동시에 지원하고, CMS 자동출금이체로 청구를 자동화했습니다.
청구 주기6개월 → 3개월수수료 정책구·신 병행 2종청구 수단CMS 자동출금
문제정의
  • 수수료 정책을 성과보수(수익률 기반)에서 건당 정액으로 바꾸기로 했는데, 기존 계약자는 약관상 이전 정책을 유지해야 했습니다.
  • 청구 주기를 6개월에서 3개월로 단축하면서 정산 기준 기간과 대상 산정이 함께 바뀌었습니다.
  • 수수료를 고객 계좌에서 직접 출금하므로, 계좌 등록·본인인증·동의의 법적 흐름과 계좌 정보 보안이 필요했습니다.
  • 정책이 바뀌면 기존 동의가 무효가 되어, 대상자에게 재동의를 받아야만 청구할 수 있었습니다.
문제해결
  • 투자내역을 적용 정책별(성과보수/건당 정액)로 분리해, 같은 정산 배치에서 각각의 기준으로 계산하도록 설계했습니다.
  • 기간 경계로 매도 투자내역을 필터링해 해당 주기의 수익만 정산하고, 소액 건은 면제 기준으로 걸러냈습니다.
  • CMS 자동출금이체를 연동해 계좌 등록·ARS 본인인증·동의서 PDF 생성을 처리하고, 계좌번호는 암호화해 저장했습니다.
  • 정책 변경 대상자를 추려(계약 보유·신정책 미동의·연락처 보유) 재동의 요청을 메일·알림톡으로 발송하고, 미동의자를 거르는 배치를 두었습니다.
  • 수수료 청구·보고 메일은 Bull Queue로 비동기 발송해 API 응답과 분리했습니다.
계약 시점이 정책을 가른다 — 기본·성과·혼합 결정 트리와 정산·출금 흐름
계약 시점이 정책을 가른다 — 기본·성과·혼합 결정 트리와 정산·출금 흐름
결과
  • 두 수수료 정책을 무중단으로 병행 운영하며, 기존 계약자 약관을 깨지 않고 신규 정책을 적용했습니다.
  • 분기 단위 정산·청구를 사람 개입 없이 자동 처리했습니다.
  • 계좌 등록부터 출금까지의 법적·보안 흐름(본인인증·동의·암호화)을 시스템화했습니다.
계약시점→정책 매핑과 정책별 청구액 산정 — 정산 시트(더미 데이터)
계약시점→정책 매핑과 정책별 청구액 산정 — 정산 시트(더미 데이터)
NestJS · TypeORM · PostgreSQL · Redis · Bull Queue
주요 증권사 일임계약 (160)
백엔드·기획
공모주 정보 제공과 청약–매도 일임 서비스의 백엔드입니다. 증권사 API 기반 일임계약 프로세스를 설계하고, 상태 정합성과 동시성 문제를 해결했습니다. 전체 6개 증권사 연동 중 하나·한국투자·KB·삼성 4사를 담당했습니다.
담당 증권사4사 (전체 6사)운용 앱13개
문제정의
  • 증권사 API 기반 일임계약의 상태를 컨트롤하기 어려웠습니다.
  • 계약 상황에 따라 고객 화면이 달라, 화면이 의미하는 정보와 실제 데이터의 정합성을 보장해야 했습니다.
  • 증권사 API·웹뷰에 종속적인 로직이라, 계약 완료 시점의 데이터를 충분히 보장하기 어려웠습니다.
  • 무중단 배포 시점과 증권사별 업무·중단 시간을 동시에 맞춰야 했습니다.
  • monolithic 레포는 CI/CD엔 유리했지만 서버–도메인 간 소통이 어려웠습니다.
문제해결
  • SOLID를 지킨 API와 응답 비교 테스트 코드를 작성해, 에러 케이스 응답을 국제 표준 규격으로 반환했습니다.
  • 증권사·에러 케이스별 뷰 테이블을 설계해 고객 상태·정보를 케이스에 맞춰 매핑했습니다.
  • 증권사 업무 중단 시 오류 상태 대기값을 queue로 처리하고, 중단 후 증권사 API로 resolve하는 로직을 작성했습니다.
  • 계약 과정의 동시성을 DB-lock 대신 Redis key-value로 진행 과정을 기록·판단하도록 바꿔 어드민 성능 문제를 해결했습니다.
  • 백엔드에서 먼저 확인 가능한 외부·내부 요인(증권사 API, DB 가용성·정합성)을 파악해 세미 기획안을 기획·디자인에 전달했습니다.
  • Bull Queue·Redis Producer–Consumer 구조로 10여 개 서버 간 통신을 구축하고, 외부 통신은 AWS SQS로 처리했습니다.
일임계약 백엔드 — 증권사별 상태기계·상태/뷰 매핑, Redis 락 동시성, Bull Queue·SQS 비동기
일임계약 백엔드 — 증권사별 상태기계·상태/뷰 매핑, Redis 락 동시성, Bull Queue·SQS 비동기
결과
  • 증권사의 Spring 규격 통신을 NestJS로 받아 고객 상태를 추적하고 어드민 응대를 정확히 했습니다.
  • 계약·청약 데이터를 DB에 정확히 적재하고, 계약 과정의 동시성 문제를 해결했습니다.
  • 복잡했던 초기 플로우를 정리·문서화하고, FE·기획과 회의를 이끌어 deprecated 엔드포인트를 정리했습니다.
  • 불필요한 로직·쿼리를 걷어내 핵심 경로만 남기는 방식으로 응답 속도를 개선했습니다.
  • 사용률에 따라 노드 배치를 달리해 서버 가용성을 높였습니다.
NestJS · REST API · k8s · TypeORM · PostgreSQL · Redis · NCP