중고차 전문 점검원이 현장에서 사용하는 모바일 웹/앱입니다. 입고, 세차, 도장, 상품화, 사진 촬영, 출고, 성능점검 및 품질검사, 하부 부품 검수까지 총 25개 화면으로 현장 프로세스 전체를 커버합니다.
이 프로젝트에서 기술적으로 가장 까다로웠던 부분은 화면 수가 아니라 점검이 이루어지는 열악한 물리적 환경이었습니다.
문제: 전파가 끊기는 지하 주차장과 정비고
차량 점검은 두꺼운 콘크리트 벽으로 둘러싸인 지하 주차장과 정비고에서 진행됩니다. LTE/5G 통신이 수시로 끊기고 극도로 불안정합니다.
차량 한 대당 고화질 사진을 수십 장씩 촬영하는데, 업로드가 끝날 때까지 로딩 스피너를 보여주면 점검 업무가 중단됩니다. 더 심각한 문제는 통신 불안정으로 업로드 중 사진이 유실되면 점검원이 해당 차량으로 다시 돌아가 재촬영해야 한다는 점입니다.
따라서 요구사항의 본질은 '업로드 속도 향상'이 아니라 '점검원이 통신 상태를 전혀 신경 쓰지 않고 논스톱으로 일할 수 있게 만드는 것'이었습니다.
해결: 철저한 오프라인 우선(Offline-First) 설계
1. UI와 업로드 프로세스의 완전한 분리
사진 촬영 즉시 로컬 메모리/스토리지에 저장하고, 화면에는 서버 URL 대신 로컬 이미지를 즉시 렌더링합니다. 점검자 입장에서는 사진이 0.1초 만에 등록된 것처럼 느껴지며, 실제 서버 전송은 백그라운드 워커가 조용히 처리합니다.
2. IndexedDB 기반의 영구 오프라인 작업 큐
업로드 대기열을 단순 메모리가 아닌 브라우저 내장 데이터베이스(IndexedDB)에 영구 저장했습니다. 점검 중 배터리가 방전되어 기기가 꺼지거나 브라우저 탭이 닫히더라도, 앱 재실행 시 큐를 복원하여 미전송 사진들을 안전하게 전송합니다.
3. 통신 회선 보호를 위한 직렬화(Concurrency: 1) 전송
네트워크가 불안정한 환경에서 여러 장을 동시 병렬(Parallel) 업로드하면 한정된 대역폭을 나눠 쓰다가 모든 요청이 타임아웃으로 실패합니다. 업로드 큐를 1건씩 순차 전송(Concurrency: 1)하도록 직렬화하여 패킷 손실률을 최소화하고 전체 완료 속도를 앞당겼습니다.
4. 서명된 URL(Presigned URL) 직접 업로드
보안 자격증명을 모바일 클라이언트에 노출하지 않고, 백엔드로부터 발급받은 임시 서명 URL을 통해 오브젝트 스토리지에 직접 업로드함으로써 백엔드 서버의 부하를 제거했습니다.
네이티브 앱 배포의 한계를 넘는 PWA + TWA
마켓 심사 지연 없이 즉각적인 기능 수정과 배포를 위해 PWA(Progressive Web App) 기반으로 개발하고 안드로이드 TWA(Trusted Web Activities)로 패키징했습니다. 설치형 앱의 사용자 경험을 그대로 제공하면서도, 배포 즉시 현장에 반영되는 웹의 기민성을 확보했습니다.
초기 설계의 치명적 결함과 개선
초기 구현 당시 "업로드 실패 시 즉시 재시도하고, 3회 연속 실패하면 파일을 폐기"하도록 단순하게 설계했었습니다.
하지만 통신이 완전히 끊긴 환경에서는 3번의 재시도가 1초도 안 되어 모두 소진되면서 현장에서 촬영한 사진이 그 자리에서 삭제되는 치명적인 버그로 이어졌습니다.
이를 해결하기 위해 지수 백오프(Exponential Backoff) 와 온라인 상태 감지 이벤트(navigator.onLine)를 결합하여, 네트워크가 복구될 때까지 큐를 안전하게 대기 상태로 유지하도록 재설계했습니다.
요약
현장용 소프트웨어의 핵심은 최상의 네트워크 환경을 가정하는 것이 아니라, 최악의 오프라인 환경에서도 데이터 유실 없이 견고하게 동작하는 안전망을 구축하는 것입니다.