Skip to content

[Feature] 학교 부서정보 화면 구현#1550

Merged
TTRR1007 merged 9 commits into
developfrom
feature/#1546-department-feature
Jul 26, 2026
Merged

[Feature] 학교 부서정보 화면 구현#1550
TTRR1007 merged 9 commits into
developfrom
feature/#1546-department-feature

Conversation

@TTRR1007

@TTRR1007 TTRR1007 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

PR 개요

이슈 번호: #1546

PR 체크리스트

  • Code convention을 잘 지켰나요?
  • Lint check를 수행하였나요?
  • Assignees를 추가했나요?

작업사항

  • 버그 수정
  • 신규 기능
  • 코드 스타일 수정 (포맷팅 등)
  • 리팩토링 (기능 수정 X, API 수정 X)
  • 기타

작업사항의 상세한 설명

학교 부서정보 화면 구현입니다

논의 사항

스크린샷

image image image image image

추가내용

  • develop, sprint 브랜치를 향하고 있습니다
  • production 브랜치를 향하고 있습니다

Summary by CodeRabbit

  • 새로운 기능
    • 부서 목록/상세 화면을 추가하고, 카테고리별로 부서를 탐색할 수 있습니다.
    • 부서명 검색을 지원하며 로딩/빈 결과/오류 상태를 화면에 표시합니다.
    • 상세 화면에서 담당 업무와 전화번호를 표 형태로 확인할 수 있습니다.
    • 전화번호를 탭해 클립보드에 복사할 수 있습니다.
    • “잘못된 정보 신고” 링크와 최신 업데이트 일자를 안내합니다.
    • 부서별 아이콘과 빈 상태/로딩 스켈레톤 UI를 제공합니다.

@TTRR1007 TTRR1007 self-assigned this Jul 25, 2026
@TTRR1007
TTRR1007 requested a review from a team as a code owner July 25, 2026 11:51
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@TTRR1007, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b7787d3b-02d9-45e9-8447-f75e4b390e5d

📥 Commits

Reviewing files that changed from the base of the PR and between 71c4c6a and 1766152.

📒 Files selected for processing (1)
  • feature/department/src/main/java/in/koreatech/koin/feature/department/state/DepartmentSearchFieldHandler.kt

Walkthrough

feature/department 모듈에 부서 목록·상세 화면, 카테고리별 조회, 검색 디바운스, 상태별 Compose UI, 전화번호 복사, 피드백 링크, 네비게이션과 관련 리소스를 추가했습니다.

Changes

Department 기능

Layer / File(s) Summary
모듈 설정과 화면 진입
feature/department/build.gradle.kts, feature/department/src/main/AndroidManifest.xml, feature/department/src/main/.../DepartmentActivity.kt, feature/department/src/main/.../navigation/*
Android 모듈 설정, Hilt 액티비티 진입점, 직렬화 가능한 목록·상세 라우트와 화면 이동을 추가했습니다.
검색 계약과 상태 처리
feature/department/src/main/.../state/*, feature/department/src/main/.../type/*
부서 카테고리·상태 모델, 도메인 변환, 검색 상태와 300ms 디바운스·최신 요청 결과 반영 로직을 추가했습니다.
목록 조회와 UI 연결
feature/department/src/main/.../screen/list/*, feature/department/src/main/.../util/*
목록 조회·검색·날짜 포맷팅·이벤트 로깅과 상세 이동 및 전화번호 복사 사이드 이펙트를 연결했습니다.
목록 및 공통 Compose UI
feature/department/src/main/.../component/*, feature/department/src/main/.../mock/*
카테고리 목록, 검색 결과, 부서 카드·업무 테이블, 로딩·빈 상태·푸터와 프리뷰용 데이터를 구현했습니다.
상세 화면 흐름
feature/department/src/main/.../screen/detail/*
카테고리별 연락처 조회, 검색 상태 갱신, 전화번호 복사 사이드 이펙트와 상세 Compose 화면을 구현했습니다.
리소스 및 유틸리티
feature/department/src/main/res/drawable/*, feature/department/src/main/res/values/strings.xml, feature/department/src/main/.../util/*
부서 카테고리·검색·복사·상태 표시용 벡터와 문자열, 클립보드·URL 처리 유틸리티를 추가했습니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • BCSDLab/KOIN_ANDROID#1547 — Department ViewModel이 사용하는 연락처 use case와 API·repository 계층을 추가합니다.

Suggested reviewers: kym-p, jaeyoung290, kongwoojin

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 학교 부서정보 화면 구현이라는 핵심 변경을 간결하고 명확하게 요약합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#1546-department-feature

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
feature/department/src/main/java/in/koreatech/koin/feature/department/type/DepartmentCategory.kt (1)

31-31: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

공개 API 타입을 명시하세요.

  • feature/department/src/main/java/in/koreatech/koin/feature/department/type/DepartmentCategory.kt#L31-L31: ALL: ImmutableList<DepartmentCategory> 타입을 명시하세요.
  • feature/department/src/main/java/in/koreatech/koin/feature/department/state/DepartmentState.kt#L23-L23: toDepartmentState(): DepartmentState 반환 타입을 명시하세요.

As per coding guidelines, “Keep public APIs explicitly typed.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/type/DepartmentCategory.kt`
at line 31, 명시적 공개 API 타입을 추가하세요. DepartmentCategory의 ALL 프로퍼티를
ImmutableList<DepartmentCategory>로 선언하고, DepartmentState의 toDepartmentState() 함수
반환 타입을 DepartmentState로 명시하세요.

Source: Coding guidelines

feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailScreenContent.kt (1)

47-47: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

하드코딩된 배경색 대신 디자인 시스템 색상 토큰 사용 권장.

Color(0xFFF8F8FA)가 두 곳에서 하드코딩되어 있습니다. 다른 department 컴포넌트들(예: DepartmentCard)은 RebrandKoinTheme.colors.*를 사용하므로, 일관성과 다크모드 대응을 위해 테마 색상 토큰으로 교체하는 것을 권장합니다.

♻️ 제안: 테마 색상 사용
     Column(
-        modifier = modifier.background(Color(0xFFF8F8FA))
+        modifier = modifier.background(RebrandKoinTheme.colors.neutral50)
     ) {
         KoinTopAppBar(
             title = stringResource(uiState.category.titleRes),
             onNavigationIconClick = onNavigationIconClick,
             colors = TopAppBarDefaults.topAppBarColors(
-                containerColor = Color(0xFFF8F8FA)
+                containerColor = RebrandKoinTheme.colors.neutral50
             )
         )

정확한 토큰명(예: neutral50)은 RebrandKoinTheme.colors 정의를 확인해 실제 존재하는 색상 토큰으로 교체해야 합니다.

Also applies to: 53-53

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailScreenContent.kt`
at line 47, Replace both hardcoded Color(0xFFF8F8FA) values in
DepartmentDetailScreenContent with the matching existing RebrandKoinTheme.colors
token, confirming the token name from the theme definition and preserving the
current background behavior.
feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailViewModel.kt (1)

42-62: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

fetchDepartments()search()의 중복 로직 정리 제안.

두 함수 모두 결과를 매핑해 Empty/Success/Failure로 reduce하는 동일한 패턴을 가지고 있습니다. 공통 헬퍼로 추출하면 중복을 줄일 수 있습니다.

♻️ 제안: 공통 헬퍼 추출
-    private fun fetchDepartments() = intent {
-        reduce { state.copy(contentUiState = DepartmentSearchUiState.Loading) }
-
-        departmentRepository.getDepartmentContactsByCategory(category = category.name)
-            .onSuccess { result ->
-                val departmentStates = result.categoryContacts.departments.map { it.toDepartmentState() }
-                reduce {
-                    state.copy(
-                        updatedAt = result.updatedAt.format(DEPARTMENT_UPDATED_AT_FORMATTER),
-                        contentUiState = if (departmentStates.isEmpty()) {
-                            DepartmentSearchUiState.Empty
-                        } else {
-                            DepartmentSearchUiState.Success(departmentStates.toImmutableList())
-                        }
-                    )
-                }
-            }
-            .onFailure {
-                reduce { state.copy(contentUiState = DepartmentSearchUiState.Failure) }
-            }
-    }
+    private fun fetchDepartments() = intent {
+        reduce { state.copy(contentUiState = DepartmentSearchUiState.Loading) }
+        departmentRepository.getDepartmentContactsByCategory(category = category.name)
+            .onSuccess { result ->
+                reduce {
+                    state.copy(
+                        updatedAt = result.updatedAt.format(DEPARTMENT_UPDATED_AT_FORMATTER),
+                        contentUiState = result.toUiState()
+                    )
+                }
+            }
+            .onFailure { reduce { state.copy(contentUiState = DepartmentSearchUiState.Failure) } }
+    }
+
+    private fun DepartmentContactsResult.toUiState(): DepartmentSearchUiState {
+        val states = categoryContacts.departments.map { it.toDepartmentState() }
+        return if (states.isEmpty()) DepartmentSearchUiState.Empty else DepartmentSearchUiState.Success(states.toImmutableList())
+    }

Also applies to: 92-109

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailViewModel.kt`
around lines 42 - 62, Refactor fetchDepartments() and search() to extract their
duplicated result-to-DepartmentSearchUiState mapping and reduce logic into a
shared helper. Reuse the helper for both success and failure paths while
preserving each operation’s existing state updates, including updatedAt handling
in fetchDepartments().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailViewModel.kt`:
- Around line 84-109: Update the shared search flow in search so it sets
searchUiState to Loading before calling
departmentRepository.getDepartmentContactsByCategory. Ensure both onSearch and
onRefresh, including retry from Failure, show Loading immediately while
preserving the existing Success, Empty, and Failure result handling.
- Around line 26-29: DepartmentDetailViewModel must not access
DepartmentRepository directly. Introduce or reuse use cases that encapsulate
fetchDepartments() and search(), inject those use cases into
DepartmentDetailViewModel, and update the corresponding fetchDepartments and
search flows to call only the use cases while preserving existing behavior.

In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListViewModel.kt`:
- Around line 24-26: DepartmentListViewModel이 DepartmentRepository를 직접 주입·호출하지
않도록 변경하세요. 기존 36행과 75행의 Repository 호출을 담당하는 적절한 use case로 이동하고, 생성자에는 해당 use
case를 주입해 ViewModel이 use case만 호출하도록 수정하세요.

---

Nitpick comments:
In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailScreenContent.kt`:
- Line 47: Replace both hardcoded Color(0xFFF8F8FA) values in
DepartmentDetailScreenContent with the matching existing RebrandKoinTheme.colors
token, confirming the token name from the theme definition and preserving the
current background behavior.

In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailViewModel.kt`:
- Around line 42-62: Refactor fetchDepartments() and search() to extract their
duplicated result-to-DepartmentSearchUiState mapping and reduce logic into a
shared helper. Reuse the helper for both success and failure paths while
preserving each operation’s existing state updates, including updatedAt handling
in fetchDepartments().

In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/type/DepartmentCategory.kt`:
- Line 31: 명시적 공개 API 타입을 추가하세요. DepartmentCategory의 ALL 프로퍼티를
ImmutableList<DepartmentCategory>로 선언하고, DepartmentState의 toDepartmentState() 함수
반환 타입을 DepartmentState로 명시하세요.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 387a85e7-f7a0-48fa-87e1-61f2b5d93779

📥 Commits

Reviewing files that changed from the base of the PR and between efd7806 and a1343b3.

📒 Files selected for processing (42)
  • feature/department/.gitignore
  • feature/department/build.gradle.kts
  • feature/department/consumer-rules.pro
  • feature/department/proguard-rules.pro
  • feature/department/src/main/AndroidManifest.xml
  • feature/department/src/main/java/in/koreatech/koin/feature/department/DepartmentActivity.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentCard.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentCategoryList.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentFooter.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentLoadingList.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentSearchField.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentSearchResult.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentStateView.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentTaskTable.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/mock/DepartmentMock.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/navigation/DepartmentNavigation.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/navigation/Routes.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailScreen.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailScreenContent.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailState.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailViewModel.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListScreen.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListScreenContent.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListState.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListViewModel.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/state/DepartmentSearchUiState.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/state/DepartmentState.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/type/DepartmentCategory.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/util/ContextExtensions.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/util/DateFormatter.kt
  • feature/department/src/main/res/drawable/ic_department_academic.xml
  • feature/department/src/main/res/drawable/ic_department_arrow_right.xml
  • feature/department/src/main/res/drawable/ic_department_caution.xml
  • feature/department/src/main/res/drawable/ic_department_copy.xml
  • feature/department/src/main/res/drawable/ic_department_employment.xml
  • feature/department/src/main/res/drawable/ic_department_facility.xml
  • feature/department/src/main/res/drawable/ic_department_international.xml
  • feature/department/src/main/res/drawable/ic_department_other.xml
  • feature/department/src/main/res/drawable/ic_department_search.xml
  • feature/department/src/main/res/drawable/ic_department_search_empty.xml
  • feature/department/src/main/res/drawable/ic_department_student_support.xml
  • feature/department/src/main/res/values/strings.xml

@bcsd-b-bot bcsd-b-bot Bot removed the ci:passed label Jul 25, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@feature/department/src/main/java/in/koreatech/koin/feature/department/state/DepartmentSearchFieldHandler.kt`:
- Around line 22-39: Update onQueryChange() so each non-blank query change
obtains and propagates a new request ID before the debounce delay and before the
prior fetch can complete; pass that ID into search() and ensure the result
application validates it, while preserving cancellation, loading, and
blank-query behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ffd6e777-e4c7-43de-a1f2-73b28484360f

📥 Commits

Reviewing files that changed from the base of the PR and between a1343b3 and 71c4c6a.

📒 Files selected for processing (12)
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentSearchResult.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentStateView.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailScreen.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailScreenContent.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailState.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailViewModel.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListScreen.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListScreenContent.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListState.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListViewModel.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/state/DepartmentSearchFieldHandler.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/state/DepartmentSearchState.kt
🚧 Files skipped from review as they are similar to previous changes (4)
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListScreenContent.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/component/DepartmentSearchResult.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/detail/DepartmentDetailState.kt
  • feature/department/src/main/java/in/koreatech/koin/feature/department/screen/list/DepartmentListState.kt

@sonarqubecloud

Copy link
Copy Markdown

@bcsd-b-bot bcsd-b-bot Bot added the ci:passed label Jul 25, 2026
@TTRR1007
TTRR1007 merged commit 2dbd3d0 into develop Jul 26, 2026
13 of 14 checks passed
@TTRR1007
TTRR1007 deleted the feature/#1546-department-feature branch July 26, 2026 04:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants