Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fun HsLinkDialog(
Text(
text = dismissText,
color = HsLinkTheme.colors.Grey500,
style = HsLinkTheme.typography.btm_M,
style = HsLinkTheme.typography.btm_S,
)
}

Expand All @@ -86,7 +86,7 @@ fun HsLinkDialog(
Text(
text = confirmText,
color = HsLinkTheme.colors.Common,
style = HsLinkTheme.typography.btm_M,
style = HsLinkTheme.typography.btm_S,
)
}
}
Expand Down
4 changes: 0 additions & 4 deletions app/src/main/java/com/hsLink/hslink/data/DummyDto.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.hsLink.hslink.data.di

import com.hsLink.hslink.data.remote.datasource.CommunityPostDataSource
import com.hsLink.hslink.data.remote.datasource.PostDataSource
import com.hsLink.hslink.data.remote.datasourceimpl.CommunityPostDataSourceImpl
import com.hsLink.hslink.data.remote.datasourceimpl.PostDataSourceImpl
import dagger.Binds
import dagger.Module
Expand All @@ -14,4 +16,9 @@ interface DataSourceModule {
abstract fun bindePostRemoteDataSource(
postDataSourceImpl: PostDataSourceImpl,
): PostDataSource

@Binds
abstract fun bindsPostLocalDataSource(
communityPostDataSourceImpl: CommunityPostDataSourceImpl,
): CommunityPostDataSource
}
6 changes: 6 additions & 0 deletions app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt
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.commuunity.CommunityPostService
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

Fix package name typo.

The package name contains a typo: commuunity should be community (has three 'u's instead of two). This should be corrected in both the package structure and all import statements.

Verify the extent of this typo across the codebase:


🏁 Script executed:

#!/bin/bash
# Search for the typo in package names and imports
rg -n "commuunity" --type=kt

Length of output: 26


🏁 Script executed:

#!/bin/bash
# Search for the typo across all files
rg -n "commuunity"

Length of output: 434


🏁 Script executed:

#!/bin/bash
# Also search for correct spelling to understand if it was fixed elsewhere
rg -n "community"

Length of output: 11323


Fix package name typo in data service layer.

The package com.hsLink.hslink.data.service.commuunity contains a typo: commuunity should be community (three 'u's instead of two). This typo exists in the package definition and is imported in two locations:

  • app/src/main/java/com/hsLink/hslink/data/service/commuunity/CommunityPostService.kt (package declaration)
  • app/src/main/java/com/hsLink/hslink/data/remote/datasourceimpl/CommunityPostDataSourceImpl.kt (import)
  • app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt (import)

Rename the package directory from commuunity to community, update the package declaration, and update both import statements accordingly.

🤖 Prompt for AI Agents
In app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt around line 4
and the related files
app/src/main/java/com/hsLink/hslink/data/service/commuunity/CommunityPostService.kt
and
app/src/main/java/com/hsLink/hslink/data/remote/datasourceimpl/CommunityPostDataSourceImpl.kt,
there is a package name typo: "commuunity" should be "community"; rename the
directory commuunity -> community, update the package declaration in
CommunityPostService.kt to use com.hsLink.hslink.data.service.community, and
update import statements in NetworkModule.kt and CommunityPostDataSourceImpl.kt
to import com.hsLink.hslink.data.service.community.CommunityPostService (and any
other occurrences) so all references use the corrected package name.

import com.hsLink.hslink.data.service.home.PostService
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import dagger.Module
Expand Down Expand Up @@ -63,4 +64,9 @@ object NetworkModule {
@Singleton
fun providePostService(retrofit: Retrofit): PostService =
retrofit.create(PostService::class.java)

@Provides
@Singleton
fun provideCommunityPostService(retrofit: Retrofit): CommunityPostService =
retrofit.create(CommunityPostService::class.java)
}
11 changes: 9 additions & 2 deletions app/src/main/java/com/hsLink/hslink/data/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.hsLink.hslink.data.di

import com.hsLink.hslink.data.repositoryimpl.CommunityRepositoryImpl
import com.hsLink.hslink.data.repositoryimpl.DummyRepositoryImpl
import com.hsLink.hslink.data.repositoryimpl.PostRepositoryImpl
import com.hsLink.hslink.data.repositoryimpl.home.PostRepositoryImpl
import com.hsLink.hslink.domain.DummyRepository
import com.hsLink.hslink.domain.repository.PostRepository
import com.hsLink.hslink.domain.repository.community.CommunityRepository
import com.hsLink.hslink.domain.repository.home.PostRepository
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -23,4 +25,9 @@ interface RepositoryModule {
postRepositoryImpl: PostRepositoryImpl,
): PostRepository

@Binds
fun bindsCommunityPostRepository(
communityPostRepositoryImpl: CommunityRepositoryImpl,
): CommunityRepository

}
4 changes: 4 additions & 0 deletions app/src/main/java/com/hsLink/hslink/data/dto/DummyDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.hsLink.hslink.data.dto

class DummyDto {
}
Comment on lines +3 to +4
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

❓ Verification inconclusive

Remove unused empty class or implement with proper DTO properties.

This empty DummyDto class serves no functional purpose. Given the PR's focus on post creation API integration, consider either:

  1. Removing this placeholder class if it's unused
  2. Implementing it with actual data transfer properties if needed

Run the following script to verify whether this class is referenced elsewhere:


🏁 Script executed:

#!/bin/bash
# Description: Check if DummyDto is referenced anywhere in the codebase

# Search for DummyDto usage across the codebase
rg -nP '\bDummyDto\b' -g '!**/DummyDto.kt'

Length of output: 0


Remove the unused DummyDto class.

The class is empty and has no references anywhere in the codebase. It appears to be leftover placeholder code that should be deleted.

🧰 Tools
🪛 detekt (1.23.8)

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

(detekt.empty-blocks.EmptyClassBlock)

🤖 Prompt for AI Agents
In app/src/main/java/com/hsLink/hslink/data/dto/DummyDto.kt around lines 3-4,
remove the unused empty DummyDto class file entirely; delete the file and ensure
no imports or references remain elsewhere (run a quick project-wide search to
confirm) and commit the deletion.

Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
package com.hsLink.hslink.data.dto.request

