일기 slecs

ASC 함정 다 밟으며 앱 넷 심사 올린 날

목차

파트너포털 주문관리 쿠폰탭 묶음 보기 기능부터 붙이기 시작했다. 아침의 첫 커밋이었다.

배치로 발급된 쿠폰들 - 예를 들어 한 파트너가 한 번에 100장 발급한 주문 - 을 개별 로우로 쭉 늘어놓으면 보기 불편하다는 피드백이 있었다. 기획은 간단했다. 배치 단위로 묶어서 접힌 상태로 보여주고, 클릭하면 펼쳐지게. 근데 쿼리부터 시작해서 ap 쿼리 매퍼, co 쿼리 매퍼 두 군데를 동시에 건드려야 했다. 파트너포털 쪽 컨트롤러 클래스도 배치 그룹 결과를 반환하는 메서드가 새로 필요했고, JSP에서는 묶음 행을 처리하는 토글 로직, 투어 스텝 JS 파일까지 수정이 번졌다. 커밋 하나에 파일이 여섯 개.

기능 자체가 문제가 아니라 그 이후가 더 걸렸다. 묶음 펼침을 다크모드로 보니까 글자가 안 보인다. 열어보니 CSS 변수가 정의되지 않은 것을 그대로 참조하고 있었다. 어딘가 복붙하다 끊어진 것인데 apple 테마 변수로 바꿔주니까 해결. 별거 아닌 것 같아도 QA 없이 올렸으면 파트너들 화면에서 다크모드 사용자만 텍스트가 검은 배경에 검은 글씨로 뜨는 상황이 됐을 거다.

명암비 전수 보정, 죽은 컬럼 처형

다크모드 수정을 하다 보니 WCAG AA 명암비 문제가 눈에 들어왔다. 쿠폰탭 전체를 양 테마에서 다 훑어야 했다. 다크, 라이트 각각 체크하면서 기준 미달인 요소들을 전수 보정했다. 이런 작업은 솔직히 시간이 얼마나 걸릴지 가늠이 안 된다. 색 하나 바꾸면 연결된 상태 색이 어긋나고, 그걸 맞추면 포커스 링이 흐려지고. 결국 orders.jsp 파일을 오늘 총 다섯 번 커밋했다.

정산 컬럼 삭제는 오히려 시원했다. 데이터가 연결되지 않은 채 컬럼만 자리 차지하고 있던 거라서, 죽은 컬럼이라는 걸 확인하자마자 그냥 날렸다. 언젠가 연결할 것처럼 남겨두는 것보다 깔끔하게 지우는 게 맞다. 애초에 있는 것처럼 보이는 빈 컬럼이 파트너 입장에서 더 혼란스럽다.

가로스크롤 문제는 구매자·수신인 필드를 한 줄로 억지로 늘리는 것에서 비롯됐다. 2줄 표기로 전환하니까 가로스크롤이 사라졌다. 대신 쿠폰명 폭을 확대하면서 구매일시를 2줄로 양보받는 식으로 균형을 잡았다. 구매일도 yyyy-MM-dd만 있던 걸 yyyy-MM-dd HH:mm으로 올렸다. 날짜만 있고 시각이 없으면 같은 날 여러 건 주문 들어왔을 때 구분이 안 된다.

묶음보기 리스트에서도 구매일시에 시각이 빠져 있어서 같이 붙였다. 기능 하나 붙이면 따라오는 게 이렇게 많다.

예치금 목록 - 쿼리에서 잘라야 할 게 두 가지였다

파트너포털 작업을 마무리하고 예치금 관리 목록으로 넘어갔다. 거절·해지 상태 파트너가 목록에 그대로 잡혀 있다는 것, 그리고 판매포탈과 발송포탈이 같은 파트너에 대해 별도 로우로 뜨고 있다는 것. 두 문제가 동시에 들어온 거다.

