-
Notifications
You must be signed in to change notification settings - Fork 0
[feat/#18] 메인화면 api 연동 #21
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
Changes from all commits
4364a44
7197b8d
60bece6
fe29bab
3d88164
8d7b219
e307ab0
11d909b
1e8a028
270f031
60ce2e1
eb63b97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -11,18 +11,12 @@ plugins { | |||||
|
|
||||||
| } | ||||||
|
|
||||||
| //val properties = Properties().apply { | ||||||
| // load(project.rootProject.file("local.properties").inputStream()) | ||||||
| //} | ||||||
|
|
||||||
|
|
||||||
| val properties = Properties().apply { | ||||||
| val localPropertiesFile = project.rootProject.file("local.properties") | ||||||
| if (localPropertiesFile.exists()) { | ||||||
| load(localPropertiesFile.inputStream()) | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| android { | ||||||
| namespace = "com.hsLink.hslink" | ||||||
| compileSdk = libs.versions.compileSdk.get().toInt() | ||||||
|
|
@@ -35,12 +29,9 @@ android { | |||||
| versionName = libs.versions.versionName.get() | ||||||
|
|
||||||
| testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" | ||||||
| buildConfigField( | ||||||
| "String", | ||||||
| "BASE_URL", | ||||||
| "\"${properties.getProperty("base.url", "https://default-url.com")}\"" | ||||||
| ) | ||||||
| //buildConfigField("String", "BASE_URL", properties["base.url"].toString()) | ||||||
|
|
||||||
| buildConfigField("String", "BASE_URL", "\"${properties["base.url"]}\"") | ||||||
|
|
||||||
| } | ||||||
|
|
||||||
| buildTypes { | ||||||
|
|
@@ -50,6 +41,7 @@ android { | |||||
| getDefaultProguardFile("proguard-android-optimize.txt"), | ||||||
| "proguard-rules.pro" | ||||||
| ) | ||||||
| buildConfigField("String", "BASE_URL", "\"${properties["base.url"]}\"") | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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
Suggested change
🤖 Prompt for AI Agents |
||||||
| } | ||||||
| } | ||||||
| compileOptions { | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| <application | ||
| android:name=".HsuConnectApplication" | ||
| android:allowBackup="true" | ||
| android:usesCleartextTraffic="true" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security concern: Restrict cleartext traffic to development only. Enabling Recommended solution: Use a Network Security Configuration file to allow cleartext traffic only for specific development domains:
<?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>
- android:usesCleartextTraffic="true"
+ android:networkSecurityConfig="@xml/network_security_config"Alternatively, use build-variant-specific manifests to enable this only in debug builds. |
||
| android:dataExtractionRules="@xml/data_extraction_rules" | ||
| android:fullBackupContent="@xml/backup_rules" | ||
| android:icon="@mipmap/ic_launcher" | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||||||||||||||||||
| package com.hsLink.hslink.data.di | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import com.hsLink.hslink.data.remote.datasource.PostDataSource | ||||||||||||||||||||||
| import com.hsLink.hslink.data.remote.datasourceimpl.PostDataSourceImpl | ||||||||||||||||||||||
| import dagger.Binds | ||||||||||||||||||||||
| import dagger.Module | ||||||||||||||||||||||
| import dagger.hilt.InstallIn | ||||||||||||||||||||||
| import dagger.hilt.components.SingletonComponent | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @Module | ||||||||||||||||||||||
| @InstallIn(SingletonComponent::class) | ||||||||||||||||||||||
| interface DataSourceModule { | ||||||||||||||||||||||
| @Binds | ||||||||||||||||||||||
| abstract fun bindePostRemoteDataSource( | ||||||||||||||||||||||
| postDataSourceImpl: PostDataSourceImpl, | ||||||||||||||||||||||
| ): PostDataSource | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+13
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix typo in method name. The method name Apply this diff: @Binds
- abstract fun bindePostRemoteDataSource(
+ abstract fun bindPostRemoteDataSource(
postDataSourceImpl: PostDataSourceImpl,
): PostDataSource📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| package com.hsLink.hslink.data.di | ||
|
|
||
| import com.hsLink.hslink.BuildConfig | ||
| import com.hsLink.hslink.data.service.home.PostService | ||
| import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory | ||
| import dagger.Module | ||
| import dagger.Provides | ||
|
|
@@ -12,6 +13,7 @@ import okhttp3.OkHttpClient | |
| import okhttp3.logging.HttpLoggingInterceptor | ||
| import retrofit2.Converter | ||
| import retrofit2.Retrofit | ||
| import timber.log.Timber | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify 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.ktLength of output: 0 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 |
||
| import java.util.concurrent.TimeUnit | ||
| import javax.inject.Singleton | ||
|
|
||
|
|
@@ -49,9 +51,16 @@ object NetworkModule { | |
| fun providesRetrofit( | ||
| client: OkHttpClient, | ||
| converterFactory: Converter.Factory, | ||
| ): Retrofit = Retrofit.Builder() | ||
| .baseUrl(BuildConfig.BASE_URL) | ||
| .addConverterFactory(converterFactory) | ||
| .client(client) | ||
| .build() | ||
| ): Retrofit { | ||
| return Retrofit.Builder() | ||
| .baseUrl(BuildConfig.BASE_URL) | ||
| .addConverterFactory(converterFactory) | ||
| .client(client) | ||
| .build() | ||
| } | ||
|
|
||
| @Provides | ||
| @Singleton | ||
| fun providePostService(retrofit: Retrofit): PostService = | ||
| retrofit.create(PostService::class.java) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| package com.hsLink.hslink.data.dto.request | ||
|
|
||
| class PostRequestDto { | ||
| } | ||
|
Comment on lines
+3
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainEmpty 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 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 |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| package com.hsLink.hslink.data.dto.response | ||
|
|
||
| import com.hsLink.hslink.domain.model.PostPopularEntity | ||
| import com.hsLink.hslink.domain.model.PostPromotionEntity | ||
| import kotlinx.serialization.SerialName | ||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class PostResponseDto( | ||
| @SerialName("posts") | ||
| val posts: List<PostPopular>, | ||
| ) | ||
|
|
||
| @Serializable | ||
| data class PostPopular( | ||
| @SerialName("id") | ||
| val id: Int, | ||
| @SerialName("title") | ||
| val title: String, | ||
| ) | ||
|
|
||
| @Serializable | ||
| data class PostPromotionDto( | ||
| @SerialName("posts") | ||
| val posts: List<PostPromotion>, | ||
| ) | ||
|
|
||
| @Serializable | ||
| data class PostPromotion( | ||
| @SerialName("id") | ||
| val id: Int, | ||
| @SerialName("title") | ||
| val title: String, | ||
| @SerialName("summary") | ||
| val summary: String, | ||
| @SerialName("author") | ||
| val author: String, | ||
| @SerialName("studentId") | ||
| val studentId: String, | ||
| @SerialName("authorStatus") | ||
| val authorStatus: String, | ||
|
|
||
| ) | ||
|
|
||
|
|
||
| fun PostPopular.toEntity(): PostPopularEntity { | ||
| return PostPopularEntity( | ||
| id = this.id, | ||
| title = this.title, | ||
| ) | ||
| } | ||
|
|
||
| fun PostPromotion.toEntity(): PostPromotionEntity { | ||
| return PostPromotionEntity( | ||
| id = this.id, | ||
| title = this.title, | ||
| summary = this.summary, | ||
| author = this.author, | ||
| studentId = this.studentId, | ||
| authorStatus = this.authorStatus, | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package com.hsLink.hslink.data.remote.datasource | ||
|
|
||
| import com.hsLink.hslink.core.network.BaseResponse | ||
| import com.hsLink.hslink.data.dto.response.PostPromotionDto | ||
| import com.hsLink.hslink.data.dto.response.PostResponseDto | ||
|
|
||
| interface PostDataSource { | ||
| suspend fun getPopularPost() : BaseResponse<PostResponseDto> | ||
|
|
||
| suspend fun getPromotionPost() : BaseResponse<PostPromotionDto> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.hsLink.hslink.data.remote.datasourceimpl | ||
|
|
||
| import com.hsLink.hslink.core.network.BaseResponse | ||
| import com.hsLink.hslink.data.dto.response.PostPromotionDto | ||
| import com.hsLink.hslink.data.dto.response.PostResponseDto | ||
| import com.hsLink.hslink.data.remote.datasource.PostDataSource | ||
| import com.hsLink.hslink.data.service.home.PostService | ||
| import javax.inject.Inject | ||
|
|
||
| class PostDataSourceImpl @Inject constructor( | ||
| private val postService: PostService | ||
| ): PostDataSource{ | ||
| override suspend fun getPopularPost() : BaseResponse<PostResponseDto>{ | ||
| return postService.getPopularPost() | ||
| } | ||
|
|
||
| override suspend fun getPromotionPost(): BaseResponse<PostPromotionDto> { | ||
| return postService.getPromotionPost() | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package com.hsLink.hslink.data.repositoryimpl | ||
|
|
||
| import com.hsLink.hslink.data.dto.response.toEntity | ||
| import com.hsLink.hslink.data.remote.datasourceimpl.PostDataSourceImpl | ||
| import com.hsLink.hslink.domain.model.PostPopularEntity | ||
| import com.hsLink.hslink.domain.model.PostPromotionEntity | ||
| import com.hsLink.hslink.domain.repository.PostRepository | ||
| import javax.inject.Inject | ||
|
|
||
| class PostRepositoryImpl @Inject constructor( | ||
| private val postDataSourceImpl: PostDataSourceImpl, | ||
| ) : PostRepository { | ||
| override suspend fun getPopularPost(): Result<List<PostPopularEntity>> = | ||
| runCatching { | ||
| val response = postDataSourceImpl.getPopularPost() | ||
| if (response.isSuccess) { | ||
| response.result.posts.map { it.toEntity() } | ||
| } else { | ||
| throw Exception(response.message) | ||
| } | ||
| } | ||
|
|
||
| override suspend fun getPromotionPost(): Result<List<PostPromotionEntity>> = | ||
| runCatching { | ||
| val respone = postDataSourceImpl.getPromotionPost() | ||
| if (respone.isSuccess) { | ||
| respone.result.posts.map { it.toEntity() } | ||
| } else { | ||
| throw Exception(respone.message) | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package com.hsLink.hslink.data.service.home | ||
|
|
||
| import com.hsLink.hslink.core.network.BaseResponse | ||
| import com.hsLink.hslink.data.dto.response.PostPromotionDto | ||
| import com.hsLink.hslink.data.dto.response.PostResponseDto | ||
| import retrofit2.http.GET | ||
|
|
||
|
|
||
| interface PostService { | ||
| @GET("posts/popular") | ||
| suspend fun getPopularPost(): BaseResponse<PostResponseDto> | ||
|
|
||
| @GET("posts/promotion") | ||
| suspend fun getPromotionPost(): BaseResponse<PostPromotionDto> | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package com.hsLink.hslink.domain.model | ||
|
|
||
| import kotlinx.serialization.SerialName | ||
|
|
||
| data class PostPopularEntity ( | ||
| val id: Int, | ||
| val title: String, | ||
| ) | ||
|
|
||
| data class PostPromotionEntity( | ||
| val id: Int, | ||
| val title: String, | ||
| val summary: String, | ||
| val author: String, | ||
| val studentId: String, | ||
| val authorStatus: String, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package com.hsLink.hslink.domain.repository | ||
|
|
||
| import com.hsLink.hslink.domain.model.PostPopularEntity | ||
| import com.hsLink.hslink.domain.model.PostPromotionEntity | ||
|
|
||
| interface PostRepository { | ||
| suspend fun getPopularPost(): Result<List<PostPopularEntity>> | ||
| suspend fun getPromotionPost(): Result<List<PostPromotionEntity>> | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
📝 Committable suggestion
🤖 Prompt for AI Agents