diff --git a/scripts/check-sdl-description-coverage.ts b/scripts/check-sdl-description-coverage.ts index c1c70c39..2c775cd6 100644 --- a/scripts/check-sdl-description-coverage.ts +++ b/scripts/check-sdl-description-coverage.ts @@ -84,6 +84,16 @@ function safeIsDir(path: string): boolean { function main(): void { const files = loadSdlFiles(); + if (files.length === 0) { + // 검사 대상이 없으면 모든 카테고리가 0/0이 되고 percentOf가 100을 돌려줘 + // 위반 없이 "통과"가 찍힌다. 이 게이트가 막으려는 것과 같은 종류의 거짓 안전이다. + console.error( + `[docs:check] SDL 파일을 찾지 못했습니다: ${SDL_ROOT}. ` + + '경로가 옳은지 확인하라 — 대상이 없으면 커버리지는 의미가 없다.', + ); + process.exitCode = 1; + return; + } const coverage = collectCoverage(files); console.log(`[docs:check] SDL 파일 ${files.length}개`); diff --git a/src/features/conversation/conversation-center.graphql b/src/features/conversation/conversation-center.graphql index 362d1416..5a94b444 100644 --- a/src/features/conversation/conversation-center.graphql +++ b/src/features/conversation/conversation-center.graphql @@ -3,7 +3,8 @@ extend type Query { myConversations(input: MyConversationsInput): MyConversationConnection! """ 채팅 상세 메시지 목록(최신순 키셋 커서). 구매자 본인 대화만 조회 가능하며, - 조회 시 last_read_at을 현재 시각으로 갱신한다(안읽음 배지 해소 부수효과). + 조회 시 last_read_at을 이번에 반환한 최신 메시지의 작성 시각까지 끌어올린다 + (안읽음 배지 해소 부수효과). 반환할 메시지가 없으면 갱신하지 않는다. 로그인 필수. """ conversationMessages(conversationId: ID!, input: ConversationMessagesInput): ConversationMessageConnection! diff --git a/src/features/order/order-checkout.graphql b/src/features/order/order-checkout.graphql index ab4c9189..0ae41297 100644 --- a/src/features/order/order-checkout.graphql +++ b/src/features/order/order-checkout.graphql @@ -28,7 +28,10 @@ type CreateOrderOutput { orderId: ID! """주문번호. 화면·문의에 쓰는 식별자.""" orderNumber: String! - """생성 직후 상태. 항상 SUBMITTED다.""" + """ + 주문 상태. 새로 생성된 경우 SUBMITTED다. 같은 idempotencyKey로 재시도하면 기존 + 주문을 그대로 돌려주므로 그 사이 진행된 상태(CONFIRMED·MADE·PICKED_UP 등)일 수 있다. + """ status: OrderStatusType! """확정된 픽업 일시. 서버가 매장 정책으로 재검증한 값이다.""" pickupAt: DateTime! diff --git a/src/features/pickup/pickup.types.graphql b/src/features/pickup/pickup.types.graphql index 7674284a..ed7994f6 100644 --- a/src/features/pickup/pickup.types.graphql +++ b/src/features/pickup/pickup.types.graphql @@ -33,9 +33,9 @@ type PickupDay { type PickupTimeSlots { """요청한 날짜. "YYYY-MM-DD" (KST).""" date: String! - """12:00 이전 슬롯.""" + """오전 슬롯. 12:00 이전(12:00은 afternoon에 들어간다).""" morning: [PickupSlot!]! - """12:00 이후 슬롯.""" + """오후 슬롯. 12:00 포함, 이후.""" afternoon: [PickupSlot!]! } diff --git a/src/features/product/product-detail.graphql b/src/features/product/product-detail.graphql index 7daf949e..3ba5da28 100644 --- a/src/features/product/product-detail.graphql +++ b/src/features/product/product-detail.graphql @@ -18,7 +18,7 @@ type ProductDetail { images: [String!]! """정가(원).""" regularPrice: Int! - """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가다.""" + """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가로 쓰인다.""" salePrice: Int """할인율(0~100). salePrice 없으면 0.""" discountRate: Int! diff --git a/src/features/product/product-home.graphql b/src/features/product/product-home.graphql index d08d2d06..9ef82864 100644 --- a/src/features/product/product-home.graphql +++ b/src/features/product/product-home.graphql @@ -116,7 +116,7 @@ type PopularCake { regionLabel: String """정가(원).""" regularPrice: Int! - """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가다.""" + """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가로 쓰인다.""" salePrice: Int """할인율(0~100). salePrice 없으면 0.""" discountRate: Int! diff --git a/src/features/product/product-search.graphql b/src/features/product/product-search.graphql index 635fc31a..c9ac1e24 100644 --- a/src/features/product/product-search.graphql +++ b/src/features/product/product-search.graphql @@ -64,7 +64,7 @@ type SearchProduct { regionLabel: String """정가(원).""" regularPrice: Int! - """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가다.""" + """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가로 쓰인다.""" salePrice: Int """할인율(0~100). salePrice 없으면 0.""" discountRate: Int! diff --git a/src/features/product/product-storefront.graphql b/src/features/product/product-storefront.graphql index 6eb6f48d..700eec77 100644 --- a/src/features/product/product-storefront.graphql +++ b/src/features/product/product-storefront.graphql @@ -63,7 +63,7 @@ type StoreProduct { thumbnailUrl: String """정가(원).""" regularPrice: Int! - """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가다.""" + """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가로 쓰인다.""" salePrice: Int """할인율(0~100). salePrice 없으면 0.""" discountRate: Int! diff --git a/src/features/seller/seller-common.graphql b/src/features/seller/seller-common.graphql index 9fef5025..e7752426 100644 --- a/src/features/seller/seller-common.graphql +++ b/src/features/seller/seller-common.graphql @@ -5,7 +5,7 @@ ID 키셋 커서 기반 목록 조회 공통 입력. 판매자 목록 API가 공 정렬 기준이 바뀌면 이전에 받은 커서는 무효가 된다. """ input SellerCursorInput { - """한 번에 가져올 개수. 기본 20, 1~100으로 보정된다.""" + """한 번에 가져올 개수. 기본 20, 1~100만 허용하며 벗어나면 BAD_REQUEST.""" limit: Int = 20 """이전 응답의 nextCursor. 첫 페이지는 생략한다.""" cursor: ID diff --git a/src/features/seller/seller-content.graphql b/src/features/seller/seller-content.graphql index 9ce0b7c7..36875f89 100644 --- a/src/features/seller/seller-content.graphql +++ b/src/features/seller/seller-content.graphql @@ -260,7 +260,7 @@ type SellerAuditLogConnection { """감사 로그 조회 조건.""" input SellerAuditLogListInput { - """한 번에 가져올 개수. 기본 20, 1~100으로 보정된다.""" + """한 번에 가져올 개수. 기본 20, 1~100만 허용하며 벗어나면 BAD_REQUEST.""" limit: Int = 20 """이전 응답의 nextCursor. 첫 페이지는 생략한다.""" cursor: ID diff --git a/src/features/seller/seller-conversation.graphql b/src/features/seller/seller-conversation.graphql index 97a0710f..b43c51f5 100644 --- a/src/features/seller/seller-conversation.graphql +++ b/src/features/seller/seller-conversation.graphql @@ -30,7 +30,7 @@ type SellerConversation { 불투명 토큰이므로 값의 형식에 의존하지 말고 이전 응답의 nextCursor를 그대로 넘긴다. """ input SellerConversationListInput { - """한 번에 가져올 개수. 기본 20, 1~100으로 보정된다.""" + """한 번에 가져올 개수. 기본 20, 1~100만 허용하며 벗어나면 BAD_REQUEST.""" limit: Int = 20 """이전 응답의 nextCursor. 첫 페이지는 생략한다.""" cursor: String diff --git a/src/features/seller/seller-order.graphql b/src/features/seller/seller-order.graphql index b1fdcbdf..0e91d164 100644 --- a/src/features/seller/seller-order.graphql +++ b/src/features/seller/seller-order.graphql @@ -45,7 +45,7 @@ type SellerOrderConnection { 주문 목록 조회 조건. 모든 필터는 AND로 결합되고, 미지정 필터는 적용되지 않는다. """ input SellerOrderListInput { - """한 번에 가져올 개수. 기본 20, 1~100으로 보정된다.""" + """한 번에 가져올 개수. 기본 20, 1~100만 허용하며 벗어나면 BAD_REQUEST.""" limit: Int = 20 """이전 응답의 nextCursor. 첫 페이지는 생략한다.""" cursor: ID diff --git a/src/features/seller/seller-product.graphql b/src/features/seller/seller-product.graphql index d8613804..7ede5a42 100644 --- a/src/features/seller/seller-product.graphql +++ b/src/features/seller/seller-product.graphql @@ -218,11 +218,11 @@ type SellerProductConnection { """상품 목록 조회 조건. 필터는 AND로 결합되고 미지정 필터는 적용되지 않는다.""" input SellerProductListInput { - """한 번에 가져올 개수. 기본 20, 1~100으로 보정된다.""" + """한 번에 가져올 개수. 기본 20, 1~100만 허용하며 벗어나면 BAD_REQUEST.""" limit: Int = 20 """이전 응답의 nextCursor. 첫 페이지는 생략한다.""" cursor: ID - """노출 여부 필터. 미지정 시 노출·미노출을 모두 포함한다.""" + """노출 여부 필터. 미지정 시 활성 상품만 반환한다(기본 true).""" isActive: Boolean """카테고리 필터. 해당 카테고리가 연결된 상품만.""" categoryId: ID diff --git a/src/features/seller/seller-store.graphql b/src/features/seller/seller-store.graphql index 383e5f57..14889d42 100644 --- a/src/features/seller/seller-store.graphql +++ b/src/features/seller/seller-store.graphql @@ -28,7 +28,7 @@ extend type Mutation { """날짜 범위 필터가 붙은 커서 목록 입력. 일별 생산 수량 조회에 쓴다.""" input SellerDateCursorInput { - """한 번에 가져올 개수. 기본 20, 1~100으로 보정된다.""" + """한 번에 가져올 개수. 기본 20, 1~100만 허용하며 벗어나면 BAD_REQUEST.""" limit: Int = 20 """이전 응답의 nextCursor. 첫 페이지는 생략한다.""" cursor: ID diff --git a/src/features/store/store-pickup-schedule.graphql b/src/features/store/store-pickup-schedule.graphql index d60b00f1..c890cef9 100644 --- a/src/features/store/store-pickup-schedule.graphql +++ b/src/features/store/store-pickup-schedule.graphql @@ -35,9 +35,9 @@ type StorePickupDay { type StorePickupTimeSlots { """요청한 날짜. "YYYY-MM-DD" (KST).""" date: String! - """12:00 이전 슬롯.""" + """오전 슬롯. 12:00 이전(12:00은 afternoon에 들어간다).""" morning: [StorePickupSlot!]! - """12:00 이후 슬롯.""" + """오후 슬롯. 12:00 포함, 이후.""" afternoon: [StorePickupSlot!]! } diff --git a/src/features/user/user-wishlist.graphql b/src/features/user/user-wishlist.graphql index d865cf7b..17108569 100644 --- a/src/features/user/user-wishlist.graphql +++ b/src/features/user/user-wishlist.graphql @@ -41,7 +41,7 @@ type WishlistItemSummary { productName: String! """대표 상품 이미지. 없으면 null.""" representativeImageUrl: String - """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가다.""" + """할인가(원). 할인이 없으면 null이고 regularPrice가 표시가로 쓰인다.""" salePrice: Int """정가(원).""" regularPrice: Int!