Here's the PR body:
## Summary
Checkout called the FX provider on every cart render. During Friday's sale that went over the provider's 1,000 requests/minute limit, and checkout started returning 429 errors. `get_rate` now keeps each rate in memory for 5 minutes.
```diff
get_rate(base, quote)
+ if base:quote was fetched less than 300s ago
+ return the saved rate
GET api.example-fx.com/latest
raise on HTTP error
+ save rate for base:quote with time.monotonic()
return rate
Evidence
-
Before:
pytestshows 14 passed. Everyget_ratecall makes its own HTTP request.
After:pytestshows 15 passed. Addedtest_get_rate_uses_cache_within_ttl:get_rate("USD", "EUR") get_rate("USD", "EUR") assert provider was called once
Merge Danger
Door: two-way
The cache only lives in memory, with nothing persisted and no schema change. To roll back, revert the commit.
Blast Radius: checkout
- Stale rates: prices can use a rate up to 5 minutes old. Confirm that's acceptable for checkout pricing.
- Per-process cache: each worker keeps its own cache. Provider calls per 5 minutes are roughly workers × currency pairs, so the limit could still be reached with many workers.
- No size limit or eviction: this is fine for a fixed set of currency pairs.
- No locking: two requests that miss the cache at the same moment can both call the provider. The only cost is an extra request.
- Test isolation:
_cacheis module-level, so it carries over between tests unless a fixture clears it.
- **No `GLOSSARY.md`:** the repo doesn't have one, so I used the wording from your context and the code.
- **Check this before merging:** `test_get_rate_returns_quote` already caches `USD:EUR`. If nothing clears `_cache` between tests, the new test should see 0 provider calls and fail. Since it passes, the `mock_get` fixture probably resets the cache, but I couldn't see the fixture to confirm. If it doesn't, the test result depends on the order tests run in, and I'd add an autouse fixture that calls `_cache.clear()`.
Real run recorded with claude-code / claude-opus-5-5. Output is shown verbatim, unmodified. The only change: the trial machine's temp-folder path was replaced with a generic placeholder.
하는 일
리뷰어가 빠르게 읽을 수 있는 Pull Request 설명을 세 부분으로 씁니다.
작동 방식
- Summary: 요점을 전하는 가장 작은 시각 자료. 의사 코드, 호출 트리, 컴포넌트 트리, 파일 트리, Mermaid 다이어그램, diff 스케치 중 하나를 그것이 뒷받침하는 짧은 글 옆에 둡니다.
- Evidence: 구체적인 변경 전후. 시각적인 변경이면 스크린샷이 가장 좋고, 아니면 실패에서 통과로 바뀐 테스트 자체를 보여 줍니다.
- Merge Danger: 변경이 한 방향 문인지 양방향 문인지(되돌릴 수 있는지), 그리고 영향 범위(레이아웃 이동, 사용하는 쪽의 깨짐 등).
- 서두를 생략하고 간결하게 쓰며, 저장소에
GLOSSARY.md가 있으면 그 용어를 씁니다.
이럴 때 좋습니다
리뷰어에게 무엇이 바뀌었고 얼마나 위험한지 보여 주어야 하는 Pull Request.
알아 둘 점
저희 테스트에서는 diff만으로 확인할 수 없는 위험(테스트 간 격리 문제)도 숨기지 않고 짚어 주었습니다.
지시문만 담긴 파일로, 스크립트가 없고 네트워크에 연결하지 않습니다. Summary 섹션의 시각 자료 목록은 Dex Horthy(HumanLayer, MIT 라이선스)의 show-me skill을 바탕으로 한 것이며, 패키지에 해당 라이선스를 LICENSE-show-me로, 설명을 CREDITS.md로 포함했습니다. 텍스트만 작성하며 git을 실행하거나 Pull Request를 대신 만들지 않습니다. 패키지에는 원본 저장소의 MIT 라이선스(LICENSE)와 agents/openai.yaml(Codex용 표시 이름)도 들어 있습니다.