웹은 정상인데 앱만 이상했습니다. 같은 제품이 어느새 두 개의 시스템이 되어 있었습니다
저는 개발자가 아닙니다.
핀테크와 크립토 업계에서 약 8년 일했고, 올해 AI를 이용해서 혼자 FX·송금·크립토 비교 서비스를 만들고 있습니다.
며칠 전 여기에도 AI 코딩을 하면서 느낀 회귀 버그 이야기를 올렸습니다.
당시 댓글에서 E2E 테스트를 만들어야 한다는 조언도 받았고, 기능별 exit 기준을 잡아야 한다는 의견도 받았습니다.
솔직히 그때도 많이 배웠습니다.
그런데 오늘은 또 다른 문제를 발견했습니다.
이번에는 단순히
“AI가 A를 고치면서 B를 깨뜨렸다”
정도의 문제가 아니었습니다.
같은 제품의 웹 버전과 Android 앱이 어느 순간부터 조금씩 다른 시스템이 되어 있었습니다.
오늘 처음 이상함을 느낀 건 아주 사소한 화면이었습니다.
Android 앱에서 USDT와 USDC 아이콘이 갑자기 이렇게 보였습니다.
US
DT
US
D
C
BTC와 ETH는 정상인데 stablecoin만 깨졌습니다.
처음에는 그냥 이미지 문제라고 생각했습니다.
그런데 그다음 화면을 보다가 더 이상한 걸 발견했습니다.
서로 다른 송금 업체 3개의 예상 수령액 상단값이 완전히 같았습니다.
OFX
7,431.91 ~ 7,470.38 GBP
Key Currency
7,424.44 ~ 7,470.38 GBP
TorFX
7,419.86 ~ 7,470.38 GBP
업체는 다른데 상단값이 전부:
7,470.38 GBP
였습니다.
소수점 둘째 자리까지 완전히 동일했습니다.
처음에는 제가 만든 계산 모델 특성상 그럴 수도 있나 싶었습니다.
그런데 웹 버전을 확인해 보니 같은 문제가 없었습니다.
그래서 오늘은 새 기능 개발을 멈췄습니다.
정상적으로 동작하는 웹 버전을 한쪽에 띄우고,
Android 앱을 다른 쪽에 띄운 뒤,
사실상 웹을 “정답지”처럼 사용해서 하나씩 대조했습니다.
그 과정에서 제가 생각했던 것보다 더 큰 문제를 봤습니다.
웹과 앱의 계산 및 필터링 규칙이 조금씩 달라져 있었습니다.
예를 들면 앱에서는 서로 다른 provider의 예상 수령액 상단이 공통 benchmark ceiling에 걸리면서 동일한 숫자로 보일 수 있는 구조가 있었습니다.
또 원래 제외되어야 하는 provider 목록은 존재했지만 실제 노출 필터와 제대로 연결되지 않은 부분도 있었습니다.
그러다 보니 제가 분명히 제외했다고 생각했던 업체가 앱에서는 다시 보였습니다.
여기까지는 그래도 눈으로 찾을 수 있습니다.
그런데 crypto off-ramp 쪽을 확인하면서 조금 더 심각하게 느꼈습니다.
화면에서는 사용자가:
USDT → BRL
USDC → BRL
BTC → BRL
ETH → BRL
중 하나를 선택할 수 있습니다.
그런데 일부 내부 rate source 로직은 선택된 자산과 별개로 특정 stablecoin 기준을 참조할 가능성이 있었습니다.
즉 최악의 경우:
화면에는 BTC → BRL
이라고 나오는데,
내부 benchmark의 일부는 USDC → BRL 기준을 사용
하는 식의 문제가 생길 수 있었습니다.
금융 비교 서비스에서 저는 이런 버그가 제일 무섭습니다.
버튼이 안 눌리면 사용자가 바로 압니다.
앱이 꺼져도 바로 압니다.
아이콘이 깨져도 바로 압니다.
그런데 잘못된 계산 결과가 그럴듯한 숫자로 나오면 잘 모릅니다.
예를 들어:
51,200 BRL
과
51,600 BRL
둘 다 화면만 보면 충분히 그럴듯합니다.
사용자는 내부에서 어떤 rate source를 사용했는지 모릅니다.
저도 화면만 보고 지나갈 수 있습니다.
그래서 오늘 느낀 핵심 문제는 개별 버그가 아니었습니다.
같은 제품을 만들고 있다고 생각했는데:
웹 수정
→ 앱에 미반영
앱 hotfix
→ 웹과 로직 차이 발생
provider 추가
→ 한쪽에만 필터 반영
crypto route 수정
→ 한쪽 source asset 처리만 변경
예외 조건 추가
→ 다른 플랫폼에는 과거 로직 유지
이런 식으로 작은 차이가 계속 누적되고 있었습니다.
각 수정 당시에는 전부 사소했습니다.
한두 줄이었습니다.
당장 화면은 잘 나왔습니다.
빌드도 성공했습니다.
그런데 몇 주가 지나니:
하나의 제품
두 개의 구현
두 개의 예외 규칙
두 개의 계산 결과
가 되어가고 있었습니다.
오늘 거의 하루 종일 이걸 대조했습니다.
새로운 기능은 사실상 거의 못 만들었습니다.
현재 제품은 웹과 Android 앱으로 운영하고 있습니다.
웹 버전은 transferiq.org 입니다.
홍보하려고 링크를 적는다기보다, 실제 공개된 제품에서 이런 문제가 발생하고 있다는 맥락을 보여드리고 싶었습니다.
저는 비개발자라서 처음에는 이렇게 생각했습니다.
“웹도 만들고 앱도 만들면 되지.”
그런데 지금은 생각이 달라졌습니다.
특히 금융 계산처럼 같은 입력이면 플랫폼과 관계없이 같은 결과가 나와야 하는 제품에서는, UI보다 먼저 공통 계산 엔진을 강제해야 하는 것 아닌가 싶습니다.
현재 제가 생각 중인 방향은 이렇습니다.
1. quote engine을 공통 core로 분리
2. 웹과 앱이 동일한 JSON fixture 사용
3. 주요 통화쌍에 golden test 작성
4. 동일 입력값을 웹/앱에 넣고 결과 차이를 자동 비교
5. disabled provider가 다시 노출되지 않는 regression check
6. selected asset과 실제 market rate source가 일치하는지 검사
여기서 경험 있는 개발자분들께 정말 피드백을 받고 싶습니다.
제 상황이라면 무엇부터 하는 게 맞을까요?
공통 shared core부터 분리하는 게 우선일까요?
아니면 현재 구조를 유지하면서 parity test부터 만드는 게 현실적일까요?
unit test를 먼저 해야 할까요?
E2E를 먼저 해야 할까요?
CI에서 웹과 앱 결과를 비교하게 만드는 게 맞을까요?
특히 웹과 모바일에서 동일한 금융 계산 결과를 유지해야 하는 서비스를 운영해 보신 분들의 경험이 궁금합니다.
오늘은 정말 답답했습니다.
기능 하나 고치면 다른 문제가 보이고,
그걸 고치면 또 과거에 정상이라고 생각했던 부분이 이상해 보였습니다.
그래도 오늘 하나는 확실히 배웠습니다.
같은 제품이라고 해서,
같은 로직으로 움직이는 것은 아니었습니다.
그걸 시스템적으로 강제하지 않으면,
웹과 앱은 생각보다 빠르게 서로 다른 제품이 되는 것 같습니다.