Resume portfolio

Mail

백종환

Frontend Engineer

복잡한 운영 문제를 구조로 풀고,제품의 시작부터 결과까지 책임집니다.

React·Next.js 기반 실서비스를 신규 구축하고 운영하며, 복잡한 상태와 실패 비용이 큰 흐름을 다뤄왔습니다.

LMS
7개 역할과 제한 시간 평가, HLS, 12~14GB 업로드를 화면별 예외가 아닌 공통 경계로 설계했습니다.
통합 계정
4,000명의 기존 로그인을 유지해 이관하고, 첫 장애를 약 1시간 안에 복구한 뒤 재전환했습니다.
홈페이지
대표 미디어를 67.5MB에서 3.1MB로 줄이고, LCP를 3.1초에서 1.1초로 개선했습니다.
Develog
학습 기록 문제를 제안해 약 한 달 만에 출시하고, 선택 사용 환경에서 341개 글과 검색 클릭 3,224회를 확인했습니다.
백종환 프로필 사진

경력 기록

경력과 성장 흐름

경력

2023.09.25 - 2026.08.31

디벨로켓에듀 · 스마트 훈련 플랫폼 개발팀 / 프론트엔드

LMS V2·V3 프론트엔드 신규 구축과 운영을 중심으로 통합 계정, 모집 백오피스, 기업 홈페이지, 학습 기록 제품을 개발했습니다. 기획·디자인·백엔드·인프라·운영 담당자와 기능의 책임 경계를 조율했습니다.

교육

2023.10 - 2026.08

학점은행제(국가평생교육진흥원) · 컴퓨터공학전공

컴퓨터공학 전공 학위를 이수했습니다.

2022.10 - 2023.07

경일게임아카데미 · 웹 개발/블록체인 과정

HTML, CSS, JavaScript의 동작 원리부터 React, Node.js와 Solidity를 학습하고 팀 프로젝트와 해커톤을 경험했습니다.

2013.03 졸업

오금고등학교 · 이공계열

기초 학력 사항입니다.

프로젝트 기록

결과와 판단을 함께 남긴 일

프로젝트 01복잡한 상태와 미디어 운영

LMS V2·V3 프론트엔드 신규 구축 및 운영

역할·평가·영상·파일 업로드처럼 운영 중 반복해서 어긋날 수 있는 상태를 명시적인 경계와 복구 가능한 흐름으로 정리했습니다.

기간
2023.09 - 2026.08
역할
프론트엔드 신규 구축·운영 담당 · BE·Designer·Infra와 협업
ReactNext.jsTypeScriptTanStack QueryZustandS3HLS

문제 상황

학생·교강사·운영자가 함께 사용하는 LMS에서는 역할과 과정 상태에 따라 같은 기능도 접근 가능 여부와 표시 정보가 달랐습니다. 화면마다 조건문을 추가하면 권한 정책과 캐시가 서로 다른 기준을 갖기 쉬웠습니다.

제한 시간 평가는 새로고침과 뒤로가기에서 답안·현재 문제·남은 시간이 어긋날 수 있었고, 영상은 이용 증가에 따라 비용과 재생 문제가 함께 커졌습니다. 프로젝트·평가·실습에는 10GB가 넘는 파일도 사용됐습니다.

해결 목표

권한과 평가 규칙을 개별 화면의 예외 처리가 아니라 역할·서버 상태·로컬 작성 상태의 경계로 관리하고자 했습니다.

영상과 업로드는 정상 경로뿐 아니라 브라우저 자원, 네트워크 실패와 화면 전환까지 고려해 운영 가능한 구조로 만드는 것을 목표로 했습니다.

판단과 실행

01

7개 역할과 복수 역할을 공통 구조로 관리

ADMIN, COORDINATOR, PROFESSOR, CONTENT_MANAGER, CAREER_MANAGER, CREW, MEMBER를 중앙 설정에서 관리했습니다. 사용자 정보의 roles 배열과 우선순위를 기준으로 최초 진입 경로를 정하고, 보유 역할 사이를 명시적으로 전환하게 했습니다.

공통 RoleGuard와 역할별 query cache를 적용했습니다. 다만 프론트엔드의 화면 진입 제어이며 모든 API의 최종 인가를 대신한다고 확대하지 않았습니다.

02

제한 시간 평가의 서버 상태와 작성 상태를 분리

평가 시작 여부와 제한 시간은 서버의 startedAt, timeLimit과 status를 기준으로 계산했습니다. 시작 API 성공 뒤 문제를 열고, 화면 타이머는 표시를 갱신하면서 서버 상태를 주기적으로 다시 동기화했습니다.

작성 중인 답변과 문제 위치는 같은 기기에서 복원할 수 있게 했습니다. 서버 자동 저장이나 파일 답안까지 완전히 복원하는 구조는 아니라는 경계도 함께 두었습니다.

03

브라우저 POC 뒤 HLS 전달 구조를 협업 선택

ffmpeg WASM 변환 POC로 구현 가능성과 브라우저 자원 비용을 확인했습니다. 긴 변환 시간과 자원 점유를 업로더에게 전가하지 않기 위해 운영안에서는 제외했습니다.

인프라 담당자가 MediaConvert·S3·CloudFront를 구성하고, 프론트엔드는 변환 상태와 결과 URL을 제품 흐름에 연결했습니다. 완료 전 MP4, 완료 후 HLS를 재생하는 fallback과 공통 플레이어 인터페이스를 구성했습니다.

04

화면 전환 뒤 남던 요청과 대용량 업로드를 복구 가능하게 처리

영상 A에서 B로 이동한 뒤 두 contentId의 진도 요청이 함께 발생하는 문제를 Network payload로 재현했습니다. 대상이 바뀌면 이전 interval을 정리해 현재 영상 요청만 남도록 수정했습니다.

10MB 미만은 일반 업로드, 그 이상은 Multipart로 분기했습니다. 1GB 초과 파일은 part 수가 약 500개 이내가 되도록 크기를 계산하고, 실패한 part만 새 서명 URL로 최대 4회 재시도했습니다.

결과와 검증

  • 과정당 약 50~75명, 동시에 2~4개 과정이 운영되는 범위에서 V2·V3 프론트엔드를 구축·운영했습니다.
  • 7개 역할과 복수 역할의 우선순위·기본 경로·전환 흐름을 공통 기준으로 관리했습니다.
  • 영상 이동 시 서로 다른 contentId로 발생하던 진도 요청을 현재 콘텐츠 한 건으로 줄였습니다.
  • 12~14GB 실제 영상 파일의 업로드 완료를 확인했습니다.
  • HLS 전환 뒤 비용과 재생 경험이 안정됐다는 협업자·운영자의 정성 피드백을 확인했습니다.

배운 점

복잡한 프론트엔드 문제는 조건문의 수보다 역할, 서버 상태, 로컬 작성 상태와 자원 생명주기의 경계가 불분명할 때 커졌습니다.

기술 선택에서도 구현 가능성만 보지 않고 비용이 사용자·브라우저·서버·운영 조직 중 어디에 발생하는지를 함께 판단하게 됐습니다.

프로젝트 02인증 마이그레이션과 복구

사내 통합 계정 구축 및 기존 사용자 이관

기존 사용자의 ID와 비밀번호를 유지하면서 계정을 통합하고, 첫 전환 실패를 빠르게 되돌린 뒤 신원과 서비스 데이터의 책임을 다시 나눴습니다.

기간
2026.06 - 2026.08
역할
계정 애플리케이션·스키마·인증 호환·이관 담당 · 운영 전환 협업
Next.jsTypeScriptPrismaOAuth2SSOAuth.js

문제 상황

홈페이지·LMS·백오피스의 계정 체계를 통합하면서 기존 사용자가 비밀번호를 다시 설정하거나 새로운 사용자로 인식되지 않게 해야 했습니다.

이메일이 같아도 동일인이라고 단정할 수 없는 충돌 계정이 있었고, 잘못된 자동 병합은 다른 사용자의 데이터 접근으로 이어질 수 있어 편의보다 정확성과 복구 가능성이 중요했습니다.

해결 목표

사용자 신원과 서비스별 역할·수강 데이터를 분리하면서 기존 ID와 비밀번호 hash를 보존하는 것을 목표로 했습니다.

새 인증 경로에서 문제가 생겨도 기존 로그인으로 빠르게 돌아갈 수 있는 실제 복구 경로를 유지하고자 했습니다.

판단과 실행

01

신원과 서비스 컨텍스트의 소유권 분리

통합 계정은 신원, credential, social identity와 본인인증을 소유하고 각 서비스는 역할·수강 정보 같은 도메인 데이터를 소유하도록 나눴습니다.

소셜 계정은 이메일이 아니라 provider와 providerUserId 조합으로 식별하고 credential·role·탈퇴 이력을 관계 모델로 분리했습니다.

02

기존 계약을 유지한 단계적 전환

기존 사용자 UUID와 비밀번호 hash를 보존하고, 레거시 로그인 proxy와 accounts native 인증 경로를 함께 유지했습니다.

이메일만으로 동일인임을 증명할 수 없는 계정은 자동 병합하지 않고 별도 확인 대상으로 분리했습니다.

03

첫 cutover 실패를 복구하고 책임 경계 재설계

첫 v2 전환에서 신규 LMS 사용자의 token 생성이 accounts가 소유하지 않는 서비스 정보에 의존해 실패했습니다. 장애 상태를 유지한 채 전면 수정하지 않고 개발팀 접수 후 약 1시간 안에 v1으로 복구했습니다.

이후 인증 서버에 LMS 데이터를 결합하지 않고 신원 확인 뒤 각 서비스가 필요한 컨텍스트를 조회·생성하도록 보완해 재전환했습니다.

결과와 검증

  • 약 4,000명의 기존 사용자 ID와 비밀번호 hash를 보존한 계정 이관을 수행했습니다.
  • 동일인 확인이 어려운 이메일 충돌 계정 10명 미만을 자동 병합에서 제외했습니다.
  • 첫 전환 실패를 개발팀 접수 후 약 1시간 안에 기존 v1 로그인으로 복구했습니다.
  • 보완 후 재배포했으며 같은 로그인 문제는 다시 보고되지 않았습니다.

배운 점

인증 전환은 로그인 화면 교체가 아니라 사용자 식별 경계, 데이터 소유권과 실패 복구를 함께 설계하는 문제였습니다.

정상 전환만큼 token 수명과 폐기, 추적 가능한 감사 로그 같은 운영 안전장치를 단계적으로 갖춰야 한다는 기준을 얻었습니다.

프로젝트 03문제 정의부터 운영 지표까지

Develog 기획·개발·출시 및 운영

LMS 안에서 사라지던 TIL을 공개 성장 기록으로 바꾸는 문제를 제안하고, 약 한 달 안에 기록·발견·축적·공유가 이어지는 제품을 출시했습니다.

기간
2026.02 - 2026.08
역할
제품 기획·애플리케이션 개발 주도 · 초기 레이아웃·배포 환경 협업
Next.jsTypeScriptPrismaTiptapMarkdownGA4Search Console서비스 보기

문제 상황

기존 LMS의 TIL은 로그인한 과정 참여자만 볼 수 있어 수료 후 외부 포트폴리오나 지속적인 학습 기록으로 연결되기 어려웠습니다.

정해진 기획을 전달받은 프로젝트가 아니어서 어떤 사용자의 문제를 해결할지, 한 달 안에 어디까지 구현해야 제품 가치가 완결되는지, 출시 후 무엇으로 사용 여부를 판단할지 직접 정해야 했습니다.

해결 목표

기록이 피드에서 발견되고 프로필에 축적되며 성장과 관심사를 시각화한 뒤 URL로 공유되고 다시 기록으로 돌아오는 제품 루프를 목표로 정했습니다.

제품 기획과 애플리케이션 코드는 직접 담당하고 초기 큰 레이아웃과 배포 환경은 각 담당자에게 요청해 약 한 달의 일정 안에서 범위를 완결하고자 했습니다.

판단과 실행

01

약 한 달 안에 완결된 제품 루프 구현

글 작성·상세, 피드, 프로필, 활동 히트맵, 태그 그래프, 좋아요·댓글과 검색을 초기 범위로 정했습니다. 2026년 2월 중순 데이터 모델부터 API와 사용자 화면을 구현해 3월 말 공개 준비와 사용자 보정을 마쳤습니다.

스트릭, 집중 타이머와 SSO 전환은 최초 MVP 이후의 기능으로 시간순서를 분리했습니다.

02

Markdown의 이식성과 WYSIWYG 편집을 연결

Tiptap 입력과 Markdown 저장을 결합하고, 붙여넣은 Markdown은 marked에서 HTML, ProseMirror DOM parser로 변환했습니다.

단순 표는 GFM으로 저장하고 이미지 속성과 복잡한 표는 HTML fallback으로 보존했습니다. 완전한 round-trip을 보장한다고 표현하지 않고 저장 형식의 차이를 명시적으로 다뤘습니다.

03

유실 피드백을 30초 자동 임시저장으로 연결

뒤로가기로 작성 내용이 사라졌다는 피드백 뒤 기존 Post의 unpublished 상태를 재사용해 변경된 본문을 약 30초마다 저장하고 프로필에서 다시 열게 했습니다.

