7개 앱 프로 게이트 총공
목차
오늘은 커밋 로그만 봐도 좀 멍해진다. 앱 일곱 개를 하루에 동시에 손댔다. 각각 다른 언어, 다른 도메인, 다른 스토어 상태. Flutter 다섯 개에 Swift 하나, 그리고 JSP 웹 대시보드 하나. 아침부터 밤까지 맥락 전환이 끊이지 않았고 어느 순간부터는 "지금 내가 어느 앱 보고 있지?"를 머릿속에서 한 번씩 확인하면서 코딩하고 있었다.
발단은 ops 문서였다. docs/pro-gate-remediation.md에 "2026-08-02 감사 후속"이라고 박혀 있는 게 오늘 아침 제일 먼저 만든 커밋이다. 플릿 전체 앱을 훑어보니 Pro 게이트가 이름뿐이거나 우회가 너무 쉬운 게 눈에 띄었다. 광고 제거 단일 수익 모델로 가고 있는 앱들인데, 정작 Pro 실질 기능이 허술하면 전환 이유가 없다. 그래서 하루 계획이 그렇게 잡혔다 - 7개 앱 Pro 게이트 전면 보강, 그리고 각각 iOS/Android 재제출.
앱 일곱 개를 동시에 끓이는 법
방법이 딱히 우아하진 않았다. 앱마다 패턴을 하나 잡아서 찍어냈다. CSV 내보내기 Pro 게이트가 젤 많았다. 히스토리 내보내기, 수면 데이터 내보내기, 취업 정보 내보내기, 청소 통계, 스코어보드 공유, 현상로그... 전부 같은 구조다 - 버튼 탭하면 Pro 체크, 미가입이면 페이월 시트, 가입이면 share_plus 통해서 share sheet 호출.
근데 이 share sheet 하나가 iOS에서 꼭 한 번씩 발목을 잡는다. sharePositionOrigin 안 넘기면 iPad에서 PlatformException 터진다. 예전에 한 앱에서 고쳤던 걸 이번에 나머지 앱 전부 다 확인하면서 빠진 데마다 심어줬다. lib/services/job_export.dart, lib/services/score_export.dart, lib/data/sleep_export.dart, lib/services/export_service.dart - 파일명만 다르고 패턴은 똑같다. 이 정도면 공통 유틸 하나로 올려야 하는데, 앱이 모노레포가 아니다 보니 매번 복붙이 답이 된다. 찝찝하지만 지금 구조에서 다른 선택지가 없다.
CSV 빌더 접근 제어도 하나 정리했다. job_export.dart에서 _buildCsv 같은 메서드가 public으로 열려 있으면 Pro 게이트를 우회해서 직접 빌더 호출할 수 있다. 외부 노출은 필요 없으니 private으로 막고, 내보내기 진입점을 Pro 게이트 하나로 단일화. 작은 거지만 이런 거 안 챙기면 게이트가 흐물거린다.
Flutter 앱 디버그 검증도 공통으로 박았다. 시뮬레이터에서 Pro 상태 전환 확인하려면 매번 실제 구매를 태울 수 없으니 kDebugMode 체크 후 VM 서비스 익스텐션으로 Pro 토글 플래그 꽂는 하네스. 이걸 lib/main.dart에 추가한 앱이 서너 개다. 나중에 "Pro 게이트 실제로 작동하냐"는 질문 받을 때마다 이 토글로 시뮬 돌려서 두 상태 다 보여줄 수 있다.
ITMS-90683 이 녀석
iOS 재제출 과정에서 거의 매 앱마다 NSUserTrackingUsageDescription 관련 처리가 있었다. ITMS-90683은 앱에 ATT 퍼미션 스트링 없이 트래킹 관련 프레임워크가 탐지될 때 App Store Connect가 뱉는 경고다.
근데 이번에 한 앱은 방향을 달리 잡았다. 광고 없는 앱인데 ATT 프롬프트를 띄우고 있었다. App Privacy 섹션에서 "데이터 수집 안 함"으로 선언해놓고 정작 앱에서 ATT 퍼미션 요청이 나가면 리뷰어 눈에 모순으로 보인다. 그래서 그 앱은 ATT를 아예 들어냈다. att_service.dart 삭제, Info.plist에서 NSUserTrackingUsageDescription 제거, main.dart에서 호출부 제거. 반대로 다른 앱들은 스트링 누락이 문제였으니 추가. 앱마다 상황이 달라서 기계적으로 적용할 수 없었다.
docs/mobile-app-launch.md에 이 함정을 정리해뒀다. "광고 없는 앱에 ATT 넣으면 App Privacy 선언이랑 충돌 리스크"라고. 다음 앱 만들 때 초기 세팅에서 이걸 놓치지 않으려고. 오늘 여섯 개 앱을 재제출하면서 처음 이 패턴이 분명해졌다.
force-update 게이트와 1분 리프롬프트
fleet standard로 박는 패턴이 하나 더 있었다. force-update 게이트 - 앱 진입 시 버전 체크해서 지정 버전 미만이면 업데이트 다이얼로그 강제 노출. 이게 lib/app.dart나 lib/main.dart에 들어가는데, 문제는 "닫기" 없는 다이얼로그여도 앱 재시작으로 우회가 가능했던 것. 콜드 스타트 때마다 체크가 다시 돌지만 "re-prompt delay"를 며칠로 잡아두면 재시작 사이 간격에서 구멍이 생긴다.
그래서 days를 1분으로 수정했다. 정확히는 days 단위 값을 분 단위로 교체. 1분이면 사실상 매 시작마다 체크한다. 이게 fleet standard라고 적어뒀다 - 다음 앱에도 처음부터 이 값으로 쓰겠다는 뜻.
가격 인상과 무료 한도 칼질
오늘 두 가지 정책 변경이 있었다. 하나는 Pro 가격 인상 - $4.99에서 $14.99로. 삼 배. docs/ 기록에 "ASC+Play 전지역 동기 반영"이라고 적혀 있다. 이게 어느 앱인지는 커밋에서 특정 앱 이름이 마스킹되어 있어서 정확히는 모르지만, FilmDev는 $4.99→$6.99로 별도 인상 기록이 있으니 다른 앱일 것이다.
다른 하나는 무료 항목 한도 25→3개 축소. 이건 좀 과감한 쪽이다. 25개면 사실 Pro 안 사도 왠만한 사용자는 불편 없이 쓸 수 있다. 3개로 줄이면 첫 세션에서 바로 한도에 걸린다. 전환 유도 강화가 목적인데, 이렇게까지 낮추는 게 맞나 싶은 생각이 없진 않았다. 근데 광고도 없고 Pro 수익이 유일한 모델인 앱에서 무료 한도 25개는 너무 관대했던 것도 사실이다.
대시보드 쪽은 별세계였다
오전 오후 내내 Flutter/Swift 달리다가 대시보드 작업이 끼어 있었다. 파트너 포탈 - 총판, 대리점이 접속하는 정산 현황 화면. 오늘 주된 작업은 "오늘 판매대금" 그리드 신설이었다.
파트너별 오늘 판매대금 - 대리점만 표시 + 15초 라이브 폴링. 나중에 폴링을 5초로 단축했다. 15초는 실시간이라고 부르기 애매하다는 판단이었던 것 같다. 정산대기·총잔액은 매 tick 갱신, 그리드는 5초. 이 차이를 두는 이유는 그리드가 더 무거운 쿼리이기 때문이다 - 아마 서브쿼리나 집계가 들어갈 테니 interval을 분리했을 것.
자정 롤오버 처리가 리뷰에서 지적됐다. "오늘"이라는 기준이 서버 자정 기준인데, 클라이언트에서 폴링하다가 자정을 넘기면 화면의 날짜 범위가 갱신이 안 될 수 있다. 레벨 설정 폴백, 재정렬, 타임아웃도 같이 반영. 이 네 가지가 한 커밋에 묶여 있는 걸 보면 리뷰에서 한꺼번에 지적이 나온 것 같다.
ACTIVE 대리점만 표시하는 조건도 쿼리에 추가됐다. 처음엔 전체 파트너 다 나왔는데, 비활성 대리점이 그리드에 섞이면 실무에서 혼란이 생긴다. 쿼리 매퍼에 status = 'ACTIVE' 조건 추가 - 단순하지만 처음부터 이걸 안 넣은 게 좀 아쉬운 부분이다.
예치금 카드 번복 사건
오늘 제일 황당했던 건 예치금 카드 복구 커밋이다.
흐름이 이렇다. feat: 오늘 판매대금 카드 리디자인 + 전항목 실시간 + 대시보드 예치금 카드 제거 - 이게 먼저 들어갔다. 대시보드에서 예치금 카드 네 종류를 없앴다. 그리고 다음 커밋이 fix: 예치금 카드 4종 복구(사용자 지시 번복). 사용자 지시 번복. 지웠더니 다시 넣으라고.
이런 번복은 종종 있는 일이지만 그래도 한 번씩 맥 빠지는 건 어쩔 수 없다. 지우면서 "이게 맞겠구나"하고 검토했던 시간, 제거 과정에서 정리한 코드들이 다시 원상복구. 그래도 복구하면서 하위 예치금 현황 sdc 디자인 통일을 같이 챙겼으니 완전 헛수고는 아니었다.
그리고 바로 이어서 다른 디자인 버그가 터졌다. sdc 공용 스타일을 판매대금 카드 c:if 밖으로 이동 - 총판 등 일부 파트너 유형은 "오늘 판매대금" 그리드 자체가 안 뜨는 화면인데, c:if 조건 안에 sdc 스타일을 같이 넣어두다 보니 그 조건이 false일 때 스타일이 통째로 날아가버렸다. 예치금 현황 레이아웃이 깨지는 증상. JSTL c:if 밖으로 스타일 블록 이동. 이런 거 초반에 구조 잡을 때 생각했어야 하는데, 빠르게 치다 보면 나중에 이런 식으로 하나씩 회수된다.
ops 문서 정리가 진짜 일이었다
오늘 커밋 중 docs: 프리픽스가 얼마나 많은지 세보면 두 자릿수다. pro-gate-remediation.md 하나만 여섯 번 이상 업데이트됐다. 이게 단순히 작업 기록 남기는 게 아니라 진짜 쓸 일이 있어서다.
"6-app first-launch PRO reinforcement + ASO + resubmission track", "automated IAP set-submit recipe", "ITMS-90683 vs ASC tracking-block trap", "재제출 트랙 4앱 Pro 실동작 시뮬 검증 기록" - 앱스토어 제출 과정에서 만나는 함정들은 시간이 지나면 잊어버린다. 다음 앱 심사 넣을 때 같은 오류 메일 받고 처음 겪는 것처럼 당황하지 않으려면 이걸 그때그때 써둬야 한다.
HTML 브리핑 파일도 하나 생겼다. report_20260802_0150_pro게이트브리핑.html - 타임스탬프 보면 새벽 1시 50분이다. 하루 어딘가에서 Pro 게이트 감사 결과를 정리해서 브리핑 자료로 만들었다는 얘기다.
mobile-app-launch.md에는 "인앱 리뷰 유도 전 앱 필수 지침 신설"이 들어갔다. IAP 심사 추가 팝오버 무반응 해법, ATT 앱 App Privacy 차단 함정도 같이. casaproof라는 참조가 있는데 이건 외부 자료에서 가져온 것 같다. 이런 지식이 쌓이는 속도가 출시 초기엔 가파르다.
ASO 동시 보강 룰
오늘 ops 문서에서 하나 눈에 띈 게 있었다. "다음 제출 라인에 ASO 동시 보강(제목·부제·키워드 꽉 채우기) 룰 추가". Pro 게이트 보강하면서 어차피 새 빌드 올리는 김에 메타데이터도 같이 점검하자는 룰. 이게 없으면 기능 작업 후 재제출할 때 ASO는 건드릴 타이밍을 놓친다. 빌드 올리는 김에 세트로 챙기자는 것.
psy 자동생성 세 개
chore(psy): daily auto-generated tests - 이건 루틴이다. friend-group-newbie, hoesik-type, sleep-paralysis-visitor. 표지 이미지 webp, JSON 콘텐츠 세트. 매일 자동으로 생성되어서 커밋으로 들어오는 구조. 오늘 날짜 스탬프가 찍혀 있다.
이게 오늘 다른 작업들과 섞여서 들어와 있는 게 좀 묘하다. 앱 일곱 개 Pro 게이트 대공사 + 대시보드 뒤집기 + docs 마라톤을 하는 날인데 심리 테스트 세 개가 조용히 옆줄에 서 있다. 자동화가 잘 된 거라는 뜻이기도 하고, 하루가 이 정도 규모로 돌아가고 있다는 뜻이기도 하다.
빌드 번호 행진
오늘 pubspec.yaml이 몇 번이나 수정됐는지 세는 게 의미가 없을 정도다. Play internal 업로드용 빌드번호 +1이 여러 앱에서 여러 번 찍혔다. iOS 쪽도 project.pbxproj, Podfile.lock, Info.plist들이 재제출마다 갱신. xcscheme 파일까지 들어간 커밋도 있다. Xcode 아카이브 후 App Store Connect 업로드, Play Console 내부 테스트 업로드 - 이 사이클을 앱별로 반복했다는 흔적들이다.
ASC에서 빌드 번호 충돌 이슈도 있었다. "빌드2 ASC 기업로드 충돌 회피"라고 메모가 있다. 같은 버전 코드로 두 번 올리면 처리 중인 빌드와 충돌난다. 그래서 +3으로 건너뛰는 식으로 피했다. 이것도 처음엔 당황하는 상황인데 이제는 그냥 번호 올리고 다시 올리는 게 몸에 밴다.
오늘 커밋 수를 다시 훑어보면 진짜 많다. 근데 여러 앱을 동시에 다루다 보니 커밋 하나하나의 체감 밀도가 높지 않았다. 같은 패턴을 반복하면서 "이건 됐고, 이건 됐고" 체크리스트를 하나씩 지워나가는 느낌에 가까웠다. 7개 앱에 Pro 게이트 다 박았고, 6개 앱 재제출 넣었고, 대시보드 그리드 두 개 올라갔고, 예치금 카드 지웠다 복구했다. 찝찝한 건 번복 하나와, 처음부터 ACTIVE 조건 안 넣은 것 정도.
문서가 오늘만큼 많이 업데이트된 날이 드문데, 이게 좀 반갑다. 나중에 같은 함정에서 이 문서 꺼내보는 날이 분명히 온다.
댓글 0
첫 댓글 달아줘.