Skip to content

Conversation

@vvan2
Copy link
Member

@vvan2 vvan2 commented Nov 10, 2025

ISSUE

❗ WORK DESCRIPTION

  • manifest(http 오류 수정)
  • build.gradle 수정 (local.properties에 들어가는 url 은 보내드릴게요)
  • baseresponse 구조 수정
  • module 추가 및 수정
  • 메인화면 API 연동( 1. 인기 게시글 , 2. 최신 홍보 게시글)
  • domain,data 쪽에 구조 나눠놨습니다.
  • homeviewmodel 추가 및 screen 연동

📸 SCREENSHOT

image image

📢 TO REVIEWERS

  • 카카오 로그인 연동되면 우선순위 확인하고 api 연동 하겠습니다. 지금은 토큰이 없어서 사용안해도 되는 api 먼저 연결할게욥

Summary by CodeRabbit

  • New Features

    • Popular posts feed on Home
    • Promotion posts carousel (horizontal) on Home
    • Dynamic post cards showing title, author, summary, and identifiers; click navigation to Home
  • Chores

    • Enabled cleartext (HTTP) traffic
    • Updated API response shape and DTOs for unified result payloads and codes

@vvan2 vvan2 self-assigned this Nov 10, 2025
@vvan2 vvan2 added feature ✨ 기능 구현 주완🐹 주완 전용 라벨 labels Nov 10, 2025
@vvan2 vvan2 linked an issue Nov 10, 2025 that may be closed by this pull request
1 task
@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Warning

Rate limit exceeded

@vvan2 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 23 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 60ce2e1 and eb63b97.

📒 Files selected for processing (1)
  • app/src/main/java/com/hsLink/hslink/presentation/main/MainNavigator.kt (2 hunks)

Walkthrough

Adds remote API integration for home posts: new Retrofit service, DTOs, datasource, repository, DI bindings, ViewModel, and UI wiring; restructures network response model; updates build config and manifest to source BASE_URL from properties and enable cleartext traffic; adjusts home UI composables to render popular and promotion posts.

Changes

Cohort / File(s) Summary
Build Configuration
app/build.gradle.kts
Use properties["base.url"] directly for buildConfigField("String", "BASE_URL", ...) in defaultConfig and release (moved loading into properties block).
Manifest Configuration
app/src/main/AndroidManifest.xml
Added android:usesCleartextTraffic="true" on the <application> element.
Network Response Model
app/src/main/java/.../core/network/BaseResponse.kt
Replaced success/error/data shape with isSuccess/code/message/result and removed nested ErrorResponse.
Service
app/src/main/java/.../data/service/home/PostService.kt
Added Retrofit PostService with GET posts/popular and GET posts/promotion.
DataSource & Impl
app/src/main/java/.../data/remote/datasource/PostDataSource.kt, app/src/main/java/.../data/remote/datasourceimpl/PostDataSourceImpl.kt
New PostDataSource interface and PostDataSourceImpl delegating calls to PostService.
DTOs & Mappers
app/src/main/java/.../data/dto/request/PostRequestDto.kt, app/src/main/java/.../data/dto/response/PostResponseDto.kt
Added PostRequestDto (placeholder) and PostResponseDto with PostPopular/PostPromotion DTOs and toEntity() mappers.
Repository & Impl
app/src/main/java/.../data/repositoryimpl/PostRepositoryImpl.kt, app/src/main/java/.../domain/repository/PostRepository.kt
New PostRepository interface and PostRepositoryImpl implementing it; methods return Result-wrapped entity lists after mapping and success checks.
Domain Models
app/src/main/java/.../domain/model/PostResponseEntity.kt
Added PostPopularEntity and PostPromotionEntity data classes.
Dependency Injection
app/src/main/java/.../data/di/DataSourceModule.kt, .../NetworkModule.kt, .../RepositoryModule.kt
Added DI bindings: DataSourceModule binds PostDataSourceImpl -> PostDataSource; RepositoryModule binds PostRepositoryImpl -> PostRepository; NetworkModule provides PostService.
Presentation — State & VM
app/src/main/java/.../presentation/home/state/HomeContract.kt, .../viewmodel/HomeViewModel.kt
New immutable HomeContract state and HomeViewModel exposing StateFlow, fetching popular and promotion posts on init and updating state.
Presentation — UI Components
app/src/main/java/.../presentation/home/component/HomeCardItem.kt, .../HomePostContainer.kt
HomeCardItem signature extended with userId and routeId; added HomePromotionPost; HomePost had route removed and annotated @Immutable.
Presentation — Screen & Navigation
app/src/main/java/.../presentation/home/screen/HomeScreen.kt, .../navigation/HomeNavigation.kt, .../presentation/main/MainNavigator.kt
HomeScreen/HomeRoute now collect VM state and accept popularPosts/promotionPosts plus click handlers; added horizontal promotion LazyRow; HomeNavigation import path updated; MainNavigator gained navigateToHome(...).

Sequence Diagram(s)

sequenceDiagram
    participant UI as HomeScreen
    participant VM as HomeViewModel
    participant Repo as PostRepositoryImpl
    participant DS as PostDataSourceImpl
    participant Service as PostService
    participant API as Remote API

    UI->>VM: collect state
    VM->>VM: init -> fetchPopularPosts(), fetchPromotionPosts()
    VM->>Repo: getPopularPost()
    Repo->>DS: getPopularPost()
    DS->>Service: retrofit.getPopularPost()
    Service->>API: GET /posts/popular
    API-->>Service: BaseResponse<PostResponseDto>
    Service-->>DS: BaseResponse<PostResponseDto>
    DS-->>Repo: BaseResponse<PostResponseDto>

    rect rgb(220,240,220)
      Note over Repo: evaluate isSuccess / map result
      alt success
        Repo-->>VM: Result.success(List<PostPopularEntity>)
      else failure
        Repo-->>VM: Result.failure(Exception)
      end
    end

    VM->>VM: update HomeContract state
    VM-->>UI: emit state
    UI->>UI: render LazyRow(s)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • BaseResponse deserialization and impact across services.
    • Error handling and exception messages in PostRepositoryImpl.
    • Hilt DI bindings and scoping between modules.
    • ViewModel lifecycle and concurrent state updates.
    • UI parameter changes (call sites of changed composables).

Possibly related PRs

Suggested reviewers

  • dmp100

Poem

🐇 In burrows where the API carrots grow,

I hop and fetch the posts in a row.
Popular hops and promos in flight,
ViewModel steadies each data byte.
Repos and DTOs join the spring show. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title '[feat/#18] 메인화면 api 연동' clearly and concisely summarizes the main change: integrating the API for the main screen home feature.
Description check ✅ Passed The PR description covers the required template sections including issue reference (#18), work description with specific implementation details, screenshots, and notes to reviewers.
Linked Issues check ✅ Passed The PR successfully implements the main objective from issue #18: integrating home screen API connections for popular posts and promotional posts, with proper domain/data layer structure and ViewModel integration.
Out of Scope Changes check ✅ Passed All changes are directly related to the PR objective of implementing main screen API integration. Changes include necessary supporting infrastructure (BaseResponse update, DI modules, services, repositories) and UI components for displaying fetched data.

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

❤️ Share

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

Copy link

@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: 8

🧹 Nitpick comments (6)
app/src/main/java/com/hsLink/hslink/presentation/home/state/HomeContract.kt (1)

7-15: Remove unnecessary empty body.

The data class doesn't need an empty body block. Data classes with only constructor parameters can omit the body entirely.

Apply this diff:

 @Immutable
 data class HomeContract (
     val isLoading: Boolean = false,
     val error: String? = null,
     val postPopular : List<PostPopularEntity> = emptyList(),
     val postPromotion : List<PostPromotionEntity> = emptyList()
-){
-
-}
+)
app/src/main/java/com/hsLink/hslink/domain/model/PostResponseEntity.kt (1)

3-3: Remove unused serialization import.

Domain entities shouldn't reference serialization libraries—serialization belongs in the data layer (DTOs). This import is unused and should be removed.

Apply this diff:

 package com.hsLink.hslink.domain.model
 
