Skip to content

refactor(platform): 컴포저블 no-op 콜백 디폴트 — 재발 가드·컨벤션 도입 + afternote 잔여 2건 #1388

Closed

Description

@OnlyReadOneBook

작업 유형

refactor — 동작 변경 없는 구조·책임·경계 개선

주 담당 모듈

platform — Android 앱·CI·빌드·릴리스·저장소 운영

개요

컴포저블 콜백 파라미터의 no-op 디폴트(onXxx: (...) -> Unit = {})는 배선을 빠뜨려도 컴파일이 통과하고 조용히 no-op 이 되게 한다. 실사고 전례가 #582 · #618 · #722 · #777 로 반복됐다.

2026-08-30 — 담당 모듈별로 분할했다. 이 이슈에는 전 모듈 공통 재발 가드·컨벤션과 afternote 잔여 2건만 남는다. 실제 청소 작업 84건은 아래 자식 이슈가 담당한다.

현행 실측 (origin/develop, 2026-08-30)

git grep -cE "on[A-Z][A-Za-z]*: \(\([^)]*\) -> Unit\) = \{ ?\}" -- "*/src/main/*.kt"
모듈 0828 최초 실측 현행 담당 추적
mindrecord 33 47 (+14) @Sadturtleman #1540
timeletter 34 34 @koongmai #1541
home 3 3 @Sadturtleman #1540
afternote 24 2 @1hyok 이 이슈
receiver 14 0 ✅ @1hyok 해소됨
core · app 0 0 — —
합계 108 86

afternote 22건과 receiver 14건은 그동안의 개별 PR 로 해소됐다. 이 이슈의 직접 청소 범위는 2건으로 줄었다.

feature/afternote/presentation/.../author/detail/MemorialDetailScreen.kt:93  onEditClick: () -> Unit = {},
feature/afternote/presentation/.../author/detail/MemorialDetailScreen.kt:94  onDeleteConfirm: () -> Unit = {},

🔴 청소만으로는 끝나지 않는다 — 재발이 실측됐다

부모 이슈를 연 지 이틀 만에 mindrecord 가 33 → 47 로 늘었다. 유입은 두 파일에 집중됐고, 주 유입 커밋은 69f63a22f (refactor(mindrecord): 작성 화면의 screenshotTest용 Content 경계를 분리한다) 다.

파일 0828 현행
DiaryWriteScreen.kt 3 11
DailyQuestionWriteScreen.kt 3 9

screenshotTest·프리뷰 용으로 Content 경계를 분리하면서 새 컴포저블에 디폴트를 붙이는 것이 현재의 주 유입 경로다. 호출부에서 {} 를 명시하면 되는 자리이므로 선언에 디폴트를 둘 이유가 없다. 이 이슈가 최초에 「청소만 하면 새 코드로 다시 스며든다」 고 적은 우려가 그대로 실측됐고, 가드 도입이 이 이슈의 본체가 됐다.

이 이슈의 범위

  1. 재발 유입 가드 1종 도입 — lint/ktlint 커스텀 룰이 가능하면 룰로, 아니면 CI 스크립트 카운트 가드(현재 값을 상한으로 고정하고 초과 시 fail)로. 자식 이슈들이 청소를 마치면 상한을 0 으로 내린다.
  2. 컨벤션 문서화 — 「화면 컴포저블은 required, 리프의 선택적 상호작용은 nullable 핸들러 또는 오버로드 분리」 를 docs/ 에 명문화. 프리뷰·screenshotTest 는 호출부에서 {} 명시.
  3. afternote 잔여 2건 — MemorialDetailScreen.kt:93-94.