debounce나 실시간 저장이 아니며 빈 본문과 업로드 전 blob 이미지에는 현재도 보완할 경계가 남아 있습니다.

04

검색 유입과 제품 행동을 다른 지표로 관찰

동적 sitemap, metadata·canonical, Person·BlogPosting·BreadcrumbList JSON-LD와 crawler policy를 구현했습니다. Search Console의 노출·클릭과 GA4의 제품 행동·source/medium을 분리했습니다.

18주 누적 검색 노출 70,841회와 클릭 3,224회, WAW 3~11명을 운영 지표로 확인했습니다. 생성형 AI 노출 704회는 방문으로 환산하지 않았고 AI Overview는 한 사례로만 기록했습니다.

결과와 검증

  • 2026년 2월 중순 착수해 약 한 달간 집중 구축하고 3월 말 초기 제품을 공개했습니다.
  • 2026-08-31 기준 가입 계정 약 100개와 게시글 341개가 누적됐습니다. 가입자는 대부분 학생·직원이며 외부 자연 유입 100명으로 표현하지 않습니다.
  • 18주 주별 활성 작성자 WAW는 3~11명이었고 Search Console 누적 노출 70,841회·클릭 3,224회를 별도 지표로 확인했습니다.
  • GA4에서 Gemini·ChatGPT·Perplexity referral과 Google AI Overview 참고 출처 한 사례를 관찰했습니다.

배운 점

제품을 주도한다는 것은 기능 수가 아니라 문제를 정의하고 제한된 시간 안에서 가치가 완결되는 범위를 선택하며, 공개 이후 행동을 다음 판단으로 연결하는 일이었습니다.

검색 노출·클릭·WAW·제품 행동을 서로 다른 신호로 관리하고 확인하지 못한 인과관계는 성과로 주장하지 않는 기준을 갖게 됐습니다.

프로젝트 04측정 기반 브라우저 성능

기업 홈페이지 리뉴얼 및 미디어 성능 개선

Lighthouse에서 시작해 Network와 Performance로 병목을 좁히고, 정적 배포에 맞는 미디어 변환·fallback·검색 기본기를 구성했습니다.

기간
2025.06 - 2025.07
역할
프론트엔드 기술 선택·구축·초기 운영 담당 · 디자인·콘텐츠·배포 협업
Next.jsTypeScriptTailwind CSSLighthouseFFmpegGTM

문제 상황

외주 PHP 홈페이지를 사내에서 유지·확장하기 어려웠고, 시각 콘텐츠 비중이 큰 첫 화면의 대용량 미디어가 렌더링을 지연시키고 있었습니다.

정적 배포 구조에서 콘텐츠 담당자의 작업 흐름을 유지하면서 미디어를 가볍게 만들고 검색엔진이 페이지 정보를 이해할 수 있는 기본 구조도 정리해야 했습니다.

해결 목표

조직이 유지할 수 있는 React·Next.js 기반으로 프론트엔드를 재구축하고, 체감이 아니라 같은 조건의 측정값으로 성능 개선 대상을 선택하고자 했습니다.

별도 runtime 변환 서버 없이 배포 전에 미디어를 변환하고 브라우저 호환 fallback을 제공하는 운영 흐름을 목표로 했습니다.

판단과 실행

01

Lighthouse에서 Network로 병목을 좁힘

Lighthouse로 LCP를 확인하고 Network에서 초기 화면의 대용량 GIF를 병목 후보로 좁혔습니다. Performance로 다른 렌더링 병목을 함께 확인한 뒤 미디어 형식을 우선 개선했습니다.

대표 파일을 WebM으로 변환하고 MP4 fallback을 두었습니다. 현재 hero source에도 WebM 우선·MP4 fallback 구조가 남아 있습니다.

02

정적 배포에 맞는 사전 변환 도구와 문서 제공

별도 변환 서버 대신 FFmpeg CLI로 GIF·MP4를 H.264 MP4와 VP9 WebM으로 만드는 배포 전 도구를 구성했습니다.

설치, 출력 형식, 품질 조정, 배치 처리와 문제 해결 방법을 문서화해 콘텐츠 작업자가 같은 규칙을 반복 적용할 수 있게 했습니다.

03

검색과 계측의 기본 구조 정리

sitemap, robots.txt, 페이지별 title·description과 OG 이미지를 정비했습니다. 전환 추적 스크립트와 GTM 기본 POC를 연결하고 설정 방법을 마케팅 담당자에게 안내했습니다.

canonical·JSON-LD·AEO/GEO나 결제 퍼널 전체를 이 프로젝트의 개인 성과로 확대하지 않았습니다.

결과와 검증

  • 여러 미디어 중 대표 파일 한 건을 67.5MB에서 3.1MB로 줄였습니다.
  • 동일한 데스크톱 환경에서 Lighthouse LCP 대표값을 3.1초에서 1.1초로 확인했습니다.
  • Lighthouse SEO 대표값을 58점에서 92점으로 확인했습니다.
  • WebM·MP4 변환 도구와 운영 문서를 만들어 초기 구축 이후의 반복 작업 기준을 남겼습니다.

배운 점

브라우저 성능은 코드만이 아니라 첫 화면 자원, 렌더링 순서와 콘텐츠 제공 흐름을 함께 측정해야 하는 문제였습니다.

이후에는 단일 최고 점수보다 측정 대상과 조건을 먼저 고정하고, 공통화도 외형보다 변경 주기와 요구 수렴 정도를 기준으로 판단하게 됐습니다.

프로젝트 05운영 규칙을 제품 구조로 전환

모집·운영 백오피스 구축 및 고도화

엑셀·전화·외부 캘린더에 흩어진 모집 업무를 지원자의 상태·이력·담당자·다음 행동이 이어지는 하나의 운영 흐름으로 바꿨습니다.

기간
2024.10 - 2026.08
역할
모집 CRM 프론트엔드 흐름 담당 · 영업·모집·백엔드와 업무 모델 협업
Next.jsTypeScriptTanStack QueryCASLS3

문제 상황

모집 담당자는 전화로 상담하고 결과를 엑셀에 기록했으며 일정은 외부 캘린더에서 관리했습니다. 정보가 담당자별 문서에 흩어져 이전 상담과 다음 행동을 이어보기 어려웠습니다.

같은 지원자도 현재 단계와 연락 가능성에 따라 필요한 행동이 달랐습니다. 기존 문서를 화면으로 옮기는 것만으로는 예외 상태와 인수인계 문제를 해결할 수 없었습니다.

해결 목표

지원자 한 명의 유입부터 과정 합류까지 현재 상태, 변경 이유, 담당자와 다음 행동을 추적할 수 있는 운영 도구를 만들고자 했습니다.

운영자가 같은 조회 조건과 상세 맥락을 동료에게 넘길 수 있도록 화면 상태와 서버 조회 상태를 함께 구조화했습니다.

판단과 실행

01

업무를 캠페인과 지원자 관계로 모델링

엑셀의 한 행을 복제하지 않고 캠페인, 지원자, 담당자, 모집 상태와 이력, 상담 예약, 체크리스트와 과정의 관계로 정의했습니다.

정상 퍼널과 별도로 재컨택·대기/관리·부재/관리처럼 다음 행동이 다른 예외 상태를 분리했습니다. 현재 구조는 5개 상위 단계와 27개 상태 라벨로 업무 상황을 표현합니다.

02

상담 맥락과 다음 행동을 상세 화면에 연결

신청서·캠페인·담당자·체크리스트·상담 일정·상태와 메모 이력을 지원자 상세에서 이어보게 했습니다. 예약 현황과 입력 영역을 인접 배치해 빈 시간을 본 흐름에서 상담을 등록하게 했습니다.

상태 변경 시 사유·알림 여부·첨부를 함께 전송하고 성공 후 지원자와 이력 query를 갱신했습니다. 상태 변경의 맥락과 일반 메모는 서로 다른 운영 기록으로 다뤘습니다.

03

조회 조건을 URL과 query cache에 함께 반영

검색어·기간·단계·복수 상태·page를 URL로 표현하고 전체 query string을 TanStack Query key에 포함했습니다.

동료가 같은 화면과 조건을 공유할 수 있게 했지만 일부 필터 변경에서 page가 초기화되지 않는 사용성 과제도 남겼습니다.

결과와 검증

  • 모집 실무자 약 2~3명이 지원자 한 명의 상담과 후속 행동 맥락을 한 화면에서 확인했습니다.
  • 이전 상담 이력과 메모를 후속 상담과 담당자 인수인계에 활용할 수 있게 했습니다.
  • 외부 캘린더와 입력 화면을 오가던 예약 흐름을 지원자 상세 맥락에 연결했습니다.

배운 점

백오피스 복잡도는 화면 수보다 운영 규칙과 예외 상태에서 발생했습니다.

모든 기능을 완성도 높게 확장하기보다 실제 사용자 수와 우선순위를 고려해 사용자-facing 프로젝트를 먼저 선택했고, 일부 필터 개선은 기술 부채로 남겼습니다.