리포트·종목 상세의 이전 숫자 노출에서 최신 확인 후 공개로 (2026-09-11)
- 기간: 2026-09-11 — 오너 보고 "기존 숫자가 한번 떴다가 재계산되서 뭔가 숫자가 바뀌는 모습이 보여"에 따른 #1563 수리.
- 랜딩: 앱 PR #1570,
release/v0.17.11, merge782248231b59f1005d44aff68bd5a84044badd7c, 14:26:40 KST. DB·Edge 변경 없음, Production 미출시. - 설계서: 없음(수리 건).
- 정본: 리포트 계약, 종목 상세 계약, 앱의
reportStatsReadiness.ts·statsNumberReadiness.ts·공용StatValue.tsx. - 도구: 기존 Node 테스트·실제 React 컨트롤러/화면 브라우저 검사, 지연 응답 fixture. 로컬 로그는 작업 디렉터리의
precheck-final.log·targeted-candidate.log·overview-fixed2.log이며 문서에 실행 결과만 기록한다. - 게이트: 최종 로컬 precheck 성공, 관련 회귀 40/40 및 게시 후 개요 보완 24/24 성공(중복 합산 안 함). 이슈 검증 보고, Merge Check 전체 성공(57초), 실제 병합 보고. DB·pgTAP 변경 없음.
- 버그리포트: BUG-119.
- 계약: 두 화면 계약의
최신 통계 숫자 공개절과 종목 상세statsStatus·onRetryStatsprops.
1. 배경
v0.17.10의 화면 깜빡임·로딩 개선 후, 오너가 리포트 또는 종목 상세에서 이전 통계 숫자가 먼저 보였다가 바뀌는 현상을 보고했다. 이번 범위는 본인 모바일·PC 리포트와 종목 상세이며 홈 UI는 변경하지 않았다.
2. 문제 제기
캐시가 있다는 사실이 최신 수치의 근거가 됐다
완성된 화면을 보존하는 데이터 캐시와 최신 통계의 준비 상태가 함께 취급됐다. 조회 시작 뒤에만 숫자를 가리면 첫 프레임의 이전 수치는 여전히 보인다. 리포트 개요만 최신이거나 종목 initial만 새로 도착한 경우에도 상세의 필수 응답이 아직 이전 세대일 수 있었다. 원인과 재현은 BUG-119에 기록했다.
3. 해결 방안
원칙 — D1, 2026-09-11
오너 요청 "그 숫자만 스켈레톤 처리 했다가, 나중에 완료되서 보여주게 할 수 있을까?"를 첫 렌더와 재계산 갱신에 모두 적용했다. 캐시 → 스켈레톤 → 최신 숫자 노출을 피하려고 최신 여부 미확인 상태부터 pending으로 시작한다.
접근
표시 상태를 데이터 객체와 분리하고 기존 live 응답을 확인한다. 고정 대기 시간이나 캐시 선공개 뒤 숨기기는 완료를 보장하지 못해 기각했다. 공개 조건과 대안 비교는 BUG-119를 따른다.
4. 적용한 내용
주요 결정과 그 근거
- 리포트는 현재 owner·기간·필터·
asOf의 개요와 모바일 정밀 응답을 기다린다. 통계 요청 세대가 증가하면 정밀 조회의 revision도 바꾼다. - 종목 상세는 같은 owner·exercise·세대·
asOf의 live initial과 현재 연도·PR 기록·운동 이력 필수 조각을 모두 확인한다. 늦게 도착한 다른 조건의 응답은 공개 근거가 될 수 없다. pending은 숫자 자리 스켈레톤,ready는 최신 수치,error는—와 다시 불러오기다. 수치와 연관된 비율·등급·그래프 값도 같은 기준으로 표시한다. 제목·카드·선택 상태·스크롤은 보존한다.- 이미 확인된 같은 조건의 화면 왕복은 확인 결과를 재사용한다. Home/Report 스택에서 연 활성 종목 상세도 최신 게시 뒤 다시 읽는다.
작업 중 드러난 것
사용하지 않는 탭의 오래된 스냅샷이 현재 화면의 회복을 반복시키지 않도록 개요의 관측 범위를 조정했다. 회복 게시 직후 이전 개요가 남는 시점도 검사하고 보완 묶음 24/24로 재검증했다. 실패나 회복 시도 소진을 무한 스켈레톤으로 남기지 않는다. 테스트 단언 완화·skip 추가·고정 지연으로 통과시키지 않았다.
5. 적용 결과
| 항목 | 결과 |
|---|---|
| 최초 숫자 공개 | 캐시 숫자 선노출 가능 → live 최신 여부 및 필수 응답 확인 후 공개 |
| 재계산 중 표시 | 이전 값 표시 후 숫자 교체 → 숫자 자리 스켈레톤 후 최신 값 공개 |
| 조회 실패 | 이전 값이 확정 값처럼 남을 가능성 → — 및 재시도 |
| 화면 왕복 | 같은 조건의 최신 응답 재사용, 불필요한 숫자 가림 방지 |
| 최종 로컬 precheck | local-1789100574325-38416, 타입·lint·unused·빌드·산출물 성공. 전체 3,450 / 성공 3,415 / 실패 0 / 조건부 skip 35, 성공률 98.99%. 브라우저 제외 |
| 관련 회귀 | 40/40 성공, 실패·skip 0, 성공률 100%. 실제 컨트롤러와 화면의 최초 노출·순서·레이아웃·오류 검사 |
| 게시 후 개요 보완 회귀 | 24/24 성공, 실패·skip 0, 성공률 100%. 앞선 묶음과 중복되어 합산하지 않음 |
| 적용·미검증 | v0.17.11 release 병합 완료. Production 미출시, 운영 서버를 포함한 전체 사용자 여정 미검증. 이번 로컬 precheck를 앱 Full CI 통과로 보고하지 않음 |
6. 이번 개선으로 향상된 것
최신 수치인지 화면에서 구분할 수 있다
첫 프레임부터 준비 상태를 표시하고 완료 후 숫자를 공개한다. 캐시·현재 요청·필수 조각·실패를 별도 상태로 다루는 계약과 회귀 검사가 남아, 화면 보존이 오래된 숫자 공개로 이어지는 것을 막는다. 실제 노출 시간·발생 빈도에 대한 Production 전후 수치는 측정하지 않았다.
남은 것
Production 출시는 후속 릴리스 승격 범위다. 이번 기록은 release/v0.17.11 반영과 로컬 검증을 다루며 운영 반영 완료로 표시하지 않는다.