Skip to content

Conversation

@vvan2
Copy link
Member

@vvan2 vvan2 commented Nov 10, 2025

ISSUE

❗ WORK DESCRIPTION

  • module 및 경로 수정
  • 공통 컴포넌트( dialog/text ) 수정
  • data 계층 게시물 작성 API 추가
  • domain 계층 게시물 작성 API 추가
  • icon 및 string 수정 -> bottomNavigation GUI에 맞춰 수정했습니다.
  • community 컴포넌트 수정
  • community 게시물 작성 API 연동
  • home topbar , communityWriteScreen 디자인 수정(디테일 안맞는게 있어서..)

📸 SCREENSHOT

image image

📢 TO REVIEWERS

  • api에 토큰 넣어야 함..

Summary by CodeRabbit

Release Notes

  • New Features

    • Added community post creation functionality with a dedicated writing interface
    • Redesigned bottom navigation bar with updated icons and Korean labels
  • Style

    • Added visual indicators (red asterisks) for required form fields
    • Enhanced bottom bar styling with divider and theme-based colors
    • Updated button and dropdown menu padding for improved spacing
    • Adjusted dialog button typography for better consistency

@vvan2 vvan2 requested a review from dmp100 November 10, 2025 16:37
@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

Walkthrough

This pull request implements community post creation functionality by adding a complete data pipeline from network API through repositories to the presentation layer, reorganizes post-related repositories into a home subdirectory, updates dependency injection configurations, and enhances the UI with Korean labels, updated bottom navigation icons, and dialog styling refinements.

Changes

Cohort / File(s) Summary
Data Transfer Objects
app/src/main/java/com/hsLink/hslink/data/dto/request/PostRequestDto.kt, app/src/main/java/com/hsLink/hslink/data/dto/response/CommunityPostResponseDto.kt, app/src/main/java/com/hsLink/hslink/data/dto/DummyDto.kt, app/src/main/java/com/hsLink/hslink/data/DummyDto.kt
Enhanced PostRequestDto from empty placeholder to serializable data class with three properties; added new CommunityPostResponseDto for API response mapping; relocated DummyDto to dto package.
Network Service & Remote Data Sources
app/src/main/java/com/hsLink/hslink/data/service/commuunity/CommunityPostService.kt, app/src/main/java/com/hsLink/hslink/data/remote/datasource/CommunityPostDataSource.kt, app/src/main/java/com/hsLink/hslink/data/remote/datasourceimpl/CommunityPostDataSourceImpl.kt
Introduced CommunityPostService Retrofit interface with postCommunity endpoint and corresponding data source abstraction/implementation for creating community posts.
Repository Layer & Dependency Injection
app/src/main/java/com/hsLink/hslink/domain/repository/community/CommunityRepository.kt, app/src/main/java/com/hsLink/hslink/data/repositoryimpl/CommunityRepositoryImpl.kt, app/src/main/java/com/hsLink/hslink/data/di/DataSourceModule.kt, app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt, app/src/main/java/com/hsLink/hslink/data/di/RepositoryModule.kt
Added CommunityRepository interface and implementation with DI bindings; updated NetworkModule and RepositoryModule to provide CommunityPostService and repository mappings.
Post Repository Reorganization
app/src/main/java/com/hsLink/hslink/domain/repository/PostRepository.kt, app/src/main/java/com/hsLink/hslink/domain/repository/home/PostRepository.kt, app/src/main/java/com/hsLink/hslink/data/repositoryimpl/home/PostRepositoryImpl.kt
Moved PostRepository interface and PostRepositoryImpl to home subdirectory; removed original at root repository package.
Domain Entity Reorganization
app/src/main/java/com/hsLink/hslink/domain/model/community/CommunityPostResponseEntity.kt, app/src/main/java/com/hsLink/hslink/domain/model/home/PostResponseEntity.kt
Added CommunityPostResponseEntity in new community subdirectory; moved PostResponseEntity to home subdirectory.
Presentation Layer - Community Feature
app/src/main/java/com/hsLink/hslink/presentation/community/state/CommunityContract.kt, app/src/main/java/com/hsLink/hslink/presentation/community/viewmodel/CommunityViewModel.kt, app/src/main/java/com/hsLink/hslink/presentation/community/component/write/BoardSelectionField.kt, app/src/main/java/com/hsLink/hslink/presentation/community/component/write/CommunityWriteButton.kt, app/src/main/java/com/hsLink/hslink/presentation/community/screen/write/CommunityWritingScreen.kt
Introduced CommunityContract immutable state class and CommunityViewModel for post creation; updated UI components with padding adjustments and red asterisk annotations for required fields.
Presentation Layer - Home & Navigation Updates
app/src/main/java/com/hsLink/hslink/presentation/home/state/HomeContract.kt, app/src/main/java/com/hsLink/hslink/presentation/home/viewmodel/HomeViewModel.kt, app/src/main/java/com/hsLink/hslink/presentation/home/screen/HomeScreen.kt, app/src/main/java/com/hsLink/hslink/presentation/main/MainTab.kt, app/src/main/java/com/hsLink/hslink/presentation/main/component/MainBottomBar.kt
Updated import paths to reflect home subdirectory reorganization; changed MainTab icons to specific bottom bar icons; enhanced MainBottomBar with divider, themed colors, and new typography style.
Dialog Component
app/src/main/java/com/hsLink/hslink/core/designsystem/component/HsLinkDialog.kt
Changed button text typography from btm_M to btm_S.
Bottom Navigation Icons
app/src/main/res/drawable/ic_bottombar_home_off.xml, app/src/main/res/drawable/ic_bottombar_home_on.xml, app/src/main/res/drawable/ic_bottombar_search_off.xml, app/src/main/res/drawable/ic_bottombar_search_on.xml, app/src/main/res/drawable/ic_bottombar_community_off.xml, app/src/main/res/drawable/ic_bottombar_community_on.xml, app/src/main/res/drawable/ic_bottombar_mypage_off.xml, app/src/main/res/drawable/ic_bottombar_mypage_on.xml
Added vector drawable resources for bottom navigation with on/off states for home, search, community, and mypage tabs.
Localization
app/src/main/res/values/strings.xml
Updated bottom navigation label strings from English to Korean (home → 홈, search → 한성인 찾기, community → 커뮤니티, mypage → 마이페이지).

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Screen as CommunityWritingScreen
    participant VM as CommunityViewModel
    participant Repo as CommunityRepositoryImpl
    participant DS as CommunityPostDataSourceImpl
    participant Service as CommunityPostService
    participant API as API Server

    User->>Screen: Enter post details (type, title, body)
    User->>Screen: Click create button
    Screen->>VM: createPost(postType, title, body)
    activate VM
    VM->>VM: Build PostRequestDto
    VM->>Repo: createCommunityPost(request)
    activate Repo
    Repo->>DS: createCommunityPost(request)
    activate DS
    DS->>Service: postCommunity(token, request)
    activate Service
    Service->>API: POST /posts
    activate API
    API-->>Service: BaseResponse<CommunityPostResponseDto>
    deactivate API
    Service-->>DS: return response
    deactivate Service
    DS-->>Repo: return BaseResponse
    deactivate DS
    alt Success
        Repo->>Repo: runCatching success path
        Repo-->>VM: Result.success(CommunityPostResponseDto)
    else Failure
        Repo->>Repo: runCatching failure path
        Repo-->>VM: Result.failure(exception)
    end
    deactivate Repo
    VM->>VM: Update _state with result
    deactivate VM
    VM-->>Screen: Emit state update
    Screen->>Screen: Recompose UI with new state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Areas requiring extra attention:

  • CommunityPostDataSourceImpl.kt — Contains a TODO placeholder for token replacement with real access token; verify that the token handling approach aligns with the authentication strategy in the codebase.
  • Package reorganization — Verify that all import statements across the codebase have been properly updated following the move of PostRepository/PostRepositoryImpl to the home subdirectory; check for any missed references.
  • CommunityViewModel.kt — Review the onSuccess/onFailure placeholder implementations in the coroutine to ensure proper state management and error propagation align with the application's error handling patterns.
  • DI Module updates — Confirm that DataSourceModule, NetworkModule, and RepositoryModule changes are consistent and complete; verify no circular dependencies or missing bindings.

Possibly related PRs

  • [setting/#1] 프로젝트 기본세팅 #2: Extends initial project setup by adding community-specific DTOs, services, and repository bindings across the same DI/network/repository layers.
  • [feat/#11] 홈 화면 작업 #13: Modifies Home screen and related UI assets (HomeScreen and home-related drawables/strings) with overlapping changes.
  • [feat/#14] Community UI #15: Overlaps with community UI components and navigation modifications (HsLinkDialog, BoardSelectionField, CommunityWriteButton, CommunityWritingScreen).

Suggested reviewers

  • dmp100

Poem

🐰 A post now flows from screen to server's keep,
Through repos and sources, data runs so deep,
Korean labels dance on tabs so bright,
Red asterisks mark what must be right!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
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.
Out of Scope Changes check ❓ Inconclusive Most changes directly support the post creation API integration. However, the PR includes several peripheral changes (icon/string updates for bottomNavigation, typography style changes in dialog, path reorganization) that extend beyond the core API integration objective. Clarify whether bottomNavigation icon/string updates, dialog component styling, and module path reorganizations are part of issue #22 scope or should be separated into distinct PRs.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title '[feat/#22] 게시물 작성 API 연동' clearly describes the main change - integrating the post creation API feature, matching the primary objective in linked issue #22.
Description check ✅ Passed The PR description addresses all required template sections: ISSUE (closed #22), WORK DESCRIPTION (detailed list of changes), SCREENSHOT (three images provided), and TO REVIEWERS (token note). Description is mostly complete with comprehensive work items.
Linked Issues check ✅ Passed The PR successfully implements the post creation API integration from issue #22 with data layer (CommunityPostDataSource, Service, DTO), domain layer (CommunityRepository, Entity), and presentation layer (ViewModel, UI components) additions. Token handling is noted as incomplete.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#22-post-api

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/src/main/java/com/hsLink/hslink/presentation/main/component/MainBottomBar.kt (1)

50-78: Fix the layout structure for HorizontalDivider.

The HorizontalDivider and Row are both direct children of the Surface, but Surface can only have a single child composable. This will cause a compilation error. Wrap them in a Column to properly stack the divider above the navigation items.

Apply this diff:

         Surface(
             color = Color.White,
         ) {
+            Column {
-            HorizontalDivider(
-                modifier = Modifier.fillMaxWidth(),
-                thickness = 1.dp,
-                color = HsLinkTheme.colors.Grey100,
-            )
-            Row(
-                modifier = modifier
-                    .fillMaxWidth()
-                    .navigationBarsPadding()
-                    .padding(horizontal = 5.dp)
-                    .selectableGroup(),
-                horizontalArrangement = Arrangement.SpaceBetween,
-                verticalAlignment = Alignment.CenterVertically,
-            ) {
-                tabs.forEach { tab ->
-                    MainNavigationBarItem(
-                        selected = tab == currentTab,
-                        tab = tab,
-                        onClick = { onTabSelected(tab) },
-                        modifier = Modifier
-                            .weight(1f)
-                            .padding(vertical = 12.dp),
-                    )
+                HorizontalDivider(
+                    modifier = Modifier.fillMaxWidth(),
+                    thickness = 1.dp,
+                    color = HsLinkTheme.colors.Grey100,
+                )
+                Row(
+                    modifier = modifier
+                        .fillMaxWidth()
+                        .navigationBarsPadding()
+                        .padding(horizontal = 5.dp)
+                        .selectableGroup(),
+                    horizontalArrangement = Arrangement.SpaceBetween,
+                    verticalAlignment = Alignment.CenterVertically,
+                ) {
+                    tabs.forEach { tab ->
+                        MainNavigationBarItem(
+                            selected = tab == currentTab,
+                            tab = tab,
+                            onClick = { onTabSelected(tab) },
+                            modifier = Modifier
+                                .weight(1f)
+                                .padding(vertical = 12.dp),
+                        )
+                    }
                 }
             }
         }
app/src/main/java/com/hsLink/hslink/presentation/community/screen/write/CommunityWritingScreen.kt (1)

257-271: Missing ViewModel integration for post creation in upload dialog.

The upload dialog's onConfirm handler (lines 265-267) only dismisses the dialog and navigates away, without creating the post. The screen requires:

  1. Inject CommunityViewModel via Hilt
  2. Call viewModel.createPost(selectedBoardType.apiValue, title, content) before navigating
  3. Handle loading/success/error states from the ViewModel's state

Currently, users confirm upload but no post is created—critical functionality gap for the API integration feature.

🧹 Nitpick comments (5)
app/src/main/java/com/hsLink/hslink/data/repositoryimpl/home/PostRepositoryImpl.kt (1)

25-29: Fix variable name typo for consistency.

There's a typo in the variable name: respone should be response to match the naming convention used in getPopularPost() (line 15).

Apply this diff to fix the typo:

-        val respone = postDataSourceImpl.getPromotionPost()
-        if (respone.isSuccess) {
-            respone.result.posts.map { it.toEntity() }
+        val response = postDataSourceImpl.getPromotionPost()
+        if (response.isSuccess) {
+            response.result.posts.map { it.toEntity() }
         } else {
-            throw Exception(respone.message)
+            throw Exception(response.message)
         }
app/src/main/java/com/hsLink/hslink/presentation/main/component/MainBottomBar.kt (1)

50-52: Consider using a theme color for the Surface background.

The Surface uses a hardcoded Color.White. For better theme consistency and support for dark mode or alternative themes, consider using a theme color like HsLinkTheme.colors.Background or HsLinkTheme.colors.Surface.

app/src/main/java/com/hsLink/hslink/presentation/community/component/write/CommunityWriteButton.kt (1)

51-51: Verify the large horizontal padding value.

The horizontal padding of 100.dp (200.dp total) is quite substantial and may constrain the button content on smaller screens or narrower layouts. Please confirm this value aligns with the design specifications.

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

20-23: Rename method to reflect remote data source.

The method name bindsPostLocalDataSource is misleading since CommunityPostDataSourceImpl uses a network service (CommunityPostService). Consider renaming to bindsCommunityPostRemoteDataSource or simply bindsCommunityPostDataSource for consistency.

Also note: the existing method at line 16 has a typo (bindePostRemoteDataSource should be bindsPostRemoteDataSource).

Apply this diff:

     @Binds
-    abstract fun bindsPostLocalDataSource(
+    abstract fun bindsCommunityPostDataSource(
         communityPostDataSourceImpl: CommunityPostDataSourceImpl,
     ): CommunityPostDataSource
app/src/main/java/com/hsLink/hslink/data/repositoryimpl/CommunityRepositoryImpl.kt (1)

3-11: Inject the data source interface, not the implementation

Lines 9-10 bind directly to CommunityPostDataSourceImpl, which couples the repository to a concrete class and undermines the interface we just introduced. Switch the dependency to CommunityPostDataSource so you can mock it in tests and keep the DI graph flexible.

-import com.hsLink.hslink.data.remote.datasourceimpl.CommunityPostDataSourceImpl
+import com.hsLink.hslink.data.remote.datasource.CommunityPostDataSource
@@
-class CommunityRepositoryImpl @Inject constructor(
-    private val communityPostDataSourceImpl: CommunityPostDataSourceImpl,
+class CommunityRepositoryImpl @Inject constructor(
+    private val communityPostDataSource: CommunityPostDataSource,
 ) : CommunityRepository {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a7514c and 3566d32.

📒 Files selected for processing (38)
  • app/src/main/java/com/hsLink/hslink/core/designsystem/component/HsLinkDialog.kt (2 hunks)
  • app/src/main/java/com/hsLink/hslink/data/DummyDto.kt (0 hunks)
  • app/src/main/java/com/hsLink/hslink/data/di/DataSourceModule.kt (2 hunks)
  • app/src/main/java/com/hsLink/hslink/data/di/NetworkModule.kt (2 hunks)
  • app/src/main/java/com/hsLink/hslink/data/di/RepositoryModule.kt (2 hunks)
  • app/src/main/java/com/hsLink/hslink/data/dto/DummyDto.kt (1 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/CommunityPostResponseDto.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/CommunityPostDataSource.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/remote/datasourceimpl/CommunityPostDataSourceImpl.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/repositoryimpl/CommunityRepositoryImpl.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/repositoryimpl/home/PostRepositoryImpl.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/data/service/commuunity/CommunityPostService.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/domain/model/community/CommunityPostResponseEntity.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/domain/model/home/PostResponseEntity.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/domain/repository/PostRepository.kt (0 hunks)
  • app/src/main/java/com/hsLink/hslink/domain/repository/community/CommunityRepository.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/domain/repository/home/PostRepository.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/community/component/write/BoardSelectionField.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/community/component/write/CommunityWriteButton.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/community/screen/write/CommunityWritingScreen.kt (4 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/community/state/CommunityContract.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/community/viewmodel/CommunityViewModel.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/home/screen/HomeScreen.kt (1 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/MainTab.kt (1 hunks)
  • app/src/main/java/com/hsLink/hslink/presentation/main/component/MainBottomBar.kt (5 hunks)
  • app/src/main/res/drawable/ic_bottombar_community_off.xml (1 hunks)
  • app/src/main/res/drawable/ic_bottombar_community_on.xml (1 hunks)
  • app/src/main/res/drawable/ic_bottombar_home_off.xml (1 hunks)
  • app/src/main/res/drawable/ic_bottombar_home_on.xml (1 hunks)
  • app/src/main/res/drawable/ic_bottombar_mypage_off.xml (1 hunks)
  • app/src/main/res/drawable/ic_bottombar_mypage_on.xml (1 hunks)
  • app/src/main/res/drawable/ic_bottombar_search_off.xml (1 hunks)
  • app/src/main/res/drawable/ic_bottombar_search_on.xml (1 hunks)
  • app/src/main/res/values/strings.xml (1 hunks)
💤 Files with no reviewable changes (2)
  • app/src/main/java/com/hsLink/hslink/domain/repository/PostRepository.kt
  • app/src/main/java/com/hsLink/hslink/data/DummyDto.kt
🧰 Additional context used
🪛 detekt (1.23.8)
app/src/main/java/com/hsLink/hslink/data/dto/DummyDto.kt

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

(detekt.empty-blocks.EmptyClassBlock)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-test
🔇 Additional comments (28)
app/src/main/java/com/hsLink/hslink/data/repositoryimpl/home/PostRepositoryImpl.kt (1)

1-1: LGTM! Package reorganization looks good.

The refactoring to move this repository into the home subdirectory aligns with the domain structure reorganization. The package declaration and import paths are correctly updated.

Also applies to: 5-7

app/src/main/java/com/hsLink/hslink/core/designsystem/component/HsLinkDialog.kt (1)

71-71: LGTM!

The typography change from btm_M to btm_S consistently reduces button text size for both dismiss and confirm actions, aligning with the dialog styling refinements noted in the PR.

Also applies to: 89-89

app/src/main/res/drawable/ic_bottombar_home_off.xml (1)

1-9: LGTM!

The vector drawable follows standard conventions with appropriate dimensions (28dp) and uses the correct off-state color (#3B3C3F) consistent with the bottom navigation icon set.

app/src/main/res/drawable/ic_bottombar_community_off.xml (1)

1-9: LGTM!

The community off-state icon follows the same conventions as the other bottom bar icons with consistent sizing and color scheme.

app/src/main/res/drawable/ic_bottombar_search_on.xml (1)

1-9: LGTM!

The search on-state icon correctly uses the active color (#0047BB) and maintains consistent dimensions with the rest of the bottom bar icon set.

app/src/main/res/drawable/ic_bottombar_mypage_off.xml (1)

1-9: LGTM!

The mypage off-state icon is consistent with the bottom navigation icon set in terms of dimensions and color scheme.

app/src/main/res/drawable/ic_bottombar_home_on.xml (1)

1-9: LGTM!

The home on-state icon properly uses the active blue color (#0047BB) and pairs well with the home_off variant to provide clear visual feedback for navigation state.

app/src/main/res/drawable/ic_bottombar_search_off.xml (1)

1-9: LGTM!

The search off-state icon completes the search icon pair with appropriate off-state styling, maintaining consistency across the bottom navigation icon set.

app/src/main/java/com/hsLink/hslink/presentation/home/screen/HomeScreen.kt (1)

104-105: LGTM!

The addition of 12.dp start padding to the HsLinkTopBar improves alignment and is consistent with the home topbar design updates noted in the PR.

app/src/main/res/drawable/ic_bottombar_community_on.xml (1)

1-9: Looks good.

The drawable resource is properly structured and uses the same color as the other on-state icons for consistency.

app/src/main/res/values/strings.xml (1)

4-7: LGTM! Good localization.

The Korean labels for bottom navigation items are clear and appropriate for both UI display and accessibility (screen reader) purposes.

app/src/main/java/com/hsLink/hslink/presentation/main/MainTab.kt (1)

21-43: All drawable resources verified as present.

All 8 bottom navigation icon drawable resources referenced in the code are present in the codebase at app/src/main/res/drawable/.

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

104-108: No issues found.

The typography style caption_12Normal is properly defined in app/src/main/java/com/hsLink/hslink/core/designsystem/theme/Type.kt and is consistently used across multiple components in the codebase. The code change is valid.

app/src/main/res/drawable/ic_bottombar_mypage_on.xml (1)

8-8: Verified — no changes needed.

The hardcoded color #0047BB correctly matches DeepBlue500 from the theme and is consistently applied across all bottom bar selected-state icons. No action required.

app/src/main/java/com/hsLink/hslink/presentation/community/component/write/BoardSelectionField.kt (1)

86-86: LGTM!

The horizontal padding adjustment improves the visual spacing of the dropdown menu.

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

7-11: LGTM!

The data source interface is clean and follows the repository pattern correctly for the community post creation flow.

app/src/main/java/com/hsLink/hslink/data/service/commuunity/CommunityPostService.kt (1)

11-17: Token handling is incomplete.

The service correctly accepts an Authorization token parameter. However, based on the PR objectives, authentication token handling is noted as incomplete and needs to be addressed.

Please ensure:

  1. Token is properly retrieved from a secure source (e.g., encrypted SharedPreferences, keystore)
  2. Token refresh logic is implemented if needed
  3. Proper error handling for authentication failures (401/403 responses)
app/src/main/java/com/hsLink/hslink/data/dto/request/PostRequestDto.kt (1)

6-14: LGTM!

The DTO structure is well-defined with appropriate serialization annotations for the post creation request payload.

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

3-4: LGTM!

The import path updates align with the domain model reorganization into the home subdirectory, improving code organization.

app/src/main/java/com/hsLink/hslink/domain/model/home/PostResponseEntity.kt (1)

1-1: LGTM!

The package reorganization improves code structure by grouping home-related domain models. The removal of the unused SerialName import is also a good cleanup.

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

5-5: LGTM!

The import path correctly follows the repository reorganization to the home subdirectory.

app/src/main/java/com/hsLink/hslink/domain/model/community/CommunityPostResponseEntity.kt (1)

3-5: LGTM!

Clean domain entity for the post creation response. The structure is appropriate for the API response mapping flow.

app/src/main/java/com/hsLink/hslink/presentation/community/screen/write/CommunityWritingScreen.kt (1)

22-24: LGTM!

The addition of red asterisks to required field labels enhances UX by clearly indicating mandatory inputs. The implementation using buildAnnotatedString is clean and consistent across all three fields.

Also applies to: 123-128, 151-156, 186-191

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

68-71: LGTM!

The service provider follows the established pattern and is correctly annotated for dependency injection.

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

4-5: LGTM!

The import path updates align with the domain model reorganization, improving code organization by grouping home-related entities under the home subpackage.

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

6-9: LGTM!

Clean repository interface following Kotlin best practices with suspend functions and Result for error handling. The reorganization into the home subpackage improves code organization.

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

3-3: LGTM!

The dependency injection configuration properly wires the new community repository and updates import paths to reflect the reorganized package structure. The binding follows the established pattern.

Also applies to: 5-5, 7-8, 28-31

app/src/main/java/com/hsLink/hslink/presentation/community/viewmodel/CommunityViewModel.kt (1)

15-21: LGTM!

The ViewModel structure follows best practices with Hilt dependency injection and StateFlow for state management.

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.

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

❓ 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.

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

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

@@ -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.

Comment on lines +3 to +7
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>
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.

Comment on lines +23 to +38
fun createPost(postType: String, title: String, body: String) {
viewModelScope.launch {
val request = PostRequestDto(
postType = postType,
title = title,
body = body
)
repository.createCommunityPost(request)
.onSuccess {
// Handle success
}
.onFailure {
// Handle failure
}
}
}
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

Implement state management for post creation.

The createPost function has placeholder handlers that don't update UI state, resulting in no user feedback. Essential improvements needed:

  1. Loading state: Set _state.value = _state.value.copy(isLoading = true) before the call
  2. Success handling: Update state, possibly emit a success event, enable navigation
  3. Error handling: Update _state.value = _state.value.copy(error = it.message)
  4. Final cleanup: Reset loading state in both paths

Without these updates, users receive no feedback about post creation success or failure.

Note: Token authentication is acknowledged as missing per PR objectives.

Example implementation:

 fun createPost(postType: String, title: String, body: String) {
     viewModelScope.launch {
+        _state.value = _state.value.copy(isLoading = true)
         val request = PostRequestDto(
             postType = postType,
             title = title,
             body = body
         )
         repository.createCommunityPost(request)
             .onSuccess {
-                // Handle success
+                _state.value = _state.value.copy(
+                    isLoading = false,
+                    error = null
+                )
+                // Navigate or show success message
             }
             .onFailure {
-                // Handle failure
+                _state.value = _state.value.copy(
+                    isLoading = false,
+                    error = it.message ?: "Post creation failed"
+                )
             }
     }
 }

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

🤖 Prompt for AI Agents
In
app/src/main/java/com/hsLink/hslink/presentation/community/viewmodel/CommunityViewModel.kt
around lines 23 to 38, the createPost function currently has placeholder
success/failure handlers and does not update UI state; before calling
repository.createCommunityPost set the loading flag like _state.value =
_state.value.copy(isLoading = true), onSuccess update the state to reflect
success (e.g., clear error, set any success flag or emit a one-shot
navigation/event), onFailure set _state.value = _state.value.copy(error =
it.message) (and preserve any error details), and ensure you reset loading in a
finally-style path (or after both handlers) so _state.value =
_state.value.copy(isLoading = false) always runs.

@vvan2 vvan2 merged commit 9855ed4 into develop Nov 10, 2025
3 checks passed
@vvan2 vvan2 deleted the feat/#22-post-api branch November 10, 2025 17:55
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