Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
Walkthrough관리자 할당 기능과 좋아요·북마크 메타데이터 조회를 위해 Reaction/User gRPC 클라이언트가 통합되고, 생성·수정 시 관리자 검증·저장 로직이 추가되며 조회 응답에 liked/bookmarked/managers 정보가 포함되도록 확장됩니다. (50단어 이내) Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant GroupCardsetController
participant CardsetUseCase
participant CardsetRepository
participant CardsetManagerRepository
participant ReactionGrpcClient
participant UserGrpcClient
Client->>GroupCardsetController: GET /groups/:groupId/card-sets (X-USER-ID)
GroupCardsetController->>CardsetUseCase: findByGroupId(groupId, userId)
CardsetUseCase->>CardsetRepository: findByGroupId(groupId)
CardsetRepository-->>CardsetUseCase: Cardset[]
CardsetUseCase->>CardsetManagerRepository: findByCardSetIds(cardsetIds)
CardsetManagerRepository-->>CardsetUseCase: CardsetManager[]
CardsetUseCase->>UserGrpcClient: getUsersByIds(managerIds)
UserGrpcClient-->>CardsetUseCase: UserInfo[]
CardsetUseCase->>ReactionGrpcClient: areLiked(cardsetIds, userId) / areBookmarked(cardsetIds, userId)
ReactionGrpcClient-->>CardsetUseCase: Map<id,liked> / Map<id,bookmarked>
CardsetUseCase-->>GroupCardsetController: enriched CardsetListItemResponse[]
GroupCardsetController-->>Client: ApiResponse<CardsetListItemResponse[]>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/cardset/infrastructure/http/card.controller.ts (1)
1-23:⚠️ Potential issue | 🟠 Major주석 처리 상태와 불일치한 import/DI로 CI가 깨집니다.
Line 1-23, 28의 심볼들이 현재 활성 코드에서 사용되지 않아 ESLint 실패(
Get is defined but never used, Line 3)가 발생했습니다. 임시 비활성화 상태를 유지할 거면 import와 constructor를 같이 정리해 CI를 통과시켜야 합니다.임시 비활성화 상태 기준 최소 정리안
import { - Controller, - Get, - Post, - Put, - Delete, - Body, - Param, - Headers, + Controller, } from '@nestjs/common'; import { - ApiTags, - ApiOperation, - ApiResponse as SwaggerApiResponse, - ApiParam, + ApiTags, } from '@nestjs/swagger'; -import { CardUseCase } from '../../application/card.use-case'; -import { CreateCardRequest } from '../../application/dto/request/create-card.request'; -import { UpdateCardRequest } from '../../application/dto/request/update-card.request'; -import { ReorderCardsRequest } from '../../application/dto/request/reorder-cards.request'; -import { CardCreateResponse } from '../../application/dto/response/card-create.response'; -import { CardResponse } from '../../application/dto/response/card.response'; -import { ApiResponse } from '../../../shared/common/api-response'; `@ApiTags`('cards') `@Controller`('cards') export class CardController { - constructor(private readonly cardUseCase: CardUseCase) { } + constructor() {}Also applies to: 28-28
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/infrastructure/http/card.controller.ts` around lines 1 - 23, The file has unused Nest/Swagger imports (Get, Post, Put, Delete, Body, Param, Headers, ApiOperation, ApiResponse/SwaggerApiResponse, ApiParam) and an unused injected dependency CardUseCase (constructor) causing ESLint errors; either restore the commented controller methods that reference these symbols or remove the unused imports and the CardUseCase constructor parameter so the import/DI surface matches active code—specifically update imports at the top (remove the unused symbols) and update the class constructor that injects CardUseCase (remove the injection if no methods use it) to eliminate the "defined but never used" diagnostics.src/cardset/infrastructure/http/cardset.controller.ts (1)
134-134:⚠️ Potential issue | 🟡 Minor
update메서드의 응답이 기본값을 반환합니다.
update메서드는CardsetResponse.from(cardset)만 호출하여liked,bookmarked,managers필드가 항상 기본값(false, false, [])으로 설정됩니다. 반면findAll과findOne은 실제 값을 전달하고 있습니다. 응답 일관성을 위해update메서드도 동일하게 추가 매개변수를 전달해야 합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/infrastructure/http/cardset.controller.ts` at line 134, The update method currently returns ApiResponse.success(CardsetResponse.from(cardset)) which causes liked, bookmarked and managers to remain defaulted; update the return in the update handler to call CardsetResponse.from with the same extra arguments used by findAll/findOne (pass the cardset's liked, bookmarked and managers values or the same parameter signature those calls use) so the response includes actual liked/bookmarked booleans and managers array and matches the other endpoints' shape.
🧹 Nitpick comments (10)
src/cardset/infrastructure/http/cardset.controller.ts (1)
150-170: 주석 처리된 코드를 제거해 주세요.더 이상 사용하지 않는
updateCardCount엔드포인트가 주석 처리되어 있습니다. 코드베이스를 깔끔하게 유지하기 위해 주석 처리된 코드는 제거하는 것이 좋습니다. 필요 시 Git 히스토리에서 복구할 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/infrastructure/http/cardset.controller.ts` around lines 150 - 170, Remove the entire commented-out updateCardCount endpoint block (the commented async function named updateCardCount and its related decorators and Swagger comments) from the cardset controller file; ensure no references remain to updateCardCount in the class and verify imports/unused symbols are adjusted if necessary so the controller compiles cleanly after deletion.src/cardset/application/dto/response/cardset-list-item.response.ts (2)
64-71: Manager 매핑 로직이 중복됩니다.이 매핑 로직이
CardsetResponse.from(lines 79-86)에도 동일하게 존재합니다.ManagerInfoResponse에 정적 팩토리 메서드를 추가하여 중복을 제거하는 것을 고려해 주세요.♻️ 제안하는 리팩토링
manager-info.response.ts에 팩토리 메서드 추가:static from(userInfo: UserInfo): ManagerInfoResponse { const info = new ManagerInfoResponse(); info.id = userInfo.id; info.email = userInfo.email; info.nickname = userInfo.nickname; info.profileImageUrl = userInfo.profileImageUrl; return info; }그 후 사용처에서:
-res.managers = managers.map((m) => { - const info = new ManagerInfoResponse(); - info.id = m.id; - info.email = m.email; - info.nickname = m.nickname; - info.profileImageUrl = m.profileImageUrl; - return info; -}); +res.managers = managers.map(ManagerInfoResponse.from);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/application/dto/response/cardset-list-item.response.ts` around lines 64 - 71, Add a static factory method on ManagerInfoResponse (e.g., static from(userInfo: UserInfo): ManagerInfoResponse) that constructs and returns a ManagerInfoResponse from a UserInfo, then replace the duplicated mapping code in both the res.managers assignment and inside CardsetResponse.from to call ManagerInfoResponse.from(m) instead of manually copying fields; this removes the duplication and centralizes the mapping logic.
4-4: Application 레이어에서 Infrastructure 레이어 타입을 직접 참조합니다.
UserInfo타입을 Infrastructure 레이어(grpc/user-grpc.client.ts)에서 직접 import하고 있습니다. Clean Architecture 원칙에 따르면 Application 레이어는 Infrastructure 레이어에 의존하지 않아야 합니다.
UserInfo인터페이스를 Application 또는 Domain 레이어로 이동하는 것을 고려해 주세요.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/application/dto/response/cardset-list-item.response.ts` at line 4, The file cardset-list-item.response.ts imports the Infrastructure type UserInfo directly, violating layer dependencies; create a new UserInfo interface (or shared DTO) inside the Application or Domain layer (e.g., in application/dto or domain/model) that matches the needed shape, update cardset-list-item.response.ts to import that application/domain UserInfo instead of ../../../infrastructure/grpc/user-grpc.client, and remove the infrastructure import so the Application layer no longer depends on Infrastructure; ensure any other files using the original Infrastructure UserInfo are updated to use the new Application/Domain type or map between types where necessary.src/cardset/application/dto/response/cardset.response.ts (1)
4-5: Application 레이어에서 Infrastructure 레이어 타입을 참조합니다.
CardsetListItemResponse와 동일한 이슈입니다.UserInfo타입이 Infrastructure 레이어에서 import되고 있습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/application/dto/response/cardset.response.ts` around lines 4 - 5, Cardset.application is importing the infrastructure type UserInfo directly; create or use an application-layer DTO instead and replace the infra import. Define a new application DTO (e.g., UserInfoResponse or move an existing ManagerInfoResponse usage) in the application/dto folder, update cardset.response.ts to import that application-level type and ensure any references in CardsetListItemResponse and ManagerInfoResponse use the new DTO so the application layer no longer depends on infrastructure.src/proto/reaction.proto (1)
1-2: Buf 린트 경고: 패키지 디렉토리 불일치.Static analysis에서 보고된 대로,
reaction패키지의 파일은reaction/디렉토리에 위치해야 하지만 현재src/proto/에 있습니다. 프로젝트의 proto 파일 구성 규칙에 따라 이를 무시하거나, 디렉토리 구조를 조정해 주세요.기존
user.proto도 같은 디렉토리에 있다면 일관성 있게 유지하는 것이 좋습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/proto/reaction.proto` around lines 1 - 2, The proto package/location mismatch: reaction.proto declares package "reaction" but lives under src/proto/, causing buf lint warnings; fix by moving reaction.proto into a matching directory (e.g., create/update reaction/ and place reaction.proto there) or alternatively change the declared package in reaction.proto to match the current directory layout; reference the file name reaction.proto and the package declaration "package reaction" (and ensure any related files like user.proto follow the same convention) so imports and buf config remain consistent.src/cardset/infrastructure/grpc/reaction-grpc.client.ts (1)
63-75: 빈 배열에 대한 조기 반환 최적화가 없습니다.
UserGrpcClient.getUsersByIds는 빈 배열 입력 시 조기 반환하지만,areLiked와areBookmarked는 빈cardSetIds배열에 대해서도 불필요한 gRPC 호출을 수행합니다.⚡ 최적화 제안
async areLiked( cardSetIds: number[], userId: number, ): Promise<Map<number, boolean>> { + if (cardSetIds.length === 0) return new Map(); const result = await firstValueFrom( this.reactionService.areLiked({
areBookmarked에도 동일하게 적용하세요.Also applies to: 77-89
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/infrastructure/grpc/reaction-grpc.client.ts` around lines 63 - 75, The methods areLiked and areBookmarked should avoid making a gRPC call when cardSetIds is empty; add an early return that returns an empty Map<number, boolean> immediately if the input array has length 0, instead of calling reactionService.areLiked/areBookmarked and converting result.results; update the implementations for areLiked and areBookmarked to check cardSetIds.length === 0 and return new Map() early.src/cardset/application/cardset.use-case.ts (4)
144-148: N+1 gRPC 호출 문제: 가시성 검증
findAll에서 각 카드셋마다isUserInGroupgRPC 호출이 발생합니다. 카드셋 수가 많아지면 심각한 성능 문제가 발생할 수 있습니다.사용자가 속한 그룹 ID 목록을 한 번에 가져온 후 메모리에서 필터링하는 방식을 고려해 보세요.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/application/cardset.use-case.ts` around lines 144 - 148, The loop in findAll causes an N+1 gRPC call by invoking groupGrpcClient.isUserInGroup per cardset; instead, fetch the user's group IDs once (e.g., call groupGrpcClient.getUserGroupIds(userId) or similar) and then replace the per-cardset check with an in-memory membership test: keep the Visibility.PUBLIC check and for non-public use a set/Map lookup against the returned group IDs when filtering cardsets into visibleCardsets; update references to isUserInGroup, findAll, cardsets, visibleCardsets, Visibility and userId accordingly.
173-176: N+1 gRPC 호출 문제: 이미지 URL 조회루프 내에서 각 카드셋마다
getImageUrlgRPC 호출이 발생합니다.findByGroupId(line 277-280)에서도 동일한 패턴이 있습니다.
ImageGrpcClient에 배치 조회 메서드가 있다면 이를 활용하여 최적화할 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/application/cardset.use-case.ts` around lines 173 - 176, The loop over visibleCardsets is causing N+1 gRPC calls by calling imageGrpcClient.getImageUrl per cardset; instead collect the ids (or imageRefIds) for cardsets that need images, call a batch method on ImageGrpcClient (e.g., getImageUrls or add one if missing) to retrieve all URLs in one request, then map the returned URLs back to each cardset (falling back to defaultImageUrl) before returning; apply the same batching pattern to the similar code path in findByGroupId to eliminate the per-item gRPC calls.
63-65: N+1 gRPC 호출 문제: 관리자 유효성 검증추가 관리자 ID마다
checkUserInGroupgRPC 호출이 순차적으로 발생합니다. 관리자 수가 많아지면 성능 저하가 발생할 수 있습니다.그룹 서비스에 배치 멤버십 확인 API가 있다면 이를 활용하는 것이 좋습니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/application/cardset.use-case.ts` around lines 63 - 65, The current sequential loop over additionalManagerIds calling this.groupGrpcClient.checkUserInGroup causes N+1 gRPC calls; replace it with a single batched membership check (e.g., call this.groupGrpcClient.checkUsersInGroup(dto.groupId, additionalManagerIds) or the group service's batch membership API) and validate returned results, or if no batch API exists at the moment, execute the checks in parallel with Promise.all over additionalManagerIds to avoid serial calls; update any error handling/response logic in the surrounding method (the block using additionalManagerIds and checkUserInGroup) to handle batch responses and missing/invalid manager IDs accordingly.
320-331: 순차적 삭제/저장 작업 - 배치 최적화 가능기존 관리자를 하나씩 삭제하고 새 관리자를 하나씩 저장합니다. 관리자 수가 많아지면 성능 저하가 발생할 수 있습니다.
리포지토리에
deleteByCardSetId및saveAll같은 배치 메서드를 추가하면 성능을 개선할 수 있습니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/cardset/application/cardset.use-case.ts` around lines 320 - 331, The current implementation in cardset.use-case.ts iterates over existing managers (cardsetManagerRepository.findAllByCardSetId) deleting each via delete(m.id) and then saves new managers one-by-one (CardsetManager.create + cardsetManagerRepository.save), which is inefficient for large sets; introduce and use batch repository methods (e.g., cardsetManagerRepository.deleteByCardSetId(cardSetId) to remove all existing managers in one operation and cardsetManagerRepository.saveAll(cardsetManagerArray) to persist new managers in a single call), build the array of CardsetManager instances from newManagerIds before calling saveAll, and update the use-case to call these new batch methods instead of the per-item delete/save loop.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/cardset/application/cardset.use-case.ts`:
- Around line 305-335: The call to the external service
imageGrpcClient.changeImage is currently inside this.dataSource.transaction
which can cause inconsistent state if the DB transaction rolls back; move the
external call out of the transaction by performing the DB update first (the call
that ultimately runs this.cardsetRepository.update inside the transaction) and
then invoking imageGrpcClient.changeImage after the transaction
resolves/commits, or, if you must call it before, implement a compensation step
(e.g., call a revert method on imageGrpcClient) when the transaction fails;
update the flow around this.dataSource.transaction, imageGrpcClient.changeImage,
and cardsetRepository.update (and add a compensation call if available) to
ensure external changes are only applied after successful DB commit or are
rolled back on failure.
In `@src/cardset/infrastructure/grpc/reaction-grpc.client.ts`:
- Around line 28-39: The ReactionGrpcClient can throw if reactionService is
accessed before onModuleInit runs; change the pattern to lazily initialize and
guard access by making reactionService optional and adding a helper that returns
this.reactionService ??=
this.client.getService<ReactionService>('ReactionService'), then call that
helper from every public method instead of referencing this.reactionService
directly (or alternatively initialize in the constructor). Update the
ReactionGrpcClient class, the onModuleInit method, and all usages of
reactionService to use the new getter/initializer to ensure safe access.
In `@src/cardset/infrastructure/grpc/user-grpc.client.ts`:
- Around line 19-29: The UserGrpcClient has a race where userService is set in
onModuleInit but methods like getUsersByIds may be called earlier; update the
class to guard against uninitialized userService by either lazily resolving the
service from client inside getUsersByIds (or a private getter) or by throwing a
clear error when userService is falsy; specifically reference UserGrpcClient,
onModuleInit, userService and getUsersByIds and implement one of: (a) if
(!this.userService) this.userService =
this.client.getService<UserQueryService>('UserQueryService') at method entry, or
(b) throw new Error('UserGrpcClient not initialized') when userService is
undefined.
In `@src/cardset/infrastructure/http/card.controller.ts`:
- Around line 30-117: The CardController class has all route handlers commented
out but remains registered in the module via CardController, causing a breaking
404; either restore the routes in card.controller.ts (uncomment and ensure
methods like create, findByCardsetId, findOne, reorderCards, update, remove are
implemented) or remove CardController from the module's controllers array (the
registration referencing CardController) so it's not exposed; update related
documentation/migration notes accordingly to reflect the removal or
reinstatement.
In `@src/cardset/infrastructure/http/group-cardset.controller.ts`:
- Around line 30-37: In findByGroupId (controller method using
`@Headers`('X-USER-ID') userId and `@Param`('groupId') groupId) validate the
parseInt results before calling cardsetUseCase.findByGroupId: either apply
NestJS ParseIntPipe on the route parameter and a custom pipe or DTO for the
header, or manually parse both values to integers, check isNaN(parsedUserId) ||
isNaN(parsedGroupId) and throw a BadRequestException with a clear message if
invalid, then pass the safe parsed integers to cardsetUseCase.findByGroupId.
---
Outside diff comments:
In `@src/cardset/infrastructure/http/card.controller.ts`:
- Around line 1-23: The file has unused Nest/Swagger imports (Get, Post, Put,
Delete, Body, Param, Headers, ApiOperation, ApiResponse/SwaggerApiResponse,
ApiParam) and an unused injected dependency CardUseCase (constructor) causing
ESLint errors; either restore the commented controller methods that reference
these symbols or remove the unused imports and the CardUseCase constructor
parameter so the import/DI surface matches active code—specifically update
imports at the top (remove the unused symbols) and update the class constructor
that injects CardUseCase (remove the injection if no methods use it) to
eliminate the "defined but never used" diagnostics.
In `@src/cardset/infrastructure/http/cardset.controller.ts`:
- Line 134: The update method currently returns
ApiResponse.success(CardsetResponse.from(cardset)) which causes liked,
bookmarked and managers to remain defaulted; update the return in the update
handler to call CardsetResponse.from with the same extra arguments used by
findAll/findOne (pass the cardset's liked, bookmarked and managers values or the
same parameter signature those calls use) so the response includes actual
liked/bookmarked booleans and managers array and matches the other endpoints'
shape.
---
Nitpick comments:
In `@src/cardset/application/cardset.use-case.ts`:
- Around line 144-148: The loop in findAll causes an N+1 gRPC call by invoking
groupGrpcClient.isUserInGroup per cardset; instead, fetch the user's group IDs
once (e.g., call groupGrpcClient.getUserGroupIds(userId) or similar) and then
replace the per-cardset check with an in-memory membership test: keep the
Visibility.PUBLIC check and for non-public use a set/Map lookup against the
returned group IDs when filtering cardsets into visibleCardsets; update
references to isUserInGroup, findAll, cardsets, visibleCardsets, Visibility and
userId accordingly.
- Around line 173-176: The loop over visibleCardsets is causing N+1 gRPC calls
by calling imageGrpcClient.getImageUrl per cardset; instead collect the ids (or
imageRefIds) for cardsets that need images, call a batch method on
ImageGrpcClient (e.g., getImageUrls or add one if missing) to retrieve all URLs
in one request, then map the returned URLs back to each cardset (falling back to
defaultImageUrl) before returning; apply the same batching pattern to the
similar code path in findByGroupId to eliminate the per-item gRPC calls.
- Around line 63-65: The current sequential loop over additionalManagerIds
calling this.groupGrpcClient.checkUserInGroup causes N+1 gRPC calls; replace it
with a single batched membership check (e.g., call
this.groupGrpcClient.checkUsersInGroup(dto.groupId, additionalManagerIds) or the
group service's batch membership API) and validate returned results, or if no
batch API exists at the moment, execute the checks in parallel with Promise.all
over additionalManagerIds to avoid serial calls; update any error
handling/response logic in the surrounding method (the block using
additionalManagerIds and checkUserInGroup) to handle batch responses and
missing/invalid manager IDs accordingly.
- Around line 320-331: The current implementation in cardset.use-case.ts
iterates over existing managers (cardsetManagerRepository.findAllByCardSetId)
deleting each via delete(m.id) and then saves new managers one-by-one
(CardsetManager.create + cardsetManagerRepository.save), which is inefficient
for large sets; introduce and use batch repository methods (e.g.,
cardsetManagerRepository.deleteByCardSetId(cardSetId) to remove all existing
managers in one operation and
cardsetManagerRepository.saveAll(cardsetManagerArray) to persist new managers in
a single call), build the array of CardsetManager instances from newManagerIds
before calling saveAll, and update the use-case to call these new batch methods
instead of the per-item delete/save loop.
In `@src/cardset/application/dto/response/cardset-list-item.response.ts`:
- Around line 64-71: Add a static factory method on ManagerInfoResponse (e.g.,
static from(userInfo: UserInfo): ManagerInfoResponse) that constructs and
returns a ManagerInfoResponse from a UserInfo, then replace the duplicated
mapping code in both the res.managers assignment and inside CardsetResponse.from
to call ManagerInfoResponse.from(m) instead of manually copying fields; this
removes the duplication and centralizes the mapping logic.
- Line 4: The file cardset-list-item.response.ts imports the Infrastructure type
UserInfo directly, violating layer dependencies; create a new UserInfo interface
(or shared DTO) inside the Application or Domain layer (e.g., in application/dto
or domain/model) that matches the needed shape, update
cardset-list-item.response.ts to import that application/domain UserInfo instead
of ../../../infrastructure/grpc/user-grpc.client, and remove the infrastructure
import so the Application layer no longer depends on Infrastructure; ensure any
other files using the original Infrastructure UserInfo are updated to use the
new Application/Domain type or map between types where necessary.
In `@src/cardset/application/dto/response/cardset.response.ts`:
- Around line 4-5: Cardset.application is importing the infrastructure type
UserInfo directly; create or use an application-layer DTO instead and replace
the infra import. Define a new application DTO (e.g., UserInfoResponse or move
an existing ManagerInfoResponse usage) in the application/dto folder, update
cardset.response.ts to import that application-level type and ensure any
references in CardsetListItemResponse and ManagerInfoResponse use the new DTO so
the application layer no longer depends on infrastructure.
In `@src/cardset/infrastructure/grpc/reaction-grpc.client.ts`:
- Around line 63-75: The methods areLiked and areBookmarked should avoid making
a gRPC call when cardSetIds is empty; add an early return that returns an empty
Map<number, boolean> immediately if the input array has length 0, instead of
calling reactionService.areLiked/areBookmarked and converting result.results;
update the implementations for areLiked and areBookmarked to check
cardSetIds.length === 0 and return new Map() early.
In `@src/cardset/infrastructure/http/cardset.controller.ts`:
- Around line 150-170: Remove the entire commented-out updateCardCount endpoint
block (the commented async function named updateCardCount and its related
decorators and Swagger comments) from the cardset controller file; ensure no
references remain to updateCardCount in the class and verify imports/unused
symbols are adjusted if necessary so the controller compiles cleanly after
deletion.
In `@src/proto/reaction.proto`:
- Around line 1-2: The proto package/location mismatch: reaction.proto declares
package "reaction" but lives under src/proto/, causing buf lint warnings; fix by
moving reaction.proto into a matching directory (e.g., create/update reaction/
and place reaction.proto there) or alternatively change the declared package in
reaction.proto to match the current directory layout; reference the file name
reaction.proto and the package declaration "package reaction" (and ensure any
related files like user.proto follow the same convention) so imports and buf
config remain consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fc14f0a6-f243-4af5-a4cb-95e7fab63f02
📒 Files selected for processing (18)
src/cardset/application/cardset.use-case.tssrc/cardset/application/dto/request/create-cardset.request.tssrc/cardset/application/dto/request/update-cardset.request.tssrc/cardset/application/dto/response/cardset-list-item.response.tssrc/cardset/application/dto/response/cardset.response.tssrc/cardset/application/dto/response/manager-info.response.tssrc/cardset/cardset.module.tssrc/cardset/domain/repository/cardset-manager.repository.tssrc/cardset/domain/repository/cardset.repository.tssrc/cardset/infrastructure/grpc/reaction-grpc.client.tssrc/cardset/infrastructure/grpc/user-grpc.client.tssrc/cardset/infrastructure/http/card.controller.tssrc/cardset/infrastructure/http/cardset.controller.tssrc/cardset/infrastructure/http/group-cardset.controller.tssrc/cardset/infrastructure/persistence/cardset-manager.repository.impl.tssrc/cardset/infrastructure/persistence/cardset.repository.impl.tssrc/proto/reaction.protosrc/shared/grpc/grpc-client.module.ts
📝 변경 내용
✅ 체크리스트
💬 기타 참고 사항
Summary by CodeRabbit
새로운 기능
개선 사항
제거