처리 방침 (자식 이슈 공통)

  1. 화면 컴포저블(실호출부가 NavGraph 한 곳): 디폴트 전면 제거, 프리뷰·screenshotTest·unit test 는 {} 를 명시한다. refactor(afternote): 에디터 파라미터 봉투 2종 언번들 — AfternoteEditorScreenCallbacks·AfternoteEditorNavigationParams, no-op 디폴트 제거 포함 #602 가 에디터 봉투 2종에서 이미 같은 처분을 했고, refactor(core): 수신자 입력 거절의 서버 원문을 고정 진단 문구로 바꾼다 #934 방침(폴백보다 값 명시·타입으로 강제)과 정합이다.
  2. 다중 호출부 리프 컴포넌트: 건별 판정한다. 전 호출부가 실값을 넘기면 디폴트만 제거. 상호작용이 진짜 선택적이면 = {} 로 「눌러도 아무 일 없는 버튼」을 그리는 대신 nullable 핸들러+UI 숨김 또는 오버로드 분리로 재모델링한다. (fix(afternote): 미배선 콜백 4건 — 남기실 말씀 등록·수신 상세 확인하기·홈 NEXT STEP 카드 무동작, no-op 디폴트가 은폐 #777 이 「리프의 정상적 선택 콜백」으로 판정한 다수가 여기 해당 — 재판정이 아니라 모델링 교정이 목적)

완료 조건

  • 신규 유입 가드 1종이 CI 에서 동작한다 (초과 시 fail)
  • 컨벤션이 docs/ 에 명문화되고, 프리뷰·screenshotTest 의 처리 방식이 예시로 들어간다
  • MemorialDetailScreen.kt:93-94 2건 처리
  • 자식 이슈 완료 후 가드 상한을 0 으로 내린다

자식 이슈

참고

Activity

  1. added
    refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업
    area:platformCI·빌드·릴리스·저장소 운영 영역
    on Aug 28, 2026
  2. OnlyReadOneBook commented on Aug 28, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    PR #1336 의 신설분(MemorialDetailScreen.onVideoClick)은 e6c37e3 에서 디폴트 제거 완료 — 이 이슈의 잔여 카운트에서 제외. 재측정 시 107건 기준.

  3. changed the title [-]refactor: 컴포저블 no-op 콜백 디폴트 108건 전수 청소 — 화면은 required 로, 리프는 선택성 재모델링 + 재발 가드[/-] [+]refactor(platform): 컴포저블 no-op 콜백 디폴트 — 재발 가드·컨벤션 도입 + afternote 잔여 2건[/+] on Aug 29, 2026
  4. added
    pr-open이 이슈를 구현하는 PR 이 열려 있다 — base 가 기본 브랜치가 아니어도 드러낸다
    on Aug 29, 2026
  5. removed
    pr-open이 이슈를 구현하는 PR 이 열려 있다 — base 가 기본 브랜치가 아니어도 드러낸다
    on Aug 30, 2026
  6. OnlyReadOneBook commented on Aug 30, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    완료 조건 3종이 전부 origin/develop fc8f32cd5 에 들어가 있어 닫습니다. 실측 근거입니다.

    완료 조건 상태 근거
    재발 가드 ✅ konsist/src/test/kotlin/com/afternote/konsist/NoOpCallbackDefaultKonsistTest.kt — @composable 파라미터 + 클래스 주 생성자 파라미터 양쪽 검사, LEGACY 목록은 관대 판정 + 해소 항목 경고
    컨벤션 문서 ✅ docs/convention/composable-callback-defaults.md
    afternote 잔여 2건 ✅ MemorialDetailScreen.kt 의 onEditClick·onDeleteConfirm 이 디폴트 없는 required 파라미터로 바뀜 (PR #1544, dc8641db8)

    가드의 LEGACY_NO_OP_DEFAULT_FILES 에도 afternote·receiver 항목이 남아 있지 않고 home·mindrecord 만 남아 있습니다 — 자식 이슈 몫과 정확히 일치합니다.

    모듈별 청소는 #1540(Sadturtleman · mindrecord·home) · #1541(koongmai · timeletter) 이 각자 어사인된 채 열려 있어 그쪽에서 추적됩니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:platformCI·빌드·릴리스·저장소 운영 영역refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions