Conversation
커스텀 단계 스펙 미확정 상태에서 FE가 주문 생성 흐름을 테스트할 수 있도록, 확정된 부분(단일 상품·옵션 선택·픽업 일시·수량)만으로 정식 주문 생성 경로를 구현한다. 커스텀 입력은 스펙 확정 후 optional 필드로 확장한다 (임시 스텁이 아니므로 이후 계약 변경 없음 — 사용자 확정 방향). - SDL order-checkout.graphql: createOrder(input) → 요약(CreateOrderOutput), 상세는 기존 myOrder 재조회 전제 - OrderCheckoutService: 옵션 그룹 규칙(필수/min/max/중복/타 상품) 검증, 가격 서버 스냅샷(subtotal 정가·discount 정가-판매가 차액·total 판매가 기준), 주문자 정보 input 우선 + 프로필(닉네임·전화) fallback, 둘 다 없으면 거절 - StorePickupScheduleService.isPickupSlotAvailable 신설: 달력·슬롯과 동일 규칙 + 슬롯 시작 시각 정합 + capacity 잔여(기존 점유+수량 ≤ capacity) 재검증 — 판정 로직은 store feature에 유지(배럴 export) - OrderRepository.createSubmittedOrder: Order+Item+옵션 스냅샷+상태 히스토리 중첩 create 원자 생성, SUBMITTED는 기존 규칙대로 알림 미발송 - 주문번호 ORD-YYYYMMDD-XXXXXX(KST 날짜+혼동 문자 제외 랜덤 6자리, RandomService 주입) — 명세 외 정책 결정. P2002 충돌 시 3회 재시도 회귀 테스트 24건: 생성 스냅샷·가격·히스토리 / 옵션 규칙 전 분기 / buyer fallback / 픽업 판정(휴무·정렬·리드타임·capacity 잔여·초 이하) / 주문번호 충돌 재시도·소진 / NOT_FOUND / input 검증 / resolver 통합
- 커밋 전 금액 검증: subtotal/discount/itemSubtotal이 음수·비안전 정수· GraphQL Int 상한(2,147,483,647) 초과면 거절 — 저장 후 응답 직렬화 실패로 인한 재시도 중복 주문 경로 차단, 음수 델타 언더플로 방지 - createSubmittedOrder를 트랜잭션화하고 capacity 행 FOR UPDATE 잠금 후 점유 재집계 — 동시 주문이 마지막 잔여를 함께 차지하는 race 차단 (초과 시 null 반환 → 서비스가 BadRequest 변환) - 회귀 테스트 3건 추가: 32비트 초과/음수 금액 거절, 동시 주문 2건 중 정확히 1건만 성공(real DB 동시성)
- findProductDetailById에 preparation_time_minutes·currency 활용 추가, 체크아웃에서 pickupAt ≥ now + 제작 소요시간을 매장 리드타임과 별개로 강제 - Order/OrderItem에 통화 스냅샷 컬럼이 없어 비 KRW 상품은 주문 거절 (명세 외 정책 결정 — 다국통화 스냅샷은 후속 이슈로 추적) - 상품 팩토리에 currency·preparation_time_minutes override 추가 (테스트 기본 제작시간 0분 — 스키마 기본 180분은 당일 픽업 테스트 방해) - 회귀 테스트 2건 추가 (제작시간 미달 거절/충족 허용, USD 상품 거절)
- 체크아웃 진입 시 활성 USER 계정+활성 프로필을 강제한다 (requireActiveUser와 동일 의미론 — SELLER/ADMIN이 구매자 mutation으로 주문을 만들어 capacity·랭킹을 오염시키는 경로 차단) - buyerPhone에 프로필 전화번호와 동일한 010-XXXX-XXXX 고정 형식 강제 (임의 문자열이 검증된 프로필 값을 덮어쓰지 못하게) - 프로필 닉네임이 NOT NULL 최종 fallback이라 도달 불가가 된 BUYER_NAME_REQUIRED 분기 제거 - 회귀 테스트 3건 추가 (SELLER 거절/프로필 없음 거절/전화 형식)
buyerName을 trim해 빈 값이면 프로필 닉네임 fallback으로 처리한다 — 공백 이름이 검증된 닉네임을 덮어써 판매자에게 빈 표기로 보이는 것 방지. 회귀 케이스 1건 추가.
feat(order): 주문 생성 mutation(createOrder) — 정식 API의 확정 부분집합
|
Warning Review limit reachedNext included review available in 37 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (19)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
🩺 NestJS Doctor — 89/100 (Good)진단 282건 (error 0).
architecture / security 상위 항목
|
🧹 knip — dead-code 리포트전체 리포트
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f5966d09bf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| const buyerProfile = await this.requireActiveBuyer(accountId); | ||
|
|
||
| const product = await this.productRepo.findProductDetailById(productId); |
There was a problem hiding this comment.
Reject orders missing required option customization
When a selected option group has option_requires_description or option_requires_image enabled, this flow never loads those flags and CreateOrderInput has no corresponding customization data, yet the order is still submitted with only the option-item snapshot. This permits seller-configured products to enter SUBMITTED without required instructions or assets; either persist those required values or reject these products until custom checkout is supported.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
반영: PR #210 — 설명/이미지 필수 옵션 그룹을 선택한 주문은 커스텀 체크아웃 확장 전까지 거절 (develop 경유 후 본 릴리즈에 포함). 커스텀 입력 추가 시 이 가드를 실제 데이터 검증으로 대체 예정.
| @@ -0,0 +1,27 @@ | |||
| extend type Mutation { | |||
| """주문 생성(구매자). 옵션·픽업 일시를 서버가 재검증하고 가격을 스냅샷한다. 로그인 필수.""" | |||
| createOrder(input: CreateOrderInput!): CreateOrderOutput! | |||
There was a problem hiding this comment.
Deduplicate retried order submissions
When a client retries after a timeout or submits twice, this mutation has no idempotency key or equivalent lookup, and every invocation generates a fresh random order number. The same checkout therefore creates multiple independent SUBMITTED orders and consumes capacity multiple times; accept a client request key, enforce uniqueness per account, and return the existing result on replay.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
미반영(후속 추적): 멱등 키는 주문 요청 키 컬럼+unique 등 스키마 변경 동반이라 릴리즈 리뷰 fix 범위 초과. 결제 없는 현 단계 위험도가 낮아, 커스텀 확장 시 입력 계약과 함께 설계하기로 하고 후속 이슈로 등록 예정.
Coverage report
Test suite run success1603 tests passing in 187 suites. Report generated by 🧪jest coverage report action from 9181128 |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
릴리즈 PR #209 Codex 지적 반영. option_requires_description/image가 켜진 옵션 그룹은 판매자가 요구한 커스텀 정보 없이는 주문이 완성되지 않는데, 체크아웃이 플래그를 읽지 않아 스냅샷만으로 SUBMITTED가 됐다. - findProductDetailById에 두 플래그 로드 추가 - 해당 그룹 옵션을 선택한 주문은 커스텀 체크아웃 확장 전까지 거절 (미선택이면 기존대로 허용) - 회귀 테스트 1건 추가
…on-customization fix: 릴리즈 리뷰 반영 (설명/이미지 필수 옵션 선택 시 주문 거절)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2acfcc68d3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return false; | ||
| } | ||
|
|
||
| const isToday = kstDayDiff(now, args.pickupAt) === 0; |
There was a problem hiding this comment.
Enforce lead times across future calendar days
When a seller configures minLeadTimeMinutes longer than the remainder of the current day—values up to seven days are allowed in seller.constants.ts—any pickup on tomorrow or later makes isToday false, causing buildDaySlots to replace the current time with -Infinity and ignore the lead time entirely. Consequently, createOrder can commit an order for tomorrow despite a seven-day store lead time whenever the product's separate preparation time is shorter; compare pickupAt against an absolute now + min_lead_time_minutes cutoff for future dates as well.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
반영: PR #211 — buildDaySlots 컷오프를 절대 시각(now+리드타임) 기준으로 변경해 하루 넘는 리드타임이 미래 날짜에도 적용되게 수정 (달력 CLOSED 판정 포함, develop 경유 후 본 릴리즈에 포함).
릴리즈 PR #209 Codex 지적 반영. 리드타임 컷오프를 당일(isToday)에만 적용해, 판매자 설정 리드타임이 하루를 넘으면(최대 7일) 미래 날짜에서 무시됐다 — 7일 리드타임 매장의 내일 슬롯이 예약 가능으로 보이고 createOrder도 통과하는 문제. - buildDaySlots 컷오프를 절대 시각(now + 리드타임) 기준으로 변경 (해당 날짜 자정 대비 경과 분이 미래일에 음수가 되어 자연 반영) - 달력 판정도 동일 규칙: 리드타임에 완전히 덮인 미래일은 CLOSED - 회귀 테스트 1건 추가 (3일 리드: 슬롯 판정·달력·시간 슬롯 3면 검증)
…-time fix: 릴리즈 리뷰 반영 (하루 넘는 리드타임을 미래 날짜에도 적용)
릴리즈 개요
구매자 주문 생성 mutation
createOrder1건을 릴리즈합니다.develop → main이며, 포함된 변경은 PR #208 하나입니다.
배경
커스텀 단계 UI·기획이 미확정이라 주문 생성 API가 없어 FE가 주문 흐름을 테스트할 수단이 없었습니다.
임시 스텁 대신 정식 API의 확정 부분집합(단일 상품·옵션 일괄 제출·픽업 일시·수량·서버 가격 스냅샷)으로 구현했고, 커스텀은 스펙 확정 후 optional 필드로 확장합니다.
따라서 이후 계약 변경 없이 FE가 최종 계약의 부분집합에 맞춰 개발할 수 있습니다.
주요 결정 사항
FOR UPDATE잠금 + 점유 재집계로 동시 주문 race 차단 (Codex 리뷰 반영).ORD-YYYYMMDD-XXXXXX, SUBMITTED 알림 미발송(기존 규칙), 스키마 변경(마이그레이션) 없음.검증
yarn validate전체 통과.Summary by CodeRabbit
새로운 기능
버그 수정
테스트