Skip to content

Conversation

@Hrepay
Copy link
Collaborator

@Hrepay Hrepay commented Jan 25, 2026

🔗 연결된 이슈

Resolved #53

✨ 주요 작업사항

이번 PR의 핵심 변경사항을 알려주세요!

  • DI/아키텍처 개선

    • ProfileDIContainer 신규 추가: 프로필 기능 전용 DI 컨테이너로 API 서비스→레포→유스케이스→VM→View까지 구성해 모듈화/테스트 용이성 강화.
    • AppDIContainer, FeedDIContainer 정리: ProfileDIContainer 생성/제공 연결, 네비게이션 라우터 주입 흐름을 factory/container 기준으로 일관되게 정돈.

  • API 연동 & 데이터소스 리팩터링

    • 댓글/피드/검색에서 Mock DataSource 제거 → 실제 API 기반 DataSource로 교체, 백엔드 통신 가능 상태로 전환.
    • FeedRepositoryImpl 개선: DataSource 외에 HistoryAPIService도 주입받도록 변경 → 피드 관련 데이터 관리/확장성 향상.

  • 기능 확장 (댓글/피드)

    • 댓글 답글 기능 강화: 답글 조회/작성 유스케이스 추가 및 댓글 흐름에 통합.
    • 피드 기능 확장: 좋아요 토글, 의류 태그 조회 등 유스케이스 추가하고 VM 의존성에 반영.
    • 피드/댓글 VM Factory & View 초기화도 신규 의존성과 컨테이너 구조에 맞게 수정.

  • 옷장(Closet) & 데이터 모델링

    • ProductItem 개선: imageName뿐 아니라 imageUrl도 지원하도록 확장, 초기화 유연화.
    • DefaultClothDataSource 리팩터: API에서 실제 의류 아이템을 조회하도록 변경(목업 제거), 필터링/매핑 지원.
    • ClothDetailResult 확장: seasons(계절) 데이터 포함하도록 API 매핑 강화 → 계절 정보 표시/처리 정확도 향상.
    • ClothDetailViewModel: API 시즌 데이터가 있으면 우선 사용하도록 변경.

  • UI/기타

    • CustomAIRecommendationView 썸네일 영역: 가로 스크롤로 UX 개선.
    • TextLiteral의 작업 상황 라벨 문구 오타/표현 수정.
    • SplashViewModel자동 로그인 로직 임시 재활성화(개발 진행 목적).

🔍 리뷰어에게 (선택)

코드 리뷰 시 특별히 확인했으면 하는 부분이나, 의견을 묻고 싶은 내용을 적어주세요!

  • 계속해서 3차로 API 연결해 나갈 계획입니다.

Hrepay added 29 commits January 25, 2026 17:34
- 피드 목록 조회 API 구현
- 히드 상세 조회 API 구현 및 UI 추가
- UseCase 파일 생성
- Repository 확장
- ViewModel 수정
- Comment 모델에 API 응답 매핑 메서드 추가
- CommentRepository에 대댓글 메서드 추가
- DefaultCommentDataSource 구현 (CodiveAuthMiddleware 포함)
  - 댓글 조회/작성: GET, POST /comments
  - 대댓글 조회/작성: GET, POST /comments/{commentId}/replies
- CommentRepositoryImpl에 대댓글 구현 추가
- FetchRepliesUseCase, PostReplyUseCase 생성
- CommentViewModel에 대댓글 관련 상태 추가
  - replyingToCommentId, currentReplyText
- reloadComments(), reloadReplies() 메서드로 실시간 업데이트
- setReplyingTo(), cancelReply(), postReply() 메서드 구현
- CommentRow에 viewModel 주입으로 대댓글 기능 활성화
- isMine일 때 '(작성자)' 표시
- 대댓글 입력 모드 시 댓글 미리보기 표시
- FeedDetailView에 CommentView 바텀시트 연결
- CommentDIContainer에서 DefaultCommentDataSource 사용
- FeedDIContainer에 CommentDIContainer 통합
- TextLiteral의 situationWork 문자열을 Constants와 일치시킴 ("출근복" -> "출근룩")
- SituationConstants에 getIds() 메서드 추가로 StyleConstants와 동일한 인터페이스 제공
- FeedView에서 상단 카테고리 선택 시 StyleConstants를 사용하여 스타일 ID로 변환
- FeedFilterBottomSheet의 필터 적용 시 StyleConstants/SituationConstants를 사용하여 ID 배열로 변환
- 선택된 필터가 없을 때 nil 처리로 전체 피드 조회 가능
- selectedCategory를 String에서 Set<String>으로 변경하여 여러 개 선택 지원
- FeedFilterBar에서 다중 선택 가능하도록 로직 수정
- 바텀시트에서 선택한 스타일이 상단 카테고리에도 자동으로 표시됨
- 필터 초기화 시 selectedCategory.removeAll() 사용
- FeedView와 FeedFilterBottomSheet의 스타일 순서 통일
- sortedCategories computed property 추가로 선택된 항목을 최우선으로 앞에 배치
- 비선택 항목들은 원래 순서대로 뒤에 배치
- FeedFilterBar에 정렬된 배열 전달
- Domain 계층 추가:
  * ProfileRepository protocol
  * FetchMyProfileUseCase / DefaultFetchMyProfileUseCase
  * FetchFollowsUseCase / DefaultFetchFollowsUseCase
  * ProfileEntity (도메인 모델)

- Data 계층 확충:
  * ProfileDataSource - API 호출 추상화
  * ProfileRepositoryImpl - Repository 구현
  * 의존성 체인: Repository → DataSource → APIService

- ProfileDIContainer 생성:
  * 모든 뷰 생성 메서드 제공
  * 의존성 주입 관리

- ViewModel 개선:
  * ProfileViewModel: APIService → FetchMyProfileUseCase
  * FollowListViewModel: APIService → FetchFollowsUseCase
  * 모든 ViewModel이 DIContainer에서 주입됨

- View 구조 정리:
  * ProfileView, FollowListView, ProfileSettingView, OtherProfileView
  * 모두 DIContainer 주입 방식으로 변경

- 라우팅 일관성 확보:
  * MainTabView에서 profileDIContainer 사용
  * FeedViewFactory에서 profileDIContainer.makeOtherProfileViewModel() 사용
  * 모든 Profile 관련 라우팅이 DIContainer 경유
@Hrepay Hrepay requested a review from taebin2 January 25, 2026 08:37
@Hrepay Hrepay requested a review from Funital January 25, 2026 08:37
@Hrepay Hrepay self-assigned this Jan 25, 2026
@Hrepay Hrepay added the 🛠️ Fix 버그를 수정하거나 문제를 해결하는 실제 개발 작업 label Jan 25, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @Hrepay, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 Codive 앱의 핵심 백엔드 API 연동 2차 구현을 목표로 합니다. 주요 기능 영역인 피드, 댓글, 검색, 프로필, 옷장 등에 실제 API를 연결하고, 이에 맞춰 앱의 DI(Dependency Injection) 아키텍처를 개선하며 데이터 모델링을 확장합니다. 사용자 경험을 향상시키기 위한 UI 개선과 함께, 향후 기능 확장을 위한 기반을 마련하는 데 중점을 두었습니다.

Highlights

  • DI/아키텍처 개선: 프로필 기능 전용 DI 컨테이너인 ProfileDIContainer를 신규 추가하여 API 서비스부터 View까지 모듈화 및 테스트 용이성을 강화했습니다. 또한, AppDIContainerFeedDIContainer를 정리하여 ProfileDIContainer 생성 및 제공을 연결하고, 내비게이션 라우터 주입 흐름을 일관되게 정돈했습니다.
  • API 연동 및 데이터소스 리팩터링: 댓글, 피드, 검색 기능에서 Mock DataSource를 제거하고 실제 API 기반 DataSource로 교체하여 백엔드 통신이 가능하도록 전환했습니다. FeedRepositoryImpl에는 HistoryAPIService를 주입받도록 변경하여 피드 관련 데이터 관리 및 확장성을 향상시켰습니다.
  • 기능 확장 (댓글/피드): 댓글에 답글 조회 및 작성 유스케이스를 추가하고 댓글 흐름에 통합했습니다. 피드 기능에는 좋아요 토글, 의류 태그 조회 등 새로운 유스케이스를 추가하고 ViewModel 의존성에 반영했습니다. 피드/댓글 ViewModel Factory 및 View 초기화도 신규 의존성과 컨테이너 구조에 맞게 수정되었습니다.
  • 옷장(Closet) 및 데이터 모델링: ProductItemimageUrl 필드를 추가하여 초기화 유연성을 높였습니다. DefaultClothDataSource는 API에서 실제 의류 아이템을 조회하도록 리팩터링되었고, ClothDetailResultseasons 데이터를 포함하도록 확장되었습니다. ClothDetailViewModel은 API 시즌 데이터를 우선 사용하도록 변경되었습니다.
  • UI/기타 개선: CustomAIRecommendationView의 썸네일 영역에 가로 스크롤을 추가하여 UX를 개선했습니다. TextLiteral의 '출근복' 오타를 '출근룩'으로 수정했으며, SplashViewModel의 자동 로그인 로직을 개발 진행을 위해 임시로 재활성화했습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


코드의 강물 흐르네, API 다리 놓으니, 기능의 꽃 피어나라.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 PR은 Mock 데이터를 실제 API로 교체하고 프로필 관련 기능을 모듈화하는 등 대규모 리팩터링과 기능 구현이 포함되어 있네요. 전반적으로 DI 컨테이너를 활용한 구조 개선과 API 연동이 깔끔하게 잘 이루어졌습니다. 특히 TaskGroup을 사용한 병렬 처리 등 성능을 고려한 점이 인상적입니다. 몇 가지 아쉬운 점(데이터소스의 반환 값, DateFormatter 성능, View의 결합도)에 대해 코멘트를 남겼으니 확인해보시면 좋겠습니다. 다음 3차 API 구현도 기대됩니다!

Comment on lines +98 to +109
// 새로운 댓글 객체 생성 (추가 정보는 필요하면 별도로 조회)
let currentUser = User(id: "", nickname: "현재 사용자", profileImageUrl: nil)
let newComment = Comment(
id: Int(commentId),
content: content,
author: currentUser,
isMine: true,
hasReplies: false,
replies: []
)

return newComment

Choose a reason for hiding this comment

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

medium

postComment 메서드에서 댓글 생성 후 currentUser 정보를 하드코딩하여 Comment 객체를 반환하고 있습니다. ViewModel에서 목록을 새로고침하여 이 문제를 해결하고 있지만, 이는 비효율적이며 DataSource의 메서드가 일시적으로 부정확한 데이터를 반환하게 만듭니다. API가 생성된 댓글 객체 전체를 반환하거나, 이 메서드가 Void를 반환하여 호출 측에서 데이터 리프레시를 명확히 책임지도록 하는 것이 더 나은 설계입니다. postReply 메서드(170-181 라인)에도 동일한 문제가 있습니다.

Comment on lines +153 to +154
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withFullDate, .withDashSeparatorInDate]

Choose a reason for hiding this comment

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

medium

toDomain 메서드가 호출될 때마다 ISO8601DateFormatter 인스턴스가 새로 생성됩니다. DateFormatter 생성은 비용이 큰 작업이므로, extension HistoryDetailDTO 내부에 static let 프로퍼티로 만들어 재사용하는 것이 성능에 유리합니다.

private static let iso8601DateFormatter: ISO8601DateFormatter = {
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = [.withFullDate, .withDashSeparatorInDate]
    return formatter
}()

위와 같이 선언 후 Self.iso8601DateFormatter로 접근하여 사용하시는 것을 권장합니다.

let comment: Comment
var isReply: Bool = false

@ObservedObject var viewModel: CommentViewModel

Choose a reason for hiding this comment

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

medium

CommentRow 뷰가 CommentViewModel 전체에 의존하고 있습니다. 이는 CommentRowCommentViewModel 간의 강한 결합(tight coupling)을 만들어 재사용성을 낮추고, 독립적인 테스트 및 SwiftUI 프리뷰를 어렵게 만듭니다. 필요한 데이터와 액션 클로저(예: onReplyTap: (Int) -> Void, onFetchRepliesTap: (Int) -> Void)를 파라미터로 전달하는 방식이 더 유연한 구조입니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ Fix 버그를 수정하거나 문제를 해결하는 실제 개발 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] API 2차 구현

2 participants