class PostRequestDto {
}
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class PostRequestDto (
@SerialName("postType")
val postType: String,
@SerialName("title")
val title : String,
@SerialName("body")
val body : String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.hsLink.hslink.data.dto.response

import com.hsLink.hslink.domain.model.community.CommunityPostResponseEntity
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class CommunityPostResponseDto (
@SerialName("postId")
val postId: Int,
)


fun CommunityPostResponseDto.toEntity(): CommunityPostResponseEntity {
return CommunityPostResponseEntity(
postId = this.postId,
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.hsLink.hslink.data.dto.response

import com.hsLink.hslink.domain.model.PostPopularEntity
import com.hsLink.hslink.domain.model.PostPromotionEntity
import com.hsLink.hslink.domain.model.home.PostPopularEntity
import com.hsLink.hslink.domain.model.home.PostPromotionEntity
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

Expand Down
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.request.PostRequestDto
import com.hsLink.hslink.data.dto.response.CommunityPostResponseDto

interface CommunityPostDataSource {
suspend fun createCommunityPost(
request : PostRequestDto
): BaseResponse<CommunityPostResponseDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.hsLink.hslink.data.remote.datasourceimpl

import com.hsLink.hslink.core.network.BaseResponse
import com.hsLink.hslink.data.dto.request.PostRequestDto
import com.hsLink.hslink.data.dto.response.CommunityPostResponseDto
import com.hsLink.hslink.data.remote.datasource.CommunityPostDataSource
import com.hsLink.hslink.data.service.commuunity.CommunityPostService
import javax.inject.Inject

class CommunityPostDataSourceImpl @Inject constructor(
private val communityPostService: CommunityPostService
) : CommunityPostDataSource {
override suspend fun createCommunityPost(
request : PostRequestDto
) : BaseResponse<CommunityPostResponseDto> {
// TODO: Replace dummy token with real access token
return communityPostService.postCommunity(token = "", requestBody = request)
}
Comment on lines +13 to +18
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

Pass the real auth token to the API call

Right now Line 17 hardcodes token = "". The backend requires an authenticated request, so every call will come back 401/403 and the feature can never succeed in any real environment. Please retrieve the access token from the token store (or inject a token provider) and send the correctly prefixed value when calling the service.

-class CommunityPostDataSourceImpl @Inject constructor(
-    private val communityPostService: CommunityPostService
-) : CommunityPostDataSource {
+class CommunityPostDataSourceImpl @Inject constructor(
+    private val communityPostService: CommunityPostService,
+    private val tokenProvider: TokenProvider,
+) : CommunityPostDataSource {
     override suspend fun createCommunityPost(
         request : PostRequestDto
     ) : BaseResponse<CommunityPostResponseDto> {
-        // TODO: Replace dummy token with real access token
-        return communityPostService.postCommunity(token = "", requestBody = request)
+        val accessToken = tokenProvider.requireAccessToken()
+        return communityPostService.postCommunity(
+            token = "Bearer $accessToken",
+            requestBody = request
+        )
     }
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
app/src/main/java/com/hsLink/hslink/data/remote/datasourceimpl/CommunityPostDataSourceImpl.kt
around lines 13 to 18, the API call currently hardcodes token = "" — replace
this with the real access token fetched from your token provider/store and pass
it with the proper Authorization prefix. Inject (or use the existing)
TokenProvider/TokenStore into this data source, call its method to obtain the
access token (await/suspend if required), validate or handle a missing token
(throw or return an appropriate error), and call
communityPostService.postCommunity(token = "Bearer <accessToken>", requestBody =
request). Ensure to propagate errors cleanly if token retrieval fails.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.hsLink.hslink.data.repositoryimpl

import com.hsLink.hslink.data.dto.request.PostRequestDto
import com.hsLink.hslink.data.dto.response.CommunityPostResponseDto
import com.hsLink.hslink.data.remote.datasourceimpl.CommunityPostDataSourceImpl
import com.hsLink.hslink.domain.repository.community.CommunityRepository
import javax.inject.Inject

class CommunityRepositoryImpl @Inject constructor(
private val communityPostDataSourceImpl: CommunityPostDataSourceImpl,
) : CommunityRepository {
override suspend fun createCommunityPost(communityRequestDto: PostRequestDto): Result<CommunityPostResponseDto> = runCatching {
val response = communityPostDataSourceImpl.createCommunityPost(communityRequestDto)
if (response.isSuccess) {
response.result
} else {
throw Exception(response.message)
}
}
Comment on lines +12 to +19
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

Map the response to the domain model before returning

Lines 12-16 still hand out CommunityPostResponseDto. Combined with the interface change above, the domain/presentation layers remain coupled to data-layer DTOs, and there’s also no guard if result comes back null. Please keep the mapping in the data layer: check isSuccess, ensure the payload exists, convert it via toEntity(), and return Result<CommunityPostResponseEntity>.

-    override suspend fun createCommunityPost(communityRequestDto: PostRequestDto): Result<CommunityPostResponseDto> = runCatching {
-        val response = communityPostDataSourceImpl.createCommunityPost(communityRequestDto)
-        if (response.isSuccess) {
-            response.result
-        } else {
-            throw Exception(response.message)
-        }
-    }
+    override suspend fun createCommunityPost(communityRequestDto: PostRequestDto): Result<CommunityPostResponseEntity> =
+        runCatching {
+            val response = communityPostDataSource.createCommunityPost(communityRequestDto)
+            if (!response.isSuccess) {
+                throw IllegalStateException(response.message ?: "Failed to create community post")
+            }
+            val body = response.result ?: throw IllegalStateException("Create community post returned no body")
+            body.toEntity()
+        }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
app/src/main/java/com/hsLink/hslink/data/repositoryimpl/CommunityRepositoryImpl.kt
around lines 12 to 19, the method currently returns the DTO directly and doesn't
guard against a null payload; update the implementation so after calling
communityPostDataSourceImpl.createCommunityPost(...) you check
response.isSuccess, ensure response.result is non-null (throw a meaningful
exception if null), map the DTO to the domain entity via toEntity(), and return
Result.success(mappedEntity); if not successful throw or return Result.failure
with the response.message wrapped as an exception — ensure the repository
signature returns Result<CommunityPostResponseEntity>.

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.hsLink.hslink.data.repositoryimpl
package com.hsLink.hslink.data.repositoryimpl.home

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 com.hsLink.hslink.domain.model.home.PostPopularEntity
import com.hsLink.hslink.domain.model.home.PostPromotionEntity
import com.hsLink.hslink.domain.repository.home.PostRepository
import javax.inject.Inject

class PostRepositoryImpl @Inject constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.hsLink.hslink.data.service.commuunity
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

Fix package name typo.

The package name contains a typo: "commuunity" should be "community" (remove the extra 'u'). This affects the file location and all imports referencing this service.

Apply this fix:

-package com.hsLink.hslink.data.service.commuunity
+package com.hsLink.hslink.data.service.community

Note: You'll also need to move the file from data/service/commuunity/ to data/service/community/ and update all import statements that reference this package.

📝 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
package com.hsLink.hslink.data.service.commuunity
package com.hsLink.hslink.data.service.community
🤖 Prompt for AI Agents
In
app/src/main/java/com/hsLink/hslink/data/service/commuunity/CommunityPostService.kt
around line 1, the package declaration has a typo ("commuunity"); change it to
"community", move the file from data/service/commuunity/ to
data/service/community/, update the package declaration at the top of the file
accordingly, and update every import and any references across the codebase that
point to com.hsLink.hslink.data.service.commuunity to the corrected
com.hsLink.hslink.data.service.community so imports and file paths remain
consistent.


import com.hsLink.hslink.core.network.BaseResponse
import com.hsLink.hslink.data.dto.request.PostRequestDto
import com.hsLink.hslink.data.dto.response.CommunityPostResponseDto
import retrofit2.http.Body
import retrofit2.http.Header
import retrofit2.http.POST


interface CommunityPostService {
@POST("posts")
suspend fun postCommunity(
@Header("Authorization") token: String,
@Body requestBody: PostRequestDto,
): BaseResponse<CommunityPostResponseDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.hsLink.hslink.domain.model.community

data class CommunityPostResponseEntity(
val postId: Int,
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
package com.hsLink.hslink.domain.model

import kotlinx.serialization.SerialName
package com.hsLink.hslink.domain.model.home

data class PostPopularEntity (
val id: Int,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.hsLink.hslink.domain.repository.community

import com.hsLink.hslink.data.dto.request.PostRequestDto
import com.hsLink.hslink.data.dto.response.CommunityPostResponseDto

interface CommunityRepository {
suspend fun createCommunityPost(communityRequestDto: PostRequestDto): Result<CommunityPostResponseDto>
Comment on lines +3 to +7
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

Keep the domain contract free of data-layer DTOs

Line 7 exposes PostRequestDto and CommunityPostResponseDto from the data module directly in the domain interface. That breaks the layering we rely on (domain → data) and forces the rest of the domain/presentation layers to depend on serialization DTOs, making testing harder and risking future regressions whenever the API payload changes. Please keep the contract expressed in domain models (e.g., introduce a CommunityPostRequestEntity and return CommunityPostResponseEntity). That keeps the mapping inside the data layer where it belongs and preserves the intended dependency direction.

-import com.hsLink.hslink.data.dto.request.PostRequestDto
-import com.hsLink.hslink.data.dto.response.CommunityPostResponseDto
+import com.hsLink.hslink.domain.model.community.CommunityPostRequestEntity
+import com.hsLink.hslink.domain.model.community.CommunityPostResponseEntity
@@
-interface CommunityRepository {
-    suspend fun createCommunityPost(communityRequestDto: PostRequestDto): Result<CommunityPostResponseDto>
-}
+interface CommunityRepository {
+    suspend fun createCommunityPost(request: CommunityPostRequestEntity): Result<CommunityPostResponseEntity>
+}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
app/src/main/java/com/hsLink/hslink/domain/repository/community/CommunityRepository.kt
around lines 3 to 7, the domain interface currently references data-layer DTOs
(PostRequestDto, CommunityPostResponseDto); replace those with domain model
types (e.g., CommunityPostRequestEntity and CommunityPostResponseEntity) so the
domain contract depends only on domain types, not data DTOs. Create the new
entities in the domain module, update this interface signature to use them,
remove imports of data DTOs from this file, and then implement mapping inside
the data layer (map domain entities to/from
PostRequestDto/CommunityPostResponseDto) so only the data module knows about
DTOs while keeping the Result return type unchanged.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.hsLink.hslink.domain.repository.home

import com.hsLink.hslink.domain.model.home.PostPopularEntity
import com.hsLink.hslink.domain.model.home.PostPromotionEntity

interface PostRepository {
suspend fun getPopularPost(): Result<List<PostPopularEntity>>
suspend fun getPromotionPost(): Result<List<PostPromotionEntity>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ fun BoardSelectionField(
modifier = Modifier
.fillMaxWidth()
.background(HsLinkTheme.colors.Common)
.padding(horizontal = 16.dp)
) {
BoardType.entries.forEach { board ->
DropdownMenuItem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fun CommunityWriteButton(
.fillMaxWidth()
.background(backColor, shape = RoundedCornerShape(8.dp))
.noRippleClickable(onClick = onClick)
.padding(vertical = 12.dp),
.padding(vertical = 12.dp, horizontal = 100.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.hsLink.hslink.R
Expand Down Expand Up @@ -117,7 +120,12 @@ fun CommunityWritingScreen(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = "게시판 선택",
text = buildAnnotatedString {
append("게시판 선택 ")
withStyle(style = SpanStyle(color = HsLinkTheme.colors.Red500)) {
append("*")
}
},
color = HsLinkTheme.colors.Grey700,
style = HsLinkTheme.typography.title_14Strong
)
Expand All @@ -140,7 +148,12 @@ fun CommunityWritingScreen(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = "제목",
text = buildAnnotatedString {
append("제목 ")
withStyle(style = SpanStyle(color = HsLinkTheme.colors.Red500)) {
append("*")
}
},
color = HsLinkTheme.colors.Grey700,
style = HsLinkTheme.typography.title_14Strong
)
Expand Down Expand Up @@ -170,7 +183,12 @@ fun CommunityWritingScreen(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = "내용",
text = buildAnnotatedString {
append("글 작성 ")
withStyle(style = SpanStyle(color = HsLinkTheme.colors.Red500)) {
append("*")
}
},
color = HsLinkTheme.colors.Grey700,
style = HsLinkTheme.typography.title_14Strong
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.hsLink.hslink.presentation.community.state

import androidx.compose.runtime.Immutable
import com.hsLink.hslink.domain.model.community.CommunityPostResponseEntity

@Immutable
data class CommunityContract (
val isLoading: Boolean = false,
val error: String? = null,
val communityEntity: CommunityPostResponseEntity ? = null
)
Loading