chorock.page
소개글시리즈프로젝트
© 2026 chorock.page
← 프로젝트 목록

Project

ForA(포에이)

국내 최초 ADHD 커뮤니티 앱, 앱스토어·구글 플레이스토어 서비스 중

작업 기간

2026.03 — 현재

프로젝트 정보

팀 구성

포에이 창업팀 (기획·디자인·백엔드·프론트엔드)

담당 역할

프론트엔드 개발 및 유지보수 (인수인계)

Play StoreApp Store

목차

맡은 일성과와 한계주요 기능설계 판단문제 해결스크린샷
목차
맡은 일성과와 한계주요 기능설계 판단문제 해결스크린샷

사용 기술

앱

Expo SDK 54React Native 0.81React 19TypeScriptExpo Router v6

상태·네트워크

Tanstack QueryAxiosexpo-secure-storeReact-Hook-Form

인증·네이티브

네이버 로그인 SDKexpo-apple-authenticationexpo-notificationsexpo-updates

운영

Firebase AnalyticsGoogle Mobile Ads

프로젝트 개요

국내 최초의 ADHD 커뮤니티 앱입니다. 커뮤니티, 약 검색·리뷰, 건강 매거진을 갖춘 헬스케어 앱으로, Expo(React Native) 한 코드베이스로 iOS·Android를 함께 빌드하며 앱스토어와 구글 플레이스토어에서 서비스 중입니다. 2026년 3월부터 합류해, 전임 개발자가 초기 구축을 마쳐둔 코드베이스를 인수인계받아 프론트엔드 개발과 유지보수를 맡고 있습니다.

맡은 일

  • 창업팀의 기획자·디자이너·백엔드 개발자와 한 팀으로 일합니다. 서버 API는 백엔드가, 화면 설계는 디자이너가 맡고, 저는 앱 구현과 스토어 릴리즈를 담당합니다.
  • 인수인계 이후 제가 붙인 주력 영역은 소셜 로그인 전 과정과 건강 매거진 전반입니다. 커뮤니티(게시글·댓글·신고·차단)는 기존 구현을 이어받아 보수하고 있습니다. 약 검색·리뷰, 푸시 알림, 광고·분석은 전임자가 만든 영역입니다.
  • 소셜 로그인은 백엔드 연동 문서 작성부터 시작해 SDK 연동, 서버 배선, 가입·계정 연결 화면, 엣지케이스 점검, 네이버 사전 검수, 스토어 릴리즈까지 맡았고, 출시 뒤에는 계정 병합과 소셜 계정 관리로 넓히고 있습니다.
  • 남이 만든 코드베이스를 이어받은 만큼, 파악한 내용을 도메인별 문서로 남기면서 작업했습니다. 문서가 없는 상태로 넘겨받았을 때 무엇이 힘든지 겪었기 때문입니다.

성과와 한계

  • 앱 전체 누적 지표는 다운로드 2,000건 이상, 가입 회원 1,500명 이상입니다. 전임자가 만든 시기까지 포함한 수치입니다.
  • 네이버·애플 소셜 로그인을 1.6.0 버전으로 앱스토어·구글 플레이스토어에 출시했습니다(2026.09). 백엔드 연동 문서부터 네이버 사전 검수 승인, App Store 심사 대응까지 전 과정을 맡았습니다.
  • 매거진 기사 발행과 오늘탭 배너 운영이 개발자를 거치지 않게 되면서, 콘텐츠 운영이 개발 일정에서 분리됐습니다.
  • 네이티브 릴리즈와 OTA를 구분해 운영합니다. JS만 바뀌는 수정은 OTA로 내보내되, 심사 중인 바이너리와 배포되는 JS가 갈리지 않도록 발행 시점을 스토어 배포 뒤로 미룬 판단도 있었습니다.
  • 테스트 코드가 없습니다. 작업 규칙 문서에 검증 기준은 세워뒀지만 자동화된 테스트는 아직 없어서, 회귀 확인이 실기기 수동 검증에 의존합니다.

주요 기능

  • 소셜 로그인 — 네이버·애플. 로그인, 신규 가입(2단계), 30일 내 재연결(이전 계정 안내와 "새 계정으로 시작" 선택지), 이메일 인증을 통한 계정 병합까지 갈래별 화면으로 처리합니다.
  • 소셜 계정 관리 — 마이페이지에서 연동·해제합니다. 이메일 등록이 기존 계정과의 병합이 되는 경우에는 확인 모달과 상시 경고 박스, 두 겹으로 안내합니다 — 되돌릴 수 없는 일이기 때문입니다.
  • 계정 관리 — 소셜 전용 계정에는 비밀번호 변경 메뉴를 감추고, 탈퇴 시 소셜 세션까지 함께 정리합니다.
  • 매거진 — 관리자가 앱 안에서 직접 기사를 쓰고 발행합니다(발행 전 미리보기, 썸네일·본문 이미지 업로드, 발행 알림). 인기순·24시간 급상승 탐색과 핀치줌 이미지 뷰어를 갖췄습니다.
  • 매거진 댓글·대댓글 — 작성·수정·삭제·좋아요. 작성자는 실명 대신 익명 1·익명 2로 노출하고, 삭제된 댓글은 감추되 대댓글이 남아 있으면 안내 문구만 남깁니다.
  • 오늘탭 배너·인기글 — 배너는 관리자가 앱에서 등록·수정·삭제하고, 인기글은 서버의 조회 전용 카테고리를 받아 그립니다.

설계 판단

계약이 비어 있는 동안 네이티브부터

소셜 로그인은 백엔드 계약 회신을 기다려야 했습니다. 네이티브 설정과 prebuild가 가장 오래 걸리고 가장 잘 깨지는 구간인데, API가 확정된 뒤에 시작하면 그때부터 일정이 통째로 밀립니다. 그래서 SDK 연동과 네이티브 설정을 먼저 끝내고 서버 요청부만 비워뒀습니다. 나중에 서버 엔드포인트가 올라왔을 때 배선만 이으면 됐습니다.

같은 기간에 약관 동의처럼 "계약 없이 할 수 있는" 작업도 함께 훑었는데, 거기서 회원가입 약관 동의가 하드코딩돼 사용자 입력이 서버로 가지 않던 문제를 발견했습니다.

연동 요청을 코드가 아니라 문서로 먼저

백엔드에 소셜 로그인을 요청할 때, 필요한 것을 말로 전하는 대신 "서버가 무엇을 검증하고 무엇을 결정해야 하는지"를 문서로 만들어 넘겼습니다. 전송 필드 표와 분기별 응답까지 적었습니다.

덕분에 제공자가 카카오에서 네이버로 바뀌었을 때 손실이 적었습니다. 카카오 문서를 넘기기 직전이었는데 앱 코드는 아직 착수 전이라, 문서만 legacy로 돌리고 네이버 문서를 새로 쓰면 됐습니다.

이후 서버 명세가 개편됐을 때도 명세서만 믿지 않고 서버 코드로 직접 대조했습니다. 실제로 명세와 구현이 다른 곳이 있었습니다.

릴리즈 전제를 문서가 아니라 실측으로

네이버 검수가 승인된 뒤, 검수 문서에 "릴리스 직전에 확인해야 한다"고만 적혀 있고 아무도 확인하지 않은 전제 3건을 전부 실측했습니다. 검수를 통과시켜 놓고 출시본에서 로그인이 안 되는 것이 제일 아까운 실패이기 때문입니다. 둘은 기우였습니다 — 배포용 프로비저닝 프로파일은 대시보드의 초록 배지(만료 여부만 검사합니다)를 믿는 대신 직접 복호화해 애플 로그인 entitlement가 들어 있는 것을 확인했고, "로컬 빌드"라고 단정한 문서는 실제 이력과 대조해 클라우드 빌드로 정정했습니다.

하나는 진짜였습니다. 클라우드 빌드는 EAS에 등록된 환경변수만 쓰는데 네이버 키 2개가 등록돼 있지 않았습니다. 키가 비면 SDK 초기화를 건너뛰므로, 빌드 에러도 크래시도 없이 출시본에서 네이버 로그인만 조용히 죽는 경로였습니다. 출시 전에 등록했고, 빌드 로그에서 키가 실제로 주입된 것까지 확인했습니다.

애플 계정의 2FA 코드가 계정 소유자에게만 가서 연락이 닿지 않았을 때도 멈추지 않았습니다. 빌드와 업로드는 웹 로그인이 아니라 API 키 인증이라 2FA를 타지 않는다는 것을 확인하고, 바이너리를 먼저 만들어 올려둔 뒤 웹에서 할 일만 소유자 시간대로 미뤘습니다. 대기 시간이 낭비가 아니라 프로덕션 빌드를 실기기로 검증하는 시간이 됐습니다.

좋아요 반응을 낙관적 업데이트로

좋아요를 누르면 서버 왕복이 끝나야 숫자가 바뀌어서, 네트워크가 느릴 때 버튼이 먹통처럼 보였습니다. 좋아요는 실패가 드물고 실패해도 되돌릴 수 있는 조작이라, 먼저 화면에 반영하고 실패 시 되돌리는 쪽을 골랐습니다.

요청 전에 진행 중인 조회를 취소해, 앞서 떠 있던 응답이 늦게 도착해 방금 반영한 값을 덮어쓰지 않게 했습니다. 댓글 쪽은 무한 스크롤이라 페이지 묶음을 순회해야 하고 대댓글이 중첩돼 있어, 최상위와 자식 양쪽에서 대상 하나만 찾아 뒤집도록 했습니다.

문제 해결

로그인 버튼이 먹통이던 문제 — 원인을 두 번 잘못 짚었다

검수 승인 후 일반 네이버 계정으로 처음 실기기 확인을 하는데, 버튼을 눌러도 아무 반응이 없었습니다. 원인을 세 번 만에 맞혔고, 앞의 두 오진은 각각 다른 이유로 틀렸습니다.

1차 진단은 낡은 토큰이 재로그인 요청에 붙어 401 재시도 루프에 빠진다는 것이었는데, 로그를 보지 않고 코드만 읽고 세운 가설이었습니다. 실기기 로그를 받아보니 401이 한 번도 없었습니다. 2차 진단은 서버가 요구사항을 반쪽만 반영한 버그라는 것이었는데, 이번엔 참조 문서만 읽고 작업 이력을 보지 않은 게 문제였습니다. "이메일 없이도 가입이 성립해야 한다"는 계약이 문서 통합 과정에서 삭제돼 참조 문서에서 사라져 있었고, 작업 로그에만 남아 있었습니다.

3차에서야 전체가 보였습니다. 이메일 없는 소셜 계정을 GUEST로 두고 마이페이지에서 이메일을 추가하면 승격시키는 의도된 구조인데, GUEST는 사용자 조회가 거부돼 로그인 자체가 안 되니 마이페이지에 갈 수 없었습니다. 이메일을 추가해야 로그인이 되는데, 추가하는 화면이 로그인 뒤에 있는 닫힌 고리였습니다. 가입 흐름 안에 이메일 인증을 넣어 풀었고, 백엔드에 승격 기준 변경을 제안해 채택되면서 같은 날 그 우회를 걷어내고 이메일 등록을 설정 화면으로 옮겼습니다.

두 오진은 기록에서 지우지 않고 정정 표시와 함께 남겼습니다. 하나는 로그를 안 봐서, 하나는 이력을 안 봐서 틀린 서로 다른 실패이고, 지우면 같은 방식으로 또 틀리기 때문입니다.

App Store 심사가 사람을 만나기도 전에 반려된 문제

1.6.0 제출이 자동 분석 단계에서 반려됐습니다. 마이크 권한 설명 문구가 플레이스홀더라는 지적이었는데, 앱은 마이크를 쓰지 않고 그 문구를 적은 적도 없었습니다.

