Skip to content

BFF Stream — Changelog

Authoritative artefact: arda-frontend-app PR #832 (merged 2026-05-08).

  • /api/amazon/import BFF Route Handler: accepts { asinOrUrl }, returns the v1 DTO with HTTP 200 (complete) / 206 (partial) / error-coded 4xx.
  • src/server/lib/amazon/creators-client.ts: typed wrapper around amazon-creators-api@1.2.2 (pinned exactly, no caret). ApiClient hoisted to module scope so the SDK’s per-instance OAuth2 token cache survives across BFF requests.
  • src/lib/shared/amazon/: extractAsin (URL/ASIN normaliser), buildAffiliateUrl, v1 DTO types, MARKETPLACE = "www.amazon.com" constant.
  • Four AMAZON_* entries in src/lib/env.ts (AMAZON_CREATORS_CREDENTIAL_ID, AMAZON_CREATORS_CREDENTIAL_SECRET, AMAZON_CREATORS_CREDENTIAL_VERSION, AMAZON_ASSOCIATE_TAG) with mock-mode fallbacks; matching entries in amplify.yml allowlist.
  • MSW handler src/mocks/handlers/amazon.ts for mock-mode dev and E2E.
  • Unit-test coverage: ASIN extractor URL-form matrix; affiliate-URL builder; Creators API client (stubbed SDK); route logic (full error matrix); Route Handler (JWT gate + error-code → HTTP-status mapping).
  • B1 (review) — JWT-failure path now returns { ok: false, code: "AUTHENTICATION_REQUIRED", message } with HTTP 401, matching the { ok, code, message } contract used by all other error paths.
  • M3 (review)buildAffiliateUrl wraps tag with encodeURIComponent so future tags containing +, &, =, or % do not corrupt the query string.
  • M3 (review)amazon-creators-api ApiClient hoisted to module scope (lazy-init), restoring per-process OAuth2 token caching across BFF requests (previously a fresh ApiClient was constructed per call, forcing a new auth/o2/token round trip every ~9-minute token lifetime instead of once).
  • B2 (review)AmazonImportDto fields name, image, price, productUrl are nullable; the mapper passes null through verbatim when Amazon omits a field, so callers can distinguish “Amazon did not provide this” from a real empty value. image and price are either fully-populated or null — never partial. asin is always sourced from the validated input.
  • B3 (review) — Route returns HTTP 200 only when all four core fields (name, image, price, productUrl) are present; HTTP 206 when any core field is null. unitCount / unit / upc do not affect completeness.