Skip to content

Feature/#88#95

Merged
vkehfdl1 merged 2 commits intodevfrom
feature/#88
Apr 9, 2026
Merged

Feature/#88#95
vkehfdl1 merged 2 commits intodevfrom
feature/#88

Conversation

@vkehfdl1
Copy link
Copy Markdown
Contributor

@vkehfdl1 vkehfdl1 commented Apr 9, 2026

Summary

  • add a publishable market-kurly-search workspace package for unauthenticated Kurly search/count/detail lookups
  • add the market-kurly-search skill and feature docs, plus README/install/roadmap/source registry updates
  • cover the new package and docs with regression tests and a changeset entry

Verification

  • npm run ci
  • live Node smoke: countProducts('우유'), searchProducts('우유'), getProductDetail(5063110) on 2026-04-09

Implement a reusable Market Kurly workspace package plus a repo skill/doc set
that uses the unauthenticated Kurly search and goods-page surfaces.
The change keeps the scope read-only, adds regression coverage, updates
release/docs metadata, and records the new publishable package through
Changesets.

Constraint: Must rely on unauthenticated public web surfaces instead of login/session flows
Constraint: Release workflow requires Changesets for publishable Node packages
Rejected: Docs-only skill | issue approval called for real lookup helpers and live verification
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Kurly endpoints are web-internal surfaces; verify schema behavior before extending fields or adding action flows
Tested: npm run ci; live node smoke for countProducts/searchProducts/getProductDetail on 2026-04-09
Not-tested: Pagination beyond page 1; long-term stability of Kurly internal response schema
@vkehfdl1
Copy link
Copy Markdown
Contributor Author

vkehfdl1 commented Apr 9, 2026

REQUEST CHANGES

I ran the required verification locally.

Real Result

  • npm run ci
  • live smoke from the PR body ✅
    • countProducts('우유'){ query: '우유', count: 468 }
    • searchProducts('우유') → first item 5063110 / [연세우유 x 마켓컬리] 전용목장우유 900mL / currentPrice 2780 / isSoldOut false
    • getProductDetail(5063110)productNo 5063110 / currentPrice 2780 / deliveryTypeNames ['샛별배송(내일 아침)']
  • additional live check for a discounted product ❌

HIGH

  1. Discounted detail pages normalize the wrong fields, so getProductDetail() drops discount/original-price/image data.
    File: packages/market-kurly-search/src/parse.js:140-160

    normalizeDetailCandidate() only reads candidate.basePrice, candidate.salesPrice, candidate.discountedPrice, and candidate.imageUrl/listImageUrl/productVerticalMediumUrl. But the live Kurly goods payload for discounted items is currently exposing the important values under showablePrices.retailPrice / showablePrices.salesPrice and mainImageUrl.

    I verified this locally with a real discounted product:

    {
      "productNo": 5048935,
      "name": "금실 딸기 2종",
      "currentPrice": 9900,
      "originalPrice": 9900,
      "salesPrice": null,
      "discountedPrice": null,
      "discountRate": 28,
      "imageUrl": null,
      "rawShowablePrices": {
        "salesPrice": 9900,
        "basePrice": null,
        "retailPrice": 13900,
        "couponDiscountedPrice": null
      },
      "rawRetailPrice": 13900,
      "rawMainImageUrl": "https://img-cf.kurly.com/shop/data/goods/1581671553838l0.jpg"
    }

    So the helper currently reports no original price, no discounted price, and no image for a product that is visibly discounted in the live payload. That is a user-facing correctness bug for the advertised “detail/follow-up lookup” flow.

    Please normalize detail pricing from the live detail shape (showablePrices / retailPrice, plus the relevant image fields such as mainImageUrl) and add a regression test for a discounted goods-page payload. The current detail test fixture at packages/market-kurly-search/test/index.test.js:73-125 only covers a non-discounted detail response, so it would not catch this regression.

Discounted goods pages are currently exposing original-price and image data
through retail/showable fields that the detail normalizer was not reading,
so the follow-up fix prefers those live fields and locks the behavior with
a discounted-detail regression fixture.

Constraint: Kurly detail payloads do not mirror the search API price field semantics
Rejected: Trust top-level basePrice alone | discounted live pages currently use retailPrice/showablePrices for the original price
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep detail normalization aligned with live goods-page payloads; verify real discounted products before changing price precedence again
Tested: node --test packages/market-kurly-search/test/index.test.js; npm run ci; live Node smoke for countProducts('우유'), searchProducts('우유'), getProductDetail(5063110), getProductDetail(5048935) on 2026-04-09
Not-tested: Additional undiscovered Market Kurly detail payload variants beyond the covered discounted fixture and live sample
@vkehfdl1
Copy link
Copy Markdown
Contributor Author

vkehfdl1 commented Apr 9, 2026

Fixed the discounted-detail normalization gap in market-kurly-search.

  • added a regression fixture/test for a discounted goods-page __NEXT_DATA__ payload
  • updated detail normalization to prefer retailPrice / showablePrices.retailPrice for the original price, infer discountedPrice from the lower live sales price when Kurly omits it explicitly, and fall back to mainImageUrl
  • verified the live discounted product path with getProductDetail(5048935) on 2026-04-09

Verification:

  • node --test packages/market-kurly-search/test/index.test.js
  • npm run ci
  • live Node smoke on 2026-04-09:
    • countProducts('우유')468
    • searchProducts('우유') first item → 5063110 / [연세우유 x 마켓컬리] 전용목장우유 900mL / 2780 / false
    • getProductDetail(5063110)2780 / 2780 / ['샛별배송(내일 아침)']
    • getProductDetail(5048935)9900 / 13900 / 9900 / imageUrl set

@vkehfdl1
Copy link
Copy Markdown
Contributor Author

vkehfdl1 commented Apr 9, 2026

APPROVE

Real Result

  • npm run ci
  • node --test packages/market-kurly-search/test/index.test.js
  • live Node smoke on 2026-04-09 ✅
    • countProducts('우유'){ query: '우유', count: 468 }
    • searchProducts('우유') first item → 5063110 / [연세우유 x 마켓컬리] 전용목장우유 900mL / 2780 / false
    • getProductDetail(5063110)currentPrice 2780 / originalPrice 2780 / discountedPrice null / deliveryTypeNames ['샛별배송(내일 아침)']
    • getProductDetail(5048935)currentPrice 9900 / originalPrice 13900 / discountedPrice 9900 / imageUrl present

Review

No blocking issues found in round 2.

Concrete evidence:

  • packages/market-kurly-search/src/parse.js:140-180 now normalizes detail pricing from retailPrice / showablePrices.retailPrice, infers discountedPrice from the lower live sales price when Kurly omits it explicitly, and falls back to mainImageUrl.
  • packages/market-kurly-search/test/index.test.js:151-163 adds a regression case for the discounted goods-page payload that previously failed review.
  • I also ran the code-review workflow locally; no additional CRITICAL/HIGH/MEDIUM/LOW issues surfaced for the market-kurly-search scope.

APPROVE.

@vkehfdl1
Copy link
Copy Markdown
Contributor Author

vkehfdl1 commented Apr 9, 2026

Re-verified the approved market-kurly-search follow-up on feature/#88.

  • confirmed the discounted detail normalization fix is present in packages/market-kurly-search/src/parse.js
  • confirmed the discounted goods-page regression coverage is present in packages/market-kurly-search/test/index.test.js
  • re-ran the required verification on 2026-04-09; no additional code delta was needed because feature/#88 already matched origin/feature/#88

Verification:

  • npm run ci
  • live Node smoke on 2026-04-09:
    • countProducts('우유'){ query: '우유', count: 468 }
    • searchProducts('우유') first item → 5063110 / [연세우유 x 마켓컬리] 전용목장우유 900mL / 2780 / false
    • getProductDetail(5063110)2780 / 2780 / null / ['샛별배송(내일 아침)']
    • getProductDetail(5048935)9900 / 13900 / 9900 / imageUrl present

@vkehfdl1
Copy link
Copy Markdown
Contributor Author

vkehfdl1 commented Apr 9, 2026

APPROVE

Real Result

  • npm run ci
  • node --test packages/market-kurly-search/test/index.test.js
  • live Node smoke on 2026-04-09 ✅
    • countProducts('우유'){ query: '우유', count: 468 }
    • searchProducts('우유') first item → 5063110 / [연세우유 x 마켓컬리] 전용목장우유 900mL / currentPrice 2780 / originalPrice 2780 / discountedPrice null / isSoldOut false
    • getProductDetail(5063110)currentPrice 2780 / originalPrice 2780 / discountedPrice null / deliveryTypeNames ['샛별배송(내일 아침)'] / imageUrl present
    • getProductDetail(5048935)currentPrice 9900 / originalPrice 13900 / discountedPrice 9900 / discountRate 28 / imageUrl present

Review

No blocking issues found in round 3.

Concrete evidence:

  • packages/market-kurly-search/src/index.js:58-86 still exposes the public searchProducts, countProducts, and getProductDetail helpers against the unauthenticated Kurly search/count/goods surfaces that the live smoke exercised.
  • packages/market-kurly-search/src/parse.js:140-180 keeps the discounted-detail normalization fix: it prefers retailPrice / showablePrices.retailPrice, infers discountedPrice from the lower live sales price when Kurly omits it explicitly, and falls back to mainImageUrl.
  • packages/market-kurly-search/test/index.test.js:92-163 locks the discounted goods-page regression with a fixture asserting originalPrice 13900, discountedPrice 9900, and the mainImageUrl fallback.
  • scripts/skill-docs.test.js:832-878 keeps the README/install/roadmap/sources/skill-doc coverage aligned and verifies the workspace exports for the new package.

I also ran the code-review workflow locally against the PR diff; no additional CRITICAL/HIGH/MEDIUM/LOW issues surfaced for the market-kurly-search scope.

APPROVE.

@vkehfdl1
Copy link
Copy Markdown
Contributor Author

vkehfdl1 commented Apr 9, 2026

Re-verified the approved market-kurly-search implementation on feature/#88; no additional code delta was needed because the branch already contains the discounted-detail normalization fix and regression coverage.

  • confirmed packages/market-kurly-search/src/parse.js still prefers retailPrice / showablePrices.retailPrice, infers discountedPrice from the lower live sales price, and falls back to mainImageUrl
  • confirmed packages/market-kurly-search/test/index.test.js still locks the discounted goods-page regression for originalPrice 13900, discountedPrice 9900, and the mainImageUrl fallback
  • confirmed package/docs/README/changeset alignment remains in place for the published market-kurly-search workspace and skill docs
  • confirmed PR Feature/#88 #95 already targets dev from feature/#88

Verification on 2026-04-09:

  • node --test packages/market-kurly-search/test/index.test.js
  • npm run ci
  • live Node smoke:
    • countProducts('우유'){ query: '우유', count: 468 }
    • searchProducts('우유') first item → 5063110 / [연세우유 x 마켓컬리] 전용목장우유 900mL / currentPrice 2780 / originalPrice 2780 / discountedPrice null / isSoldOut false
    • getProductDetail(5063110)currentPrice 2780 / originalPrice 2780 / discountedPrice null / deliveryTypeNames ['샛별배송(내일 아침)'] / imageUrl present
    • getProductDetail(5048935)currentPrice 9900 / originalPrice 13900 / discountedPrice 9900 / discountRate 28 / imageUrl present

@vkehfdl1
Copy link
Copy Markdown
Contributor Author

vkehfdl1 commented Apr 9, 2026

APPROVE

Short reason: Required verification still passes on 2026-04-09, and the previously blocking discounted-detail normalization bug is fixed and covered by regression tests.

Real Result

  • npm run ci
  • node --test packages/market-kurly-search/test/index.test.js
  • live Node smoke on 2026-04-09 ✅
    • countProducts('우유'){ query: '우유', count: 468 }
    • searchProducts('우유') first item → 5063110 / [연세우유 x 마켓컬리] 전용목장우유 900mL / currentPrice 2780 / originalPrice 2780 / discountedPrice null / isSoldOut false
    • getProductDetail(5063110)currentPrice 2780 / originalPrice 2780 / discountedPrice null / deliveryTypeNames ['샛별배송(내일 아침)'] / imageUrl present
    • getProductDetail(5048935)currentPrice 9900 / originalPrice 13900 / discountedPrice 9900 / discountRate 28 / imageUrl present

Concrete evidence

  • packages/market-kurly-search/src/parse.js:140-180 prefers retailPrice / showablePrices.retailPrice, infers discountedPrice from the lower live sales price when Kurly omits it explicitly, and falls back to mainImageUrl.
  • packages/market-kurly-search/test/index.test.js:151-163 locks the discounted goods-page regression with assertions for originalPrice 13900, discountedPrice 9900, and the mainImageUrl fallback.
  • scripts/skill-docs.test.js:832-878 keeps the README/install/roadmap/source/skill-doc coverage aligned and verifies the exported searchProducts, countProducts, and getProductDetail helpers.

APPROVE.

@vkehfdl1 vkehfdl1 merged commit 224fd3a into dev Apr 9, 2026
1 check passed
@vkehfdl1 vkehfdl1 deleted the feature/#88 branch April 9, 2026 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant