Upbox Cloud

폐기물 수집운반 업계를 디지털화하여 투명하고 신뢰성 높은 데이터를 관리하고 제공하는 서비스입니다.

리코에 입사한 후 바로 맡아서 진행하게 된 프론트엔드 프로젝트입니다.

이 프로덕트의 궁극적 목표와 가치는 지속 가능한 폐기물 관리의 새로운 기준을 설정하는 것입니다.

목표

  • 수거 일정과 동선 관리
  • 기사님의 작업 효율 극대화
  • 정산 자동화
  • 정확한 데이터 관리

개발 가치관

나중에 언제 보더라도, 빠른 파악이 가능하게끔 직관적으로 설계

백오피스 특성 상 UI의 빠른 피드백이 중요하고, 필요한 정보를 친절하게 제공해야 한다.

인원 구성

2020
백엔드(1), 프론트(1), 디자이너(1), PM(1)
2025
백엔드(4), 프론트(2), 디자이너(2), PO(3), QA(1), PM(1)

설계 관점

유효성 체크

입력 form 을 위한 유효성 체크 로직은 직접 구현함. 업박스의 컴포넌트 수준에서 원하는 방식으로 사용할 수 있음. 다중 depth 유효성 검사 존재

권한 체계

권한별 접근 가능한 메뉴, 페이지, 필드가 존재함. user 의 권한을 가지고 접근 가능한지 여부를 한곳에서 관리.

enum 관리

enum 과 locale 을 함께 관리 프론트에서 관리하기 때문에, 서버와 통신이 불필요하지만, 변경이되면 패치가 필요하다는 단점 i18n 과 연관되어 있음

DTO 구조

여러 형태의 dto (리스트 조회, 상세 조회, 그 외 기타 조회 dto) 를 하나의 모델에서 관리할 수 있도록 함. 각 dto 사이의 브릿지 역할을 하고, 프론트에서는 모델을 공통으로 핸들링하고, dto 로 상호 변환하는 과정을 가짐.
스케줄의 경우 스케줄과 코스를 같은 UI에서 같은 형태로 처리하지만 DTO 형태가 다름. 하나의 모델로 처리하고, 상황에 맞는 DTO로 변환함.
DTO 구조

provide / inject

하나의 페이지에서 다수의 컴포넌트가 높은수의 깊이를 가지고 있는 경우가 많음. store 로도 처리할 수 있지만, 앱 레벨이 아닌, 컴포넌트 단위로 데이터를 관리하고 싶었음

provide / inject - 스케줄

스케줄 편집 화면이 프론트의 작업이 가장 많이 들어가는 영역. 다루는 데이터 다수. 컴포넌트 다수.

스케줄 편집 페이지에서 전역으로 다루는 데이터를 provide 자식 컴포넌트에서 필요한 데이터 inject useScheduleInjection 에 구현하여, 어떤 데이터를 inject 하는지 누락되지 않음. prop drilling 방지.

스케줄 편집 화면
prop provide
컴포넌트 1
컴포넌트 3
컴포넌트 6
컴포넌트 2
컴포넌트 4
컴포넌트 5
컴포넌트 7

provide / inject - 계약

계약도 탭으로 나뉘어 있고, 탭 간의 데이터 끼리 유효성 검사 케이스가 많음.

계약 수정
prop provide
컴포넌트 1
컴포넌트 3
컴포넌트 6
컴포넌트 2
컴포넌트 4
컴포넌트 5
...

웹뷰

적은 인력으로 앱 지원, 웹과 동일한 UI 제공.

웹뷰 캐시 문제

문제 상황

지속적으로 발생하는 원인 불명 프론트엔드 이상 동작 내부 사용자가 주 고객이기 때문에, 업무가 마비되기도 함. (야간 업무자들 다수) CS팀에 인입이 다수 되어 비효율.

데이터독 도입 이전

캐시문제인지 확실하지 않았으며 기능 버그로 오인하여 분석 공수 증가 야간 빠른 대응 놓침 배포 직후 주로 발생하여 업데이트가 제대로 되지 않는 것으로 추측

데이터독 도입 적극 추진
모니터링의 필요성

버그 발생 시점을 세션 리플레이로 확인 기록된 버전을 확인하여, 이전 버전을 사용중임을 확인. 새로운 버전이 배포가 되어도 웹뷰 SPA 특성상 캐시가 남아서 일주일 넘게 까지도 옛 버전 사용

신규 버전으로 업데이트를 강제로 진행할 수 있도록 기능 추가

CICD 과정 중 버전 정보가 담긴 파일을 업로드 * 서버 관리가 없어야 함 * 프론트 파일은 이미 캐시되어 있기에 별도 파일을 s3에 업로드하여 이를 동적으로 확인하는 형태를 취함 관리 포인트 없이 자동화

버전을 체크하고 업데이트를 안내하는 컴포넌트 추가

페이지 로딩 이전에 전처리를 함. 안드로이드 역시 새로운 버전이 존재하면 강제로 업데이트 하도록 Google Play 서비스을 활용해 구현.

페이지 진입 시 버전 체크
📦
meta.json
{ version: "2.1.2.3" }

푸시 데이터 관리

서버에 푸시 데이터를 저장하지 않고, 프론트엔드에서 디바이스에 저장/관리. 푸시 알림은 네이티브 기능이고 UI는 웹뷰로 구현. 네이티브 앱과 웹뷰 간의 데이터 전달이 중요.

푸시 데이터 관리
Server
FCM
FCM
Background
안드로이드 앱 (Native)
Noti 표시
앱이 꺼져 있는 상태이기 때문에, ROOM 에 노티 데이터를 일단 저장
ROOM
안드로이드 앱 (Native)
앱이 가동되는 순간 웹뷰로 푸시 데이터 전달
안드로이드 앱 (Native)
웹뷰
Foreground
안드로이드 앱 (Native)
Noti 표시
켜져 있는 웹뷰에 바로 전달
안드로이드 앱 (Native)
웹뷰
웹뷰
웹뷰에서는 IndexedDB 에 저장
IndexedDB

CICD

Github actions 를 활용해 CICD 진행

초기 CICD 프로세스

초기에는 단순히 빌드 후 배포까지 한번에 진행

Build Storybook
Build
Artifact
Datadog sourcemap
Deploy
Datadog upload

CI/CD 분리

CI CD를 분리함

스토리북은 보는 이는 없고 관리포인트가 늘어서 삭제함

Build
Artifact
Datadog sourcemap
Github
Deploy (workflow_dispatch)
Datadog upload

release 자동 생성

지정 태그로 배포/롤백 구조 구성

Build
Artifact
Github
Github release

앱 별 빌드 분리, 배포 분리

Build admin
Artifact admin
Build driver
Artifact driver
Build customer
Artifact customer

기획 및 디자인 협업 관점

개발자로서 개발만 하는 것이 아니라 프로덕트를 함께 만들어나간다고 생각합니다.

기획 및 디자인이 진행되면서도 좋은 방향을 떠올리려 하고 도움이 될 수 있도록 의견을 피력합니다.

드라이버 계근 플로우 화면 설계

기사님이 여러 사진을 한번에 계근 작업으로 등록하는 플로우가 제안됨 사진 하나씩 등록하는 게 맞다고 의견을 제시하고, 받아들여짐

*기사님의 연령대
*UIUX 복잡도를 고려
*여러개를 한번에 왔다갔다하며 수정하는 것보다. 하나씩 흐름대로 진행하는 편이 직관적일 것이라 예상
*여러장을 한번에 업로드하는 횟수가 적음
*화면 설계 복잡도도 낮춤
Step 1: 계근 정보 입력
Step 2: 수거 작업 선택
Step 3: 총 계근 정보
Step 4: 계근 작업 등록