우리집 - 커플·가족 생활 앱 개발기

ReactNative
날짜 없음

woori-zib-logo

커플·가족 생활 앱 「우리집」 개발기 — Expo · Supabase · App Store

일정, 가계부, 디데이를 같이 쓰는 모바일 앱 우리집을 만들고 스토어 올리는 과정까지 정리했음.

1. 무엇을 만들었나

우리집은 커플·가족이 일상을 같이 관리하는 앱이다.

  • 공유 캘린더(일정) — 반복, 알림, 양력/음력, 사진
  • 공유 가계부 — 수입/지출, 카테고리, 반복
  • 디데이
  • 가족 초대·연결, 프로필, 고객지원(공지/FAQ/문의), 회원탈퇴
    타깃은 한국 사용자다. UI 문구는 한국어로 하드코딩했고, 공휴일은 공공데이터 API를 사용했음.
    식별 정보:
    | 항목 | 값 |
    |------|-----|
    | 앱 이름 | 우리집 |
    | Expo | SDK 54 |
    | React Native | 0.81.5 |
    | 백엔드 | Supabase (Auth, Postgres, Realtime, Storage, Edge Functions) |

2. 기술 스택

클라이언트

분류라이브러리용도
프레임워크Expo ~54, React 19, React Native 0.81앱 런타임
라우팅expo-router ~6파일 기반 네비게이션
백엔드 SDK@supabase/supabase-jsAuth / DB / Realtime
로컬 저장@react-native-async-storage/async-storage세션·공휴일 캐시
제스처·애니메이션react-native-gesture-handler, reanimated, worklets스와이프 캘린더, 모달 등
화면 구조react-native-screens, safe-area-context네이티브 스택·세이프에리어
OAuthexpo-auth-session, expo-web-browserGoogle 로그인
Appleexpo-apple-authenticationSign in with Apple (심사 대응)
알림expo-notifications일정 리마인더
미디어expo-image-picker일정 사진
입력@react-native-community/datetimepicker, @react-native-picker/picker, wheel-picker날짜·시간·반복
음력korean-lunar-calendar음력 일정
빌드expo-build-properties, EAS Build/SubmitiOS 스토어 배포
패치patch-packageRN 0.81 TurboModule 크래시 우회

서버 (Supabase)

  • Auth: 이메일, Google, Apple
  • Postgres + RLS: household 단위 데이터 격리
  • Realtime: 일정·가계부·디데이·멤버십 변경 동기화
  • Storage: household 사진
  • Edge Functions (Deno) + Resend: 인증메일, 초대메일, 계정/탈퇴 메일, 비밀번호 재설정, 공휴일 프록시

3. 코드 구성

대략적인 디렉터리 역할은 다음과 같다.

app/                 # expo-router 화면 (파일 = 라우트)
contexts/            # Auth, AppData, Profile, Toast
services/            # Supabase·OAuth·메일·알림 API 래퍼
components/          # 화면별 UI
constants/           # 테마, 카테고리, household 정책 등
lib/supabase.ts      # 클라이언트 싱글톤
hooks/               # 새로고침 등
supabase/
  schema.sql
  migrations/
  functions/         # Edge Functions
  상태 관리
전역 상태는 Context로 나눴다.

AuthContext
세션, 프로필, household 멤버(최대 4명), 초대/링크 요청, 가입·로그인·탈퇴, Realtime으로 멤버십 갱신

AppDataContext
calendar_events, ledger_items, dday_items, ledger_categories CRUD
household 기준으로 fetch하고 Realtime으로 상대방 변경을 반영, 토스트로 알림

ProfileContext / ToastContext
프로필 UI·전역 토스트

비즈니스 로직은 services/*에 두고 Context는 조합·구독에 집중했다.
patches/             # react-native 패치
plugins/             # Expo config plugin (Xcode 26 fmt 우회)
docs/                # release / dev-log 핸드오프

4. 페이지(화면)별 기능

인증 — app/(auth)/

경로기능
welcome이메일 가입, Google, Apple 진입
login이메일 로그인
signup/email이메일 인증코드 → 프로필 → 혼자/가족과 쓰기
signup/google, signup/apple소셜 이후 온보딩(닉네임·사용 방식)
forgot-password, reset-password비밀번호 재설정 (Edge Function)
find-account계정 찾기
가입 시 혼자 쓸게요 / 가족과 쓸게요를 고른다.
가족과 쓰기면 초대 메일 또는 상대 이메일을 받아 가족에 합류·병합한다.

메인 탭 — app/(tabs)/

파일기능
index날짜 스트립, 가계 요약, 오늘 일정, 퀵액션, Expandable FAB(일정/가계/디데이 추가)
일정calendar월 캘린더, 공휴일·일요일 강조, 일자 상세 시트, 스와이프 월 이동
디데이dday디데이 목록·카드·액션 메뉴
가계부ledger수입/지출 목록, 카테고리
마이my프로필, 메뉴(초대·설정·지원), 버전

홈화면2

일정 화면3

디데이 화면4

가계부 화면5

마이페이지 화면6

기능 모달/스택

경로기능
schedule/create, [id], edit일정 CRUD. 대상(나/상대/우리), 종일, 반복, 색, 리마인더, 양·음력, 사진, 메모
ledger/create, [id], edit가계부 CRUD, 카테고리, 반복
dday/create, edit디데이 CRUD
invite가족 초대
profile/*닉네임·비밀번호 변경
support/*공지, FAQ, 약관, 문의
withdraw탈퇴 + 설문 → 관리자 메일
일정·가계 작성 UI는 휠 피커·멀티데이트 캘린더 등 커스텀 컴포넌트를 components/schedule, components/ledger에 모았다.

5. 백엔드 설계 요약

Household

핵심 단위는 household다.

  • 가입 시 ensure_personal_household로 개인 가구 생성
  • 초대·수락 시 초대자 household로 병합 (merge_households)
  • 멤버 상한 4명
  • 나가기/탈퇴 시 데이터 정책(남길지·지울지)을 migration으로 정의
    앱 데이터 테이블은 대체로 household_id로 묶이고, RLS로 “내 household만” 접근한다.

Edge Functions

함수역할
send-verification-email가입·인증 코드 (Resend)
send-invitation-email가족 초대
send-account-email환영/탈퇴 관련 메일
reset-password비밀번호 재설정
get-holidaysdata.go.kr 특일 API 프록시
시크릿은 Supabase secrets에 두고, 앱에는 anon key만 넣는다.

Realtime

calendar_events, ledger_items, dday_items, ledger_categories, household_members 등을 구독해 가족이 동시에 수정해도 목록이 갱신되게 했다.

6. 로컬 개발

npm install
# .env 에 EXPO_PUBLIC_SUPABASE_URL / ANON_KEY
npx expo start
# 네이티브 모듈 변경 시
npx expo run:ios
npx expo run:android
os/, android/는 gitignore다. EAS는 app.json 기준으로 클라우드에서 prebuild한다.
로컬에서 Apple 로그인·알림·태블릿 설정을 검증할 때는 expo run:ios가 필요하다.

Supabase는 schema.sql + migrations/*.sql을 SQL Editor 또는 CLI로 적용하고, Edge Function을 deploy한다.

7. 배포 방식 (EAS → App Store)

버전은 app.jsonexpo.version(마케팅 버전)과 ios.buildNumber(빌드 번호)로 관리한다.
eas.jsonappVersionSource: local이라 로컬 app.json이 기준이다.

환경 변수

로컬 .env만 있으면 EAS production 빌드에는 값이 안 들어간다.
스토어 바이너리에 Supabase URL/키가 비면 런치·인증이 깨질 수 있어, Expo 대시보드 또는 CLI로 production env를 등록했다.

npx eas-cli env:create --environment production --name EXPO_PUBLIC_SUPABASE_URL ...
npx eas-cli env:create --environment production --name EXPO_PUBLIC_SUPABASE_ANON_KEY ...

빌드·제출

npx eas-cli build --platform ios --profile production --non-interactive
npx eas-cli submit --platform ios --latest --profile production --non-interactive

eas.json submit 프로필에 App Store Connect App ID를 넣어 두었다.
같은 마케팅 버전으로 다시 올리면 buildNumber만 올리고, 새 스토어 버전이면 version을 올린다.
예: 1.0.1 (build 4) 핫픽스 → 1.0.2 (build 1) 기능/디자인 업데이트.
Android는 preview 프로필로 APK, production으로 AAB를 만들 수 있게 설정해 두었다. 현재 스토어 포커스는 iOS다.

App Store Connect 쪽

바이너리 업로드 후 Apple 처리(수분)가 끝나면 해당 버전 페이지에서 빌드를 고르고 심사에 제출한다.
스토어 설명·키워드·새로운 기능 같은 메타데이터는 바이너리와 별개라, 기본 언어(한국어)와 버전 페이지 언어 탭의 문구를 따로 채워야 한다.
심사에서 겪었던 것:

  1. Guideline 4.8 — Google 로그인만 있으면 Apple 로그인 필요 → Sign in with Apple + iPad(supportsTablet) 추가
  2. Guideline 2.1(a) 런치 크래시 — RN 0.81 TurboModule void 예외 처리와 Hermes 이슈 → patch-package + buildReactNativeFromSource: true
  3. 런치 후 빈 화면 — 스플래시/로딩/return null + EAS env 누락 → 부트 hardening + production env 등록
    소스로 RN을 빌드하면 Xcode 26에서 fmt consteval 오류가 나서, Expo config plugin으로 Podfile에 워크어라운드를 넣었다.

8. 구현하면서 신경 쓴 점

  • 가족 단위 동기화: household + Realtime으로 “상대가 방금 쓴 가계부”가 바로 보이게
  • 가입 UX: 혼자/가족 분기와 이후 초대 가능 안내
  • 캘린더 UX: 공휴일 캐시, 월 스와이프, 색·반복·음력
  • 릴리즈 안정성: 스플래시를 너무 일찍 끄지 않기, Auth timeout, EAS env를 로컬과 맞추기
  • 핸드오프 문서: docs/dev-log.md, docs/release.md, CHANGELOG.md에 빌드 번호·심사 이슈·명령을 남겨 다음 배포를 빠르게

9. 앞으로

  • Android 스토어 정식 배포
  • App Store 메타데이터(설명, 스크린샷) 한국어 검수 강화
  • 알림·반복 일정 고도화, 성능·오프라인 경험

참고 명령 요약

# 로컬
npm install
npx expo start
npx expo run:ios
# Edge Functions (예시)
npx supabase functions deploy send-verification-email
npx supabase functions deploy get-holidays
# 스토어
npx eas-cli build --platform ios --profile production
npx eas-cli submit --platform ios --latest

혼자 쓰는 생활 앱에서 시작해, household·Realtime·스토어 심사까지 한 사이클로 밀어붙인 기록이다.
같은 스택(Expo Router + Supabase)으로 가족형 제품을 만들 때 라우팅·권한·배포 env 쪽을 특히 먼저 고정해 두는 편이 좋다.

댓글

Top