diff --git a/src/features/review/dto/inputs/product-reviews.input.ts b/src/features/review/dto/inputs/product-reviews.input.ts index f9bbe3c3..a8f44265 100644 --- a/src/features/review/dto/inputs/product-reviews.input.ts +++ b/src/features/review/dto/inputs/product-reviews.input.ts @@ -30,7 +30,7 @@ export class ProductReviewsInput { @IsOptional() @IsString() @IsNotEmpty() - cursor?: string; + cursor?: string | null; @IsOptional() @IsInt() diff --git a/src/features/review/dto/inputs/store-reviews.input.ts b/src/features/review/dto/inputs/store-reviews.input.ts index 5ed50380..d1159fc1 100644 --- a/src/features/review/dto/inputs/store-reviews.input.ts +++ b/src/features/review/dto/inputs/store-reviews.input.ts @@ -30,7 +30,7 @@ export class StoreReviewsInput { @IsOptional() @IsString() @IsNotEmpty() - cursor?: string; + cursor?: string | null; @IsOptional() @IsInt() diff --git a/src/features/review/services/review-listing.service.spec.ts b/src/features/review/services/review-listing.service.spec.ts index 0a54cad8..53ce6495 100644 --- a/src/features/review/services/review-listing.service.spec.ts +++ b/src/features/review/services/review-listing.service.spec.ts @@ -106,7 +106,7 @@ describe('ReviewListingService (real DB)', () => { args: { photoOnly?: boolean; sort?: 'LATEST' | 'LIKES'; - cursor?: string; + cursor?: string | null; limit?: number; } = {}, accountId?: bigint, @@ -270,6 +270,18 @@ describe('ReviewListingService (real DB)', () => { ); }); + it.each(['LATEST', 'LIKES'] as const)( + 'cursor null은 첫 페이지로 처리한다 (%s)', + async (sort) => { + const target = await makeTarget(); + const review = await makeReview(target); + + const result = await list(kind, target, { sort, cursor: null }); + + expect(result.items.map((r) => r.id)).toEqual([review.id.toString()]); + }, + ); + it('cursor "0"은 페이지를 리셋하지 않고 빈 결과를 반환한다', async () => { const target = await makeTarget(); await makeReview(target); diff --git a/src/features/review/services/review-listing.service.ts b/src/features/review/services/review-listing.service.ts index e5007f3f..1fb1693c 100644 --- a/src/features/review/services/review-listing.service.ts +++ b/src/features/review/services/review-listing.service.ts @@ -29,7 +29,7 @@ import type { interface ListingArgs { photoOnly?: boolean; sort?: ReviewSort; - cursor?: string; + cursor?: string | null; limit?: number; } @@ -115,7 +115,8 @@ export class ReviewListingService { photoOnly, sort, limit, - cursorRaw: input.cursor, + // 명시적 cursor: null도 첫 페이지 요청이다 + cursorRaw: input.cursor ?? undefined, }), this.repo.countReviews({ scope, photoOnly: false }), this.repo.countReviews({ scope, photoOnly: true }),