생성된 Info.plist를 전수 확인해 보니 같은 부류가 셋이었습니다 — 마이크·카메라·Face ID 문구를 config plugin(이미지 피커·보안 저장소)이 기본값으로 조용히 넣고 있었습니다. 셋 다 실제로 쓰지 않는 자원이라, 문구를 그럴듯하게 고치는 대신 플러그인 옵션으로 권한 자체를 꺼서 키를 제거했고, prebuild 산출물에서 세 키가 사라진 것을 확인한 뒤 재제출해 통과했습니다.

지적받은 것은 마이크 하나였지만, 같은 부류를 전부 훑지 않았다면 카메라와 Face ID로 두 번 더 반려될 수 있었습니다. 릴리즈 체크리스트에 "생성된 Info.plist의 권한 문구 전수 확인"을 추가했습니다.

로그인은 되는데 앱을 못 벗어나던 문제

소셜 로그인 배선을 끝내고 보니, 서버 응답의 세 갈래 중 두 갈래가 토스트만 띄우고 끝났습니다. 신규 가입 갈래는 앱을 껐다 켜도 로그인 화면을 벗어날 수 없는 막다른 길이었고, 계정 연결 갈래는 훅만 있고 호출처가 없었습니다.

두 갈래에 각각 화면을 붙인 뒤 전 경로를 훑어 엣지케이스를 전수 점검했습니다. 구멍이 6개였고, 다시 조사하지 않도록 대응 표로 남겼습니다.

연동을 끊거나 탈퇴해도 로그인 상태로 남던 문제

사용자가 iOS 설정에서 애플 로그인 연동을 끊어도 서버 토큰이 살아 있어 앱은 계속 로그인 상태로 보였습니다. 앱이 켜질 때 credential 상태를 확인해, 폐기됐으면 로그아웃하도록 했습니다.

비슷한 결로, 탈퇴 후 네이버 버튼을 다시 누르면 계정 선택 없이 바로 로그인됐습니다. 로그아웃과 탈퇴가 각자 세션을 정리하던 것을 한 곳으로 모았고, 가입을 마치지 못하고 이탈한 경우에도 네이버 세션을 끊어 다음 시도에서 정보제공 동의를 다시 고를 수 있게 했습니다.

애플 재로그인 때 이름·이메일이 null로 오던 문제

로그인은 되는데 이름과 이메일이 비어서 왔습니다. 연동 코드를 의심하기 딱 좋은 증상이었지만, 실기기로 1회차와 2회차 로그인을 나눠 확인하니 1회차에는 두 값이 정상이었고 2회차부터 둘 다 null, 사용자 식별자는 두 번 다 동일했습니다. 코드 문제가 아니라 애플이 개인정보를 최초 1회만 내려주는 정책이었습니다.

문서로만 알던 전제를 실측으로 확정한 셈이고, 서버가 첫 응답을 저장하지 못하면 재로그인으로는 복구할 방법이 없으므로 최초 응답 저장을 서버 필수 조건으로 못 박았습니다.

에러 없이 조용히 틀어져 있던 렌더링 둘

기사 본문 글자가 잘리던 문제는 4월과 5월에 두 번 우회했는데도 재발했습니다. 같은 자리가 세 번 깨지는 건 개별 케이스가 아니라 렌더러 자체의 문제라는 신호로 보고, 마침 유지보수가 끊길 예정이던 마크다운 라이브러리를 호환성 좋은 것으로 교체했습니다. 이후 같은 증상은 재발하지 않았습니다.

글꼴도 같은 부류였습니다. 안드로이드와 iOS에 같은 화면을 나란히 띄우니 줄바꿈 위치가 달랐고, 추적해 보니 Pretendard SemiBold의 등록 이름이 어긋나 89곳이 시스템 폰트로 폴백되고 있었습니다. 에러가 나지 않는 어긋남이라 나란히 놓기 전까지 아무도 몰랐습니다. 이름을 맞추고, 마크다운 본문이 별도 경로로 시스템 폰트를 쓰던 것도 함께 고쳤습니다.

스크린샷

배너 배너2

화면1 화면2

화면3