Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

๐Ÿ”— :: (#448) ์ทจ์—…๋ฅ  ์ƒ์„ธ ์กฐํšŒ ํŽ˜์ด์ง€ ์ œ์ž‘ #449

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from

Conversation

uson1004
Copy link
Member

@uson1004 uson1004 commented Mar 5, 2025

๊ฐœ์š”

์ž‘์—… ๋‚ด์šฉ

  • ์ƒ์„ธ ์ทจ์—…๋ฅ  ํŽ˜์ด์ง€๋ฅผ ๊ฐœ๋ฐœํ•˜์˜€์Šต๋‹ˆ๋‹ค
  • ์ด ํ•™์ƒ ์ทจ์—…๋ฅ  ํ™”๋ฉด ํผ๋ธ”๋ฆฌ์‹ฑ
  • splits api ๋น„ํ™œ์„ฑํ™”
  • employment ๋ชจ๋“ˆ ์ถ”๊ฐ€
  • ResourseKey ์ถ”๊ฐ€
  • ์„œ๋ฒ„ ๋กœ์ง ์ž‘์„ฑ
  • ์ด๋ฏธ์ง€ ์ถ”๊ฐ€

ํ•  ๋ง

๋ถ€์กฑํ•œ ์ ์ด ๋งŽ์ด ํ”ผ๋“œ๋ฐฑ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค

Summary by CodeRabbit

  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ

    • ์ฑ„์šฉ(์ทจ์—…) ๋ชจ๋“ˆ์ด ์ถ”๊ฐ€๋˜์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์ฑ„์šฉ ํ˜„ํ™ฉ ๋ฐ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์•ฑ ๋‚ด ๋„ค๋น„๊ฒŒ์ด์…˜์ด ๊ฐœ์„ ๋˜์–ด ํ™ˆ ํ™”๋ฉด์—์„œ ์ฑ„์šฉ ๊ด€๋ จ ํ™”๋ฉด์œผ๋กœ ์†์‰ฝ๊ฒŒ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ฑ„์šฉ ์„ธ๋ถ€ ํ™”๋ฉด์—์„œ๋Š” ํšŒ์‚ฌ ๋กœ๊ณ ์™€ ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ์ œ๊ณตํ•ด ์ง๊ด€์ ์ธ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
    • ์ฑ„์šฉ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๋Š” UI๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์ทจ์—…๋ฅ , ์ด ํ•™์ƒ ์ˆ˜, ํ•ฉ๊ฒฉ ํ•™์ƒ ์ˆ˜๋ฅผ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ํ•œ๊ตญ์–ด๋กœ ๋œ ์ฑ„์šฉ ๊ด€๋ จ ์ƒํƒœ ๋ฉ”์‹œ์ง€๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ๋‹ค๊ตญ์–ด ์ง€์›์ด ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • Chores

    • ํ”„๋กœ์ ํŠธ ์˜์กด์„ฑ, ๋นŒ๋“œ ์„ค์ •, Gradle ์Šคํฌ๋ฆฝํŠธ ๋“ฑ์ด ์—…๋ฐ์ดํŠธ๋˜์–ด ์ „๋ฐ˜์ ์ธ ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@uson1004 uson1004 added ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ํผ๋ธ”๋ฆฌ์‹ฑ ํ™”๋ฉด์„ ํผ๋ธ”๋ฆฌ์‹ฑ ํ•ฉ๋‹ˆ๋‹ค. labels Mar 5, 2025
@uson1004 uson1004 self-assigned this Mar 5, 2025
@uson1004 uson1004 requested a review from a team as a code owner March 5, 2025 11:08
Copy link
Contributor

coderabbitai bot commented Mar 5, 2025

Walkthrough

์ด๋ฒˆ PR์—์„œ๋Š” ๊ณ ์šฉ(employment) ๊ธฐ๋Šฅ์˜ ๋„์ž…๊ณผ ๊ด€๋ จ๋œ ์—ฌ๋Ÿฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ ๋ชจ๋“ˆ์—์„œ ๊ณ ์šฉ ๊ด€๋ จ ๋„ค๋น„๊ฒŒ์ด์…˜ ๊ธฐ๋Šฅ ๋ฐ ์˜์กด์„ฑ์ด ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฉฐ, Core ๊ณ„์ธต์—์„œ๋Š” ๊ณ ์šฉ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” API์™€ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ, ์œ ์ฆˆ์ผ€์ด์Šค ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํ™•์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ๊ณ ์šฉ ๊ธฐ๋Šฅ ์ „์šฉ ๋ชจ๋“ˆ์ด ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋˜์–ด UI, ๋„ค๋น„๊ฒŒ์ด์…˜, ๋ทฐ๋ชจ๋ธ ๋ฐ ๋ฆฌ์†Œ์Šค ๋“ฑ์ด ์ •์˜๋˜์—ˆ๊ณ , Gradle ๊ตฌ์„ฑ ํŒŒ์ผ๊ณผ ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ์—์„œ๋„ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

Changes

ํŒŒ์ผ ๋ณ€๊ฒฝ ์š”์•ฝ
์•ฑ ๋ฐ ํ™ˆ ๋ชจ๋“ˆ
app/build.gradle.kts, app/.../JobisNavigator.kt, app/.../MainNavigation.kt, app/.../RootNavigation.kt, app/.../RootScreen.kt, feature/home/.../HomeNavigation.kt, feature/home/.../HomeScreen.kt
Debug ๋นŒ๋“œ ์„ค์ •์˜ ์ผ๋ถ€ ์ฃผ์„ ์ฒ˜๋ฆฌ ๋ฐ ๊ณ ์šฉ ์˜์กด์„ฑ ์ถ”๊ฐ€, ๊ณ ์šฉ ๋„ค๋น„๊ฒŒ์ด์…˜ ๊ธฐ๋Šฅ (onEmploymentClick ์ฝœ๋ฐฑ) ํ†ตํ•ฉ
Core ๋ชจ๋“ˆ
core/common/.../ResourceKeys.kt
core/data/.../ApplicationRepository.kt, core/data/.../ApplicationRepositoryImpl.kt
core/domain/.../EmploymentStatusEntity.kt, core/domain/.../FetchEmploymentStatusUseCase.kt
core/network/.../ApplicationApi.kt, core/network/.../RemoteApplicationDataSource.kt, core/network/.../RemoteApplicationDataSourceImpl.kt, core/network/.../RequestUrls.kt, core/network/.../FetchEmploymentStatusResponse.kt
๊ณ ์šฉ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” API, ์ €์žฅ์†Œ ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ ๊ตฌํ˜„, ์—”ํ‹ฐํ‹ฐ์™€ ํ™•์žฅ ํ•จ์ˆ˜ ์ถ”๊ฐ€๋กœ ๊ณ ์šฉ ์ƒํƒœ ๊ธฐ๋Šฅ ๊ตฌํ˜„
Employment Feature ๋ชจ๋“ˆ
feature/employment/.gitignore, feature/employment/build.gradle.kts, feature/employment/src/main/AndroidManifest.xml, feature/employment/src/main/java/.../CompanyItem.kt, feature/employment/src/main/java/.../EmploymentNavigation.kt, feature/employment/src/main/java/.../EmploymentDetailScreen.kt, feature/employment/src/main/java/.../EmploymentScreen.kt, feature/employment/src/main/java/.../EmploymentDetailViewModel.kt, feature/employment/src/main/java/.../EmploymentViewModel.kt, feature/employment/src/main/res/values/strings.xml
๊ณ ์šฉ ๊ธฐ๋Šฅ ์ „์šฉ ๋ชจ๋“ˆ ์ถ”๊ฐ€: UI ๊ตฌ์„ฑ์š”์†Œ, ๋„ค๋น„๊ฒŒ์ด์…˜, ๋ฐ์ดํ„ฐ ๋ชจ๋ธ, ๋ทฐ๋ชจ๋ธ, ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค ๋“ฑ ์ „๋ฐ˜์ ์ธ ๊ธฐ๋Šฅ ๋„์ž…
Gradle ๋ฐ ์Šคํฌ๋ฆฝํŠธ
gradle/libs.versions.toml, gradle/wrapper/gradle-wrapper.properties, gradlew, gradlew.bat, settings.gradle.kts
Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „ ์—…๋ฐ์ดํŠธ, Gradle ๋ž˜ํผ ๋ฒ„์ „ ๋ณ€๊ฒฝ, ์Šคํฌ๋ฆฝํŠธ ๊ฐœ์„  ๋ฐ ๋ชจ๋“ˆ ์„ค์ •์— ๊ณ ์šฉ ๋ชจ๋“ˆ ์ถ”๊ฐ€

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant HomeScreen
    participant JobisNavigator
    participant NavController
    participant EmploymentScreen

    User->>HomeScreen: ๊ณ ์šฉ ๋ฒ„ํŠผ ํด๋ฆญ
    HomeScreen->>JobisNavigator: onEmploymentClick ์ฝœ๋ฐฑ ํ˜ธ์ถœ
    JobisNavigator->>NavController: navigateToEmployment() ํ˜ธ์ถœ
    NavController->>EmploymentScreen: ๊ณ ์šฉ ํ™”๋ฉด์œผ๋กœ ์ด๋™
Loading
sequenceDiagram
    participant EmploymentViewModel
    participant FetchEmploymentStatusUseCase
    participant ApplicationRepository
    participant NetworkLayer

    EmploymentViewModel->>FetchEmploymentStatusUseCase: invoke() ํ˜ธ์ถœ
    FetchEmploymentStatusUseCase->>ApplicationRepository: fetchEmploymentStatus() ์š”์ฒญ
    ApplicationRepository->>NetworkLayer: ๊ณ ์šฉ ์ƒํƒœ ์š”์ฒญ
    NetworkLayer-->>ApplicationRepository: FetchEmploymentStatusResponse ๋ฐ˜ํ™˜
    ApplicationRepository-->>FetchEmploymentStatusUseCase: ์‘๋‹ต ์ „๋‹ฌ
    FetchEmploymentStatusUseCase-->>EmploymentViewModel: ์—”ํ‹ฐํ‹ฐ ๋ณ€ํ™˜ ํ›„ ๋ฐ˜ํ™˜
Loading

Suggested reviewers

  • Tmdhoon2

Poem

๋‚˜๋Š” ๊ท€์—ฌ์šด ํ† ๋ผ, ์ฝ”๋ฅผ ํ‚ํ‚
์ฝ” ์•ž์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ๋ฐ˜์ง๋ฐ˜์ง
๊ณ ์šฉ์˜ ๊ธธ ์—ด์–ด์ฃผ๋Š” ๋„ค๋น„๊ฒŒ์ดํ„ฐ
์ฝ”๋“œ ์ˆฒ์„ ๋›ฐ์–ด๋‹ค๋‹ˆ๋ฉฐ ํฌ๋ง์„ ๋…ธ๋ž˜ํ•ด
"Hop hop!"ํ•˜๋ฉฐ ์•ž์œผ๋กœ ๋‹ฌ๋ ค๊ฐ€๋„ค ๐Ÿฐโœจ

โœจ Finishing Touches
  • ๐Ÿ“ Generate Docstrings

๐Ÿชง Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@uson1004 uson1004 closed this Mar 5, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 15

๐Ÿงน Nitpick comments (17)
app/build.gradle.kts (1)

56-59: ์ฃผ์„ ์ฒ˜๋ฆฌ๋œ ๋””๋ฒ„๊ทธ ๊ตฌ์„ฑ์„ ์ •๋ฆฌํ•˜์„ธ์š”.

์ฃผ์„ ์ฒ˜๋ฆฌ๋œ ๊ตฌ์„ฑ ์„ค์ •(ABI ๋ถ„ํ• , AAPT ํฌ๋Ÿฐ์น˜, ๋ฐ€๋„ ๋ถ„ํ• )์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ฃผ์„์„ ์œ ์ง€ํ•˜๋Š” ์ด์œ ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ฃผ์„์œผ๋กœ ์„ค๋ช…์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ๋ถˆํ•„์š”ํ•˜๋‹ค๋ฉด ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

-//            splits.abi.isEnable = false
-//            aaptOptions.cruncherEnabled = false
-//            splits.density.isEnable = false
-//            aaptOptions.cruncherEnabled = false
core/network/src/main/java/team/retum/network/api/ApplicationApi.kt (1)

39-40: API ํ•จ์ˆ˜์— ๋ฌธ์„œ ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๊ณ ์šฉ ์ƒํƒœ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” API ํ•จ์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์ง€๋งŒ, ์ด ํ•จ์ˆ˜์˜ ๋ชฉ์ ๊ณผ ๋ฐ˜ํ™˜๊ฐ’์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ์œ ์ง€๋ณด์ˆ˜์™€ ์ดํ•ด๋ฅผ ์œ„ํ•ด KDoc ํ˜•์‹์˜ ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

+    /**
+     * ์ทจ์—… ํ˜„ํ™ฉ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
+     * 
+     * @return ์ทจ์—… ์ƒํƒœ ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ ์‘๋‹ต ๊ฐ์ฒด
+     */
     @GET(RequestUrls.Applications.employment)
     suspend fun fetchEmploymentStatus(): FetchEmploymentStatusResponse
core/network/src/main/java/team/retum/network/datasource/application/RemoteApplicationDataSource.kt (1)

26-26: ๋ฐ์ดํ„ฐ ์†Œ์Šค ํ•จ์ˆ˜์— ๋ฌธ์„œ ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

๊ณ ์šฉ ์ƒํƒœ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค์— ์ถ”๊ฐ€๋˜์—ˆ์ง€๋งŒ, ์ด ํ•จ์ˆ˜์˜ ๋ชฉ์ ๊ณผ ๋ฐ˜ํ™˜๊ฐ’์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ์œ ์ง€๋ณด์ˆ˜์™€ ์ดํ•ด๋ฅผ ์œ„ํ•ด KDoc ํ˜•์‹์˜ ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

+    /**
+     * ์ทจ์—… ํ˜„ํ™ฉ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
+     * 
+     * @return ์ทจ์—… ์ƒํƒœ ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ ์‘๋‹ต ๊ฐ์ฒด
+     */
     suspend fun fetchEmploymentStatus(): FetchEmploymentStatusResponse
core/network/src/main/java/team/retum/network/datasource/application/RemoteApplicationDataSourceImpl.kt (1)

21-25: ์ฝ”๋“œ ์ค‘๋ณต์ด ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๊ฐ fetch ๋ฉ”์„œ๋“œ๋งˆ๋‹ค RequestHandler ํ˜ธ์ถœ ํŒจํ„ด์ด ๋ฐ˜๋ณต๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐ˜๋ณต ํŒจํ„ด์€ ์ฝ”๋“œ ์ค‘๋ณต์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ๊ณตํ†ต fetch ๋กœ์ง์„ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”:

+ private suspend fun <T> fetch(request: suspend () -> T): T {
+     return RequestHandler<T>().request {
+         request()
+     }
+ }

  override suspend fun fetchEmploymentCount(): FetchEmploymentCountResponse {
-     return RequestHandler<FetchEmploymentCountResponse>().request {
-         applicationApi.fetchEmploymentCount()
-     }
+     return fetch { applicationApi.fetchEmploymentCount() }
  }

  override suspend fun fetchEmploymentStatus(): FetchEmploymentStatusResponse {
-     return RequestHandler<FetchEmploymentStatusResponse>().request {
-         applicationApi.fetchEmploymentStatus()
-     }
+     return fetch { applicationApi.fetchEmploymentStatus() }
  }

์ด๋Ÿฌํ•œ ํŒจํ„ด์„ ๋ชจ๋“  fetch ๋ฉ”์„œ๋“œ์— ์ ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ์ค‘๋ณต์„ ์ค„์ด๊ณ  ํ–ฅํ›„ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ๋” ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Also applies to: 57-61

gradlew.bat (1)

28-29: ๋ฐฐ์น˜ ์Šคํฌ๋ฆฝํŠธ ์ฃผ์„ ๊ด€๋ จ ์กฐ์–ธ

์—ฌ๊ธฐ์— ์ถ”๊ฐ€๋œ ์ฃผ์„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฃผ์„์€ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด์ง€๋งŒ, ์“ฐ์ด์ง€ ์•Š๋Š” ๋ณ€์ˆ˜๋ผ๋ฉด ์ด ์ฃผ์„์ด ์‹ค์ œ๋กœ ํ•„์š”ํ•œ์ง€ ๊ฒ€ํ† ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

core/network/src/main/java/team/retum/network/model/response/application/FetchEmploymentStatusResponse.kt (1)

6-24: ์‘๋‹ต ๋ชจ๋ธ ํด๋ž˜์Šค๊ฐ€ ์ž˜ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ์—”๋“œ API ์‘๋‹ต์„ ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค ๊ตฌ์กฐ๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ค‘์ฒฉ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ณ„์ธต์  ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ž˜ ํ‘œํ˜„ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, JSON ์–ด๋…ธํ…Œ์ด์…˜๋„ ์ ์ ˆํžˆ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋งŒ, ์ถ”ํ›„ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ๋‚ด๋ถ€ ํด๋ž˜์Šค๋ฅผ ๋ณ„๋„ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ๋„ ๊ณ ๋ คํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๋ถ€ ํด๋ž˜์Šค๋ฅผ ๋ณ„๋„ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•:

// GetEmploymentRateList.kt
@JsonClass(generateAdapter = true)
data class GetEmploymentRateList(
    @Json(name = "id") val id: Int,
    @Json(name = "company_name") val companyName: String,
    @Json(name = "logo_url") val logoUrl: String
)

// ClassEmploymentStatusResponse.kt
@JsonClass(generateAdapter = true)
data class ClassEmploymentStatusResponse(
    @Json(name = "class_id") val classId: Int,
    @Json(name = "employment_rate_response_list") val employmentRateList: List<GetEmploymentRateList>,
    @Json(name = "total_students") val totalStudents: Int,
    @Json(name = "passed_students") val passedStudents: Int
)

// FetchEmploymentStatusResponse.kt
@JsonClass(generateAdapter = true)
data class FetchEmploymentStatusResponse(
    @Json(name = "classes") val classes: List<ClassEmploymentStatusResponse>
)
feature/home/src/main/java/team/retum/home/ui/HomeScreen.kt (2)

323-331: ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šคํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋ฒ„ํŠผ์˜ ํ…์ŠคํŠธ๊ฐ€ ํ•˜๋“œ์ฝ”๋”ฉ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๊ตญ์–ด ์ง€์› ๋ฐ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

-                text = "ํ˜„ํ™ฉ ๋ณด๋Ÿฌ ๊ฐ€๊ธฐ ->",
+                text = stringResource(id = R.string.view_employment_status),

strings.xml ํŒŒ์ผ์— ๋‹ค์Œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”:

<string name="view_employment_status">ํ˜„ํ™ฉ ๋ณด๋Ÿฌ ๊ฐ€๊ธฐ -></string>

323-331: ๋ฒ„ํŠผ ์Šคํƒ€์ผ ๋ฐ ๋ ˆ์ด์•„์›ƒ ๊ฐœ์„ ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋ฒ„ํŠผ์˜ ์Šคํƒ€์ผ๋ง์ด ๋‹ค์†Œ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. wrapContentSize()์™€ fillMaxWidth(0.4f)๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ผ๊ด€๋œ UI๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ๊ฐ„๋‹จํ•˜๊ณ  ๋ช…ํ™•ํ•œ ๋ฐฉ์‹์œผ๋กœ ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

-            JobisSmallButton(
-                modifier = Modifier
-                    .wrapContentSize()
-                    .background(Color.Transparent)
-                    .fillMaxWidth(0.4f),
-                text = "ํ˜„ํ™ฉ ๋ณด๋Ÿฌ ๊ฐ€๊ธฐ ->",
-                color = ButtonColor.Primary,
-                onClick = onEmploymentClick,
-            )
+            JobisSmallButton(
+                modifier = Modifier
+                    .background(Color.Transparent),
+                text = stringResource(id = R.string.view_employment_status),
+                color = ButtonColor.Primary,
+                onClick = onEmploymentClick,
+            )
core/domain/src/main/java/team/retum/usecase/entity/application/EmploymentStatusEntity.kt (2)

23-24: TODO ์ฃผ์„ ์ œ๊ฑฐ ํ•„์š”

์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๊ฐ€๋…์„ฑ๊ณผ ํ”„๋กœํŽ˜์…”๋„๋ฆฌ์ฆ˜์„ ์œ„ํ•ด ์ด TODO ์ฃผ์„์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ์‹ค์ œ ์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ์„ธ์š”.

-    classes = this.classes.map { it.toEntity() } // TODO :: ์ด ๊ตฌ์กฐ ์ดํ•ด ํ•„์š”
+    classes = this.classes.map { it.toEntity() }

15-19: ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค ๋„ค์ด๋ฐ ๊ฐœ์„  ์ œ์•ˆ

GetEmploymentRateList๋ผ๋Š” ์ด๋ฆ„์—๋Š” "Get" ์ ‘๋‘์‚ฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด ์ผ๋ฐ˜์ ์ธ ์—”ํ‹ฐํ‹ฐ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค๋“ค๊ณผ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด "Get" ์ ‘๋‘์‚ฌ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

-        data class GetEmploymentRateList(
+        data class EmploymentRateEntity(
             val id: Int,
             val companyName: String,
             val logoUrl: String,
         )

์ดํ›„์— ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์€ ๊ด€๋ จ ์ฐธ์กฐ๋“ค๋„ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

  • 30์ค„: employmentRateList = this.employmentRateList.map { it.toEntity() },
  • 35-39์ค„: ํ™•์žฅ ํ•จ์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธ
feature/employment/src/main/java/team/retum/employment/viewmodel/EmploymentViewModel.kt (2)

49-52: ํ•œ๊ตญ์–ด ์ฃผ์„์€ ์˜์–ด๋กœ ๋ฒˆ์—ญ ๋˜๋Š” ํ†ต์ผ ํ•„์š”

์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ํ•œ๊ตญ์–ด ์ฃผ์„("์ต์…‰์…˜์˜ ์ง‘ํ•ฉ")์„ ์˜์–ด๋กœ ๋ฒˆ์—ญํ•˜๊ฑฐ๋‚˜, ํ”„๋กœ์ ํŠธ ์ „์ฒด์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ฃผ์„ ์–ธ์–ด๋ฅผ ํ†ต์ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

-sealed interface EmploymentSideEffect { // ์ต์…‰์…˜์˜ ์ง‘ํ•ฉ
+sealed interface EmploymentSideEffect { // Collection of exceptions/side effects

18-29: ์†Œ์ˆ˜์  ํ‘œ์‹œ ๋กœ์ง ๊ฐœ์„  ํ•„์š”

ํ˜„์žฌ ์†Œ์ˆ˜์  ํ‘œ์‹œ๋ฅผ ์œ„ํ•ด DecimalFormat("##.#").format(rate)๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํ•œ๊ธ€ ๋กœ์ผ€์ผ์—์„œ๋Š” ์†Œ์ˆ˜์ ์ด ์‰ผํ‘œ(,)๋กœ ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ์ผ€์ผ์— ๊ด€๊ณ„์—†์ด ์ผ๊ด€๋œ ํ‘œ์‹œ๋ฅผ ์œ„ํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๋กœ์ผ€์ผ์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

-                        rate = DecimalFormat("##.#").format(rate),
+                        rate = DecimalFormat("##.#").apply { 
+                            DecimalFormatSymbols.getInstance(Locale.US).also { symbols ->
+                                decimalFormatSymbols = symbols
+                            }
+                        }.format(rate),

์ด๋ฅผ ์œ„ํ•ด ์ž„ํฌํŠธ ์ถ”๊ฐ€๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค:

import java.text.DecimalFormatSymbols
import java.util.Locale
feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (5)

60-60: TODO ์ฃผ์„ ์ œ๊ฑฐ ํ•„์š”

์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๊ฐ€๋…์„ฑ๊ณผ ํ”„๋กœํŽ˜์…”๋„๋ฆฌ์ฆ˜์„ ์œ„ํ•ด TODO ์ฃผ์„์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ์‹ค์ œ ์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ์„ธ์š”.

-) { // TODO :: ๋„ค๋น„๊ฒŒ์ด์…˜ ์ถ”๊ฐ€ ๋ฐ ๋ถ€์ˆ˜
+) {

61-71: ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋…ผ๋ฆฌ ๊ฐœ์„  ํ•„์š”

ํ˜„์žฌ animatedValue๋Š” animateTo๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ ๊ฐ™์€ ๊ฐ’(rate)์œผ๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, UI์— ์ด ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ’์ด ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถˆํ•„์š”ํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ณ„์‚ฐ์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

-    val animatedValue = remember { Animatable(rate) }
-    LaunchedEffect(Unit) {
-        animatedValue.animateTo(
-            targetValue = rate,
-            animationSpec = tween(durationMillis = 1000, easing = LinearEasing)
-        )
-        with(employmentViewModel) {
-            fetchEmploymentCount()
-        }
-    }
+    LaunchedEffect(Unit) {
+        employmentViewModel.fetchEmploymentCount()
+    }

๋˜ํ•œ CircleProgress ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์ฒด ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋กœ์ง์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.


89-89: TODO ์ฃผ์„ ์ œ๊ฑฐ ํ•„์š”

์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๊ฐ€๋…์„ฑ๊ณผ ํ”„๋กœํŽ˜์…”๋„๋ฆฌ์ฆ˜์„ ์œ„ํ•ด TODO ์ฃผ์„์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ์‹ค์ œ ์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ์„ธ์š”.

-) { // TODO :: UI ํผ๋ธ”๋ฆฌ์‹ฑ
+) {

252-308: CircleProgress ์ปดํฌ๋„ŒํŠธ ๊ฐœ์„  ์ œ์•ˆ

CircleProgress ์ปดํฌ๋„ŒํŠธ์— ๋ช‡ ๊ฐ€์ง€ ๊ฐœ์„  ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  1. StrokeCap.Butt์™€ StrokeCap.Round ๋ถˆ์ผ์น˜: ๋‘ ์•„ํฌ ์‚ฌ์ด์— ์Šคํƒ€์ผ ๋ถˆ์ผ์น˜๊ฐ€ ์žˆ์–ด ์‹œ๊ฐ์ ์œผ๋กœ ์ผ๊ด€์„ฑ์ด ์—†์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ์ค‘๋ณต ์ฝ”๋“œ: ๋‘ ์•„ํฌ๊ฐ€ ๋™์ผํ•œ ํฌ๊ธฐ์™€ ์œ„์น˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์ด๋ฅผ ๊ณต์œ  ๋ณ€์ˆ˜๋กœ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. scaleX = -1f๋Š” ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์— ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ณด๋‹ค๋Š” startAngle๊ณผ sweepAngle์„ ์กฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค.
 Canvas(
     modifier = Modifier
         .size(radius)
-        .scale(scaleX = -1f, scaleY = 1f)
 ) {
     val canvasSize = size.minDimension
     val arcRadius = canvasSize / 2 - strokeWidth.toPx() / 2
+    val arcSize = Size(arcRadius * 2, arcRadius * 2)
+    val arcOffset = Offset(
+        (size.width - arcRadius * 2) / 2,
+        (size.height - arcRadius * 2) / 2
+    )

     drawArc(
         color = primaryColor,
-        startAngle = 270f,
-        sweepAngle = 360f,
+        startAngle = 90f,
+        sweepAngle = 360f,
         useCenter = false,
         style = Stroke(width = strokeWidth.toPx(), cap = StrokeCap.Round),
-        size = Size(arcRadius * 2, arcRadius * 2),
-        topLeft = Offset(
-            (size.width - arcRadius * 2) / 2,
-            (size.height - arcRadius * 2) / 2
-        )
+        size = arcSize,
+        topLeft = arcOffset
     )

     drawArc(
         color = secondaryColor,
-        startAngle = 270f,
-        sweepAngle = animatedValue.value * 3.6f,
+        startAngle = 90f,
+        sweepAngle = animatedValue.value * 3.6f,
         useCenter = false,
-        style = Stroke(width = strokeWidth.toPx(), cap = StrokeCap.Butt),
-        size = Size(arcRadius * 2, arcRadius * 2),
-        topLeft = Offset(
-            (size.width - arcRadius * 2) / 2,
-            (size.height - arcRadius * 2) / 2
-        )
+        style = Stroke(width = strokeWidth.toPx(), cap = StrokeCap.Round),
+        size = arcSize,
+        topLeft = arcOffset
     )
 }

310-363: ClassEmploymentButton UI ๊ตฌ์กฐ ๊ฐœ์„  ์ œ์•ˆ

ClassEmploymentButton ์ปดํฌ๋„ŒํŠธ์—๋Š” ์ค‘์ฒฉ๋œ Surface์™€ Column์ด ๋งŽ์ด ์žˆ์–ด ๋ถˆํ•„์š”ํ•œ ๋ณต์žก์„ฑ์„ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์—ฌ๋Ÿฌ ์ค‘์ฒฉ๋œ ํŒจ๋”ฉ ๊ตฌ์„ฑ์ด ์žˆ์œผ๋ฉฐ ์ผ๋ถ€๋Š” ์ค‘๋ณต๋ฉ๋‹ˆ๋‹ค.

  1. ์ค‘์ฒฉ๋œ Surface ๋ฐ Column ๊ตฌ์กฐ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ณ 
  2. ํŒจ๋”ฉ ๊ฐ’์„ ํ†ตํ•ฉ/์ •๋ฆฌํ•˜๋ฉฐ
  3. contentAlignment๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ ˆ์ด์•„์›ƒ์„ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋ฆฌํŒฉํ† ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
 @Composable
 fun ClassEmploymentButton(
     onClassClick: () -> Unit,
     @DrawableRes image: Int,
     description: String = "",
     text: String,
 ) {
     Surface(
-        modifier = Modifier.padding(),
+        modifier = Modifier,
         onClick = onClassClick,
         color = JobisTheme.colors.inverseSurface,
         shape = RoundedCornerShape(8.dp),
     ) {
         Column(
-            modifier = Modifier.background(color = JobisTheme.colors.inverseSurface)
+            modifier = Modifier
+                .padding(horizontal = 34.dp, vertical = 20.dp),
+            horizontalAlignment = Alignment.CenterHorizontally
         ) {
-            Column(
-                modifier = Modifier.padding(top = 20.dp, start = 34.dp, end = 34.dp),
-                verticalArrangement = Arrangement.SpaceBetween,
-                horizontalAlignment = Alignment.CenterHorizontally
-            ) {
-                Box(
-                    modifier = Modifier
-                        .size(80.dp)
-                        .clip(CircleShape)
-                        .background(JobisTheme.colors.background),
-                    contentAlignment = Alignment.Center
-                ) {
-                    Icon(
-                        modifier = Modifier
-                            .size(48.dp),
-                        painter = painterResource(image),
-                        contentDescription = description,
-                        tint = Color.Unspecified
-                    )
-                }
+            Box(
+                modifier = Modifier
+                    .size(80.dp)
+                    .clip(CircleShape)
+                    .background(JobisTheme.colors.background),
+                contentAlignment = Alignment.Center
+            ) {
+                Icon(
+                    modifier = Modifier
+                        .size(48.dp),
+                    painter = painterResource(image),
+                    contentDescription = description,
+                    tint = Color.Unspecified
+                )
             }
+            Spacer(modifier = Modifier.height(16.dp))
             Surface(
                 color = JobisTheme.colors.surfaceTint,
                 shape = RoundedCornerShape(12.dp),
                 modifier = Modifier
-                    .padding(top = 16.dp, start = 12.dp, bottom = 12.dp),
+                    .padding(start = 12.dp),
             ) {
                 JobisText(
                     text = text,
                     style = JobisTypography.SubBody,
                     color = JobisTheme.colors.background,
                     modifier = Modifier
                         .padding(horizontal = 16.dp, vertical = 8.dp)
                 )
             }
         }
     }
 }
๐Ÿ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 1734fe8 and 597e908.

โ›” Files ignored due to path filters (4)
  • core/design-system/src/main/res/drawable/ic_computer.png is excluded by !**/*.png
  • core/design-system/src/main/res/drawable/ic_robot.png is excluded by !**/*.png
  • core/design-system/src/main/res/drawable/ic_spanner.png is excluded by !**/*.png
  • gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
๐Ÿ“’ Files selected for processing (32)
  • app/build.gradle.kts (2 hunks)
  • app/src/main/java/team/retum/jobisandroidv2/JobisNavigator.kt (2 hunks)
  • app/src/main/java/team/retum/jobisandroidv2/navigation/MainNavigation.kt (3 hunks)
  • app/src/main/java/team/retum/jobisandroidv2/root/RootNavigation.kt (2 hunks)
  • app/src/main/java/team/retum/jobisandroidv2/root/RootScreen.kt (4 hunks)
  • core/common/src/main/java/team/retum/common/utils/ResourceKeys.kt (2 hunks)
  • core/data/src/main/java/team/retum/data/repository/application/ApplicationRepository.kt (2 hunks)
  • core/data/src/main/java/team/retum/data/repository/application/ApplicationRepositoryImpl.kt (2 hunks)
  • core/domain/src/main/java/team/retum/usecase/entity/application/EmploymentStatusEntity.kt (1 hunks)
  • core/domain/src/main/java/team/retum/usecase/usecase/application/FetchEmploymentStatusUseCase.kt (1 hunks)
  • core/network/src/main/java/team/retum/network/api/ApplicationApi.kt (2 hunks)
  • core/network/src/main/java/team/retum/network/datasource/application/RemoteApplicationDataSource.kt (2 hunks)
  • core/network/src/main/java/team/retum/network/datasource/application/RemoteApplicationDataSourceImpl.kt (2 hunks)
  • core/network/src/main/java/team/retum/network/di/RequestUrls.kt (1 hunks)
  • core/network/src/main/java/team/retum/network/model/response/application/FetchEmploymentStatusResponse.kt (1 hunks)
  • feature/employment/.gitignore (1 hunks)
  • feature/employment/build.gradle.kts (1 hunks)
  • feature/employment/src/main/AndroidManifest.xml (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/model/CompanyItem.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/navigation/EmploymentNavigation.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/ui/EmploymentDetailScreen.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/viewmodel/EmploymentDetailViewModel.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/viewmodel/EmploymentViewModel.kt (1 hunks)
  • feature/employment/src/main/res/values/strings.xml (1 hunks)
  • feature/home/src/main/java/team/retum/home/navigation/HomeNavigation.kt (2 hunks)
  • feature/home/src/main/java/team/retum/home/ui/HomeScreen.kt (12 hunks)
  • gradle/libs.versions.toml (3 hunks)
  • gradle/wrapper/gradle-wrapper.properties (1 hunks)
  • gradlew (4 hunks)
  • gradlew.bat (4 hunks)
  • settings.gradle.kts (1 hunks)
โœ… Files skipped from review due to trivial changes (4)
  • feature/employment/src/main/java/team/retum/employment/model/CompanyItem.kt
  • feature/employment/.gitignore
  • feature/employment/src/main/AndroidManifest.xml
  • feature/employment/src/main/res/values/strings.xml
โฐ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: lint_and_build (build)
  • GitHub Check: lint_and_build (lint)
๐Ÿ”‡ Additional comments (56)
settings.gradle.kts (1)

46-46: ๋ชจ๋“ˆ ์ถ”๊ฐ€ ํ™•์ธ๋จ

์ทจ์—…๋ฅ  ์ƒ์„ธ ์กฐํšŒ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ :feature:employment ๋ชจ๋“ˆ์ด ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ์ถ”๊ฐ€๊ฐ€ ์ž˜ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

core/network/src/main/java/team/retum/network/di/RequestUrls.kt (1)

71-71: API ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€ ํ™•์ธ๋จ

์ทจ์—…๋ฅ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ API ์—”๋“œํฌ์ธํŠธ employment๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ํŒจํ„ด์— ๋งž๊ฒŒ $path/employment ํ˜•์‹์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ์–ด ์ผ๊ด€์„ฑ์ด ์œ ์ง€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

app/src/main/java/team/retum/jobisandroidv2/JobisNavigator.kt (2)

13-13: ์ƒˆ๋กœ์šด ๋„ค๋น„๊ฒŒ์ด์…˜ ์ž„ํฌํŠธ ์ถ”๊ฐ€๋จ

์ทจ์—…๋ฅ  ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๊ธฐ ์œ„ํ•œ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ž„ํฌํŠธ๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


138-140: ์ทจ์—…๋ฅ  ํ™”๋ฉด ๋„ค๋น„๊ฒŒ์ด์…˜ ํ•จ์ˆ˜ ๊ตฌํ˜„ ํ™•์ธ

์ทจ์—…๋ฅ  ์ƒ์„ธ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๋Š” navigateToEmployment() ํ•จ์ˆ˜๊ฐ€ ๊ธฐ์กด ๋„ค๋น„๊ฒŒ์ด์…˜ ํŒจํ„ด์— ๋งž๊ฒŒ ์ž˜ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. navController์˜ ํ™•์žฅ ํ•จ์ˆ˜๋ฅผ ์ ์ ˆํžˆ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

feature/employment/build.gradle.kts (4)

1-5: Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์ • ํ™•์ธ

Android ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, Kotlin Android, KSP ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์ ์ ˆํ•˜๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์ด ๋ชจ๋‘ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


7-8: ๊ณตํ†ต Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ ์ ์šฉ ํ™•์ธ

CommonGradlePlugin๊ณผ ComposeGradlePlugin์ด ์ ์šฉ๋˜์–ด ์žˆ์–ด ํ”„๋กœ์ ํŠธ์˜ ์ผ๊ด€๋œ ๋นŒ๋“œ ์„ค์ •์ด ์œ ์ง€๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


10-17: Android ์„ค์ • ํ™•์ธ

๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ "team.retum.employment"๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Java ํ˜ธํ™˜์„ฑ๋„ 21 ๋ฒ„์ „์œผ๋กœ ์ ์ ˆํžˆ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


19-22: ์ข…์†์„ฑ ํ™•์ธ

UI ํˆด๋ง ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ํ•„์ˆ˜ ์ข…์†์„ฑ์ด ์ผ๋ถ€ ๋ˆ„๋ฝ๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ทจ์—…๋ฅ  ํ™”๋ฉด ๊ตฌํ˜„์— ํ•„์š”ํ•œ core ๋ชจ๋“ˆ๋“ค(์˜ˆ: design-system, domain ๋“ฑ)์— ๋Œ€ํ•œ ์˜์กด์„ฑ์ด ์ถ”๊ฐ€๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”. ์ผ๋ฐ˜์ ์œผ๋กœ feature ๋ชจ๋“ˆ์€ ๊ธฐ๋ณธ์ ์ธ core ๋ชจ๋“ˆ๋“ค์„ ์˜์กด์„ฑ์œผ๋กœ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

app/build.gradle.kts (1)

117-117: ๊ณ ์šฉ ๊ธฐ๋Šฅ ๋ชจ๋“ˆ ์ถ”๊ฐ€ ํ™•์ธ๋จ.

๊ณ ์šฉ๋ฅ  ์ƒ์„ธ ์กฐํšŒ ํŽ˜์ด์ง€ ์ œ์ž‘์„ ์œ„ํ•œ :feature:employment ๋ชจ๋“ˆ ์˜์กด์„ฑ์ด ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ์— ์ž˜ ํ†ตํ•ฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

core/network/src/main/java/team/retum/network/api/ApplicationApi.kt (1)

12-12: ImportFetchEmploymentStatusResponse ์ถ”๊ฐ€ ํ™•์ธ๋จ.

๊ณ ์šฉ ์ƒํƒœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์‘๋‹ต ๋ชจ๋ธ import๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

core/network/src/main/java/team/retum/network/datasource/application/RemoteApplicationDataSource.kt (1)

6-6: FetchEmploymentStatusResponse ์ž„ํฌํŠธ ์ถ”๊ฐ€ ํ™•์ธ๋จ.

๊ณ ์šฉ ์ƒํƒœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์‘๋‹ต ๋ชจ๋ธ import๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

app/src/main/java/team/retum/jobisandroidv2/root/RootNavigation.kt (2)

15-15: ๊ณ ์šฉ ํ™”๋ฉด ํƒ์ƒ‰ ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ํ™•์ธ๋จ.

์ทจ์—…๋ฅ  ์ƒ์„ธ ์กฐํšŒ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ธฐ ์œ„ํ•œ onEmploymentClick ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ฝœ๋ฐฑ๊ณผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


39-39: Root ์ปดํฌ์ €๋ธ”์— onEmploymentClick ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ ํ™•์ธ๋จ.

onEmploymentClick ์ฝœ๋ฐฑ์ด Root ์ปดํฌ์ €๋ธ”์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋„ค๋น„๊ฒŒ์ด์…˜ ํ๋ฆ„์ด ์ ์ ˆํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

core/data/src/main/java/team/retum/data/repository/application/ApplicationRepository.kt (2)

6-6: ํ•„์š”ํ•œ import ๋ฌธ์ด ์ ์ ˆํžˆ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋„คํŠธ์›Œํฌ ๋ชจ๋ธ์˜ ์‘๋‹ต ํด๋ž˜์Šค๊ฐ€ ์ ์ ˆํžˆ ์ž„ํฌํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


26-26: ์‹ ๊ทœ ๊ณ ์šฉ ์ƒํƒœ ์กฐํšŒ ๋ฉ”์„œ๋“œ๊ฐ€ ์ž˜ ์ •์˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

fetchEmploymentStatus ๋ฉ”์„œ๋“œ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค์— ์ ์ ˆํžˆ ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฉฐ, ๋‹ค๋ฅธ fetch ๋ฉ”์„œ๋“œ๋“ค๊ณผ ๋™์ผํ•œ ํŒจํ„ด์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ์ž‘์—…์„ ์œ„ํ•œ suspend ํ‚ค์›Œ๋“œ๋„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

gradle/wrapper/gradle-wrapper.properties (1)

3-5:

โ“ Verification inconclusive

Gradle ๋ฒ„์ „ ์—…๋ฐ์ดํŠธ ๋ฐ ๋„คํŠธ์›Œํฌ ์„ค์ • ์ถ”๊ฐ€์— ๋Œ€ํ•œ ๊ฒ€ํ†  ํ•„์š”

Gradle ๋ฒ„์ „์„ 8.2์—์„œ 8.9๋กœ ์ƒ๋‹นํžˆ ํฐ ํญ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํ”„๋กœ์ ํŠธ์˜ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค์— ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋„คํŠธ์›Œํฌ ํƒ€์ž„์•„์›ƒ๊ณผ URL ๊ฒ€์ฆ ์„ค์ •์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์ด ํ”„๋กœ์ ํŠธ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š”์ง€, ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์˜ ํ™˜๊ฒฝ๊ณผ ํ˜ธํ™˜๋˜๋Š”์ง€ ํ™•์ธํ•ด์ฃผ์„ธ์š”.


๐Ÿ Script executed:

#!/bin/bash
# Gradle ๋ฒ„์ „ ๋ณ€๊ฒฝ์ด ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ
echo "Checking for compatibility issues with Gradle 8.9"

# build.gradle ํŒŒ์ผ์—์„œ AGP ๋ฒ„์ „ ํ™•์ธ
AGP_VERSION=$(grep -r "com.android.application" --include="*.gradle*" . | grep -o "version ['\"].*['\"]" | head -1 | cut -d"'" -f2 | cut -d'"' -f2)

if [ -n "$AGP_VERSION" ]; then
  echo "Android Gradle Plugin version found: $AGP_VERSION"
  
  # AGP ๋ฒ„์ „๊ณผ Gradle 8.9 ํ˜ธํ™˜์„ฑ ์ฒดํฌ (๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ)
  # ์‹ค์ œ๋กœ๋Š” ๋” ๋ณต์žกํ•œ ๋ฒ„์ „ ํ˜ธํ™˜์„ฑ ๋กœ์ง์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Œ
  VERSION_MAJOR=$(echo $AGP_VERSION | cut -d. -f1)
  
  if [ "$VERSION_MAJOR" -lt "8" ]; then
    echo "WARNING: AGP version $AGP_VERSION might not be fully compatible with Gradle 8.9"
  else
    echo "AGP version appears to be compatible with Gradle 8.9"
  fi
else
  echo "Could not determine Android Gradle Plugin version"
fi

# ํ”„๋กœ์ ํŠธ ๋‚ด์˜ ๋‹ค๋ฅธ ํ”Œ๋Ÿฌ๊ทธ์ธ ํ™•์ธ
echo "Checking other plugins in the project"
grep -r "apply plugin" --include="*.gradle*" .

Length of output: 527


[AGP ๋ฒ„์ „ ํ™•์ธ ๋ฐ Gradle 8.9 ์—…๋ฐ์ดํŠธ ๊ฒ€์ฆ ์š”์ฒญ]

  • Gradle ๋ฒ„์ „์„ 8.2์—์„œ 8.9๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ณ , ๋„คํŠธ์›Œํฌ ํƒ€์ž„์•„์›ƒ(networkTimeout=10000)๊ณผ URL ๊ฒ€์ฆ(validateDistributionUrl=true) ์„ค์ •์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์ž๋™ํ™”๋œ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ๊ฒฐ๊ณผ, Android Gradle Plugin(AGP) ๋ฒ„์ „์ด ๊ฐ์ง€๋˜์ง€ ์•Š์•„ ํ•ด๋‹น ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์‹ค์ œ๋กœ ์‚ฌ์šฉ ์ค‘์ธ์ง€ ํ™•์ธ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํ”„๋กœ์ ํŠธ์˜ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋‚˜ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž ํ™˜๊ฒฝ์— ๋ฏธ์น  ์˜ํ–ฅ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, AGP ๋ฐ ๊ธฐํƒ€ ๊ด€๋ จ ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์˜ ํ˜ธํ™˜์„ฑ์„ ์ˆ˜๋™์œผ๋กœ ๊ฒ€ํ† ํ•ด์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.
core/domain/src/main/java/team/retum/usecase/usecase/application/FetchEmploymentStatusUseCase.kt (1)

1-13: UseCase ๊ตฌํ˜„์ด ์ž˜ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

FetchEmploymentStatusUseCase์˜ ๊ตฌํ˜„์ด ํ”„๋กœ์ ํŠธ์˜ ๋‹ค๋ฅธ UseCase ํŒจํ„ด์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค:

  1. ApplicationRepository ์˜์กด์„ฑ ์ฃผ์ž…์ด ์ ์ ˆํ•˜๊ฒŒ ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค.
  2. suspend operator ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ ์‹œ ๊ฐ„๊ฒฐํ•œ ๋ฌธ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  3. runCatching์„ ํ†ตํ•ด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ์ ์ ˆํžˆ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  4. ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ์—”ํ‹ฐํ‹ฐ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” extension ํ•จ์ˆ˜ ์‚ฌ์šฉ์ด ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
core/network/src/main/java/team/retum/network/datasource/application/RemoteApplicationDataSourceImpl.kt (2)

7-7: ํ•„์š”ํ•œ import ๋ฌธ์ด ์ ์ ˆํžˆ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ์‘๋‹ต ๋ชจ๋ธ ํด๋ž˜์Šค๊ฐ€ ์ž˜ ์ž„ํฌํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


57-61: ๊ณ ์šฉ ์ƒํƒœ ์กฐํšŒ ๋ฉ”์„œ๋“œ๊ฐ€ ์ผ๊ด€๋œ ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

fetchEmploymentStatus ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋“ค๊ณผ ๋™์ผํ•œ ํŒจํ„ด์„ ๋”ฐ๋ผ ์ž˜ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

  1. RequestHandler๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  2. ์ ์ ˆํ•œ API ์—”๋“œํฌ์ธํŠธ(applicationApi.fetchEmploymentStatus())๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  3. ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์˜€์Šต๋‹ˆ๋‹ค.
gradlew.bat (4)

17-17: Windows ๋ฐฐ์น˜ ์Šคํฌ๋ฆฝํŠธ ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•œ ๊ฒ€ํ† 

์ด ๋ถ€๋ถ„์€ ๊ธฐ์กด ์ฝ”๋“œ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. %DEBUG% ๋ณ€์ˆ˜๊ฐ€ ๋น„์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ๋น„์–ด์žˆ์œผ๋ฉด echo๋ฅผ ๊บผ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.


44-44: Windows ๋ฐฐ์น˜ ์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ ๊ฐœ์„ 

์ˆซ์ž ๋น„๊ต์— == ์—ฐ์‚ฐ์ž ๋Œ€์‹  equ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ Windows ๋ฐฐ์น˜ ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋” ์ •ํ™•ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ์€ ์Šคํฌ๋ฆฝํŠธ์˜ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.


79-79: Windows ๋ฐฐ์น˜ ์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ ๊ฐœ์„ 

์—ฌ๊ธฐ์„œ๋„ ์ˆซ์ž ๋น„๊ต๋ฅผ ์œ„ํ•ด == ์—ฐ์‚ฐ์ž ๋Œ€์‹  equ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐฐ์น˜ ์Šคํฌ๋ฆฝํŠธ์˜ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋ถ€๋ถ„์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.


84-87: ํ–ฅ์ƒ๋œ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋กœ์ง

์ด ๋ถ€๋ถ„์—์„œ๋Š” ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

  1. ERRORLEVEL ๊ฐ’์„ EXIT_CODE ๋ณ€์ˆ˜์— ์ €์žฅ
  2. EXIT_CODE๊ฐ€ 0์ด๋ฉด 1๋กœ ์„ค์ • (์˜ค๋ฅ˜ ํ”Œ๋ž˜๊ทธ)
  3. GRADLE_EXIT_CONSOLE ๋ณ€์ˆ˜ ๊ฐ’์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ์ข…๋ฃŒ ์ฝ”๋“œ๋กœ ์Šคํฌ๋ฆฝํŠธ ์ข…๋ฃŒ

์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ์€ ์Šคํฌ๋ฆฝํŠธ์˜ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋” ๋ช…ํ™•ํ•˜๊ณ  ๊ฐ•๋ ฅํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

core/data/src/main/java/team/retum/data/repository/application/ApplicationRepositoryImpl.kt (2)

7-7: ๊ณ ์šฉ ์ƒํƒœ ์‘๋‹ต ๋ชจ๋ธ ์ถ”๊ฐ€

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ํ•„์š”ํ•œ FetchEmploymentStatusResponse ๋ชจ๋ธ์„ ๊ฐ€์ ธ์˜ค๋Š” import ๋ฌธ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‹ ๊ทœ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ์ ์ ˆํ•œ ๋ณ€๊ฒฝ์ž…๋‹ˆ๋‹ค.


46-48: ๊ณ ์šฉ ์ƒํƒœ ์กฐํšŒ ๊ธฐ๋Šฅ ๊ตฌํ˜„

์ƒˆ๋กœ์šด ๊ณ ์šฉ ์ƒํƒœ ์กฐํšŒ ๊ธฐ๋Šฅ์ธ fetchEmploymentStatus() ๋ฉ”์„œ๋“œ๊ฐ€ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋กœ๋ถ€ํ„ฐ ๊ณ ์šฉ ์ƒํƒœ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋‹จ์ˆœ ์œ„์ž„ ํŒจํ„ด์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์–ด, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๊ณ„์ธต์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ ๊ตฌํ˜„์ด ๊น”๋”ํ•˜๋ฉฐ ๊ธฐ์กด ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ ํŒจํ„ด์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

core/common/src/main/java/team/retum/common/utils/ResourceKeys.kt (1)

26-28: ๊ณ ์šฉ ๊ด€๋ จ ๋ฆฌ์†Œ์Šค ํ‚ค ์ถ”๊ฐ€

๊ณ ์šฉ ์ƒํƒœ ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ์ƒˆ๋กœ์šด ์ƒ์ˆ˜๋“ค์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

  • RATE: ๊ณ ์šฉ๋ฅ  ์ •๋ณด๋ฅผ ์œ„ํ•œ ํ‚ค
  • TOTAL_STUDENT_COUNT: ์ „์ฒด ํ•™์ƒ ์ˆ˜๋ฅผ ์œ„ํ•œ ํ‚ค
  • PASS_COUNT: ํ•ฉ๊ฒฉ ํ•™์ƒ ์ˆ˜๋ฅผ ์œ„ํ•œ ํ‚ค

์ด ์ƒ์ˆ˜๋“ค์€ ํ™”๋ฉด ๊ฐ„ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์ด๋‚˜ SharedPreferences ๋“ฑ์—์„œ ์‚ฌ์šฉ๋  ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๋ช…ํ™•ํ•œ ์ƒ์ˆ˜๋ช…์„ ์‚ฌ์šฉํ•œ ์ข‹์€ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค.

app/src/main/java/team/retum/jobisandroidv2/navigation/MainNavigation.kt (3)

9-9: ๊ณ ์šฉ ๋ชจ๋“ˆ ๋„ค๋น„๊ฒŒ์ด์…˜ import ์ถ”๊ฐ€

์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๊ณ ์šฉ ๊ด€๋ จ ๊ธฐ๋Šฅ์˜ ๋„ค๋น„๊ฒŒ์ด์…˜์„ ์œ„ํ•œ import ๋ฌธ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‹ ๊ทœ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ์ ์ ˆํ•œ ๋ณ€๊ฒฝ์ž…๋‹ˆ๋‹ค.


38-38: Root ๋„ค๋น„๊ฒŒ์ด์…˜์— ๊ณ ์šฉ ๊ธฐ๋Šฅ ์ด๋™ ์ฝœ๋ฐฑ ์ถ”๊ฐ€

Root ๋„ค๋น„๊ฒŒ์ด์…˜์— ๊ณ ์šฉ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๊ธฐ ์œ„ํ•œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ onEmploymentClick์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฝœ๋ฐฑ์€ navigator::navigateToEmployment์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ์šฉ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.


108-111: ๊ณ ์šฉ ๊ธฐ๋Šฅ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ถ”๊ฐ€

๊ณ ์šฉ ํ™”๋ฉด์„ ์œ„ํ•œ ์ƒˆ๋กœ์šด ๋„ค๋น„๊ฒŒ์ด์…˜ ๊ฒฝ๋กœ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ๋กœ๋Š” ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ฝœ๋ฐฑ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค:

  1. onBackPressed: ๋’ค๋กœ ๊ฐ€๊ธฐ ๋ฒ„ํŠผ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ฝœ๋ฐฑ
  2. onClassClick: ํŠน์ • ํ•™๊ธ‰์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ฝœ๋ฐฑ

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ๋„ค๋น„๊ฒŒ์ด์…˜ ๊ตฌ์„ฑ์ด ๊ธฐ์กด ํŒจํ„ด์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

feature/home/src/main/java/team/retum/home/navigation/HomeNavigation.kt (2)

15-15: ์ฝ”๋“œ ๊ตฌํ˜„์ด ์ž˜ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด onEmploymentClick ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž˜ ์ถ”๊ฐ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ์ฝ”๋“œ ํŒจํ„ด์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹ค๋ฅธ ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ์™€ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


27-27: Home ์ปดํฌ์ €๋ธ”์— onEmploymentClick ์ „๋‹ฌ ๊ตฌํ˜„์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

Home ์ปดํฌ์ €๋ธ”์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ onEmploymentClick ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

feature/home/src/main/java/team/retum/home/ui/HomeScreen.kt (9)

23-23: ์ƒˆ๋กœ์šด ๋ ˆ์ด์•„์›ƒ ์†์„ฑ ์ถ”๊ฐ€๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

wrapContentSize๋ฅผ importํ•˜์—ฌ ๋ฒ„ํŠผ์˜ ํฌ๊ธฐ ์กฐ์ •์„ ์œ„ํ•ด ์‚ฌ์šฉํ•œ ๊ฒƒ์ด ์ข‹๋„ค์š”.


61-63: ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ ๊ด€๋ จ import๊ฐ€ ์ •ํ™•ํžˆ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ButtonColor ๋ฐ JobisSmallButton import๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


83-83: API ์ผ๊ด€์„ฑ์„ ์œ„ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ถ”๊ฐ€๊ฐ€ ์ž˜ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Home ํ•จ์ˆ˜์— onEmploymentClick ์ฝœ๋ฐฑ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ UI์™€ ๋‚ด๋น„๊ฒŒ์ด์…˜ ๋กœ์ง์ด ์ž˜ ์—ฐ๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


130-131: HomeScreen ํ•จ์ˆ˜์— ์ฝœ๋ฐฑ ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

HomeScreen์— onEmploymentClick ์ฝœ๋ฐฑ์„ ์ „๋‹ฌํ•˜๋Š” ๋ถ€๋ถ„์ด ์ž˜ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


154-154: ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์ •ํ™•ํžˆ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

HomeScreen ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜์— onEmploymentClick ์ฝœ๋ฐฑ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


186-187: Banner ์ปดํฌ๋„ŒํŠธ์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ ์ ˆํžˆ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Banner ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ onEmploymentClick ์ฝœ๋ฐฑ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


228-228: Banner ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜์— ์ฝœ๋ฐฑ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Banner ํ•จ์ˆ˜์— onEmploymentClick ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์ ์ ˆํžˆ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


270-271: EmploymentRate ์ปดํฌ๋„ŒํŠธ์— ์ฝœ๋ฐฑ์ด ์ž˜ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

EmploymentRate ํ˜ธ์ถœ ์‹œ onEmploymentClick ์ฝœ๋ฐฑ์ด ์ •ํ™•ํžˆ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


309-309: ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์ ์ ˆํžˆ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

EmploymentRate ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜์— onEmploymentClick ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

gradlew (7)

4-4: ์ €์ž‘๊ถŒ ์ •๋ณด๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ €์ž‘๊ถŒ ์ •๋ณด๊ฐ€ ์ตœ์‹  ์—ฐ๋„๋กœ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


20-62: ์Šคํฌ๋ฆฝํŠธ ๋ฌธ์„œํ™” ๋ฐ ์ฃผ์„์ด ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Gradle ์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•œ ๋ฌธ์„œํ™” ๋ฐ ์„ค๋ช…์ด ์ƒ์„ธํ•˜๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์œผ๋ฉฐ, ์‹คํ–‰ ๋ฐ ํŒจ์น˜ ๊ด€๋ จ ์ค‘์š” ์ง€์นจ์ด ํฌํ•จ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


70-81: ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

expr ๋Œ€์‹  ์‰˜ ํŒŒ๋ผ๋ฏธํ„ฐ ํ™•์žฅ๊ณผ case ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋” ๊ฒฌ๊ณ ํ•˜๊ณ  ๊ฐ€๋…์„ฑ ์žˆ๋Š” ์ฝ”๋“œ๋กœ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


133-140: Java ๋ช…๋ น ๊ฒ€์ถœ ๋กœ์ง ๊ฐœ์„ ์ด ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค.

which ๋Œ€์‹  command -v๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์ด์‹์„ฑ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ Java ๋ช…๋ น์„ ๊ฒ€์ƒ‰ํ•˜๋„๋ก ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


144-160: ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ์„ค์ • ๋กœ์ง์ด ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ์ตœ๋Œ€๊ฐ’ ์„ค์ • ๋กœ์ง์ด ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


211-247: ์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ˆ˜ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

JVM ์˜ต์…˜๊ณผ ๋ช…๋ น ์ธ์ˆ˜ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๋กœ์ง์ด ๋” ๊ฒฌ๊ณ ํ•˜๊ณ  ์•ˆ์ „ํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ฐœ์„ ๋˜์—ˆ์œผ๋ฉฐ, xargs๋ฅผ ํ™œ์šฉํ•œ ์ธ์ˆ˜ ํŒŒ์‹ฑ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


1-1:

โ“ Verification inconclusive

์…ธ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ง€์ • ๋ฐฉ์‹ ๋ณ€๊ฒฝ ๊ฒ€ํ† ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

#!/usr/bin/env sh์—์„œ #!/bin/sh๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‹œ์Šคํ…œ ๊ฐ„ ํ˜ธํ™˜์„ฑ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #!/usr/bin/env sh๊ฐ€ ๋” ์ด์‹์„ฑ์ด ๋†’์ง€๋งŒ, ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๊ฒฐ์ •ํ•ด์ฃผ์„ธ์š”.


๐Ÿ Script executed:

#!/bin/bash
# Check if /bin/sh is POSIX compliant
/bin/sh -c 'echo $POSIX2_VERSION'

Length of output: 36


๊ฒ€์ฆ ํ•„์š”: ์…ธ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ง€์ • ๋ฐฉ์‹ ๋ณ€๊ฒฝ ๊ด€๋ จ ์ถ”๊ฐ€ ํ™•์ธ ์š”์ฒญ

  • ํŒŒ์ผ: gradlew (๋ผ์ธ 1)
  • ๋ณ€๊ฒฝ ๋‚ด์—ญ: ๊ธฐ์กด์˜ #!/usr/bin/env sh์—์„œ #!/bin/sh๋กœ ๋ณ€๊ฒฝ๋จ.
  • ์šฐ๋ ค์‚ฌํ•ญ: /bin/sh๊ฐ€ POSIX ํ˜ธํ™˜์„ฑ์„ ์ถฉ์‹คํžˆ ์ œ๊ณตํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๊ฒ€์ฆ ๋ช…๋ น์–ด(echo $POSIX2_VERSION) ์‹คํ–‰ ๊ฒฐ๊ณผ ์•„๋ฌด ์ถœ๋ ฅ๋„ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„, ํ•ด๋‹น ์…ธ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ๋™์ž‘์„ ๋ณด์žฅํ•˜๋Š”์ง€ ๋ถˆ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ถŒ์žฅ ์กฐ์น˜:
    • ํ”„๋กœ์ ํŠธ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์ด์‹์„ฑ์ด ๋†’์€ /usr/bin/env sh ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ์žฌ๊ฒ€ํ† ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

    • ์ถ”๊ฐ€ ๊ฒ€์ฆ์„ ์œ„ํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋ช…๋ น์–ด๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜, ์ˆ˜๋™์œผ๋กœ POSIX ํ˜ธํ™˜์„ฑ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

      #!/bin/bash
      # POSIX2_VERSION ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ๋Š”์ง€ ๋ช…ํ™•ํžˆ ํ™•์ธํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ์˜ˆ์‹œ
      output=$(/bin/sh -c 'if [ -n "$POSIX2_VERSION" ]; then echo "POSIX compliant: $POSIX2_VERSION"; else echo "POSIX2_VERSION not set"; fi')
      echo "POSIX check: $output"

์œ„์™€ ๊ฐ™์ด ๊ฒฐ๊ณผ๊ฐ€ ๋ช…ํ™•ํ•˜๊ฒŒ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค๋ฉด, ํ•ด๋‹น ๋ณ€๊ฒฝ์ด ์‹œ์Šคํ…œ ๊ฐ„ ํ˜ธํ™˜์„ฑ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์„ ์ถฉ๋ถ„ํžˆ ๊ฒ€ํ† ํ•œ ํ›„ ๊ฒฐ์ •ํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.

app/src/main/java/team/retum/jobisandroidv2/root/RootScreen.kt (4)

49-49: Root ํ•จ์ˆ˜์— ๊ณ ์šฉ ํ˜„ํ™ฉ ํŽ˜์ด์ง€ ์ด๋™ ์ฝœ๋ฐฑ์ด ์ ์ ˆํžˆ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

onEmploymentClick ์ฝœ๋ฐฑ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ Root ํ•จ์ˆ˜์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


83-83: RootScreen ํ˜ธ์ถœ์— ์ฝœ๋ฐฑ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

RootScreen ํ˜ธ์ถœ ์‹œ onEmploymentClick ์ฝœ๋ฐฑ์ด ์ ์ ˆํžˆ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


117-117: RootScreen ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜์— ์ฝœ๋ฐฑ์ด ์ •ํ™•ํžˆ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

RootScreen ํ•จ์ˆ˜์— onEmploymentClick ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


163-163: NavHost์˜ home ํ•จ์ˆ˜ ํ˜ธ์ถœ์— ์ฝœ๋ฐฑ์ด ์ž˜ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

NavigationHost์˜ home ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ onEmploymentClick ์ฝœ๋ฐฑ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ „๋‹ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

feature/employment/src/main/java/team/retum/employment/viewmodel/EmploymentDetailViewModel.kt (1)

11-13: ViewModel ์ดˆ๊ธฐํ™” ๋ฐ ์˜์กด์„ฑ ์ฃผ์ž…์ด ์ž˜ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ViewModel ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์˜์กด์„ฑ ์ฃผ์ž…์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ฐ›๊ณ  ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ ์ƒํƒœ ์ดˆ๊ธฐํ™”๋„ ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

core/domain/src/main/java/team/retum/usecase/entity/application/EmploymentStatusEntity.kt (1)

35-40:

โ“ Verification inconclusive

URL ๊ตฌ์„ฑ ๋กœ์ง ํ™•์ธ ํ•„์š”

์ด๋ฏธ์ง€ URL์„ ๊ตฌ์„ฑํ•  ๋•Œ ๋‹จ์ˆœํžˆ ๋ฌธ์ž์—ด์„ ์—ฐ๊ฒฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด logoUrl์— ์ด๋ฏธ ์ „์ฒด URL์ด ํฌํ•จ๋˜์–ด ์žˆ๊ฑฐ๋‚˜ ์Šฌ๋ž˜์‹œ('/')๊ฐ€ ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ Script executed:

#!/bin/bash
# ResourceKeys.IMAGE_URL์˜ ํ˜•์‹๊ณผ ์‚ฌ์šฉ ๋ฐฉ์‹ ํ™•์ธ
cat $(fd ResourceKeys --type file) | grep -A 5 "IMAGE_URL"

Length of output: 463


URL ๊ตฌ์„ฑ ๋กœ์ง ๊ฐœ์„  ํ•„์š”

ํ˜„์žฌ EmploymentStatusEntity.ClassEmploymentStatusEntity.GetEmploymentRateList.toEntity()์—์„œ ์ด๋ฏธ์ง€ URL์„ ๊ตฌ์„ฑํ•  ๋•Œ, ResourceKeys.IMAGE_URL ์ƒ์ˆ˜์™€ this.logoUrl๋ฅผ ๋‹จ์ˆœ ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ ๋ฐฉ์‹์œผ๋กœ ๊ฒฐํ•ฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • ResourceKeys.IMAGE_URL๋Š” "https://dsm-s3-bucket-jobis.s3.ap-northeast-2.amazonaws.com/"์™€ ๊ฐ™์ด trailing slash๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋‚˜,
    • this.logoUrl๊ฐ€ ์ƒ๋Œ€๊ฒฝ๋กœ์ธ ๊ฒฝ์šฐ์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋‚˜,
    • ๋ฐฑ์—”๋“œ ์‘๋‹ต์—์„œ logoUrl์— ์ด๋ฏธ ์ „์ฒด URL์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ ์ค‘๋ณต๋œ URL์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • this.logoUrl์— ์Šฌ๋ž˜์‹œ๊ฐ€ ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ ์˜ฌ๋ฐ”๋ฅธ URL ํ˜•์‹์ด ๋ณด์žฅ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ์—”๋“œ ์‘๋‹ต ์ŠคํŽ™๊ณผ ์ „๋‹ฌ๋˜๋Š” logoUrl ๊ฐ’์˜ ํ˜•์‹์„ ์žฌ๊ฒ€ํ† ํ•œ ํ›„, ์กฐ๊ฑด๋ถ€ ๋กœ์ง(์˜ˆ: ์ „๋‹ฌ๋œ URL์ด ์ ˆ๋Œ€ URL์ธ์ง€ ์ฒดํฌ ํ›„ ์ ‘๋‘์–ด๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฐฉ์‹)์„ ์ ์šฉํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐœ์„ ์„ ๊ฒ€ํ† ํ•ด์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

gradle/libs.versions.toml (3)

51-54:

โ“ Verification inconclusive

์ตœ์‹  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „ ์ ํ•ฉ์„ฑ ํ™•์ธ

์ด PR์— ์ถ”๊ฐ€๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „์ด ์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „์ธ์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค:

  • core-ktx: 1.15.0
  • appcompat: 1.7.0
  • tiles-tooling-preview: 1.4.1
  • ui-tooling-preview-android: 1.7.8

๐ŸŒ Web query:

Android androidx.core:core-ktx ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Error during web search


์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „ ํ™•์ธ ํ•„์š”

ํ˜„์žฌ gradle/libs.versions.toml ํŒŒ์ผ(๋ผ์ธ 51-54)์— ๋‚˜์—ด๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „๋“ค์ด ์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „์ธ์ง€ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  • core-ktx: 1.15.0
  • appcompat: 1.7.0
  • tiles-tooling-preview: 1.4.1
  • ui-tooling-preview-android: 1.7.8

์›น ๊ฒ€์ƒ‰ ์‹œ๋„ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ตœ์‹  ๋ฒ„์ „ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์˜ ์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „์„ ์ˆ˜๋™์œผ๋กœ ํ™•์ธํ•œ ํ›„, ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์—…๋ฐ์ดํŠธํ•ด์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.


20-20:

โ“ Verification inconclusive

์•ˆ๋“œ๋กœ์ด๋“œ Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฒ„์ „ ๋Œ€ํญ ์—…๋ฐ์ดํŠธ ๊ฒ€์ฆ ํ•„์š”

Android Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ์„ 8.2.2์—์„œ 8.7.0์œผ๋กœ ๋Œ€ํญ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ฃผ์š” ๋ฒ„์ „ ๋ณ€๊ฒฝ์œผ๋กœ, ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋‚˜ ๋นŒ๋“œ ์„ค์ • ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐ŸŒ Web query:

Android Gradle Plugin 8.7.0๊ณผ 8.2.2 ์‚ฌ์ด์˜ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๋ฐ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

Error during web search


๊ฒ€์ฆ ํ•„์š”: Android Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ 8.7.0 ์—…๋ฐ์ดํŠธ์˜ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ ํ™•์ธ

Android Gradle ํ”Œ๋Ÿฌ๊ทธ์ธ์„ 8.2.2์—์„œ 8.7.0์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๋ฉด์„œ, major ๋ฒ„์ „ ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ ๋‹ค์Œ ์‚ฌํ•ญ๋“ค์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”:

  • ๋ฆด๋ฆฌ์ฆˆ ๋…ธํŠธ ๊ฒ€ํ† : AGP 8.7.0์˜ ๊ธฐ๋Šฅ ์ถ”๊ฐ€, ์ œ๊ฑฐ ๋˜๋Š” ๋ณ€๊ฒฝ๋œ API ๋ฐ ๊ตฌ์„ฑ ์˜ต์…˜ ํ™•์ธ
  • ๋นŒ๋“œ ์„ค์ •: ๊ธฐ์กด์˜ ๋นŒ๋“œ ์„ค์ • ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ ๋ฐœ์ƒ ์—ฌ๋ถ€ ์ ๊ฒ€
  • ํ˜ธํ™˜์„ฑ ํ…Œ์ŠคํŠธ: ์‹ค์ œ ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ ๋ฐ ํ…Œ์ŠคํŠธ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ ์œ ๋ฌด ํ™•์ธ

ํ˜„์žฌ ์›น ๊ฒ€์ƒ‰์—์„œ ๊ด€๋ จ ์ •๋ณด๋ฅผ ๋ฐ›์ง€ ๋ชปํ–ˆ์œผ๋ฏ€๋กœ, ์œ„ ์‚ฌํ•ญ๋“ค์„ ์ถ”๊ฐ€ ๊ฒ€์ฆํ•œ ํ›„ ์ง„ํ–‰ํ•ด ์ฃผ์„ธ์š”.


120-123:

โ“ Verification inconclusive

์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ๋ชฉ์  ๋ช…ํ™•ํ™” ํ•„์š”

์ด PR์—์„œ ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค(core-ktx, appcompat, tiles-tooling-preview, ui-tooling-preview-android)์˜ ๊ตฌ์ฒด์ ์ธ ์‚ฌ์šฉ ๋ชฉ์ ๊ณผ ํ•„์š”์„ฑ์ด ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠนํžˆ tiles-tooling-preview๋Š” Wear OS ๊ฐœ๋ฐœ๊ณผ ๊ด€๋ จ์ด ์žˆ๋Š”๋ฐ, ์ด ํ”„๋กœ์ ํŠธ๊ฐ€ Wear OS ์•ฑ์„ ๊ฐœ๋ฐœํ•˜๋Š”์ง€ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ Script executed:

#!/bin/bash
# Wear OS ๊ด€๋ จ ์ฝ”๋“œ๋‚˜ ์„ค์ •์ด ์žˆ๋Š”์ง€ ํ™•์ธ
fd -E "*.git*" -E "*build*" -E "*gradle*" -t f | xargs grep -l "wear" 2>/dev/null || echo "No Wear OS references found"

# ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ชจ๋“ˆ ํ™•์ธ
grep -r "androidx-tiles-tooling-preview\|androidx-core-ktx\|androidx-appcompat\|androidx-ui-tooling-preview-android" --include="*.gradle.kts" .

Length of output: 280


๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ๋ชฉ์  ์žฌ๊ฒ€ํ†  ํ•„์š”

PR์—์„œ ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค(androidx-core-ktx, androidx-appcompat, androidx-tiles-tooling-preview, androidx-ui-tooling-preview-android)์˜ ์‚ฌ์šฉ ์šฉ๋„๊ฐ€ ์ฝ”๋“œ์ƒ์—์„œ ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠนํžˆ androidx-tiles-tooling-preview๋Š” Wear OS ๊ฐœ๋ฐœ์— ํ™œ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ณด์ด๋‚˜, ํ˜„์žฌ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ๋Š” Wear OS์™€ ๊ด€๋ จ๋œ ์ฐธ์กฐ๊ฐ€ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

  • ํŒŒ์ผ: gradle/libs.versions.toml (๋ผ์ธ: 120-123)
  • ํ™•์ธ ์š”์ฒญ: ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๋Š”์ง€, ํ˜น์€ ์•ž์œผ๋กœ ์‚ฌ์šฉ๋ ์ง€๋ฅผ ๋ช…ํ™•ํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋ถˆํ•„์š”ํ•˜๋‹ค๋ฉด ์ •๋ฆฌํ•˜๋Š” ๊ฒƒ๋„ ๊ณ ๋ คํ•ด ์ฃผ์„ธ์š”.

@@ -1,5 +1,7 @@
package team.retum.common.utils

import android.provider.Telephony.Mms.Rate
Copy link
Contributor

Choose a reason for hiding this comment

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

๐Ÿ› ๏ธ Refactor suggestion

๋ถˆํ•„์š”ํ•œ import ํ™•์ธ ํ•„์š”

android.provider.Telephony.Mms.Rate import๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์ง€๋งŒ, ์ฝ”๋“œ ๋‚ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ณณ์ด ์—†๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” import๋Š” ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

-import android.provider.Telephony.Mms.Rate
๐Ÿ“ 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 android.provider.Telephony.Mms.Rate

Comment on lines 18 to 19
route = "$NAVIGATION_EMPLOYMENT/${ResourceKeys}",
arguments = listOf(
Copy link
Contributor

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue

ResourceKeys ์‚ฌ์šฉ ๋ฐฉ์‹์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ฝ”๋“œ์—์„œ๋Š” "$NAVIGATION_EMPLOYMENT/${ResourceKeys}"์™€ ๊ฐ™์ด ResourceKeys ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ๋ฌธ์ž์—ด์— ์‚ฝ์ž…ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ResourceKeys๋Š” ํด๋ž˜์Šค๋‚˜ ๊ฐ์ฒด์ด๋ฏ€๋กœ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

- route = "$NAVIGATION_EMPLOYMENT/${ResourceKeys}",
+ route = "$NAVIGATION_EMPLOYMENT/{${ResourceKeys.RATE}}/{${ResourceKeys.TOTAL_STUDENT_COUNT}}/{${ResourceKeys.PASS_COUNT}}",
๐Ÿ“ 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
route = "$NAVIGATION_EMPLOYMENT/${ResourceKeys}",
arguments = listOf(
route = "$NAVIGATION_EMPLOYMENT/{${ResourceKeys.RATE}}/{${ResourceKeys.TOTAL_STUDENT_COUNT}}/{${ResourceKeys.PASS_COUNT}}",
arguments = listOf(

Comment on lines +38 to +40
fun NavController.navigateToEmployment() {
navigate(NAVIGATION_EMPLOYMENT)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue

navigateToEmployment ํ•จ์ˆ˜์— ํ•„์š”ํ•œ ์ธ์ˆ˜๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

navigateToEmployment ํ•จ์ˆ˜๋Š” ํ•„์š”ํ•œ ๋ชจ๋“  ์ธ์ˆ˜(rate, totalStudentCount, passCount)๋ฅผ ํฌํ•จํ•˜์—ฌ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฃจํŠธ๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์„ธ์š”:

- fun NavController.navigateToEmployment() {
-     navigate(NAVIGATION_EMPLOYMENT)
- }
+ fun NavController.navigateToEmployment(rate: Float, totalStudentCount: Long, passCount: Long) {
+     navigate("$NAVIGATION_EMPLOYMENT/$rate/$totalStudentCount/$passCount")
+ }
๐Ÿ“ 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
fun NavController.navigateToEmployment() {
navigate(NAVIGATION_EMPLOYMENT)
}
fun NavController.navigateToEmployment(rate: Float, totalStudentCount: Long, passCount: Long) {
navigate("$NAVIGATION_EMPLOYMENT/$rate/$totalStudentCount/$passCount")
}

Comment on lines +25 to +27
val rate = it.arguments?.getFloat(ResourceKeys.RATE) ?: 0f
val totalStudentCount = it.arguments?.getLong(ResourceKeys.RATE) ?: 0
val passCount = it.arguments?.getLong(ResourceKeys.RATE) ?: 0
Copy link
Contributor

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue

์ธ์ˆ˜ ํ‚ค ์ฐธ์กฐ์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ธ ๊ฐœ์˜ ๋‹ค๋ฅธ ์ธ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ ๋ชจ๋‘ ๋™์ผํ•œ ํ‚ค(ResourceKeys.RATE)๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์ธ์ˆ˜์— ๋งž๋Š” ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์„ธ์š”:

- val rate = it.arguments?.getFloat(ResourceKeys.RATE) ?: 0f
- val totalStudentCount = it.arguments?.getLong(ResourceKeys.RATE) ?: 0
- val passCount = it.arguments?.getLong(ResourceKeys.RATE) ?: 0
+ val rate = it.arguments?.getFloat(ResourceKeys.RATE) ?: 0f
+ val totalStudentCount = it.arguments?.getLong(ResourceKeys.TOTAL_STUDENT_COUNT) ?: 0
+ val passCount = it.arguments?.getLong(ResourceKeys.PASS_COUNT) ?: 0
๐Ÿ“ 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
val rate = it.arguments?.getFloat(ResourceKeys.RATE) ?: 0f
val totalStudentCount = it.arguments?.getLong(ResourceKeys.RATE) ?: 0
val passCount = it.arguments?.getLong(ResourceKeys.RATE) ?: 0
val rate = it.arguments?.getFloat(ResourceKeys.RATE) ?: 0f
val totalStudentCount = it.arguments?.getLong(ResourceKeys.TOTAL_STUDENT_COUNT) ?: 0
val passCount = it.arguments?.getLong(ResourceKeys.PASS_COUNT) ?: 0

Comment on lines 20 to 23
navArgument(ResourceKeys.RATE) { NavType.FloatType},
navArgument(ResourceKeys.TOTAL_STUDENT_COUNT) { NavType.LongType},
navArgument(ResourceKeys.PASS_COUNT) { NavType.LongType }
)
Copy link
Contributor

Choose a reason for hiding this comment

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

๐Ÿ› ๏ธ Refactor suggestion

๋„ค๋น„๊ฒŒ์ด์…˜ ์ธ์ˆ˜ ์œ ํ˜• ์ง€์ •์ด ๋ถˆ์™„์ „ํ•ฉ๋‹ˆ๋‹ค.

๋„ค๋น„๊ฒŒ์ด์…˜ ์ธ์ˆ˜์˜ ์œ ํ˜•์€ ์ง€์ •๋˜์—ˆ์ง€๋งŒ, ๊ฐ ์ธ์ˆ˜์˜ ์ด๋ฆ„์— ๋Œ€ํ•œ ์ค‘๊ด„ํ˜ธ๊ฐ€ ๋ˆ„๋ฝ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์„ธ์š”:

- navArgument(ResourceKeys.RATE) { NavType.FloatType},
- navArgument(ResourceKeys.TOTAL_STUDENT_COUNT) { NavType.LongType},
- navArgument(ResourceKeys.PASS_COUNT) { NavType.LongType }
+ navArgument(ResourceKeys.RATE) { type = NavType.FloatType },
+ navArgument(ResourceKeys.TOTAL_STUDENT_COUNT) { type = NavType.LongType },
+ navArgument(ResourceKeys.PASS_COUNT) { type = NavType.LongType }
๐Ÿ“ 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
navArgument(ResourceKeys.RATE) { NavType.FloatType},
navArgument(ResourceKeys.TOTAL_STUDENT_COUNT) { NavType.LongType},
navArgument(ResourceKeys.PASS_COUNT) { NavType.LongType }
)
navArgument(ResourceKeys.RATE) { type = NavType.FloatType },
navArgument(ResourceKeys.TOTAL_STUDENT_COUNT) { type = NavType.LongType },
navArgument(ResourceKeys.PASS_COUNT) { type = NavType.LongType }
)

Comment on lines 34 to 48
data class EmploymentDetailState(
val classId: Long,
val totalStudent: Long,
val passStudent: Long,
val companyInfo: List<CompanyItem>
) {
companion object {
fun getDefaultState() = EmploymentDetailState(
classId = 0,
totalStudent = 0,
passStudent = 0,
companyInfo = emptyList(),
)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

๐Ÿ› ๏ธ Refactor suggestion

ํด๋ž˜์Šค ๊ตฌ์กฐ ์ •๋ณด๊ฐ€ ์†์‹ค๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๊ตฌํ˜„์€ ๋ชจ๋“  ํด๋ž˜์Šค์˜ ํšŒ์‚ฌ ์ •๋ณด๋ฅผ ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋กœ ํ‰๋ฉดํ™”(flatMap)ํ•˜๊ณ  ์žˆ์–ด ์›๋ณธ ๋ฐ์ดํ„ฐ์˜ ํด๋ž˜์Šค๋ณ„ ๊ตฌ์กฐ ์ •๋ณด๊ฐ€ ์†์‹ค๋ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค ๊ตฌ์กฐ๋ฅผ ๋ณด์กดํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

data class EmploymentDetailState(
    val classId: Long,
    val totalStudent: Long,
    val passStudent: Long,
-    val companyInfo: List<CompanyItem>
+    val classCompanyInfo: List<ClassCompanyInfo>
) {
    companion object {
        fun getDefaultState() = EmploymentDetailState(
            classId = 0,
            totalStudent = 0,
            passStudent = 0,
-            companyInfo = emptyList(),
+            classCompanyInfo = emptyList(),
        )
    }
}

+data class ClassCompanyInfo(
+    val classId: Long,
+    val className: String,
+    val companies: List<CompanyItem>
+)

๊ทธ๋ฆฌ๊ณ  fetchEmploymentStatus() ํ•จ์ˆ˜๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

internal fun fetchEmploymentStatus() {
    viewModelScope.launch(Dispatchers.IO) {
        fetchEmploymentStatusUseCase().onSuccess {
            setState {
                state.value.copy(
-                    companyInfo = it.classes.flatMap { classInfo ->
-                        classInfo.employmentRateList.map { employmentRate ->
-                            CompanyItem(
-                                companyName = employmentRate.companyName,
-                                logoUrl = employmentRate.logoUrl
-                            )
-                        }
-                    }
+                    classCompanyInfo = it.classes.map { classInfo ->
+                        ClassCompanyInfo(
+                            classId = classInfo.classId,
+                            className = classInfo.className,
+                            companies = classInfo.employmentRateList.map { employmentRate ->
+                                CompanyItem(
+                                    companyName = employmentRate.companyName,
+                                    logoUrl = employmentRate.logoUrl
+                                )
+                            }
+                        )
+                    }
                )
            }
๐Ÿ“ 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
data class EmploymentDetailState(
val classId: Long,
val totalStudent: Long,
val passStudent: Long,
val companyInfo: List<CompanyItem>
) {
companion object {
fun getDefaultState() = EmploymentDetailState(
classId = 0,
totalStudent = 0,
passStudent = 0,
companyInfo = emptyList(),
)
}
data class EmploymentDetailState(
val classId: Long,
val totalStudent: Long,
val passStudent: Long,
val classCompanyInfo: List<ClassCompanyInfo>
) {
companion object {
fun getDefaultState() = EmploymentDetailState(
classId = 0,
totalStudent = 0,
passStudent = 0,
classCompanyInfo = emptyList(),
)
}
}
data class ClassCompanyInfo(
val classId: Long,
val className: String,
val companies: List<CompanyItem>
)
internal fun fetchEmploymentStatus() {
viewModelScope.launch(Dispatchers.IO) {
fetchEmploymentStatusUseCase().onSuccess {
setState {
state.value.copy(
classCompanyInfo = it.classes.map { classInfo ->
ClassCompanyInfo(
classId = classInfo.classId,
className = classInfo.className,
companies = classInfo.employmentRateList.map { employmentRate ->
CompanyItem(
companyName = employmentRate.companyName,
logoUrl = employmentRate.logoUrl
)
}
)
}
)
}
}
}
}

Comment on lines +51 to +54
sealed interface EmploymentDetailSideEffect {
data object BadRequest : EmploymentDetailSideEffect
data object Success : EmploymentDetailSideEffect
}
Copy link
Contributor

Choose a reason for hiding this comment

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

๐Ÿ› ๏ธ Refactor suggestion

SideEffect ๊ตฌํ˜„์ด ์™„์„ฑ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ EmploymentDetailSideEffect๋Š” ์ •์˜๋˜์–ด ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ViewModel์—์„œ ์ ์ ˆํ•œ ์‹œ์ ์— side effect๋ฅผ ๋ฐœํ–‰ํ•˜๋„๋ก ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

SideEffect๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋กœ๋”ฉ ์ƒํƒœ๋„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค:

sealed interface EmploymentDetailSideEffect {
    data object BadRequest : EmploymentDetailSideEffect
    data object Success : EmploymentDetailSideEffect
+    data object Loading : EmploymentDetailSideEffect
}

๊ทธ๋ฆฌ๊ณ  fetchEmploymentStatus() ํ•จ์ˆ˜ ์‹œ์ž‘ ์‹œ Loading ์ƒํƒœ๋ฅผ ๋ฐœํ–‰ํ•˜๋„๋ก ์ˆ˜์ •:

internal fun fetchEmploymentStatus() {
+    postSideEffect(EmploymentDetailSideEffect.Loading)
    viewModelScope.launch(Dispatchers.IO) {
        fetchEmploymentStatusUseCase().onSuccess {
            // ...
            postSideEffect(EmploymentDetailSideEffect.Success)
        }.onFailure {
            postSideEffect(EmploymentDetailSideEffect.BadRequest)
        }
    }
}
๐Ÿ“ 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
sealed interface EmploymentDetailSideEffect {
data object BadRequest : EmploymentDetailSideEffect
data object Success : EmploymentDetailSideEffect
}
sealed interface EmploymentDetailSideEffect {
data object BadRequest : EmploymentDetailSideEffect
data object Success : EmploymentDetailSideEffect
data object Loading : EmploymentDetailSideEffect
}
Suggested change
sealed interface EmploymentDetailSideEffect {
data object BadRequest : EmploymentDetailSideEffect
data object Success : EmploymentDetailSideEffect
}
internal fun fetchEmploymentStatus() {
postSideEffect(EmploymentDetailSideEffect.Loading)
viewModelScope.launch(Dispatchers.IO) {
fetchEmploymentStatusUseCase().onSuccess {
// ...
postSideEffect(EmploymentDetailSideEffect.Success)
}.onFailure {
postSideEffect(EmploymentDetailSideEffect.BadRequest)
}
}
}

Comment on lines +15 to +32
internal fun fetchEmploymentCount() {
viewModelScope.launch(Dispatchers.IO) {
fetchEmploymentCountUseCase().onSuccess {
setState {
val rate = if (it.passCount == 0L || it.totalStudentCount == 0L) {
0f
} else {
it.passCount.toFloat() / it.totalStudentCount.toFloat() * 100f
}
state.value.copy(
rate = DecimalFormat("##.#").format(rate),
totalStudentCount = it.totalStudentCount,
passCount = it.passCount,
)
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

๐Ÿ› ๏ธ Refactor suggestion

์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋กœ์ง ์ถ”๊ฐ€ ํ•„์š”

fetchEmploymentCount ๋ฉ”์„œ๋“œ์—์„œ API ํ˜ธ์ถœ์˜ ์„ฑ๊ณต ์ผ€์ด์Šค๋งŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์‹คํŒจ ์ผ€์ด์Šค์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ UI์— ์ ์ ˆํžˆ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 fetchEmploymentCountUseCase().onSuccess {
     setState {
         val rate = if (it.passCount == 0L || it.totalStudentCount == 0L) {
             0f
         } else {
             it.passCount.toFloat() / it.totalStudentCount.toFloat() * 100f
         }
         state.value.copy(
             rate = DecimalFormat("##.#").format(rate),
             totalStudentCount = it.totalStudentCount,
             passCount = it.passCount,
         )
     }
+ }.onFailure {
+     postSideEffect(EmploymentSideEffect.BadRequest)
 }
๐Ÿ“ 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
internal fun fetchEmploymentCount() {
viewModelScope.launch(Dispatchers.IO) {
fetchEmploymentCountUseCase().onSuccess {
setState {
val rate = if (it.passCount == 0L || it.totalStudentCount == 0L) {
0f
} else {
it.passCount.toFloat() / it.totalStudentCount.toFloat() * 100f
}
state.value.copy(
rate = DecimalFormat("##.#").format(rate),
totalStudentCount = it.totalStudentCount,
passCount = it.passCount,
)
}
}
}
}
internal fun fetchEmploymentCount() {
viewModelScope.launch(Dispatchers.IO) {
fetchEmploymentCountUseCase().onSuccess {
setState {
val rate = if (it.passCount == 0L || it.totalStudentCount == 0L) {
0f
} else {
it.passCount.toFloat() / it.totalStudentCount.toFloat() * 100f
}
state.value.copy(
rate = DecimalFormat("##.#").format(rate),
totalStudentCount = it.totalStudentCount,
passCount = it.passCount,
)
}
}.onFailure {
postSideEffect(EmploymentSideEffect.BadRequest)
}
}
}

Comment on lines +186 to +187
text = "์ „์ฒด ํ†ต๊ณ„",
style = JobisTypography.Body,
Copy link
Contributor

Choose a reason for hiding this comment

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

๐Ÿ› ๏ธ Refactor suggestion

ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด์„ ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค๋กœ ๋Œ€์ฒด ํ•„์š”

"์ „์ฒด ํ†ต๊ณ„"๋ผ๋Š” ๋ฌธ์ž์—ด์ด ํ•˜๋“œ์ฝ”๋”ฉ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๊ตญ์–ด ์ง€์›๊ณผ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ์ด๋ฅผ ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

-                            text = "์ „์ฒด ํ†ต๊ณ„",
+                            text = stringResource(id = R.string.total_statistics),

R.string.total_statistics์— ํ•ด๋‹นํ•˜๋Š” ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“ 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
text = "์ „์ฒด ํ†ต๊ณ„",
style = JobisTypography.Body,
text = stringResource(id = R.string.total_statistics),
style = JobisTypography.Body,

Comment on lines 218 to 247
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
ClassEmploymentButton(
onClassClick = onClassClick,
image = team.retum.design_system.R.drawable.ic_computer,
text = "1๋ฐ˜",
)
ClassEmploymentButton(
onClassClick = onClassClick,
image = team.retum.design_system.R.drawable.ic_computer,
text = "2๋ฐ˜",
)
}
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
ClassEmploymentButton(
onClassClick = onClassClick,
image = team.retum.design_system.R.drawable.ic_spanner,
text = "3๋ฐ˜",
)
ClassEmploymentButton(
onClassClick = onClassClick,
image = team.retum.design_system.R.drawable.ic_robot,
text = "4๋ฐ˜",
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

๐Ÿ› ๏ธ Refactor suggestion

ํด๋ž˜์Šค ๋ฒ„ํŠผ ๋กœ์ง ๊ฐœ์„  ํ•„์š”

ํ˜„์žฌ ๊ฐ ๋ฐ˜(1๋ฐ˜, 2๋ฐ˜, 3๋ฐ˜, 4๋ฐ˜)์— ๋Œ€ํ•œ ๋ฒ„ํŠผ์ด ํ•˜๋“œ์ฝ”๋”ฉ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ต๊ณ  ํ™•์žฅ์„ฑ์ด ๋–จ์–ด์ง‘๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ์™€ forEach ๋˜๋Š” forEachIndexed๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

-            Row(
-                modifier = Modifier.fillMaxWidth(),
-                horizontalArrangement = Arrangement.SpaceBetween
-            ) {
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_computer,
-                    text = "1๋ฐ˜",
-                )
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_computer,
-                    text = "2๋ฐ˜",
-                )
-            }
-            Row(
-                modifier = Modifier.fillMaxWidth(),
-                horizontalArrangement = Arrangement.SpaceBetween
-            ) {
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_spanner,
-                    text = "3๋ฐ˜",
-                )
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_robot,
-                    text = "4๋ฐ˜",
-                )
-            }
+            val classImages = listOf(
+                team.retum.design_system.R.drawable.ic_computer,
+                team.retum.design_system.R.drawable.ic_computer,
+                team.retum.design_system.R.drawable.ic_spanner,
+                team.retum.design_system.R.drawable.ic_robot
+            )
+            
+            for (rowIndex in 0..1) {
+                Row(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalArrangement = Arrangement.SpaceBetween
+                ) {
+                    for (colIndex in 0..1) {
+                        val classIndex = rowIndex * 2 + colIndex
+                        ClassEmploymentButton(
+                            onClassClick = onClassClick,
+                            image = classImages[classIndex],
+                            text = "${classIndex + 1}๋ฐ˜",
+                        )
+                    }
+                }
+            }
๐Ÿ“ 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
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
ClassEmploymentButton(
onClassClick = onClassClick,
image = team.retum.design_system.R.drawable.ic_computer,
text = "1๋ฐ˜",
)
ClassEmploymentButton(
onClassClick = onClassClick,
image = team.retum.design_system.R.drawable.ic_computer,
text = "2๋ฐ˜",
)
}
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
ClassEmploymentButton(
onClassClick = onClassClick,
image = team.retum.design_system.R.drawable.ic_spanner,
text = "3๋ฐ˜",
)
ClassEmploymentButton(
onClassClick = onClassClick,
image = team.retum.design_system.R.drawable.ic_robot,
text = "4๋ฐ˜",
)
}
val classImages = listOf(
team.retum.design_system.R.drawable.ic_computer,
team.retum.design_system.R.drawable.ic_computer,
team.retum.design_system.R.drawable.ic_spanner,
team.retum.design_system.R.drawable.ic_robot
)
for (rowIndex in 0..1) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
for (colIndex in 0..1) {
val classIndex = rowIndex * 2 + colIndex
ClassEmploymentButton(
onClassClick = onClassClick,
image = classImages[classIndex],
text = "${classIndex + 1}๋ฐ˜",
)
}
}
}

@uson1004 uson1004 reopened this Mar 5, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

๐Ÿงน Nitpick comments (3)
feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (3)

60-60: ์•„์ง ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋กœ์ง
Employment ํ•จ์ˆ˜ ๋‚ด๋ถ€์— // TODO :: ๋„ค๋น„๊ฒŒ์ด์…˜ ์ถ”๊ฐ€ ๋ฐ ๋ถ€์ˆ˜๋ผ๊ณ ๋งŒ ๋‚จ๊ฒจ๋‘๊ณ  ์‹ค์ œ ๊ตฌํ˜„์€ ๋น„์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ›„์† ์ž‘์—…์—์„œ ํ•ด๋‹น ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ์—ฐ๋™ํ•˜๋Š” ๊ณผ์ •์„ ์ง„ํ–‰ํ•ด์•ผ ํ•  ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

ํ•„์š”ํ•˜์‹œ๋‹ค๋ฉด ๋„ค๋น„๊ฒŒ์ด์…˜ ๋กœ์ง ๊ตฌํ˜„ ์˜ˆ์‹œ๋‚˜ ์ถ”๊ฐ€ ์„ค์ •์— ๊ด€ํ•œ ์•ˆ๋‚ด๋ฅผ ๋“œ๋ฆด ์ˆ˜ ์žˆ์œผ๋‹ˆ ๋ง์”€ํ•ด ์ฃผ์„ธ์š”.


62-71: ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ’์ด ํ•˜์œ„ ์ปดํฌ์ €๋ธ”์— ๋ฐ˜์˜๋˜์ง€ ์•Š์Œ
๋ถ€๋ชจ ์ปดํฌ์ €๋ธ”(Employment)์—์„œ Animatable์„ ํ†ตํ•ด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ง„ํ–‰ํ•˜์ง€๋งŒ, ์‹ค์ œ๋กœ EmploymentScreen์— ๋„˜๊ธฐ๋Š” ์ธ์ž๋Š” ๋‹จ์ˆœํžˆ rate ๊ฐ’๋งŒ ์ „๋‹ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด animatedValue.value๊ฐ€ UI์— ๋ฐ˜์˜๋˜์ง€ ์•Š์•„ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

EmploymentScreen์œผ๋กœ animatedValue.value๋ฅผ ๋„˜๊ธฐ๊ฑฐ๋‚˜, CircleProgress ๋‚ด๋ถ€ ๋กœ์ง์—์„œ ์ง์ ‘ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ณ€๊ฒฝํ•ด ์ฃผ์‹œ๋ฉด ์˜๋„ํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


261-308: CircleProgress ๋‚ด๋ถ€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋กœ์ง์ด ๋ˆ„๋ฝ๋จ
CircleProgress์—์„œ Animatable(percentage)๋กœ ์ดˆ๊ธฐํ™”๋งŒ ์ง„ํ–‰ํ•˜๊ณ , ์‹ค์ œ๋กœ ๊ฐ’์„ ๋ณ€ํ™”์‹œํ‚ค๋Š” animateTo ๋“ฑ์ด ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ์ƒํƒœ๋กœ๋Š” ์›ํ˜• ๊ทธ๋ž˜ํ”„๊ฐ€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์—†์ด ๊ณ ์ •๋œ ์ƒํƒœ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

LaunchedEffect(percentage)๋‚˜ ๋‹ค๋ฅธ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์‚ฌ์šฉํ•ด ์‹ค์ œ๋กœ animateTo(percentage)๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜, ์ƒ์œ„์—์„œ ์ด๋ฏธ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ฒ˜๋ฆฌํ•ด ์ „๋‹ฌํ•˜๋Š” ๊ตฌ์กฐ๋กœ ๊ฐœ์„ ํ•ด์ฃผ์„ธ์š”.

๐Ÿ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 597e908 and 560e029.

๐Ÿ“’ Files selected for processing (4)
  • core/common/src/main/java/team/retum/common/utils/ResourceKeys.kt (1 hunks)
  • feature/employment/build.gradle.kts (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/viewmodel/EmploymentViewModel.kt (1 hunks)
๐Ÿšง Files skipped from review as they are similar to previous changes (2)
  • feature/employment/src/main/java/team/retum/employment/viewmodel/EmploymentViewModel.kt
  • core/common/src/main/java/team/retum/common/utils/ResourceKeys.kt
โฐ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: lint_and_build (build)
  • GitHub Check: lint_and_build (lint)
๐Ÿ”‡ Additional comments (6)
feature/employment/build.gradle.kts (4)

1-7: ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์ • ํ™•์ธ
ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ธ”๋ก์—์„œ Android ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, Kotlin Android, Hilt, KSP, ๊ทธ๋ฆฌ๊ณ  ktlint ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๋ช…ํ™•ํ•˜๊ฒŒ ์ ์šฉ๋˜์–ด ์žˆ์–ด ๋ชจ๋“ˆ์˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ž˜ ๋ฐ˜์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


9-10: ์ปค์Šคํ…€ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ ์šฉ ์ ์ ˆ
apply<CommonGradlePlugin>()์™€ apply<ComposeGradlePlugin>()๋ฅผ ํ†ตํ•ด ๊ณตํ†ต ์„ค์ •๊ณผ Compose ๊ด€๋ จ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ชจ๋“ˆ์— ์†์‰ฝ๊ฒŒ ์ ์šฉํ•œ ์ ์ด ์ข‹์Šต๋‹ˆ๋‹ค.


12-18: Android ๊ตฌ์„ฑ ์„ค์ • ๊ฒ€ํ† 
android ๋ธ”๋ก ๋‚ด์—์„œ namespace๋ฅผ ๋ช…์‹œํ•˜๊ณ , kotlinOptions๋ฅผ ํ†ตํ•ด JVM ํƒ€๊ฒŸ์„ ProjectProperties.JVM_TARGET์œผ๋กœ ์„ค์ •ํ•œ ๋ถ€๋ถ„์ด ๋ชจ๋“ˆ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.


20-23: ์˜์กด์„ฑ ์ถ”๊ฐ€ ๊ฒ€ํ† 
implementation(libs.androidx.ui.tooling.preview.android) ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜์—ฌ AndroidX UI ํˆด๋ง ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•œ ์ ์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค. ํ–ฅํ›„ ํˆด๋ง ๊ด€๋ จ ๋ฒ„์ „ ์—…๋ฐ์ดํŠธ๋‚˜ ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ์„ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ ๊ฒ€ํ•˜๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (2)

185-187: ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด์„ ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค๋กœ ๋Œ€์ฒด ํ•„์š”
๊ณผ๊ฑฐ ๋ฆฌ๋ทฐ์—์„œ๋„ ์ง€์ ๋œ ๋‚ด์šฉ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๊ตญ์–ด ์ง€์› ๋ฐ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์œ„ํ•ด ํ•˜๋“œ์ฝ”๋”ฉ๋œ "์ „์ฒด ํ†ต๊ณ„" ๋ฌธ์ž์—ด์„ ๋ฆฌ์†Œ์Šค๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

-                            text = "์ „์ฒด ํ†ต๊ณ„",
+                            text = stringResource(id = R.string.total_statistics),

218-247: ํด๋ž˜์Šค ๋ฒ„ํŠผ ๋กœ์ง ๊ฐœ์„  ํ•„์š”
์ด์ „ ๋ฆฌ๋ทฐ์—์„œ ์ง€์ ๋œ ๊ฒƒ์ฒ˜๋Ÿผ โ€œ1๋ฐ˜, 2๋ฐ˜, 3๋ฐ˜, 4๋ฐ˜โ€๊ณผ ๊ด€๋ จ๋œ ๋ฒ„ํŠผ์„ ๋ฐ˜๋ณต ์ž‘์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”ํ›„ ํด๋ž˜์Šค ์ˆ˜๊ฐ€ ๋Š˜์–ด๋‚˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ ํ™•์žฅ์„ฑ์ด ๋–จ์–ด์ง€๋ฏ€๋กœ, List์™€ forEachIndexed ๋“ฑ์„ ํ™œ์šฉํ•ด ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

-            Row(
-                modifier = Modifier.fillMaxWidth(),
-                horizontalArrangement = Arrangement.SpaceBetween
-            ) {
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_computer,
-                    text = "1๋ฐ˜",
-                )
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_computer,
-                    text = "2๋ฐ˜",
-                )
-            }
-            Row(
-                modifier = Modifier.fillMaxWidth(),
-                horizontalArrangement = Arrangement.SpaceBetween
-            ) {
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_spanner,
-                    text = "3๋ฐ˜",
-                )
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_robot,
-                    text = "4๋ฐ˜",
-                )
-            }
+            val classImages = listOf(
+                team.retum.design_system.R.drawable.ic_computer,
+                team.retum.design_system.R.drawable.ic_computer,
+                team.retum.design_system.R.drawable.ic_spanner,
+                team.retum.design_system.R.drawable.ic_robot
+            )
+
+            for (rowIndex in 0..1) {
+                Row(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalArrangement = Arrangement.SpaceBetween
+                ) {
+                    for (colIndex in 0..1) {
+                        val classIndex = rowIndex * 2 + colIndex
+                        ClassEmploymentButton(
+                            onClassClick = onClassClick,
+                            image = classImages[classIndex],
+                            text = "${classIndex + 1}๋ฐ˜",
+                        )
+                    }
+                }
+            }

@uson1004 uson1004 changed the title Feature/448 ์ทจ์—…๋ฅ  ์ƒ์„ธ ์กฐํšŒ ํŽ˜์ด์ง€ ์ œ์ž‘ :: (#448) ์ทจ์—…๋ฅ  ์ƒ์„ธ ์กฐํšŒ ํŽ˜์ด์ง€ ์ œ์ž‘ Mar 5, 2025
@uson1004 uson1004 changed the title :: (#448) ์ทจ์—…๋ฅ  ์ƒ์„ธ ์กฐํšŒ ํŽ˜์ด์ง€ ์ œ์ž‘ ๐Ÿ”— :: (#448) ์ทจ์—…๋ฅ  ์ƒ์„ธ ์กฐํšŒ ํŽ˜์ด์ง€ ์ œ์ž‘ Mar 5, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

โ™ป๏ธ Duplicate comments (4)
feature/employment/src/main/java/team/retum/employment/ui/EmploymentDetailScreen.kt (3)

14-21: โš ๏ธ Potential issue

ViewModel ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•˜์ง€ ์•Š๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ViewModel์„ ์ดˆ๊ธฐํ™”ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์ƒํƒœ๋ฅผ ๊ด€์ฐฐํ•˜๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ EmploymentDetailScreen์— ์ „๋‹ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ViewModel ์ƒํƒœ๋ฅผ ๊ด€์ฐฐํ•˜๋„๋ก ์ˆ˜์ •ํ•˜์„ธ์š”:

@Composable
fun EmploymentDetail(
    employmentDetailViewModel: EmploymentDetailViewModel = hiltViewModel(),
) {
+    val state by employmentDetailViewModel.state.collectAsState()
+    
+    LaunchedEffect(Unit) {
+        employmentDetailViewModel.fetchEmploymentStatus()
+    }
+    
    EmploymentDetailScreen(
-        companyItem = emptyList(),
+        companyItem = state.companyItems,
    )
}

27-42: โš ๏ธ Potential issue

ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

companyItem ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ „๋‹ฌ๋ฐ›์•˜์ง€๋งŒ, ์ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋นˆ ํ•ญ๋ชฉ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ „๋‹ฌ๋ฐ›์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ •ํ•˜์„ธ์š”:

Column(
    modifier = Modifier
        .fillMaxSize(),
) {
-    val arr: List<CompanyItem> = listOf(
-        CompanyItem(
-            companyName = "",
-            logoUrl = "",
-        ),
-    )
    LazyHorizontalGrid(
+        modifier = Modifier.fillMaxWidth(),
        rows = GridCells.Fixed(4),
    ) {
-        items(items = arr) { person ->
+        items(items = companyItem) { company ->
+            CompanyIcon(
+                companyName = company.companyName,
+                logoUrl = company.logoUrl
+            )
        }
    }
}

40-41: โš ๏ธ Potential issue

items ๋ธ”๋ก์ด ๋น„์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

LazyHorizontalGrid์˜ items ๋ธ”๋ก ๋‚ด๋ถ€๊ฐ€ ๋น„์–ด์žˆ์–ด ์•„๋ฌด ๋‚ด์šฉ๋„ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด CompanyIcon์„ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

items(items = arr) { person ->
+    CompanyIcon(
+        companyName = person.companyName,
+        logoUrl = person.logoUrl
+    )
}

์ฐธ๊ณ : CompanyIcon ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (1)

186-187: ๐Ÿ› ๏ธ Refactor suggestion

ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด์„ ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค๋กœ ๋Œ€์ฒด ํ•„์š”

"์ „์ฒด ํ†ต๊ณ„"๋ผ๋Š” ๋ฌธ์ž์—ด์ด ํ•˜๋“œ์ฝ”๋”ฉ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๊ตญ์–ด ์ง€์›๊ณผ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ์ด๋ฅผ ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

-                            text = "์ „์ฒด ํ†ต๊ณ„",
+                            text = stringResource(id = R.string.total_statistics),

R.string.total_statistics์— ํ•ด๋‹นํ•˜๋Š” ๋ฌธ์ž์—ด ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿงน Nitpick comments (3)
feature/home/src/main/java/team/retum/home/ui/HomeScreen.kt (1)

323-331: ๊ณ ์šฉ ํ˜„ํ™ฉ ์ƒ์„ธ ํŽ˜์ด์ง€ ์ด๋™ ๋ฒ„ํŠผ์ด ์ž˜ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด ํ…์ŠคํŠธ ํ‘œ์‹œ ๋ฐฉ์‹์—์„œ ๋ฒ„ํŠผ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„ํŠผ ํ…์ŠคํŠธ "ํ˜„ํ™ฉ ๋ณด๋Ÿฌ ๊ฐ€๊ธฐ ->"๊ฐ€ ๋ชฉ์ ์„ ๋ช…ํ™•ํžˆ ํ‘œํ˜„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•œ ๊ฐ€์ง€ ์ œ์•ˆํ•  ์ ์€ ๋ฒ„ํŠผ ํ…์ŠคํŠธ๋ฅผ ๊ตญ์ œํ™”(i18n)ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด์„ strings.xml ๋ฆฌ์†Œ์Šค๋กœ ์ด๋™์‹œํ‚ค๋ฉด ๋‹ค๊ตญ์–ด ์ง€์›์ด ์šฉ์ดํ•ด์ง‘๋‹ˆ๋‹ค.

ํ…์ŠคํŠธ ๋ฌธ์ž์—ด์„ ๋ฆฌ์†Œ์Šค๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค:

-                text = "ํ˜„ํ™ฉ ๋ณด๋Ÿฌ ๊ฐ€๊ธฐ ->",
+                text = stringResource(id = R.string.view_employment_status),

strings.xml์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

<string name="view_employment_status">ํ˜„ํ™ฉ ๋ณด๋Ÿฌ ๊ฐ€๊ธฐ -></string>
feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (2)

66-68: ViewModel ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฐฉ์‹ ๊ฐœ์„  ํ•„์š”

with(employmentViewModel) ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์ง์ ‘ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋” ๊ฐ„๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฆฌํŒฉํ† ๋งํ•˜์„ธ์š”:

LaunchedEffect(Unit) {
    animatedValue.animateTo(
        targetValue = rate,
        animationSpec = tween(durationMillis = 1000, easing = LinearEasing),
    )
-    with(employmentViewModel) {
-        fetchEmploymentCount()
-    }
+    employmentViewModel.fetchEmploymentCount()
}

318-319: Surface์˜ modifier์™€ onClick ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐœ์„  ํ•„์š”

Surface์˜ modifier์— padding์ด ๋น„์–ด ์žˆ๊ณ , onClick ํ•จ์ˆ˜๊ฐ€ ์ง์ ‘ ์ „๋‹ฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐœ์„ ํ•˜์„ธ์š”:

Surface(
-    modifier = Modifier.padding(),
+    modifier = Modifier,
-    onClick = onClassClick,
+    onClick = { onClassClick() },
    color = JobisTheme.colors.inverseSurface,
    shape = RoundedCornerShape(8.dp),
)
๐Ÿ“œ Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 560e029 and 412a4c2.

๐Ÿ“’ Files selected for processing (8)
  • core/domain/src/main/java/team/retum/usecase/entity/application/EmploymentStatusEntity.kt (1 hunks)
  • core/network/src/main/java/team/retum/network/model/response/application/FetchEmploymentStatusResponse.kt (1 hunks)
  • feature/employment/build.gradle.kts (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/navigation/EmploymentNavigation.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/ui/EmploymentDetailScreen.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (1 hunks)
  • feature/employment/src/main/java/team/retum/employment/viewmodel/EmploymentDetailViewModel.kt (1 hunks)
  • feature/home/src/main/java/team/retum/home/ui/HomeScreen.kt (11 hunks)
๐Ÿšง Files skipped from review as they are similar to previous changes (5)
  • feature/employment/src/main/java/team/retum/employment/navigation/EmploymentNavigation.kt
  • feature/employment/build.gradle.kts
  • core/domain/src/main/java/team/retum/usecase/entity/application/EmploymentStatusEntity.kt
  • core/network/src/main/java/team/retum/network/model/response/application/FetchEmploymentStatusResponse.kt
  • feature/employment/src/main/java/team/retum/employment/viewmodel/EmploymentDetailViewModel.kt
โฐ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: lint_and_build (build)
  • GitHub Check: lint_and_build (lint)
๐Ÿ”‡ Additional comments (5)
feature/home/src/main/java/team/retum/home/ui/HomeScreen.kt (2)

23-23: ํ•„์š”ํ•œ import ๋ฌธ์ด ์ ์ ˆํ•˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ์™€ ๊ด€๋ จ ์Šคํƒ€์ผ๋ง์„ ์œ„ํ•œ import๊ฐ€ ์ž˜ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Also applies to: 39-39, 61-61, 63-63


83-83: ์ปดํฌ๋„ŒํŠธ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ํ†ตํ•œ ์ด๋ฒคํŠธ ์ „๋‹ฌ์ด ์ž˜ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ onEmploymentClick ์ฝœ๋ฐฑ์„ ์ „๋‹ฌํ•˜๋Š” ํŒจํ„ด์ด ์ผ๊ด€๋˜๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” Compose์˜ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ํŒจํ„ด์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ์šฉ ํ˜„ํ™ฉ ์ƒ์„ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ํšจ๊ณผ์ ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Also applies to: 130-130, 154-154, 186-186, 228-228, 270-270, 309-309

feature/employment/src/main/java/team/retum/employment/ui/EmploymentScreen.kt (3)

58-58: ์™„๋ฃŒ๋˜์ง€ ์•Š์€ TODO ์ฃผ์„์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋„ค๋น„๊ฒŒ์ด์…˜ ๊ด€๋ จ TODO ์ฃผ์„์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋„ค๋น„๊ฒŒ์ด์…˜ ๊ด€๋ จ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ํ•„์š”ํ•œ ๊ฒฝ์šฐ TODO ์ฃผ์„์„ ์ œ๊ฑฐํ•˜์„ธ์š”.


87-87: ์™„๋ฃŒ๋˜์ง€ ์•Š์€ TODO ์ฃผ์„์ด ์žˆ์Šต๋‹ˆ๋‹ค.

UI ํผ๋ธ”๋ฆฌ์‹ฑ ๊ด€๋ จ TODO ์ฃผ์„์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

UI ํผ๋ธ”๋ฆฌ์‹ฑ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ํ•„์š”ํ•œ ๊ฒฝ์šฐ TODO ์ฃผ์„์„ ์ œ๊ฑฐํ•˜์„ธ์š”.


218-247: ํด๋ž˜์Šค ๋ฒ„ํŠผ ๋กœ์ง ๊ฐœ์„  ํ•„์š”

ํ˜„์žฌ ๊ฐ ๋ฐ˜(1๋ฐ˜, 2๋ฐ˜, 3๋ฐ˜, 4๋ฐ˜)์— ๋Œ€ํ•œ ๋ฒ„ํŠผ์ด ํ•˜๋“œ์ฝ”๋”ฉ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ต๊ณ  ํ™•์žฅ์„ฑ์ด ๋–จ์–ด์ง‘๋‹ˆ๋‹ค.

๋ฆฌ์ŠคํŠธ์™€ forEach ๋˜๋Š” forEachIndexed๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

-            Row(
-                modifier = Modifier.fillMaxWidth(),
-                horizontalArrangement = Arrangement.SpaceBetween,
-            ) {
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_computer,
-                    text = "1๋ฐ˜",
-                )
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_computer,
-                    text = "2๋ฐ˜",
-                )
-            }
-            Row(
-                modifier = Modifier.fillMaxWidth(),
-                horizontalArrangement = Arrangement.SpaceBetween,
-            ) {
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_spanner,
-                    text = "3๋ฐ˜",
-                )
-                ClassEmploymentButton(
-                    onClassClick = onClassClick,
-                    image = team.retum.design_system.R.drawable.ic_robot,
-                    text = "4๋ฐ˜",
-                )
-            }
+            val classImages = listOf(
+                team.retum.design_system.R.drawable.ic_computer,
+                team.retum.design_system.R.drawable.ic_computer,
+                team.retum.design_system.R.drawable.ic_spanner,
+                team.retum.design_system.R.drawable.ic_robot
+            )
+            
+            for (rowIndex in 0..1) {
+                Row(
+                    modifier = Modifier.fillMaxWidth(),
+                    horizontalArrangement = Arrangement.SpaceBetween
+                ) {
+                    for (colIndex in 0..1) {
+                        val classIndex = rowIndex * 2 + colIndex
+                        ClassEmploymentButton(
+                            onClassClick = onClassClick,
+                            image = classImages[classIndex],
+                            text = "${classIndex + 1}๋ฐ˜",
+                        )
+                    }
+                }
+            }

}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue

CompanyIcon ํ•จ์ˆ˜๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ์—์„œ CompanyIcon ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ, ํ•จ์ˆ˜ ๊ตฌํ˜„์ด ์—†์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด CompanyIcon ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜์„ธ์š”:

@Composable
fun CompanyIcon(
    companyName: String,
    logoUrl: String
) {
    Column(
        modifier = Modifier
            .padding(8.dp)
            .fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        AsyncImage(
            model = logoUrl,
            contentDescription = "$companyName ๋กœ๊ณ ",
            modifier = Modifier
                .size(64.dp)
                .clip(CircleShape),
            contentScale = ContentScale.Crop,
            placeholder = painterResource(id = R.drawable.ic_company_placeholder)
        )
        
        Spacer(modifier = Modifier.height(4.dp))
        
        Text(
            text = companyName,
            style = MaterialTheme.typography.caption,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
    }
}

AsyncImage ์‚ฌ์šฉ์„ ์œ„ํ•ด ๋‹ค์Œ import ๋ฌธ๋„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

import coil.compose.AsyncImage
import coil.request.ImageRequest
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow

primaryColor: Color = JobisTheme.colors.secondaryContainer,
secondaryColor: Color = JobisTheme.colors.onPrimary,
) {
val animatedValue = remember { Animatable(percentage) }
Copy link
Contributor

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue

CircleProgress์—์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ’์ด ์žฌ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ

CircleProgress ์ปดํฌ์ €๋ธ”์—์„œ percentage ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์‹œ์ž‘๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด LaunchedEffect๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ percentage ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์‹œ์ž‘๋˜๋„๋ก ์ˆ˜์ •ํ•˜์„ธ์š”:

fun CircleProgress(
    percentage: Float,
    modifier: Modifier = Modifier,
    radius: Dp = 120.dp,
    strokeWidth: Dp = 25.dp,
    primaryColor: Color = JobisTheme.colors.secondaryContainer,
    secondaryColor: Color = JobisTheme.colors.onPrimary,
) {
    val animatedValue = remember { Animatable(percentage) }
+    
+    LaunchedEffect(percentage) {
+        animatedValue.animateTo(
+            targetValue = percentage,
+            animationSpec = tween(durationMillis = 1000, easing = LinearEasing)
+        )
+    }
๐Ÿ“ 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
val animatedValue = remember { Animatable(percentage) }
fun CircleProgress(
percentage: Float,
modifier: Modifier = Modifier,
radius: Dp = 120.dp,
strokeWidth: Dp = 25.dp,
primaryColor: Color = JobisTheme.colors.secondaryContainer,
secondaryColor: Color = JobisTheme.colors.onPrimary,
) {
val animatedValue = remember { Animatable(percentage) }
LaunchedEffect(percentage) {
animatedValue.animateTo(
targetValue = percentage,
animationSpec = tween(durationMillis = 1000, easing = LinearEasing)
)
}
// ... rest of the composable code
}

Comment on lines +56 to +59
// splits.abi.isEnable = false
// aaptOptions.cruncherEnabled = false
// splits.density.isEnable = false
// aaptOptions.cruncherEnabled = false
Copy link
Member

Choose a reason for hiding this comment

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

์ฃผ์„์€ ์ œ๊ฑฐ ํ•ด์ฃผ์„ธ์š”

Copy link
Member

Choose a reason for hiding this comment

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

xml ํ˜•์‹์œผ๋กœ ๋ฆฌ์†Œ์Šค๊ฐ€ ๊นจ์ง€์ง€ ์•Š๋Š”๋‹ค๋ฉด png ์‚ฌ์šฉ์€ ์ง€์–‘ํ•ด์ฃผ์„ธ์š”.
png๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŒŒ์ผ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์ ธ ์•ฑ ํฌ๊ธฐ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์–ด์š”.

}

internal fun FetchEmploymentStatusResponse.toEntity() = EmploymentStatusEntity(
classes = this.classes.map { it.toEntity() }, // TODO :: ์ด ๊ตฌ์กฐ ์ดํ•ด ํ•„์š”
Copy link
Member

Choose a reason for hiding this comment

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

todo ์ฃผ์„์€ ์ถ”ํ›„์— ๋ฆฌํŽ™ํ† ๋ง์ด๋‚˜ ๋ณ€๊ฒฝ๋  ์‚ฌํ•ญ์ด ์ƒ๊ธธ ๊ฒฝ์šฐ์—๋งŒ ๋‹ฌ์•„์ฃผ์„ธ์šฉ

import team.retum.network.model.response.application.FetchEmploymentStatusResponse

data class EmploymentStatusEntity(
val classes: List<ClassEmploymentStatusEntity>,
Copy link
Member

Choose a reason for hiding this comment

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

๋„ค์ด๋ฐ์„ classes๋กœ ํ•˜์‹  ์ด์œ ๊ฐ€ ์žˆ์„๊นŒ์š”?

private val applicationRepository: ApplicationRepository,
) {
suspend operator fun invoke() = runCatching {
applicationRepository.fetchEmploymentStatus().toEntity()
Copy link
Member

Choose a reason for hiding this comment

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

์ด ๋ถ€๋ถ„์€ ์ „์ฒด ๋ฆฌํŽ™ํ† ๋ง์„ ํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์ธ๋ฐ ๋„๋ฉ”์ธ ๋ ˆ์ด์–ด์—์„œ๋Š” ๋น„์Šค๋‹ˆ์Šค ๋กœ์ง๊ณผ ์บก์Šํ™”์˜ ์—ญํ• ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ๋งตํ•‘ ์ž‘์—…์€ data ๋ ˆ์ด์–ด์—์„œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.

modifier = Modifier
.wrapContentSize()
.background(Color.Transparent)
.fillMaxWidth(0.4f),
Copy link
Member

Choose a reason for hiding this comment

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

0.4f๋Š” ์™œ ์‚ฌ์šฉํ•˜์‹ ๊ฑด๊ฐ€์š”?

@@ -17,7 +17,7 @@ firebase-messaging = "23.4.1"

hilt-android-gradle-plugin = "2.51.1"
junit = "4.13.2"
android-gradle = "8.2.2"
android-gradle = "8.7.0"
Copy link
Member

Choose a reason for hiding this comment

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

Gradle ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜์‹  ์ด์œ ๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€์š”?

Comment on lines +122 to +123
androidx-tiles-tooling-preview = { group = "androidx.wear.tiles", name = "tiles-tooling-preview", version.ref = "tiles-tooling-preview" }
androidx-ui-tooling-preview-android = { group = "androidx.compose.ui", name = "ui-tooling-preview-android", version.ref = "ui-tooling-preview-android" }
Copy link
Member

Choose a reason for hiding this comment

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

preview๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š”๋ฐ ์ถ”๊ฐ€ํ•˜์‹  ์ด์œ ๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€์š”?

distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
Copy link
Member

Choose a reason for hiding this comment

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

์ด๊ฑธ ์ถ”๊ฐ€ํ•˜๋ฉด ์–ด๋–ค๊ฒƒ๋“ค์ด ๋ณ€๊ฒฝ์ด ๋˜๋‚˜์š”?

Copy link
Member

Choose a reason for hiding this comment

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

์ด ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜์‹  ์ด์œ ๊ฐ€ ๋ฌด์—‡์ด๊ณ  ์–ด๋–ค๊ฒƒ๋“ค์ด ๋ณ€๊ฒฝ๋˜๋Š”๊ฑด๊ฐ€์š”?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ํผ๋ธ”๋ฆฌ์‹ฑ ํ™”๋ฉด์„ ํผ๋ธ”๋ฆฌ์‹ฑ ํ•ฉ๋‹ˆ๋‹ค.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

์ทจ์—…๋ฅ  ์ƒ์„ธ ์กฐํšŒ ํŽ˜์ด์ง€ ์ œ์ž‘
2 participants