전자는 쿼리에서 상태 조건 추가하면 되는데, 후자가 좀 더 신경 썼다. 판매·발송포탈 그룹을 단일 로우로 합산하는 거라서 GROUP BY 구조를 손봐야 했고, 엑셀 내보내기 쪽 ExcelConfigRegistry.java도 컬럼 매핑이 틀어지지 않게 같이 수정했다. 엑셀 내보내기까지 건드리는 걸 빠뜨리면 화면에서는 합산돼서 보이는데 다운로드 파일에서는 분리 로우로 나오는 이상한 상황이 된다. 이런 게 나중에 리포트로 올라오면 원인 추적이 꽤 걸린다.

인증·충전 진행 페이지 당겨서-새로고침 차단은 커밋 제목만 보면 별거 아닌 것 같은데 영향 범위가 넓었다. kyc.jsp 두 군데 (공통, 멤버), account-verify.jsp 두 군데, reauth.jsp, charge.jsp까지 여섯 파일. 이유는 단순하다. 진행 중 새로고침하면 인증 상태가 초기화돼서 처음부터 다시 해야 한다. 특히 KYC 진행 중에 실수로 당겨서 새로고침 되면 사용자 입장에서는 황당한 경험이다. 브라우저 기본 동작을 막는 처리는 간단하지만 진행 페이지 전부 빠짐없이 적용해야 한다는 게 귀찮은 부분이다.

블로그 발행 성공 알림이 텔레그램으로 계속 오던 것도 오늘 잘랐다. bulk_seed.py에서 성공 케이스 텔레그램 발송만 제거했다. 디스코드 알림은 유지. 성공 알림은 노이즈다. 실패했을 때만 울리면 된다.

오늘의 본게임 - 앱 네 개 동시 ASC 제출

이쯤에서 iOS 쪽으로 전환했는데, "전환"이라고 썼지만 실제로는 파트너포털 작업 틈틈이 앱 쪽 커밋이 섞여 들어가고 있었다. 오늘의 커밋 목록을 보면 대략 감이 오겠지만, 동시에 TallUp, HearWise, ArrowWise, Zipwise 이렇게 네 앱의 스토어 제출 작업이 병렬로 돌아가고 있었다. 각 앱마다 포크 베이스가 다르고, ASC 앱 ID가 다르고, IAP 구성이 다르고, 스크린샷 팔레트가 달랐다.

ArrowWise는 양궁 앱이다. 오늘 많은 커밋이 이쪽에 몰려 있다. frame_screenshots.py로 80장 프레임드 스크린샷을 만들어야 하고, 5개 로케일 이상에서 iPad, iPhone 각 사이즈별로 찍어야 한다. 스크린샷 하네스에서 마커 폴링 방식으로 캡처 시점을 동기화하는 로직을 새로 붙였다. 이게 없으면 화면이 전환 중인 타이밍에 캡처가 터져서 반쯤 렌더된 화면이 찍힌다. path_provider도 연결해서 저장 경로 잡고, build_cap_screenshots.sh로 자동화 파이프라인 구성.

iPad 스크린샷에서 컬럼 바깥쪽에 새까만 레터박스가 생기는 문제가 있었다. Scaffold를 추가하니까 해결됐다. 별거 아닌 수정인데 이걸 모르고 제출하면 심사 중에 반려될 수 있다.

l10n 쪽에서는 양궁 용어를 제대로 잡아야 했다. ko, ja, es, pt, fr, de, it 7개 로케일에 대해 native archery terminology pass를 돌렸다. 기계 번역으로 대충 처리하면 일본어로 "화살"을 전혀 다른 문맥 단어로 쓰거나 독일어 양궁 용어가 일반 사격 용어로 섞이는 일이 생긴다.

PDF 내보내기도 이 앱에 들어갔고, 단위 전환 로직도 손봤다. imperial default 설정, 신장 차트 축이 디스플레이 단위에 맞게 플롯되도록. units_test.dart까지 붙여서 단위 변환 검증.

