Skip to content

Feature/#56 feat graduation progress - #81

Closed
BEEEAM-J wants to merge 4 commits into
developfrom
feature/#56-feat-graduation-progress
Closed

Feature/#56 feat graduation progress#81
BEEEAM-J wants to merge 4 commits into
developfrom
feature/#56-feat-graduation-progress

Conversation

@BEEEAM-J

@BEEEAM-J BEEEAM-J commented Apr 8, 2026

Copy link
Copy Markdown
Member

📌 PR 요약

🌱 작업한 내용

  • 졸업 요건 확인 화면 추가

🌱 PR 포인트

  • 졸업 요건 데이터는 더미 데이터로 구성했습니다.

📸 스크린샷

https://github.com/user-attachments/assets/af6d838e-a791-485f-9321-6cd269675c5e
파일첨부바람

📮 관련 이슈

RCA 룰을 사용하여 코드 리뷰를 해주세요

R (Request Changes) : 적극적으로 반영을 고려해주세요
C (Comment) : 웬만하면 반영해주세요
A (Approve) : 반영해도 좋고, 넘어가도 좋습니다. 사소한 의견입니다.

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 졸업 요건 진행 현황을 추적할 수 있는 새로운 졸업 진행도 화면 추가
    • 홈 화면에서 졸업 진행도 화면으로 이동할 수 있는 네비게이션 추가
  • 스타일

    • 졸업 진행도 컨테이너에 테두리 스타일 추가
    • 버튼 모듈 레이아웃 커스터마이징 개선

BEEEAM-J added 4 commits April 2, 2026 21:40
Home -> Graduation Progress Screen Navigate 동작 구현
졸업 요건 확인 화면 GUI 구현
- 졸업요건확인 화면에서 popBackStack 시 시간표 화면으로 천이 되는 현상 수정
- GraduationProgressViewModel 추가
- Graduation Progress 더미 데이터를 Remote에서 가져오는 동작 추가
@BEEEAM-J
BEEEAM-J requested a review from lluke0 April 8, 2026 13:43
@BEEEAM-J BEEEAM-J self-assigned this Apr 8, 2026
@BEEEAM-J BEEEAM-J linked an issue Apr 8, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Apr 8, 2026

Copy link
Copy Markdown

개요

이 PR은 졸업 요건 진행 현황을 표시하는 새로운 기능을 추가합니다. 데이터 모델부터 UI까지 완전한 계층을 구현하며, 졸업 진행 상황을 조회하고 화면에 표시하는 전체 흐름을 포함합니다.

변경 사항

코호트 / 파일(들) 요약
데이터 모델
common/model/graduation/GraduationProcess.kt, common/model/response/graduation/GraduationProcessResponse.kt
졸업 진행 데이터 모델 GraduationProcessListData 추가, 응답 데이터 클래스에 기본값 추가 및 변환 메서드 toGraduationProcessData() 구현
저장소 계층
domain/graduation/repository/GraduationRepository.kt, data/graduation/repository/GraduationRepositoryImpl.kt, data/graduation/datasource/RemoteGraduationDataSource.kt, remote/graduation/RemoteGraduationDataSourceImpl.kt
원격 데이터 소스 인터페이스 및 구현, 저장소 인터페이스 및 구현 추가
도메인 계층
domain/graduation/usecase/GetGraduationProgressUseCase.kt
에러 핸들링과 함께 저장소 호출을 감싸는 GetGraduationProgressUseCase 추가
프레젠테이션 계층 (ViewModel & UI)
presentation/home/graduationprogress/GraduationProgressViewModel.kt, presentation/home/graduationprogress/GraduationProgressContract.kt, presentation/home/graduationprogress/GraduationProgressScreen.kt, presentation/home/graduationprogress/GraduationProgressSampleData.kt
MVI 패턴 기반 ViewModel, UI 상태/부수 효과 계약, 졸업 진행 화면 UI 및 샘플 데이터 추가
네비게이션
presentation/timetable/navigation/TimetableNavigation.kt, presentation/timetable/timetable/TimetableScreen.kt, presentation/timetable/timetable/TimetableViewModel.kt, presentation/timetable/timetable/TimetableContract.kt
졸업 진행 화면으로의 네비게이션 경로, 네비게이션 콜백, 부수 효과 추가
홈 화면 통합
presentation/home/home/HomeScreen.kt, presentation/home/component/CchGraduationProgressContainer.kt, presentation/home/component/CchSemesterGradeButton.kt
홈 화면에 졸업 진행 네비게이션 콜백 추가, UI 컴포넌트 스타일링 개선
의존성 주입
di/DomainModules.kt, di/PresentationModules.kt, di/InitKoin.kt, data/graduation/di/GraduationRepositoryModule.kt
Koin 모듈에 졸업 관련 사용 사례, 뷰모델, 저장소 및 데이터 소스 등록
앱 진입점
App.kt, MainNavigator.kt
네비게이션 그래프에 졸업 진행 네비게이션 콜백 연결, MainNavigator에 새로운 네비게이션 메서드 추가

시퀀스 다이어그램

sequenceDiagram
    participant UI as 사용자<br/>(UI 클릭)
    participant VM as GraduationProgress<br/>ViewModel
    participant UC as GetGraduation<br/>ProgressUseCase
    participant Repo as GraduationRepository<br/>Impl
    participant DS as RemoteGraduation<br/>DataSource
    participant State as MVI State

    UI->>VM: getGraduationProgress()
    VM->>State: isLoading = true
    VM->>UC: invoke()
    UC->>Repo: getGraduationProgress()
    Repo->>DS: getGraduationProgress()
    DS-->>Repo: GraduationProcessListData
    Repo-->>UC: GraduationProcessListData
    UC-->>VM: Result<GraduationProcessListData>
    alt Success
        VM->>State: graduationProgress = data<br/>isLoading = false
    else Failure
        VM->>State: isLoading = false
        VM->>State: HandleException(throwable)
    end
Loading
sequenceDiagram
    participant Home as HomeScreen
    participant Timetable as TimetableScreen
    participant TimetableVM as TimetableViewModel
    participant Nav as NavController
    participant GradScreen as GraduationProgress<br/>Screen

    Home->>Home: 사용자가 졸업요건 클릭
    Home->>Timetable: onClickGraduationProgress()
    Timetable->>TimetableVM: navigateGraduationProgress()
    TimetableVM->>TimetableVM: post(NavigateGraduationProgress)
    Timetable->>Nav: navigateGraduationProgress()
    Nav->>GradScreen: navigate to<br/>graduation-progress route
    GradScreen-->>GradScreen: 졸업 진행 화면 표시
Loading

코드 리뷰 소요 시간

🎯 3 (Moderate) | ⏱️ ~20 minutes

관련된 PR

  • PR #73: 졸업 데이터 모델 및 응답 매핑 구조를 수정하여 GraduationProcess 관련 타입 및 변환 함수가 추가/확장됨
  • PR #80: 홈 화면/타임테이블 UI와 네비게이션 코드를 동일하게 수정하여 졸업 진행 네비게이션 콜백 및 부수 효과를 연결함

추천 검토자

  • jinukeu
  • kimmandoo

🐰 새로운 화면이 피어나네,
졸업 진행을 보여주며,
데이터 흐름이 우아하게,
계층을 타고 올라가고,
사용자의 길을 밝혀주네! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 주요 변경 사항을 명확하게 설명하고 있으며, '졸업 요건 화면' 기능 추가의 핵심을 적절히 반영하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿을 따르고 있으며, 작업 내용과 PR 포인트가 충분히 작성되었고 관련 이슈도 명시되어 있습니다.
Linked Issues check ✅ Passed PR이 #56의 요구사항인 졸업 요건 화면 GUI 구현을 완벽하게 충족하고 있으며, 네비게이션, 뷰모델, 데이터 계층 등 전체 아키텍처를 갖춘 완전한 기능 구현입니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 졸업 요건 화면 기능 구현과 직접적으로 관련되어 있으며, 범위를 벗어난 변경사항은 없습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#56-feat-graduation-progress

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@lluke0 lluke0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 좋네용 확인했어요!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/data/graduation/di/GraduationRepositoryModule.kt`:
- Around line 9-12: The module name uses PascalCase (GraduationRepositoryModule)
but project convention is camelCase; rename the module symbol to
graduationRepositoryModule and update all usages/registrations (e.g., where
InitKoin references this module) accordingly; keep the bindings inside
(RemoteGraduationDataSource -> RemoteGraduationDataSourceImpl and
GraduationRepository -> GraduationRepositoryImpl) unchanged, and ensure any
imports or tests that reference GraduationRepositoryModule are updated to the
new graduationRepositoryModule identifier.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/domain/graduation/usecase/GetGraduationProgressUseCase.kt`:
- Around line 4-5: Remove the unused imports in GetGraduationProgressUseCase.kt:
delete the imports of GraduationProcessResponseData and AcademicRepository (they
are not referenced in the file); after removal, run a quick compile or IDE
cleanup to ensure no other unused symbols remain and save the file.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressSampleData.kt`:
- Line 1: 현재 presentation 패키지의 GraduationProgressSampleData.kt에 있는
graduationProgressResponseSampleData 샘플 응답을 data 계층으로 이동시키고
RemoteGraduationDataSourceImpl이 presentation을 참조하지 않도록 수정하세요; 구체적으로
graduationProgressResponseSampleData 를 data 계층의 fixtures 또는 sample 디렉토리로 옮기고 해당
파일의 패키지 선언을 data 계층 네임스페이스로 변경한 뒤 RemoteGraduationDataSourceImpl에서 import 경로를 새
위치로 업데이트(및 불필요한 presentation 패키지 의존성 제거) 하세요.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressScreen.kt`:
- Around line 53-57: The top title and summary values in
GraduationProgressScreen are hardcoded (e.g., the CchAppBarWithTitle call and
the static "109 / 3.03 / 83.2" display); change the screen to read the current
user's data from the existing profile and academicSummary models and pass those
values into CchAppBarWithTitle and the summary section (use nullable-safe
accessors), and if profile or academicSummary is absent or incomplete hide the
related summary UI instead of showing dummy values; update
GraduationProgressScreen to fetch/inject profile/academicSummary and
conditionally render the title and summary sections accordingly.
- Around line 28-41: The route is not collecting side effects so
GraduationProgressSideEffect.HandleException emitted by
GraduationProgressViewModel is ignored; update GraduationProgressRoute to
collect viewModel.mviStore.sideEffects (or use viewModel.sideEffects collector)
and call the existing handleException function when a HandleException side
effect is received, and also ensure callers (e.g., the GraduationProgressRoute
invocation in TimetableNavigation.kt) pass through a handleException callback to
the route so exceptions are surfaced; look for GraduationProgressRoute,
GraduationProgressViewModel, GraduationProgressSideEffect.HandleException, and
handleException to add the collector and propagate the handler.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/home/HomeScreen.kt`:
- Around line 16-24: HomeRoute currently passes a no-arg callback
navigateGraduationProgress into HomeScreen so both major cards navigate to the
same destination; change the callback signature to accept an identifier (e.g.,
MajorType or majorName) and update HomeRoute, HomeScreen, and the two card click
handlers to pass the appropriate value (primary vs. double-major) through;
update all call sites (including the other occurrences around the
HomeScreen/card rendering) to use the new navigateGraduationProgress(majorId)
signature so the destination receives which major to show.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/remote/graduation/RemoteGraduationDataSourceImpl.kt`:
- Around line 5-10: RemoteGraduationDataSourceImpl is importing
presentation-level graduationProgressResponseSampleData which violates layer
dependency rules; move the sample fixture out of the presentation layer into the
data/common layer (e.g., create a sample data object in the data module) and
update RemoteGraduationDataSourceImpl to import that new location (or remove the
sample import and return a data-layer fixture). Ensure references to
graduationProgressResponseSampleData in RemoteGraduationDataSourceImpl are
replaced with the new data-layer symbol and keep the public API types
(RemoteGraduationDataSource, GraduationProcessListData) unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0e18d843-d255-407d-a9be-6641bc7a966d

📥 Commits

Reviewing files that changed from the base of the PR and between 161f3a2 and dbefe3c.

📒 Files selected for processing (24)
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/App.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/MainNavigator.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/graduation/GraduationProcess.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/common/model/response/graduation/GraduationProcessResponse.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/data/graduation/datasource/RemoteGraduationDataSource.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/data/graduation/di/GraduationRepositoryModule.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/data/graduation/repository/GraduationRepositoryImpl.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/di/DomainModules.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/di/InitKoin.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/di/PresentationModules.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/domain/graduation/repository/GraduationRepository.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/domain/graduation/usecase/GetGraduationProgressUseCase.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchGraduationProgressContainer.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/component/CchSemesterGradeButton.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressContract.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressSampleData.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressScreen.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressViewModel.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/home/HomeScreen.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/navigation/TimetableNavigation.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetable/TimetableContract.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetable/TimetableScreen.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/timetable/timetable/TimetableViewModel.kt
  • composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/remote/graduation/RemoteGraduationDataSourceImpl.kt

Comment on lines +9 to +12
val GraduationRepositoryModule = module {
single<RemoteGraduationDataSource> { RemoteGraduationDataSourceImpl() }
single<GraduationRepository> { GraduationRepositoryImpl(get()) }
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

모듈 네이밍 컨벤션 불일치

InitKoin.kt의 다른 모듈들(authRepositoryModule, timetableRepositoryModule, openMajorRepositoryModule 등)은 camelCase를 사용하는 반면, 이 모듈은 PascalCase(GraduationRepositoryModule)를 사용하고 있습니다. 일관성을 위해 graduationRepositoryModule로 변경하는 것을 권장합니다.

♻️ 제안된 수정
-val GraduationRepositoryModule = module {
+val graduationRepositoryModule = module {
     single<RemoteGraduationDataSource> { RemoteGraduationDataSourceImpl() }
     single<GraduationRepository> { GraduationRepositoryImpl(get()) }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/data/graduation/di/GraduationRepositoryModule.kt`
around lines 9 - 12, The module name uses PascalCase
(GraduationRepositoryModule) but project convention is camelCase; rename the
module symbol to graduationRepositoryModule and update all usages/registrations
(e.g., where InitKoin references this module) accordingly; keep the bindings
inside (RemoteGraduationDataSource -> RemoteGraduationDataSourceImpl and
GraduationRepository -> GraduationRepositoryImpl) unchanged, and ensure any
imports or tests that reference GraduationRepositoryModule are updated to the
new graduationRepositoryModule identifier.

Comment on lines +4 to +5
import com.chukchukhaksa.mobile.common.model.response.graduation.GraduationProcessResponseData
import com.chukchukhaksa.mobile.domain.academic.repository.AcademicRepository

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

사용되지 않는 import 제거 필요

GraduationProcessResponseDataAcademicRepository가 import되어 있지만 실제로 사용되지 않습니다. 복사-붙여넣기 과정에서 남은 것으로 보입니다.

🧹 제안된 수정
 package com.chukchukhaksa.mobile.domain.graduation.usecase
 
 import com.chukchukhaksa.mobile.common.model.graduation.GraduationProcessListData
-import com.chukchukhaksa.mobile.common.model.response.graduation.GraduationProcessResponseData
-import com.chukchukhaksa.mobile.domain.academic.repository.AcademicRepository
 import com.chukchukhaksa.mobile.domain.common.runCatchingIgnoreCancelled
 import com.chukchukhaksa.mobile.domain.graduation.repository.GraduationRepository
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import com.chukchukhaksa.mobile.common.model.response.graduation.GraduationProcessResponseData
import com.chukchukhaksa.mobile.domain.academic.repository.AcademicRepository
package com.chukchukhaksa.mobile.domain.graduation.usecase
import com.chukchukhaksa.mobile.common.model.graduation.GraduationProcessListData
import com.chukchukhaksa.mobile.domain.common.runCatchingIgnoreCancelled
import com.chukchukhaksa.mobile.domain.graduation.repository.GraduationRepository
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/domain/graduation/usecase/GetGraduationProgressUseCase.kt`
around lines 4 - 5, Remove the unused imports in
GetGraduationProgressUseCase.kt: delete the imports of
GraduationProcessResponseData and AcademicRepository (they are not referenced in
the file); after removal, run a quick compile or IDE cleanup to ensure no other
unused symbols remain and save the file.

@@ -0,0 +1,148 @@
package com.chukchukhaksa.mobile.presentation.home.graduationprogress

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
rg -n -C2 '\bgraduationProgressResponseSampleData\b|\bgraduationProgressSampleData\b' --type kt

Repository: cchaksa/cchaksa-app

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Search for usages of the sample data without specifying file type
rg -n -C2 '\bgraduationProgressResponseSampleData\b|\bgraduationProgressSampleData\b'

Repository: cchaksa/cchaksa-app

Length of output: 3366


🏁 Script executed:

#!/bin/bash
# Also search for imports of the GraduationProgressSampleData file
rg -n 'import.*GraduationProgressSampleData'

Repository: cchaksa/cchaksa-app

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check the actual content of the file to understand what's exported
cat -n composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressSampleData.kt | head -50

Repository: cchaksa/cchaksa-app

Length of output: 1738


샘플 응답을 presentation 패키지에서 제거하고 data 계층으로 이동해야 합니다.

RemoteGraduationDataSourceImpl(data 계층의 remote 구현)이 현재 com.chukchukhaksa.mobile.presentation.home.graduationprogress 패키지에서 graduationProgressResponseSampleData를 직접 import하고 있어 계층 의존성이 역전되어 있습니다. 더미 응답 데이터는 data 계층의 fixture/shared sample 디렉토리로 옮기고, RemoteGraduationDataSourceImpl의 import를 업데이트해야 합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressSampleData.kt`
at line 1, 현재 presentation 패키지의 GraduationProgressSampleData.kt에 있는
graduationProgressResponseSampleData 샘플 응답을 data 계층으로 이동시키고
RemoteGraduationDataSourceImpl이 presentation을 참조하지 않도록 수정하세요; 구체적으로
graduationProgressResponseSampleData 를 data 계층의 fixtures 또는 sample 디렉토리로 옮기고 해당
파일의 패키지 선언을 data 계층 네임스페이스로 변경한 뒤 RemoteGraduationDataSourceImpl에서 import 경로를 새
위치로 업데이트(및 불필요한 presentation 패키지 의존성 제거) 하세요.

Comment on lines +28 to +41
fun GraduationProgressRoute(
popBackStack: () -> Unit = {},
viewModel: GraduationProgressViewModel = koinViewModel(),
) {
val uiState by viewModel.mviStore.uiState.collectAsStateWithLifecycle()

LaunchedEffect(Unit) {
viewModel.getGraduationProgress()
}

GraduationProgressScreen(
graduationProgress = uiState.graduationProgress,
onClickBackButton = popBackStack,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

예외 side effect가 수집되지 않아 실패가 조용히 사라집니다.

GraduationProgressViewModel은 실패 시 GraduationProgressSideEffect.HandleException을 발행하는데, 이 라우트에서는 sideEffects를 collect하지 않습니다. 지금 상태로는 로딩만 끝나고 오류 전달은 완전히 유실됩니다.

🔧 제안된 수정
+import com.chukchukhaksa.mobile.common.ui.collectWithLifecycle
+
 `@Composable`
 fun GraduationProgressRoute(
   popBackStack: () -> Unit = {},
+  handleException: (Throwable) -> Unit = {},
   viewModel: GraduationProgressViewModel = koinViewModel(),
 ) {
   val uiState by viewModel.mviStore.uiState.collectAsStateWithLifecycle()
+
+  viewModel.mviStore.sideEffects.collectWithLifecycle { sideEffect ->
+    when (sideEffect) {
+      is GraduationProgressSideEffect.HandleException -> handleException(sideEffect.throwable)
+    }
+  }
 
   LaunchedEffect(Unit) {
     viewModel.getGraduationProgress()

TimetableNavigation.ktGraduationProgressRoute(...) 호출부에서도 handleException을 함께 넘겨야 합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressScreen.kt`
around lines 28 - 41, The route is not collecting side effects so
GraduationProgressSideEffect.HandleException emitted by
GraduationProgressViewModel is ignored; update GraduationProgressRoute to
collect viewModel.mviStore.sideEffects (or use viewModel.sideEffects collector)
and call the existing handleException function when a HandleException side
effect is received, and also ensure callers (e.g., the GraduationProgressRoute
invocation in TimetableNavigation.kt) pass through a handleException callback to
the route so exceptions are surfaced; look for GraduationProgressRoute,
GraduationProgressViewModel, GraduationProgressSideEffect.HandleException, and
handleException to add the collector and propagate the handler.

Comment on lines +53 to +57
CchAppBarWithTitle(
title = "18학번 정보통신학부 졸업요건",
isShowAddButton = false,
onClickBackButton = { onClickBackButton() },
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

사용자별로 달라져야 할 정보가 모두 하드코딩돼 있습니다.

어느 계정으로 들어와도 상단 타이틀이 "18학번 정보통신학부 졸업요건"으로 고정되고, 총 취득학점/GPA/백분위도 109 / 3.03 / 83.2로 표시됩니다. 더미 졸업요건 데이터를 쓰더라도 이 화면의 사용자 요약값은 기존 profile/academicSummary에서 받아오거나, 준비되지 않았다면 해당 섹션을 숨기는 쪽이 맞습니다.

Also applies to: 78-83

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/graduationprogress/GraduationProgressScreen.kt`
around lines 53 - 57, The top title and summary values in
GraduationProgressScreen are hardcoded (e.g., the CchAppBarWithTitle call and
the static "109 / 3.03 / 83.2" display); change the screen to read the current
user's data from the existing profile and academicSummary models and pass those
values into CchAppBarWithTitle and the summary section (use nullable-safe
accessors), and if profile or academicSummary is absent or incomplete hide the
related summary UI instead of showing dummy values; update
GraduationProgressScreen to fetch/inject profile/academicSummary and
conditionally render the title and summary sections accordingly.

Comment on lines 16 to +24
fun HomeRoute(
profile: Profile,
academicSummary: AcademicSummary
academicSummary: AcademicSummary,
navigateGraduationProgress: () -> Unit,
) {
HomeScreen(
profile = profile,
academicSummary = academicSummary
academicSummary = academicSummary,
navigateGraduationProgress = navigateGraduationProgress,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

주전공/복수전공 선택 정보가 네비게이션에서 사라집니다.

navigateGraduationProgress가 무인자 콜백이라 두 카드가 모두 같은 목적지로 이동합니다. 지금 구조로는 복수전공 사용자가 어떤 전공의 졸업요건을 보려는지 전달할 수 없어서, 두 버튼이 사실상 같은 화면/같은 데이터로 수렴합니다. 전공 타입이나 전공명을 함께 넘기도록 시그니처를 확장해야 합니다.

Also applies to: 50-66

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/presentation/home/home/HomeScreen.kt`
around lines 16 - 24, HomeRoute currently passes a no-arg callback
navigateGraduationProgress into HomeScreen so both major cards navigate to the
same destination; change the callback signature to accept an identifier (e.g.,
MajorType or majorName) and update HomeRoute, HomeScreen, and the two card click
handlers to pass the appropriate value (primary vs. double-major) through;
update all call sites (including the other occurrences around the
HomeScreen/card rendering) to use the new navigateGraduationProgress(majorId)
signature so the destination receives which major to show.

Comment on lines +5 to +10
import com.chukchukhaksa.mobile.presentation.home.graduationprogress.graduationProgressResponseSampleData

class RemoteGraduationDataSourceImpl(): RemoteGraduationDataSource {
override suspend fun getGraduationProgress(): GraduationProcessListData {
return graduationProgressResponseSampleData
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

레이어 의존성 방향 위반

remote 레이어가 presentation 레이어의 샘플 데이터를 import하고 있습니다. 이는 클린 아키텍처의 의존성 규칙을 위반합니다 (data/remote → presentation 방향).

더미 데이터라도 data 또는 common 레이어에 위치시키는 것이 바람직합니다. 실제 API 연동 시 이 import가 제거되더라도, 현재 상태에서 아키텍처 위반이 존재합니다.

🛠️ 제안된 수정

샘플 데이터를 data 레이어로 이동:

-import com.chukchukhaksa.mobile.presentation.home.graduationprogress.graduationProgressResponseSampleData
+import com.chukchukhaksa.mobile.data.graduation.GraduationProgressSampleData.graduationProgressResponseSampleData
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@composeApp/src/commonMain/kotlin/com/chukchukhaksa/mobile/remote/graduation/RemoteGraduationDataSourceImpl.kt`
around lines 5 - 10, RemoteGraduationDataSourceImpl is importing
presentation-level graduationProgressResponseSampleData which violates layer
dependency rules; move the sample fixture out of the presentation layer into the
data/common layer (e.g., create a sample data object in the data module) and
update RemoteGraduationDataSourceImpl to import that new location (or remove the
sample import and return a data-layer fixture). Ensure references to
graduationProgressResponseSampleData in RemoteGraduationDataSourceImpl are
replaced with the new data-layer symbol and keep the public API types
(RemoteGraduationDataSource, GraduationProcessListData) unchanged.

@lluke0
lluke0 deleted the branch develop June 30, 2026 11:20
@lluke0 lluke0 closed this Jun 30, 2026
@lluke0
lluke0 deleted the feature/#56-feat-graduation-progress branch June 30, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 졸업 요건 화면 GUI

2 participants