Repository navigation
fix(app): 수신자 홈 기록 수 실패를 개수 자리 대시로 표기 (#952) - #1020
Conversation
종전에는 문장을 통째로 «기록 수를 불러오지 못했습니다.» 로 갈아 끼우고 마음의 기록 통계 카드 행을 숨겼다. 실패한 화면과 정상 화면의 구성이 달라지고, 카드가 통째로 사라지면 «기능이 없는 것» 과 «못 불러온 것» 도 구분되지 않는다. 시안 확정값(4309:19394)은 레이아웃 유지 + 개수 자리만 대시다. 세 섹션 공통으로 문장 구조를 그대로 두고, 통계 카드도 숨기지 않고 «–» 를 표시한다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
❌ Screenshot test fail — baseline 과 CI rendered PNG 차이. 📦 Artifact: https://github.com/Afternote/Afternote-FE/actions/runs/32707204627 (페이지 하단 Artifacts → 🔍 확인 위치 (artifact zip 내부):
📝 조치 가이드:
CI ↔ 로컬 환경 차이는 본 워크플로의 container 단계가 root fix 한다 (README 의 "Compose Preview Screenshot Testing (docker baseline)" 섹션 참조). |
receiverHomeScreenPartialFailureScreenshot 이 mindRecord=null 상태를 그린다 — 통계 카드가 살아나고 개수 자리가 «–» 로 바뀐 의도된 시각 변경이다. CI 와 같은 docker 컨테이너(Dockerfile.screenshot)에서 생성했다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
총평
«레이아웃 유지 + 숫자 자리만 대시» 라는 확정값을 정확히 옮겼고, «카드를 숨기면 기능 없음과 못 불러옴이 구분되지 않는다» 는 판단도 맞습니다. en dash 를 리소스로 빼고 주석으로 못 박은 것도 좋습니다. 머지 전 CI red 하나만 정리해 주세요.
지적
- [blocking] 스크린샷 baseline 미갱신 — CI red. 본문에 적어 두신 그대로입니다.
receiverHomeScreenPartialFailureScreenshot이 정확히 이 상태를 덮고 있어 의도된 변경이 맞습니다. Docker 가 없어 못 하신 거면 제가 대신 돌려도 됩니다 — 말씀 주세요. - [normal]
unavailableCountLine이 남아 파라미터 2개로 부풀었다 →feature/receiver/presentation/src/main/kotlin/com/afternote/feature/receiver/presentation/home/component/HomeSectionCard.kt:99인라인. - [normal] 인덱스로 두 번째 노드만 본다 →
feature/receiver/presentation/src/test/kotlin/com/afternote/feature/receiver/presentation/home/component/ReceiverHomeCountFallbackTest.kt:49인라인.
참고 — Analyze (java-kotlin) red 는 이 PR 책임이 아닙니다
실패 원인이 KSP/Hilt 였습니다.
e: [ksp] MainActivity.kt:19: [Hilt] @AndroidEntryPoint base class must extend ComponentActivity, …
e: [ksp] GlobalApplication.kt:13: [Hilt] @HiltAndroidApp base class must extend Application. Found: kotlin.Any
> KSP failed with exit code: PROCESSING_ERROR
이 PR 은 :app 을 건드리지 않고 :feature:receiver:presentation 에서 :app 으로 가는 의존도 없습니다. 같은 base(develop)의 다른 PR(#1052·#1021)은 같은 체크가 green 이었습니다.
재실행해서 확정했습니다 — run 32728279766 에서 pass (7m38s). 코드 변경 없이 green 이 됐으니 캐시/CodeQL 트레이서 쪽 플레이키였습니다. 이 항목은 신경 쓰지 않으셔도 됩니다.
검증
- 시안 대조: 링크는 확인, 노드 직접 열람은 못 했습니다. 본문의 4309:19394 가 근거로 걸려 있으나, 이 세션의 Figma 커넥터가 미인증 상태라 노드를 직접 열지 못했습니다. 코드 쪽 결과(문장 구조 유지, 카드 존치, 개수 자리만
–)가 본문 서술과 일치하는 것까지 확인했습니다. - 실기동 QA: 해당 없음. 수신자 홈은
delivery-verificationAPPROVED 상태라야 진입하는데 승인 API 가 없어 도달 불가라는 본문 설명이 #618·#614 와 일치합니다. Robolectric 렌더 테스트로 갈음한 판단에 동의합니다.
| */ | ||
| @Composable | ||
| fun unavailableCountLine(): AnnotatedString = AnnotatedString(stringResource(R.string.receiver_home_section_count_unavailable)) | ||
| fun unavailableCountLine( |
There was a problem hiding this comment.
[normal] 이 함수가 이제 rememberCountLine 을 한 겹 감싸기만 하는데, 그 대가로 호출부마다 suffix 리터럴이 if/else 양쪽에 두 번 적히게 됐습니다.
// MindRecordSection.kt:35-42
if (summary == null) {
unavailableCountLine(suffix = "마음의 기록이 있습니다.")
} else {
rememberCountLine(prefix = "${summary.totalCount}개 ", suffix = "마음의 기록이 있습니다.")
}한 문장이 두 곳에 있으면 나중에 한쪽만 고쳐질 자리입니다. 게다가 애프터노트 섹션만 «개» 뒤 공백이 없다는 차이를 맞추려고 countUnitSpacing 파라미터까지 생겼습니다.
갈래를 개수 자리 하나로 좁히면 함수도 파라미터도 사라집니다.
countLine = rememberCountLine(
prefix = "${summary?.totalCount?.toString() ?: stringResource(R.string.receiver_home_section_count_unavailable)}개 ",
suffix = "마음의 기록이 있습니다.",
)이 PR 이 만든 문제는 아니지만(문구 하드코딩은 종전부터입니다), 지금이 갈래를 늘리지 않고 줄일 수 있는 시점이라 짚습니다.
| composeRule.onNodeWithText("데일리 질문").assertIsDisplayed() | ||
| composeRule.onNodeWithText("일기").assertIsDisplayed() | ||
| // 두 카드의 개수 자리가 모두 대시다. | ||
| composeRule.onAllNodesWithText("–")[1].assertIsDisplayed() |
There was a problem hiding this comment.
[normal] 주석은 «두 카드의 개수 자리가 모두 대시» 인데, 단언은 인덱스 1 하나만 봅니다. 0번은 확인되지 않고, 노드 순서가 바뀌면 조용히 다른 것을 보게 됩니다.
의도를 그대로 쓰는 편이 낫습니다.
composeRule.onAllNodesWithText("–").assertCountEquals(2)이러면 «한 장만 대시로 남는» 회귀도 잡힙니다.
|
스크린샷 baseline 갱신했습니다 — CI 와 같은 docker 컨테이너( |
unavailableCountLine 이 rememberCountLine 을 한 겹 감싸기만 하면서, 호출부마다 같은 문장이 if/else 양쪽에 두 번 적히게 됐다 — 한쪽만 고쳐질 자리다. 애프터노트 섹션의 «개» 뒤 공백 차이를 맞추려고 파라미터도 하나 늘었다. countText(count) 하나로 좁히면 함수도 파라미터도 사라지고 문장은 한 곳에만 남는다. 테스트도 인덱스 하나가 아니라 두 카드가 모두 대시인지 센다. 리뷰 지적. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
OnlyReadOneBook
left a comment
There was a problem hiding this comment.
총평
지적 3건 전부 정리됐습니다. 특히 2번은 «갈래를 문장이 아니라 개수 자리 하나로 좁힌다» 를 그대로 실행해, 함수 하나(unavailableCountLine)와 파라미터 하나(countUnitSpacing)가 통째로 사라지고 호출부 세 곳의 if/else 도 없어졌습니다. 같은 문장이 두 번 적혀 한쪽만 고쳐질 자리가 정리됐습니다. 승인합니다.
반영 확인
- [blocking] 해소.
a6de2040에서 baseline 갱신, 최신 head 기준Validate Compose Preview Screenshotsgreen. - [normal] 해소.
countText(count: Int?)하나로 수렴. 애프터노트 섹션만 «개» 뒤 공백이 없는 차이도 각 호출부의suffix리터럴에 그대로 남아 표기가 바뀌지 않았습니다. - [normal] 해소.
onAllNodesWithText("–").assertCountEquals(2)— «한 장만 대시로 남는» 회귀도 이제 잡힙니다.
검증
- CI: head
84c4181d기준 실패·취소 체크 0건. - 리팩터링이 렌더를 바꾸지 않았다는 실증: baseline 은 21:39(
a6de2040)에 갱신됐고 그 뒤 22:25 의 이번 리팩터링 커밋에서는 baseline 이 손대지지 않았는데도 스크린샷 체크가 green 입니다. 즉unavailableCountLine→countText전환이 출력 문자열을 그대로 유지했다는 뜻이라, 별도 확인이 필요 없습니다. - develop 접점:
merge-tree충돌 0건, merge-base 이후 develop 이 건드린 파일과의 교집합도 0건. - 시안 대조: 지난번과 같음 — 링크는 확인, 노드 직접 열람은 못 했습니다. Figma 커넥터가 여전히 미인증입니다. 다만 이번 변경은 표기가 아니라 갈래 구조만 손댔고 위 스크린샷 근거로 렌더가 동일함이 실증돼, 시안 확정값(레이아웃 유지 + 숫자 자리만
–)과의 관계는 지난 리뷰에서 확인한 그대로입니다. - 실기동 QA: 해당 없음(지난번과 동일). 수신자 홈은
delivery-verificationAPPROVED 라야 진입하는데 승인 API 가 없어 도달 불가 — #618·#614 와 같은 사정입니다. Robolectric 렌더 테스트로 갈음한 판단에 동의합니다.
작은 관찰 하나를 인라인으로 남겼습니다 — blocking 아닙니다.
| */ | ||
| @Composable | ||
| fun unavailableCountLine(): AnnotatedString = AnnotatedString(stringResource(R.string.receiver_home_section_count_unavailable)) | ||
| fun countText(count: Int?): String = count?.toString() ?: stringResource(R.string.receiver_home_section_count_unavailable) |
There was a problem hiding this comment.
[nit] 이름이 아주 일반적인데(countText) 패키지 레벨 public 입니다. 같은 패키지의 다른 화면에서 «개수를 문자열로» 정도의 뜻으로 끌어다 쓰면, 실제로는 «수신자 홈의 조회 실패 표기 규칙» 이 딸려 옵니다.
internal 로 좁히거나 이름에 맥락을 넣으면(countOrDash 류) 오용 여지가 줄어듭니다. 지금 범위에서 문제가 생기는 건 아니니 후속으로 보셔도 됩니다.
Closes #952
무엇을 했나
시안 확정값(0823, 4309:19394)대로 레이아웃은 유지하고 개수 자리만
–로 바꿨다.–개 마음의 기록이 있습니다.(문장 구조 유지)summary == null이면 행을 통째 숨김–왜 카드를 남기나
숨기면 «기능이 없는 것» 과 «못 불러온 것» 이 구분되지 않는다. 실패한 화면과 정상 화면의 구성이 달라지는 것도 이슈가 든 문제다. 개수만 미상으로 두면 둘 다 해소된다.
–는 en dash 다(hyphen 아님). 문자열 리소스에 그 취지를 주석으로 남겼다.회귀 가드
ReceiverHomeCountFallbackTest3개 — Robolectric + Compose 로 실제로 그려서 문구와 카드 존재를 읽는다. 「레이아웃을 유지하는지」는 상태 단언으로는 확인되지 않는 성질이라 렌더로 봤다.고치기 전 코드로 되돌리면 잡힌다.
receiverHomeScreenPartialFailureScreenshot이 정확히 이 상태(mindRecord = null,afternoteTotalCount = null)를 덮고 있어 의도된 시각 변경으로 baseline 이 어긋난다. CI 의Validate Compose Preview Screenshots가 이 PR 에서 실패한다.제 환경에 Docker 가 올라와 있지 않아 갱신하지 못했다. README 가 «host 직접 실행은 CI 와 baseline 이 어긋난다» 고 명시하고 있어 macOS 에서 생성하지 않았다 — 잘못된 baseline 을 커밋하면 다른 PR 까지 깨진다.
diff 는 «통계 카드 행이 살아나고 개수 자리가
–로 바뀐» 한 장이어야 한다. 그 외 변화가 있으면 알려 주시면 확인하겠다.실기기 시연은 못 했다
수신자 홈은
delivery-verificationAPPROVED 상태라야 진입하는데 승인 API 가 수신자·발신자 어느 쪽에도 없다(#618·#614 에서 확인한 것과 같은 사정). 그래서 실기 대신 JVM 에서 컴포넌트를 실제로 렌더해 문구를 읽는 테스트로 갈음했다.검증
🤖 Generated with Claude Code