HearWise 청각 앱의 의료기기 선언 게이트

HearWise는 소리 증폭기다. resono 포크라서 AVAudioEngine 네이티브 패스스루 구조를 그대로 가져왔고, 8로케일, $6.99 라이프타임 IAP. 여기서 ASC 제출할 때 하나 막혔는데, 규제 의료기기 선언 게이트가 있었다. 청각 관련 앱이라서 심사 전에 "이 앱은 규제 의료기기가 아닙니다"라는 선언을 명시적으로 체크해야 통과된다. 이게 docs에 오늘 실측으로 추가됐다. 처음 보는 화면이라서 뭔지 몰라서 잠깐 멈췄다.

TallUp은 키 높이 스트레칭 앱, bendwise 포크. 여기서 버그가 좀 있었다. DST(일광절약시간) 적용 구간에서 스트릭 카운트가 오래됐다. 자정이 넘을 때 타임존 오프셋이 바뀌면서 날짜가 두 번 또는 건너뛰는 케이스. 스트릭 계산 로직을 수정했다. 리마인더 시간대 버그도 같이 잡았는데, 타임존 기준을 로컬에서 고정 UTC로 잘못 가정하고 있던 부분이었다. Pro 환불 후에도 Pro 상태가 유지되는 버그, 리마인더 개수 제한 우회 문제. 이 세 가지가 한 커밋에 묶였다.

신장 차트 축이 안 읽히는 문제는 단위 표기 방식이 원인이었다. 축 레이블이 너무 촘촘하거나 단위가 px 단위로 표시되고 있어서 실제 수치로 바꿔주니 해결. progress_screen.dartunits.dart 수정.

iOS 키워드 확정 카피 저장 커밋이 여러 번 들어간 것은 여러 앱의 store/listing.md를 앱마다 반복해서 저장했기 때문이다. 각 앱마다 리포지터리가 분리돼 있으니 각각 커밋이 생겼다.

ASC 함정들은 오늘 docs/mobile-app-launch.md에 꽤 추가됐다. 두 가지가 오늘 실측으로 새로 들어갔다.

첫 번째, copyright 409. 이미 한 번 겪었던 오류인데 TallUp 제출하면서 재발했다. API로 copyright 필드 업데이트할 때 특정 타이밍에 충돌이 발생한다. 재시도하면 보통 해결되는데 타이밍 맞추는 게 귀찮다. 문서에 재발 함정으로 보강해서 다음에 또 보면 바로 알 수 있게.

두 번째, 신규 앱 생성 버튼. ASC에서 신규 앱을 만들 때 화면 우상단에 버튼처럼 보이는 게 사실 드롭다운 메뉴다. 처음 보면 그냥 버튼처럼 생겨서 클릭하면 앱 생성 폼으로 가는 줄 아는데, 실제로는 메뉴가 열려서 "새 앱", "새 앱 클립" 같은 선택지가 나온다. 직관적이지 않은 UI인데 이것도 실측 추가.

개발자 서명 사이드로딩 절차도 오늘 문서에 들어갔다. 실기기 직접 설치 테스트 트랙 - TestFlight 없이 개발 서명으로 .ipa를 기기에 올려서 확인하는 흐름. 이게 필요할 때마다 기억을 더듬어서 하게 되니까 한 번 적어두기로 했다. OneDrive 인증서 백업 경로 이동 반영도 같이.

ArrowWise 수동 서명과 팔레트 충돌

ArrowWise ios/Runner.xcodeproj/project.pbxproj를 직접 열어서 수동 서명으로 전환했다. Runner 타겟의 각 빌드 구성에 AppStore 프로비저닝 프로파일과 배포 아이덴티티 해시를 박았다. Xcode 자동 서명은 제출 직전에 의도치 않게 프로파일을 바꾸는 경우가 있어서 명시적으로 잡는 게 더 안전하다.

ASC 스크립트들도 오늘 정리가 많이 됐다. asc_appinfo.py에서 앱 ID를 채우고, asc_listing.py에서 ko/ja 프로모 문자열에 화살표 특수문자가 들어가면 거부되는 문제가 있어서 제거했다. ko와 일반 마크다운에서 unfenced 블록 파싱이 제대로 안 되던 것도 픽스. asc_iap.py로 IAP 등록, asc_price_avail.py로 가격·지역 설정, asc_ss_upload.py로 스크린샷 업로드까지.

스크린샷 팔레트 얘기를 하나 더 하자면, ArrowWise 프레임 색으로 앰버를 쓰는데 처음에 resono(청록 계열 그린)랑 겹치는 톤이 들어갔다. 각 앱마다 팔레트를 명확히 구분해야 ASC 스크린샷을 여러 앱에서 관리할 때 섞이지 않는다. ArrowWise는 forest/amber, resono는 초록, 이런 식으로. 틀렸을 때 다시 찍고 프레임 다시 씌워서 올리는 게 생각보다 시간을 잡아먹는다.

Zipwise는 casaproof 포크로 압축 파일 앱이다. zip/rar/7z/tar/gz/bz2 엔진을 ArchiveEngine.swift에 넣었는데, 픽스가 하나 있었다. 7z 헤더 암호화, rar 비밀번호 오류, xz 중첩 경로, zip 리더 메모리 이레게 네 개 케이스에 대한 픽스처 검증 코드. archive engine은 엣지 케이스가 많아서 테스트 케이스를 직접 만들어서 돌려봐야 한다.

여러 앱을 병렬로 들고 있다는 것

오늘 커밋 목록의 절반이 docs(store): iOS 키워드 확정 카피 저장 - 다음 버전 반영 대기다. 앱마다 리포가 분리돼 있으니 당연히 그렇게 찍힌다. 실제로 각 앱의 listing.md에 키워드, 부제목, 설명 카피를 확정한 버전으로 저장해두는 것인데, 이게 "다음 버전 반영 대기"라는 표현처럼 ASC 버전 제출 타이밍에 맞춰서 적용된다.

네 앱을 동시에 진행한다는 게 무슨 느낌이냐면, 컨텍스트 스위칭이 끊임없이 발생한다. ArrowWise IAP 설정하다가 HearWise 의료기기 선언 게이트 막히면 그쪽 처리하고, TallUp 리마인더 버그 잡다가 Zipwise archive engine 테스트 결과 확인하고. 각 앱의 ASC ID, bundle ID, 인증서 프로파일이 다 다르니까 실수 한 번 하면 잘못된 앱에 메타데이터가 들어갈 수도 있다. 그래서 locale_map.json, listing.json 같은 파일에 앱별 설정을 명시적으로 분리해두는 게 중요하다.

심사 제출 완료 - version과 IAP 모두 WAITING_FOR_REVIEW로 들어간 것도 오늘 찍혔다. feat(store): iOS 1.0 + IAP submitted for review (both WAITING_FOR_REVIEW). l10n 파일들 - de, es, fr, it, ja 로컬라이제이션 생성 파일들도 이 커밋에 들어갔다.

psy 자동 테스트와 한 줄 짜리 마무리

chore(psy): daily auto-generated tests 커밋은 심리 테스트 콘텐츠 사이트 쪽 자동 생성분이다. abandoned-hospital-bell, family-bbq-role, photo-booth-type 세 개 테스트가 오늘 날짜로 생성됐다. 이건 파이프라인이 자동으로 돌리는 거라 커밋이 찍히는 것만 확인했다.

오늘 총 커밋 수를 세면 50개가 넘는다. 파트너포털 백엔드·프론트, 예치금 쿼리, iOS 앱 네 개, ASC 스크립트, 문서화. 어느 한 파트만 있어도 하루치 작업인데 다 섞여 있다.

다 올라가 있다. 내일 심사 결과가 뭐가 나올지.

댓글 0

첫 댓글 달아줘.