-import kotlinx.serialization.SerialName
-
 data class PostPopularEntity (
app/src/main/java/com/hsLink/hslink/presentation/home/component/HomeCardItem.kt (1)

40-47: Consider extracting HomePromotionPost to a dedicated models package.

While co-locating the data class here works, presentation models are typically better organized in a separate package (e.g., presentation.home.model) for improved discoverability and maintainability.

app/src/main/java/com/hsLink/hslink/data/remote/datasourceimpl/PostDataSourceImpl.kt (1)

10-20: Consider removing the redundant data source layer.

PostDataSourceImpl is a simple pass-through wrapper that adds no value—it delegates directly to PostService without transformation, error handling, or additional logic. This introduces unnecessary complexity and indirection.

Consider having PostRepositoryImpl inject and use PostService directly, eliminating the data source interface and implementation. The data source layer becomes valuable when you need to aggregate multiple services, add caching, or apply cross-cutting concerns—none of which are present here.

app/src/main/java/com/hsLink/hslink/presentation/home/viewmodel/HomeViewModel.kt (1)

27-47: Set isLoading before launching the fetch.

Right now we only ever write isLoading = false, so subsequent refreshes never emit a “loading” state to the UI. Please push isLoading = true (and clear any stale error) before calling the repository in both fetchers so consumers can display progress.

Apply this diff pattern in each fetch:

     fun fetchPopularPosts() {
         viewModelScope.launch {
+            _state.update { it.copy(isLoading = true, error = null) }
             postRepository.getPopularPost()
                 .onSuccess { posts ->
                     _state.update { state ->
app/src/main/java/com/hsLink/hslink/data/repositoryimpl/PostRepositoryImpl.kt (1)

10-31: Depend on the PostDataSource contract, not its concrete impl.

Injecting PostDataSourceImpl couples the repository to one implementation and makes testing/mocking harder. Please inject the PostDataSource interface instead and adjust the calls accordingly.

Example adjustment:

-import com.hsLink.hslink.data.remote.datasourceimpl.PostDataSourceImpl
+import com.hsLink.hslink.data.remote.datasource.PostDataSource

-class PostRepositoryImpl @Inject constructor(
-    private val postDataSourceImpl: PostDataSourceImpl,
+class PostRepositoryImpl @Inject constructor(
+    private val postDataSource: PostDataSource,
 ) : PostRepository {
     override suspend fun getPopularPost(): Result<List<PostPopularEntity>> =
         runCatching {
-            val response = postDataSourceImpl.getPopularPost()
+            val response = postDataSource.getPopularPost()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5bfb8a2 and 1e8a028.

📒 Files selected for processing (21)
  • app/build.gradle.kts (3 hunks)
  • app/src/main/AndroidManifest.xml (1 hunks)
  • app/src/main/java/com/hsLink/hslink/core/network/BaseResponse.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/di/DataSourceModule.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt (3 hunks)
  • app/src/main/java/com/hsLink/hslink/data/di/RepositoryModule.kt (2 hunks)
  • app/src/main/java/com/hsLink/hslink/data/dto/request/PostRequestDto.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/dto/response/PostResponseDto.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/remote/datasource/PostDataSource.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/remote/datasourceimpl/PostDataSourceImpl.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/repositoryimpl/PostRepositoryImpl.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/service/home/PostService.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/domain/model/PostResponseEntity.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/domain/repository/PostRepository.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/home/component/HomeCardItem.kt (3 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/home/component/HomePostContainer.kt (2 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/home/navigation/HomeNavigation.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/home/screen/HomeScreen.kt (5 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/home/state/HomeContract.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/home/viewmodel/HomeViewModel.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/main/MainNavigator.kt (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/src/main/java/com/hsLink/hslink/presentation/home/screen/HomeScreen.kt (1)
app/src/main/java/com/hsLink/hslink/presentation/home/component/HomeCardItem.kt (1)
  • HomeCardItem (48-117)
🪛 detekt (1.23.8)
app/src/main/java/com/hsLink/hslink/presentation/home/state/HomeContract.kt

[warning] 13-15: The class or object HomeContract is empty.

(detekt.empty-blocks.EmptyClassBlock)

app/src/main/java/com/hsLink/hslink/data/dto/request/PostRequestDto.kt

[warning] 3-4: The class or object PostRequestDto is empty.

(detekt.empty-blocks.EmptyClassBlock)

🔇 Additional comments (13)
app/src/main/java/com/hsLink/hslink/presentation/main/MainNavigator.kt (1)

72-74: LGTM! Consistent navigation pattern.

The implementation correctly follows the existing pattern for navigation methods in this class and allows flexible navigation to Home with custom NavOptions.

app/src/main/java/com/hsLink/hslink/presentation/home/navigation/HomeNavigation.kt (1)

9-9: LGTM! Clean package reorganization.

The import path update aligns with the new screen subpackage structure without affecting functionality.

app/src/main/java/com/hsLink/hslink/presentation/home/component/HomeCardItem.kt (1)

49-56: Verify intended usage of routeId parameter.

The routeId parameter is accepted but not used within the composable. If it's intended for navigation on click, the click handler is missing. If it's for future use, consider documenting that intent.

app/src/main/java/com/hsLink/hslink/core/network/BaseResponse.kt (1)

7-16: LGTM! Cleaner response structure.

The flattened BaseResponse structure is simpler and more maintainable than the previous nested design. The PR context confirms that dependent services (PostService, data sources) have been updated to use this new contract.

app/src/main/java/com/hsLink/hslink/data/dto/response/PostResponseDto.kt (2)

8-43: LGTM! Well-structured DTOs with proper serialization.

The DTO structure cleanly separates data transfer concerns from domain models. All serialization annotations are correctly applied.

Minor formatting note: Line 43 has extra blank lines after the closing parenthesis—purely cosmetic.


46-62: LGTM! Clean DTO-to-entity mappings.

The extension functions provide a clear boundary between the data layer and domain layer, with straightforward field mappings.

app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt (2)

51-60: LGTM! Standard Retrofit setup.

The conversion from expression body to block body is a neutral stylistic change with no functional impact.


62-65: LGTM! Proper DI wiring for PostService.

The provider function correctly creates the PostService instance using Retrofit's standard pattern.

app/src/main/java/com/hsLink/hslink/data/remote/datasource/PostDataSource.kt (1)

7-11: LGTM!

Clean interface definition with appropriate suspend functions for async data fetching.

app/src/main/java/com/hsLink/hslink/data/service/home/PostService.kt (1)

9-15: LGTM!

Standard Retrofit service interface with properly defined endpoints.

app/src/main/java/com/hsLink/hslink/data/di/RepositoryModule.kt (1)

21-25: LGTM!

Proper Dagger-Hilt binding for the new repository.

app/src/main/java/com/hsLink/hslink/presentation/home/component/HomePostContainer.kt (1)

39-43: LGTM!

Good addition of @Immutable annotation for Compose performance optimization, and the simplified data class structure aligns with separation of concerns.

app/src/main/java/com/hsLink/hslink/domain/repository/PostRepository.kt (1)

6-9: LGTM!

Clean domain repository contract using Kotlin's Result type for proper error handling.

Comment on lines 14 to 16
val properties = Properties().apply {
val localPropertiesFile = project.rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
load(localPropertiesFile.inputStream())
}
load(project.rootProject.file("local.properties").inputStream())
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Add error handling for missing local.properties file.

The unconditional load of local.properties will cause build failure if the file doesn't exist. This is particularly problematic for new developers setting up the project or in CI/CD environments.

Apply this diff to add defensive checks:

 val properties = Properties().apply {
-    load(project.rootProject.file("local.properties").inputStream())
+    val localPropertiesFile = project.rootProject.file("local.properties")
+    if (localPropertiesFile.exists()) {
+        load(localPropertiesFile.inputStream())
+    } else {
+        throw GradleException("local.properties file not found. Please create it with base.url property.")
+    }
 }
📝 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 properties = Properties().apply {
val localPropertiesFile = project.rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
load(localPropertiesFile.inputStream())
}
load(project.rootProject.file("local.properties").inputStream())
}
val properties = Properties().apply {
val localPropertiesFile = project.rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
load(localPropertiesFile.inputStream())
} else {
throw GradleException("local.properties file not found. Please create it with base.url property.")
}
}
🤖 Prompt for AI Agents
In app/build.gradle.kts around lines 14 to 16, the code unconditionally loads
local.properties which will throw if the file is missing; add a defensive check
to see if project.rootProject.file("local.properties") exists and isFile before
calling load, and if it doesn't exist either skip loading (optionally log a
warning) or fall back to default properties so the build can proceed; ensure you
still load when present and handle IOExceptions by catching and logging them
rather than letting them fail the build.

)
//buildConfigField("String", "BASE_URL", properties["base.url"].toString())

buildConfigField("String", "BASE_URL", "\"${properties["base.url"]}\"")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Add null safety for base.url property access.

Direct property access via properties["base.url"] can fail with a NullPointerException if the property is missing. This would result in cryptic build errors.

Apply this diff to add null safety with a clear error message:

-        buildConfigField("String", "BASE_URL", "\"${properties["base.url"]}\"")
+        buildConfigField("String", "BASE_URL", "\"${properties["base.url"] ?: error("base.url property is missing in local.properties")}\"")
📝 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
buildConfigField("String", "BASE_URL", "\"${properties["base.url"]}\"")
buildConfigField("String", "BASE_URL", "\"${properties["base.url"] ?: error("base.url property is missing in local.properties")}\"")
🤖 Prompt for AI Agents
In app/build.gradle.kts around line 31, the direct access properties["base.url"]
can be null and cause an NPE; change it to safely unwrap the property and fail
fast with a clear message (e.g. use requireNotNull(properties["base.url"]) {
"Missing required project property 'base.url'" } or check
properties.containsKey("base.url") and throw a GradleException) and then use the
resulting non-null value when calling buildConfigField (preserving the
surrounding quoted string expected by buildConfigField).

getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
buildConfigField("String", "BASE_URL", "\"${properties["base.url"]}\"")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Add null safety for base.url property access in release build.

Same issue as in defaultConfig - the property access lacks null safety.

Apply this diff:

-            buildConfigField("String", "BASE_URL", "\"${properties["base.url"]}\"")
+            buildConfigField("String", "BASE_URL", "\"${properties["base.url"] ?: error("base.url property is missing in local.properties")}\"")
📝 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
buildConfigField("String", "BASE_URL", "\"${properties["base.url"]}\"")
buildConfigField("String", "BASE_URL", "\"${properties["base.url"] ?: error("base.url property is missing in local.properties")}\"")
🤖 Prompt for AI Agents
In app/build.gradle.kts around line 42, the buildConfigField call uses
properties["base.url"] without null-safety; change it to use a safe cast and
fallback or fail fast — e.g., replace the direct access with
(properties["base.url"] as? String) ?: error("base.url property is required") so
the value is null-safe and provides a clear error if missing.

<application
android:name=".HsuConnectApplication"
android:allowBackup="true"
android:usesCleartextTraffic="true"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Security concern: Restrict cleartext traffic to development only.

Enabling usesCleartextTraffic="true" globally allows unencrypted HTTP traffic, which exposes user data to interception and man-in-the-middle attacks. This should not be shipped to production.

Recommended solution: Use a Network Security Configuration file to allow cleartext traffic only for specific development domains:

  1. Create res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
        <domain includeSubdomains="true">10.0.2.2</domain>
        <!-- Add your dev server domains here -->
    </domain-config>
</network-security-config>
  1. Reference it in the manifest:
-        android:usesCleartextTraffic="true"
+        android:networkSecurityConfig="@xml/network_security_config"

Alternatively, use build-variant-specific manifests to enable this only in debug builds.

Comment on lines +13 to +17
@Binds
abstract fun bindePostRemoteDataSource(
postDataSourceImpl: PostDataSourceImpl,
): PostDataSource
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix typo in method name.

The method name bindePostRemoteDataSource has a typo—it should be bindPostRemoteDataSource for consistency with Dagger naming conventions.

Apply this diff:

     @Binds
-    abstract fun bindePostRemoteDataSource(
+    abstract fun bindPostRemoteDataSource(
         postDataSourceImpl: PostDataSourceImpl,
     ): PostDataSource
📝 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
@Binds
abstract fun bindePostRemoteDataSource(
postDataSourceImpl: PostDataSourceImpl,
): PostDataSource
}
@Binds
abstract fun bindPostRemoteDataSource(
postDataSourceImpl: PostDataSourceImpl,
): PostDataSource
}
🤖 Prompt for AI Agents
In app/src/main/java/com/hsLink/hslink/data/di/DataSourceModule.kt around lines
13 to 17, the Binds method name `bindePostRemoteDataSource` has a typo; rename
it to `bindPostRemoteDataSource` so it follows naming conventions and matches
other DI bindings, updating the method declaration only (keep parameter type and
return type unchanged).

import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Converter
import retrofit2.Retrofit
import timber.log.Timber
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify usage of Timber import.

The Timber import is added but not visibly used in the provided code. If it's unused, consider removing it.


🏁 Script executed:

#!/bin/bash
# Description: Check if Timber is used in NetworkModule.kt

# Search for Timber usage in the file
rg -n "Timber\." app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt

Length of output: 0



---

🏁 Script executed:

```shell
#!/bin/bash
# Check if file exists and view its content
if [ -f "app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt" ]; then
  echo "=== File exists. Content: ==="
  cat "app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt"
else
  echo "File not found at specified path"
fi

echo ""
echo "=== Searching for any Timber reference (including imports) ==="
rg -n "Timber" app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt

Length of output: 2038


Remove unused Timber import.

The Timber import at line 16 is not used anywhere in the file. Remove it.

🤖 Prompt for AI Agents
In app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt around line 16,
the import "timber.log.Timber" is unused; remove that import line to clean up
unused dependencies and avoid lint/compile warnings, leaving the rest of the
file unchanged.

Comment on lines +3 to +4
class PostRequestDto {
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Empty class serves no purpose.

This class has no fields or methods. If it's a placeholder for future request bodies, consider removing it until actually needed (YAGNI principle). Alternatively, if requirements are known, add the necessary fields now.

Run the following script to verify if this class is referenced anywhere in the codebase:

If no usages are found, consider removing this file to keep the codebase clean.


🏁 Script executed:

#!/bin/bash
# Description: Check if PostRequestDto is used anywhere in the codebase

# Search for imports of PostRequestDto
rg -n "import.*PostRequestDto" -g "*.kt"

# Search for usages of PostRequestDto (excluding the definition itself)
rg -n "PostRequestDto" -g "*.kt" -C 2 | grep -v "class PostRequestDto"

Length of output: 264


Remove unused empty class PostRequestDto.

Verification confirms this class is not imported or used anywhere in the codebase. It serves no purpose and should be deleted to maintain code cleanliness and avoid future confusion.

🧰 Tools
🪛 detekt (1.23.8)

[warning] 3-4: The class or object PostRequestDto is empty.

(detekt.empty-blocks.EmptyClassBlock)

🤖 Prompt for AI Agents
In app/src/main/java/com/hsLink/hslink/data/dto/request/PostRequestDto.kt around
lines 3 to 4, remove the unused empty class PostRequestDto; delete the file
entirely (or remove the class declaration) and verify there are no imports or
references left in the project, then run a full build to ensure no compilation
errors.

Comment on lines +184 to +197
LazyRow(
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
items(promotionPosts) { post ->
HomeCardItem(
userName = post.title,
userMajor = post.summary,
userInfo = post.author,
userId = post.studentId,
routeId = post.id,
modifier = Modifier.width(250.dp)
)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Wire onPromotionClick into the promotion cards.

HomeScreen exposes onPromotionClick, but the LazyRow never invokes it, so the new handler is a no-op and promotion cards stay non-interactive. Please add a Modifier.clickable { onPromotionClick(post) } (and the import) when building each card.

Suggested fix:

-import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.PaddingValues
@@
                 items(promotionPosts) { post ->
                     HomeCardItem(
                         userName = post.title,
                         userMajor = post.summary,
                         userInfo = post.author,
                         userId = post.studentId,
                         routeId = post.id,
-                        modifier = Modifier.width(250.dp)
+                        modifier = Modifier
+                            .width(250.dp)
+                            .clickable { onPromotionClick(post) }
                     )
                 }
             }
📝 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
LazyRow(
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
items(promotionPosts) { post ->
HomeCardItem(
userName = post.title,
userMajor = post.summary,
userInfo = post.author,
userId = post.studentId,
routeId = post.id,
modifier = Modifier.width(250.dp)
)
}
LazyRow(
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
items(promotionPosts) { post ->
HomeCardItem(
userName = post.title,
userMajor = post.summary,
userInfo = post.author,
userId = post.studentId,
routeId = post.id,
modifier = Modifier
.width(250.dp)
.clickable { onPromotionClick(post) }
)
}
}
🤖 Prompt for AI Agents
In app/src/main/java/com/hsLink/hslink/presentation/home/screen/HomeScreen.kt
around lines 184 to 197, the LazyRow builds promotion HomeCardItem instances but
does not wire the exposed onPromotionClick handler, leaving cards
non-interactive; update the HomeCardItem call to add a clickable modifier that
calls onPromotionClick(post) (e.g., combine Modifier.width(250.dp).clickable {
onPromotionClick(post) }) and add the necessary import for
androidx.compose.foundation.clickable so each promotion card invokes the handler
when tapped.

@vvan2 vvan2 requested a review from dmp100 November 10, 2025 12:16
@vvan2 vvan2 merged commit 4a7514c into develop Nov 10, 2025
3 checks passed
@vvan2 vvan2 deleted the feat/#18-onboarding-api branch November 10, 2025 12:26
This was referenced Nov 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature ✨ 기능 구현 주완🐹 주완 전용 라벨

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 메인화면 API 연결

2 participants