Skip to content

feat(api): cache reference data in memory for 24 hours - #132

Merged
mathieumaf merged 1 commit into
mainfrom
feat/cache-reference-data
Nov 5, 2026
Merged

mathieumaf merged 1 commit into
mainfrom
feat/cache-reference-data

Conversation

@mathieumaf

@mathieumaf mathieumaf commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Why

Cantons, institutions and the CPV/BKP/NPK/OAG nomenclatures almost never change, yet every lookup hit simap.ch and used a slot of the 60 requests/minute budget. Models often explore codes and come back to them before searching, so these calls repeat a lot within a session.

What

  • src/api/response-cache.ts (new): ResponseCache, an in-memory cache with a per-entry TTL, capped at 500 entries (least recently used evicted first). It stores the pending promise, so concurrent identical requests share one upstream call. Rejected requests, including Zod validation failures, are evicted and never cached.
  • SimapClient.get(): new opt-in cacheTtlMs option, keyed on the full URL (query params included). A cache hit skips the rate limiter and the network and is logged as GET <endpoint> (cache hit). New REFERENCE_DATA_TTL_MS constant (24 h).
  • Interaction with retries (feat(api): retry transient simap failures with exponential backoff #131): the cache wraps the retry loop. A hit skips the rate limiter, the network and any retries; on a miss the request goes through the usual retries and only the final successful result is cached. SimapClient takes the cache as an optional 4th constructor argument, after retry.
  • Cached tools: list_cantons, list_institutions, search_{cpv,bkp,npk,oag}_codes, browse_{cpv,bkp,npk,oag}_tree.
  • Not cached: search_tenders, get_tender_details, search_proc_offices, get_publication_history (live data).
  • Docs: ARCHITECTURE.md and CLAUDE.md updated. Changeset: patch, since tools, parameters and output are unchanged.

Trade-off

Reference data can be up to 24 h stale. The cache lives in process memory only and is cleared when the server restarts.

Tests

  • tests/api/response-cache.test.ts: hit/miss, TTL expiry, LRU eviction, shared in-flight load, failures not cached, clear().
  • tests/api/client.test.ts: no caching without cacheTtlMs, caching keyed on params, API errors and schema failures not cached, no rate-limit slot used on a hit, cache-hit log line, successful result of a retried request cached once.

npm run typecheck, npm run lint, npm run format:check, npm run build and npm test (364 tests, after rebasing on #130 and #131) pass locally.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 50 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 3edd454 and 0bc01bf.

Files selected for processing: 18

  • .changeset/cache-reference-data.md
  • ARCHITECTURE.md
  • CLAUDE.md
  • src/api/client.ts
  • src/api/index.ts
  • src/api/response-cache.ts
  • src/tools/codes/browse-bkp-tree.ts
  • src/tools/codes/browse-cpv-tree.ts
  • src/tools/codes/browse-npk-tree.ts
  • src/tools/codes/browse-oag-tree.ts
  • src/tools/codes/list-cantons.ts
  • src/tools/codes/search-bkp-codes.ts
  • src/tools/codes/search-cpv-codes.ts
  • src/tools/codes/search-npk-codes.ts
  • src/tools/codes/search-oag-codes.ts
  • src/tools/organizations/list-institutions.ts
  • tests/api/client.test.ts
  • tests/api/response-cache.test.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

Share

@changeset-bot

changeset-bot Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 0bc01bf

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@digilac/simap-mcp Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Add ResponseCache (TTL + LRU, in-flight dedupe, errors never cached) and
an opt-in cacheTtlMs option on SimapClient.get(). The cantons,
institutions and CPV/BKP/NPK/OAG code tools now use a 24 h TTL, so
repeated lookups skip the network and the 60 req/min rate limiter.
Tender and organization lookups stay live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mathieumaf
mathieumaf force-pushed the feat/cache-reference-data branch from 0168baa to 0bc01bf Compare November 5, 2026 10:19
@mathieumaf
mathieumaf merged commit d66011d into main Nov 5, 2026
7 checks passed
@mathieumaf
mathieumaf deleted the feat/cache-reference-data branch November 5, 2026 10:36
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