본문으로 건너뛰기
코딩 2026-03-18 01:18:00 · 2분 · -

CloudPocket — Google Sheets 시트 분리와 UX 리팩토링

CloudPocket이 뭔가

CloudPocket은 세 번째 개인 사이드 프로젝트다. React Native + Expo + TypeScript로 만든 가계부 앱이다.

시작은 단순했다. 원래 엑셀로 자산 관리를 하고 있었는데, 매번 노트북을 열어서 입력하는 게 귀찮았다. 그래서 “Google Sheets를 백엔드로 쓰면 폰에서 입력하고 스프레드시트에서 바로 볼 수 있지 않을까?”라는 생각에서 출발했다.

실제로 Google Sheets API를 연동해서, 앱에서 거래를 입력하면 스프레드시트에 자동으로 기록되고, 카테고리/결제수단 같은 설정도 시트에서 직접 편집할 수 있다. Phase 3까지 완료해서 기본 가계부 + 통계 + Google Sheets 동기화가 모두 동작하는 상태다.

오늘은 Google Sheets 연동에서 겪은 셀 범위 충돌 문제와, 그걸 해결하면서 진행한 UX 개선을 정리한다.

문제: batchUpdate 400 에러

Google Sheets API의 batchUpdate로 카테고리, 결제수단, 저축상품을 한 번에 저장하는데, 간헐적으로 400 에러가 났다.

원인은 하나의 시트에 모든 설정을 우겨넣은 구조였다. (필수)설정 시트 하나에 카테고리(A~P열), 결제수단(R열), 저축상품(T열)이 공존하고 있었는데, 각각의 범위가 겹치거나 인접하면서 batchUpdate가 충돌을 일으켰다.

해결: 시트 분리

설정 데이터를 독립 시트로 분리했다:

시트내용범위
설정-카테고리대분류+소분류 매트릭스A1:P20 (20행x16열)
설정-결제수단신용카드(A열), 체크/현금(B열)A1:B10
(필수)설정 시트나머지 데이터 유지기존 그대로

각 시트가 A1부터 시작하니까 범위 계산이 단순해지고, batchUpdate 충돌도 사라졌다. CELL_RANGES 상수를 새 시트 기반으로 변경하고, exportSettings()의 패딩을 상수로 통일했다.

필수 설정 검증도 추가 — 카테고리나 결제수단이 비어있으면 사용자에게 안내 메시지를 보여준다.

UX 개선 1: 스프레드시트 ID 모달

기존에는 설정 화면에 항상 TextInput이 노출되어 있었다. Google Sheets URL이나 ID를 잘못 건드리면 데이터 연결이 끊길 수 있는 위험한 구조.

모달 기반으로 변경했다:

  • 미등록 상태: 점선 박스 + “등록” 버튼 → 모달 열림
  • 등록 완료: ID 마스킹 표시 (앞 4자리…뒤 4자리) + “변경” 버튼
  • URL 붙여넣기: 정규식으로 스프레드시트 ID 자동 추출

UX 개선 2: 카테고리/결제수단 수정

기존에는 추가와 삭제만 가능했다. “식비”를 “식사비”로 바꾸려면 삭제하고 다시 추가해야 했다.

수정 기능을 추가했다:

  • 대분류: 수정 버튼 → 이름/아이콘 수정 모달
  • 소분류: 항목 터치 → 이름/아이콘 수정 모달
  • 결제수단: 수정 버튼 → 이름/타입/아이콘 수정 모달

기존 추가 모달을 재활용해서 추가/수정을 하나의 컴포넌트로 처리했다. 새 화면을 만들지 않아도 되니까 코드량이 적다.

테스트

726개 테스트 전체 통과:

  • GoogleSheetsService 24개 (신규 2: 빈 결제수단/카테고리 검증)
  • BackupRestoreSection 15개 (신규 7: 모달 등록/변경/URL추출/취소)

template.xlsx도 새 시트 구조에 맞게 정리하고, 개인 데이터를 전부 클리어해서 다른 사람도 템플릿으로 쓸 수 있게 했다.

공유 복사됨!

관련 글

댓글