Conversation
- Core/WatchDesignSystem 모듈 신설 — iOS 카탈로그는 watchOS 에서 항상 dark 를 resolve 하므로(브랜드색이 #4869F0 대신 #4264F0 이 됨) 워치 전용 레이어로 분리 - 토큰 3종 추가: WatchColor(표면·브랜드·상태·텍스트 20종) · WatchTypography(WatchTextRole 5종) · WatchLayout(코너·보더·패딩·스페이싱) - 표면 API 추가: watchCard(_:leadingAccent:) · watchScreenBackground() · watchListRowBackground(isSelected:) - 컴포넌트 2종 추가: WatchActionButton(역할 3종) · WatchStatusBadge(상태 5종) - Glass 절제 규칙을 API 로 강제 — WatchCardStyle 을 닫힌 enum 으로 두어 카드에 Glass 를 넣을 경로 자체를 없애고, Glass API 는 WatchActionButton 한 파일로 한정 - 토큰 드리프트 가드 테스트 추가 — iOS Colors.xcassets 를 파싱해 브랜드색 불일치 시 실패 - docs/claude/watch-design-system.md 신규 · CLAUDE.md 레퍼런스 인덱스 갱신
- WatchRoute/WatchFallbackRoute — 출석·The Ping 두 축 진입점과 폴백 3종(권한 거부·연결 끊김·큐잉)을 경로로 확보 - WatchRouter — 앱 셸이 소유하는 @observable 단일 스택. NavigationPath 대신 [WatchRoute] 구체 배열로 두어 스택 내용을 테스트로 검증 - WatchRootView — navigationDestination 단일 등록. 목적지는 후속 이슈가 교체할 플레이스홀더 - HomeGlanceView/HomeGlanceViewModel — solid 카드 글랜스, 세션·공지 행을 tap-chip 으로 승격, 세션 없을 때 "오늘 세션 없음" 빈 상태 - 승인 대기는 WatchStatus.pending(중립+인디고 링). 앰버 #FFB340 은 개정 스펙상 지각 전용이라 쓰지 않음 - 카운트·식별자는 전 레이어 String, Int 변환은 비교 시점에만 (규칙 #2). 숫자 아닌 값은 0건 처리 - watchAppProject 헬퍼에 includesTests 추가 + WKApplication 키 보강 — 없으면 테스트 호스트 설치가 거부됨 - ContentView("Hello Watch") 제거
- "오늘 세션" 라벨 + "오늘 세션 없음" 값이 같은 말을 두 줄로 반복해 위계가 흐려지던 문제 - 빈 상태는 문구 한 줄만 카드에 남긴다. 세션이 있을 때의 라벨/값 위계는 그대로
This was referenced Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔗 관련 이슈
Closes #1206
✨ PR 유형
Feature — 워치 앱의 진입 화면(홈 통합 글랜스)과
NavigationStack기반 내비게이션 IA 골격을 새로 세웁니다.기존
UMCWatchApp은WindowGroup { ContentView() }+Text("Hello Watch")뿐이라 IA 가 존재하지 않았습니다.📷 스크린샷 or 영상(UI 변경 시)
watchOS 26.5 시뮬레이터(Apple Watch Series 11 46mm)에 설치·실행해 확인했습니다.
데이터 공급원(#1210 WatchConnectivity 페이로드 계약)이 아직 없어 빈 상태가 현재의 실제 화면입니다.
#1B2140)에오늘 세션라벨 → 시작 시각(.metric, 대형 등폭) → 세션명(.cardValue) →WatchStatusBadge순으로 위계가 잡힙니다..dynamicTypeSize(.accessibility3)3종#Preview를HomeGlanceView.swift에 넣어 두었습니다.🛠️ 작업내용
라우팅 골격 (
Sources/Routing/)WatchRoute.swiftattendanceList/attendanceSession(scheduleID:)/attendanceResult(scheduleID:)/pingList/pingDetail(noticeID:)/fallback(_:).WatchFallbackRoute3종(권한 거부·연결 끊김·큐잉)WatchRouter.swift@Observable단일 스택.push/pop/popToRootWatchRootView.swiftNavigationStack(path:)셸.navigationDestination(for:)를 한 곳에서 등록WatchRoutePlaceholderView.swift케이스는 플로우 진입점 + 식별자만 담습니다. 정시/지각/지오펜스 이탈, 결과 4종 같은 화면 내부 상태는 목적지 화면이 데이터에서 파생하므로 케이스로 쪼개지 않았습니다. 그래서 후속 이슈는 enum 을 건드리지 않고
WatchRootView의 destination 만 바꿔 끼우면 됩니다.경로를
NavigationPath(타입 소거)가 아니라[WatchRoute]구체 배열로 뒀습니다. iOSPathStore가 타입 소거를 택한 이유는 "모든 Feature 목적지를 한 enum 에 모으면 Core → Feature 역방향 의존이 생긴다"인데, 워치는 단일 타겟·단일 스택이라 그 논거가 성립하지 않습니다. 구체 배열이어야 스택 내용을 테스트로 검증할 수 있습니다.홈 통합 글랜스 (
Sources/Home/)WatchGlance/GlanceSession— 표시 모델. 샘플 3종은#if DEBUG가드(절대 규칙 ✨ Feature: MainButton Component 제작 #5).HomeGlanceViewModel—@Observable. 출석 진입 경로(세션 있음 → attendanceSession,없음 → attendanceList), 승인 대기 문구, 미확인 공지 문구, 빈 상태 문구를 파생.HomeGlanceView— 세션 카드와 공지 행을 각각Button+.buttonStyle(.plain)tap-chip 으로 승격..plain이어야 카드 표면이 solid 로 남습니다(Glass 버튼 스타일을 쓰면 카드가 Glass 금지 구역을 침범).Tuist
watchAppProject헬퍼에includesTests:추가 →UMCWatchAppTestsunitTests 타겟(watchOS 26.4).WKApplication: true보강. 지시 범위 밖이지만 없으면 빌드는 통과해도 설치가 거부됩니다:App installation failed: WatchKit app being installed is missing either the WKWatchKitApp or WKApplication key set to true in its Info.plist유닛 테스트가 앱을 호스트로 설치해야 돌기 때문에 이 키 없이는 테스트 실행 자체가 불가능했습니다. 워치 앱을 한 번도 설치·실행한 적이 없어 지금까지 드러나지 않던 매니페스트 누락입니다.
Sources/ContentView.swift(Text("Hello Watch")) 삭제.이슈 본문 AC 는 "승인 대기 상태를 앰버(
#FFB340)로 표시" 인데, 그렇게 하지 않고WatchStatus.pending(중립#B2B8BF점 + 인디고 링)을 썼습니다.승인 대기 = 중립 + 인디고 링,앰버 #FFB340 = 지각(warning)전용으로 갈렸습니다. 스펙 본문도 "대기 상태를 중립 링으로 표시"라고 씁니다.WatchColor.statusPending = #B2B8BF,statusWarning = #FFB340.WatchStatusBadge를 우회해 색을 직접 칠해야 해서 디자인시스템 계약을 깨게 됩니다.HomeGlanceView.swift의pendingApprovalBadge에 주석으로 남겼습니다. 개정 전 값이 맞다면.pending→.warning한 글자만 바꾸면 됩니다.📋 추후 진행 상황
WatchGlance.empty를 표시합니다.HomeGlanceViewModel.init(glance:)이 주입 지점이고, 로딩 경로는 ♻️ Refactor: WatchConnectivity 도메인 페이로드 계약 정의 + 양방향 수신 경로 구현 #1210 이 붙입니다. (프로토콜·팩토리·DI 컨테이너를 미리 만들지 않았습니다.)WatchRoutePlaceholderView로 갑니다. 각 이슈가WatchRootView의 destination 을 실제 화면으로 교체합니다. 라우트 enum 은 그대로 두고 화면만 꽂으면 됩니다.WatchFallbackRoute)만 확보했고 진입 트리거(권한 상태·연결 상태·큐 상태 관찰)는 ✨ Feature: Watch P0 에러·오프라인 폴백 화면 8종 #1209/♻️ Refactor: WatchConnectivity 도메인 페이로드 계약 정의 + 양방향 수신 경로 구현 #1210 몫입니다. 지금은 테스트에서만 push 됩니다.#FFB340의 브랜드 팔레트 정식 편입 여부가 디자이너 검토 대기로 남아 있습니다.📌 리뷰 포인트
1. 검증 결과 (전부 통과)
make test(기본SCHEME=UMCApp, iOS 시뮬레이터)** TEST SUCCEEDED **— 32 tests / 5 suitesxcodebuild -scheme UMCWatchApp -destination 'platform=watchOS Simulator,name=Apple Watch Series 11 (46mm)' test** TEST SUCCEEDED **— 13 tests / 2 suitesmake test SCHEME=CoreWatchDesignSystem** TEST SUCCEEDED **— 회귀 없음2. 디자인시스템 계약 준수 (
docs/claude/watch-design-system.md§9 체크리스트).font(.watch(...)), 고정 pt·고정 높이 0건. 줄 길이 99자 초과 0건.WatchLayout.screenHorizontalPadding, 세로 간격stackSpacing/tightSpacing.3. 집중해서 봐주실 곳
WKApplication추가 — 헬퍼가 만드는 모든 워치 앱 타겟에 영향을 줍니다. 릴리스 빌드·업로드 경로에 부작용이 없는지 확인 부탁드립니다.[WatchRoute]vsNavigationPath— iOSPathStore와 의도적으로 다른 선택입니다. 근거는WatchRouter타입 주석에 적어 뒀습니다.String으로 들고 있는 것 — 절대 규칙 💄 [Design] 디자인 시스템 기반 토큰 및 스타일 구현 #2 를 따랐고,Int변환은HomeGlanceViewModel.count(_:)비교 시점 한 곳에서만 합니다. 숫자가 아니거나 음수인 값은 0건으로 떨어집니다("","abc","-1","3건"케이스를 테스트로 잠갔습니다).@Observable전역 관리자 예외 —WatchRouter가 절대 규칙 🎉 [Chore] 프로젝트 초기 설정 및 환경 구성 #1 의 "앱 생명주기 전역 관리자" 예외에 해당한다고 판단했습니다. iOSPathStore와 같은 성격입니다.✅ Checklist
PR이 다음 요구 사항을 충족하는지 확인해주세요!!!