Skip to content

Conversation

@piggggggggy
Copy link
Member

@piggggggggy piggggggggy commented May 29, 2025

Skip Review (optional)

  • Minor changes that don't affect the functionality (e.g. style, chore, ci, test, docs)
  • Previously reviewed in feature branch, further review is not mandatory
  • Self-merge allowed for solo developers or urgent changes

Description (optional)

Introduce

  1. useScopedPaginationQuery
    A wrapper around useInfiniteQuery to handle paginated resource fetching with:
  • Unified page parameter injection (for load, list, analyze, stat)
  • Dynamic page fetching on thisPage change
  • Grant-scope-based query execution
  • Strong type support
  1. pagination flag in useServiceQueryKey
  • Removes pagination fields (page - start, limit) from params in queryKey generation
  • Helps avoid unstable cache keys due to page changes
  • Internally handles different param structures by verb type (params.page, params.query.page, etc.)

Motivation

  • Standardizes paginated API calls with better DX and safer cache control
  • Avoids duplicated logic for queryKey cleanup and pagination-aware fetching
  • Makes queryKey generation for paginated resources more robust and intentional
/**
 * @property pagination - When true, removes pagination-related params (`page`, `start`, `limit`)
 *   from the final queryKey, depending on the verb's structure.
 *   This helps ensure queryKey stability and avoids unwanted cache misses due to pagination changes.
 *
 * Example:
 * useServiceQueryKey('dashboard', 'data-table', 'load', {
 *   params: computed(() => ({ page, sort, granularity })),
 *   pagination: true, // → will remove `page` from the key
 * });
 */

이번 PR에서는 다음 두 가지 주요 기능이 추가됩니다.

  1. useScopedPaginationQuery
  • useInfiniteQuery를 감싼 pagination 전용 래퍼입니다.
  • load, list, analyze, stat에 따라 page 파라미터를 올바른 구조로 자동 삽입
  • thisPage가 변경되면 해당 페이지까지 자동 fetch
  • 권한 기반 쿼리 실행 (requiredScopes 사용)
  • 타입 안정성 확보
  1. useServiceQueryKeypagination 옵션 추가
  • queryKey 생성 시 params에서 page(start, limit) 필드를 제거
  • 페이지 변경에 따른 쿼리키 불안정성을 방지
  • verb별 param 구조를 내부에서 자동 처리

도입 배경

  • pagination이 있는 API 호출을 표준화하고 DX를 개선하기 위함
  • 쿼리 키 생성 시 반복되던 pagination 제거 로직을 내부로 통합
  • 캐시 키의 일관성과 재사용성을 높이고, 불필요한 refetch를 방지

Things to Talk About (optional)

Signed-off-by: samuel.park <samuel.park@megazone.com>
…posable

Signed-off-by: samuel.park <samuel.park@megazone.com>
…pagination query

Signed-off-by: samuel.park <samuel.park@megazone.com>
@vercel
Copy link

vercel bot commented May 29, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
cost-report ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 29, 2025 8:33am
2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
console ⬜️ Ignored (Inspect) Visit Preview May 29, 2025 8:33am
web-storybook ⬜️ Ignored (Inspect) Visit Preview May 29, 2025 8:33am

@github-actions
Copy link
Contributor

🎉 @seungyeoneeee has been randomly selected as the reviewer! Please review. 🙏

@github-actions github-actions bot requested a review from seungyeoneeee May 29, 2025 08:23
@piggggggggy piggggggggy requested review from Copilot and skdud4659 and removed request for seungyeoneeee May 29, 2025 08:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Adds a new pagination-aware composable and enhances the existing query-key generator to support stable keys by stripping paging parameters.

  • Introduces useScopedPaginationQuery for infinite, scope-validated pagination with automatic page fetching.
  • Extends useServiceQueryKey with a pagination flag and helper to omit page params from cache keys.
  • Provides pagination-query-helper utilities to add or remove paging fields by API verb.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
apps/web/src/query/query-key/use-service-query-key.ts Added pagination option and _omitPageParamsByVerb to strip page fields from query keys.
apps/web/src/query/pagination/use-scoped-pagination-query.ts New wrapper around useScopedInfiniteQuery injecting paging logic and watching thisPage.
apps/web/src/query/pagination/pagination-query-helper.ts New helpers omitPageFromLoadParams, omitPageQueryParams, and addPageToVerbParams.
apps/web/src/query/composables/use-scoped-infinite-query.ts New scope-based infinite query hook enforcing grant-scope checks.
Comments suppressed due to low confidence (3)

apps/web/src/query/pagination/pagination-query-helper.ts:10

  • New helper functions lack dedicated unit tests; adding tests for omitPageFromLoadParams and omitPageQueryParams will ensure correct behavior across edge cases.
export const omitPageFromLoadParams = <T extends LoadParams>(params: T): Omit<T, 'page'> => {

apps/web/src/query/composables/use-scoped-infinite-query.ts:1

  • The new scoped infinite query hook would benefit from tests around scope validation and enabled-state logic to prevent regressions.
/**

apps/web/src/query/pagination/use-scoped-pagination-query.ts:12

  • The imported QueryKeyArray type isn't used in this file; consider removing it to keep imports clean.
import type { QueryKeyArray } from '@/query/query-key/_types/query-key-type';

Comment on lines +109 to +110
const calls = Array.from({ length: val - currentLength });
await Promise.all(calls.map(() => query.fetchNextPage()));
Copy link

Copilot AI May 29, 2025

Choose a reason for hiding this comment

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

Concurrent calls to fetchNextPage may race and break page ordering. Consider fetching pages sequentially or chaining with for/reduce to preserve correct order.

Suggested change
const calls = Array.from({ length: val - currentLength });
await Promise.all(calls.map(() => query.fetchNextPage()));
for (let i = currentLength; i < val; i++) {
await query.fetchNextPage();
}

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +23
const copiedQuery = params.query ? { ...params.query } : undefined;
if (copiedQuery) delete copiedQuery.page;

Copy link

Copilot AI May 29, 2025

Choose a reason for hiding this comment

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

When params.query is undefined, this helper still adds a query: undefined field, altering object shape. Consider returning params unchanged in that case to preserve the original structure.

Suggested change
const copiedQuery = params.query ? { ...params.query } : undefined;
if (copiedQuery) delete copiedQuery.page;
if (!params.query) {
return params;
}
const copiedQuery = { ...params.query };
delete copiedQuery.page;

Copilot uses AI. Check for mistakes.
Signed-off-by: samuel.park <samuel.park@megazone.com>
@piggggggggy piggggggggy merged commit 6aaf9e0 into develop May 30, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants