웹과 모바일을 함께 다루는 프론트엔드 개발자
Next.js 기반의 웹 서비스를 개발하여 Flutter WebView 기반의 앱을 운영하고 있습니다. 웹을 이용해 새로운 서비스를 빠르게 배포하고, Flutter와 Next.js 간의 핸들러 처리로 앱 업데이트를 최소화하는 구조를 만들었습니다.
Frontend Developer
보이는 화면 아래의 문제까지 바라보는 프론트엔드 개발자 김예지입니다.
Next.js 기반의 웹 서비스를 개발하여 Flutter WebView 기반의 앱을 운영하고 있습니다. 웹을 이용해 새로운 서비스를 빠르게 배포하고, Flutter와 Next.js 간의 핸들러 처리로 앱 업데이트를 최소화하는 구조를 만들었습니다.
유저가 이용하는 화면뿐만 아니라 운영자가 서비스를 관리할 때 사용하는 Admin 기능, 오프라인 행사에서 사용하는 모니터링 기능 또한 개발했습니다. 반복적으로 개발팀에게 요청되던 업무를 운영자가 직접 처리할 수 있도록 개선했습니다.
기기 성능, 네트워크 상태, 파일 형식에 따라 달라지는 문제에 대응하며 수집 방식과 실패 이후의 처리 방법을 설계했습니다. 재현하기 어려운 문제도 로그를 통해 발생 조건을 좁히고, 팀원들과 대응 방식을 의논해 서비스에 반영했습니다.
WORK
웹과 모바일 서비스를 개발하고, 출시 이후 발생하는 사용자 이슈와 운영상의 문제를 해결하며 서비스를 개선해왔습니다.
Flutter 앱 기능을 Next.js 기반 WebView로 이관하고 Native 연동 기능 개발
온라인 및 오프라인 FGT를 위한 녹화 런처와 운영 모니터링 환경 구축
관리자 페이지와 게임 결과 리포트 등 서비스 운영 도구 개발
사용자 문의와 로그, API, DB 데이터를 기반으로 서비스 장애 원인 추적 및 개선
Android와 iOS 환경 차이와 7개 언어 서비스 대응
EDUCATION
1600시간의 소프트웨어 교육 및 4회의 팀 프로젝트 우수 수료(상위 30%) · 팀 프로젝트 2회 수상
스나이퍼팩토리
기존 서비스 개선을 주제로 Next.js 기반의 팀 프로젝트 수행
JavaScript를 기반으로 Linux·프로세스·동기화 등 CS 문제 해결
기계시스템디자인공학과
온라인, 오프라인 게임 테스트를 위한 데이터 수집과 현장 운영 시스템
온라인 사용자 환경과 여러 좌석이 동시에 운영되는 오프라인 현장에서 플레이 데이터를 수집하고, 진행 중 발생하는 문제를 모니터링·복구할 수 있는 런처와 운영 도구를 개발했습니다.
온라인·오프라인 플레이 화면과 사용자 반응 데이터 → 게임별 분석 리포트 제작에 활용
기술스택Flutter · Android Native · ADB · scrcpy · FFmpeg · S3 Multipart Upload · Next.js
글로벌 FGT 운영 시스템
한 번 진행한 플레이를 다시 요청하기 어렵다는 점을 기준으로, 문제가 생겨도 테스트를 이어가고 이미 생성된 데이터는 최대한 남길 수 있도록 개선했습니다.
01 / VIDEO PROCESSING
변환 완료보다 원본 데이터 확보를 우선했습니다.
일부 Android 기기에서 미리보기용 영상 변환이 멈춰, 플레이를 끝낸 사용자가 다음 단계로 진행하지 못하는 문제가 있었습니다. 모든 기기의 변환 성공을 기다리기보다 원본 TS를 먼저 업로드해 테스트를 완료할 수 있도록 했고, 실패 건만 관리자가 로컬에서 변환해 재업로드할 수 있는 복구 기능을 만들었습니다. 빈도가 낮은 예외를 서버에서 상시 처리하기보다, 원본 확보 후 필요한 건만 복구하는 방식을 선택했습니다. 변환 실패가 테스트 완료 자체를 막지 않도록 흐름을 분리했습니다.
02 / PERMISSION
사용자가 권한 구조를 이해하는 대신 런처가 현재 상태를 판단하도록 했습니다.
테스트 시작 전에 필요한 Android 권한과 설정이 많아, 사용자가 직접 상태를 확인하고 설정 화면을 찾아야 하는 과정이 복잡했습니다. 시작 시 현재 상태를 확인해 빠진 권한만 이어서 요청하고, 앱에서 다시 요청할 수 없는 경우에는 System Settings로 연결했습니다. 사용자가 Android 권한 구조를 직접 이해하고 해결해야 하는 구간을 줄였습니다.

03 / SESSION
일시적인 이탈을 바로 테스트 실패로 처리하지 않았습니다.
게임 종료, 앱 전환이나 녹화 중단으로 하나의 플레이가 여러 파일로 나뉘는 경우가 있었습니다. 게임이 화면에서 사라졌다고 즉시 종료하지 않고 복귀할 시간을 두고, 다시 시작된 데이터는 Session Key를 기준으로 같은 테스트에 연결했습니다. 초기에는 약 5분을 기다렸지만 실제 운영에서 너무 길다는 피드백을 반영해 1분으로 조정했습니다.
04 / PRIVACY
수집할 수 있는 범위보다 테스트에 필요한 범위를 기준으로 삼았습니다.
테스트 중 다른 앱으로 이동하거나 개인적인 알림을 확인할 수 있어, 게임과 관계없는 화면까지 기록될 가능성이 있었습니다. 대상 게임이 아닌 화면은 녹화에서 제외하고 복귀를 기다리도록 했으며, 알림도 발생한 앱만 식별하고 메시지 내용은 기록하지 않았습니다. 기술적으로 수집 가능한 범위와 실제 테스트에 필요한 데이터의 범위를 구분했습니다.
글로벌 FGT 운영 시스템
온라인 방식을 그대로 옮기지 않고 통제 가능한 환경을 활용했습니다.
오프라인에서는 테스트 기기와 PC를 직접 연결할 수 있었고, 화면, 카메라, 마이크, 터치 등 온라인보다 많은 데이터를 함께 수집해야 했습니다. 기존 PC Launcher에 Mobile FGT Process를 추가해 필요한 데이터를 하나의 테스트 단위로 수집하도록 구성했습니다. 같은 FGT라도 온라인과 오프라인의 환경 차이에 따라 수집 방식을 다르게 가져갔습니다.
글로벌 FGT 운영 시스템
사후 확인보다 테스트 중 대응을 우선했습니다.
여러 좌석의 테스트가 동시에 진행되다 보니 연결이나 녹화 문제가 생겨도 운영자가 즉시 알아차리기 어려웠습니다. 테스트 종료 후 발견하면 이미 진행한 플레이 데이터를 다시 얻기 어렵기 때문에, 운영에 필요한 상태를 정의하고 좌석별 연결, 녹화와 기기 상태를 한 화면에서 확인할 수 있는 모니터링 페이지를 구현했습니다.
실제 사용자가 이용하는 서비스 개발과 운영
기존 Flutter 앱의 서비스를 Next.js 기반 웹으로 전환하고 Flutter WebView와 연결했습니다. 게임 테스트와 설문, 프로필, 리워드 등 사용자 기능과 테스트 운영에 필요한 기능을 개발하고 있습니다.
개발팀과 서비스 요구사항을 구체화하고 화면 흐름과 UI를 설계했습니다. 프론트엔드 개발부터 배포 이후 발생한 문제의 개선까지 담당하고 있습니다.
기술스택Next.js · TypeScript · React Query · Zustand · Flutter · WebView
WEB TRANSITION
운영 중 기능이 변경되어도 앱을 다시 배포하지 않고 웹 배포만으로 빠르게 반영하기 위해 Flutter 앱에 직접 구현되어 있던 서비스 화면을 Next.js로 옮겼습니다.
01
게임 테스트와 설문, 프로필, 리워드처럼 변경이 잦은 기능을 Next.js로 옮기고 반응형으로 구현했습니다. 하나의 웹 서비스를 브라우저와 Flutter WebView에서 함께 제공하며 앱 업데이트가 필요한 범위를 줄였습니다.
WEB TRANSITION
02
Next.js를 화면 구현에만 사용하지 않고 클라이언트와 백엔드 사이의 공통 처리를 담당하는 서버 계층으로 활용했습니다. 로그인 이후 필요한 인증과 ID 처리를 화면마다 반복하지 않도록 Route Handler 기반의 API 프록시를 구성했습니다. 프록시에서 쿠키의 토큰을 읽어 Authorization 헤더로 변환하고, URL에 암호화해 사용하는 ID는 실제 백엔드 요청 직전에 복호화했습니다. Steam 계정 연동도 Next.js 서버를 거쳐 통신하도록 구성해 실제 백엔드 주소와 외부 서비스 연동 구조가 클라이언트에 직접 노출되는 범위를 줄였습니다.
HYBRID APP
서비스 화면은 웹으로 옮기되 사진과 파일, 앱 권한, 딥링크처럼 기기에 의존하는 기능은 Flutter와 연결했습니다. 웹에서 변경할 영역과 Native에서 처리할 영역을 실제 문제를 기준으로 나눴습니다.
01
종료되는 순간 전송할 수 없는 오류 정보를 다음 접속까지 남겼습니다.
간헐적으로 앱이 종료되거나 멈췄다는 문의가 들어왔지만, 사용자의 설명만으로는 발생 기기와 위치, 원인을 확인하기 어려웠습니다. Native에서 오류를 감지하면 오류 내용과 발생 위치, 기기 정보를 로컬에 먼저 저장하고, 다음 앱 실행 시 WebView로 전달하도록 진단 브릿지를 구현했습니다. 웹에서는 전달받은 로그에 로그인한 회원 정보를 연결해 서버로 전송하여, 사용자에게 기종과 당시 상황을 다시 확인하지 않아도 발생 조건을 추적할 수 있도록 했습니다.
GLOBAL SERVICE
국내 사용자 중심이던 서비스를 7개 언어로 확장했습니다. 번역 문구와 화면을 추가하는 데 그치지 않고, 브라우저와 Flutter WebView에서 언어를 일관되게 결정하고 백엔드까지 전달하는 흐름을 구성했습니다.
01
브라우저와 Flutter WebView에서 같은 언어 설정을 사용할 수 있도록 Middleware 기반의 처리 구조를 설계했습니다. 사용 환경에 따라 전달되는 언어 정보를 Next.js 서버에서 일관된 흐름으로 결정하고, API 프록시를 통해 백엔드까지 전달했습니다. 이후 서비스가 7개 언어로 확장되었을 때도 기존 요청 흐름을 변경하지 않고 언어 설정을 추가하는 방식으로 대응할 수 있었습니다.
02
화면에 직접 작성되어 있던 문구를 번역 데이터로 분리하고 선택한 언어에 맞게 제공했습니다. 문장이 길어져도 버튼과 안내 영역이 밀리거나 잘리지 않도록 레이아웃을 조정했습니다.

플레이 영상과 수집 데이터를 하나의 리포트로
여러 형태의 게임 데이터를 하나의 분석 화면으로 연결하고 게임사에서 확인할 수 있는 리포트로 정리했습니다.
01
플레이 중 문제가 발생한 상황을 파악하려면 영상과 여러 수집 데이터를 함께 살펴봐야 했습니다. 영상의 특정 시점에서 입력, 기기 상태, 성능 정보와 분석 구간을 함께 확인하도록 연결해 여러 데이터를 오가며 대조할 필요를 줄였습니다.

02
백엔드에서 완성된 결과를 받아 표시하는 대신, 생성과 검수를 단계별로 진행하는 흐름을 구성했습니다. 레퍼런스 게임을 선정하고 게임별 장점과 단점을 생성한 뒤 운영자가 검수합니다. 이를 기본 리포트 점수와 비교해 테스트 게임의 강점과 약점을 생성하고 다시 검수합니다. 각 단계의 결과를 확인하고 수정할 수 있으며, 최종적으로 정리된 JSON만 백엔드에 저장해 완성된 마켓핏 리포트를 확인하도록 했습니다. AI 프롬프트는 게임사 관련 업무 담당자와 협의해 실제 리포트 작성 기준에 맞게 설계했습니다.

03
여러 회차의 결과를 비교하려면 각각의 기본 리포트 데이터를 함께 확인할 수 있어야 했습니다. 프론트엔드에서 회차별 데이터를 필터링하고 조합해 여러 회차의 결과를 한 화면에서 비교할 수 있도록 구현했습니다.

국내 거주 외국인을 위한 다국어 레시피 추천 모바일 앱
팀 프로젝트 · 프론트엔드국내에 거주하는 외국인이 한국에서 구할 수 있는 식재료로 자국 요리를 만들어볼 수 있도록 AI 레시피 추천 기능을 제공했습니다.
무료 레시피 공공데이터와 제철 농산물 정보를 한국어, 일본어, 중국어와 영어로 확인할 수 있도록 구성했습니다. 식재료 가격 데이터를 차트로 제공해 요리에 필요한 재료의 시세를 함께 확인할 수 있도록 구현했습니다.


HTP 그림심리검사 결과에 따른 3D 마을형 심리 서비스
SSAFY 특화 프로젝트 · 우수상HTP 그림심리검사로 사용자의 심리 상태를 파악하고, 검사 결과에 따라 유형별 3D 마을을 탐색할 수 있도록 구성했습니다. 초기 화면과 메인 화면의 3D 모델을 렌더링하고 마을의 회전과 확대·축소 인터랙션을 구현했습니다.
사용자가 직접 그림을 그리고 설문에 응답할 수 있는 검사 화면을 구현해 HTP 그림심리검사 과정을 서비스 안에서 진행하도록 했습니다.


길드 레이드 신청과 파티 편성을 자동화한 운영 시스템
개인 프로젝트 · 실서비스 운영길드원들이 Google Form으로 주간 레이드 참여를 신청하면, 신청 데이터를 사이트에 등록해 운영자가 한곳에서 확인할 수 있도록 구성했습니다. 길드 운영진이 실제 파티를 편성하며 필요로 한 조건을 기준으로 화면과 흐름을 정리했습니다.
각 캐릭터의 전투력과 역할, 파티 구성 조건을 함께 고려해 레이드 파티를 자동으로 편성합니다. 신청 명단을 확인하고 파티를 직접 조합하던 주간 운영 작업을 줄였습니다.
편성이 끝난 파티는 Discord Webhook을 통해 길드 Discord 채널에 자동으로 업로드됩니다. 현재 약 4개월째 실제 길드 운영에 사용하며 운영진의 요구사항을 반영해 개선하고 있습니다.


