Amazon Import — Task Plan
Author: Miguel Pinilla Date: 2026-05-20 Status: Planning
User Request
Section titled “User Request”Implement the POST /api/amazon/search BFF route in arda-frontend-app
per the design in spec-analysis.md, plus the
shared URL/ASIN input normalisation layer that broadens the set of
accepted URL/ASIN shapes for both /api/amazon/import and
/api/amazon/search. The work covers: schemeless / path-only / mixed-case
URL handling; extended US sub-hosts (m., smile., read.); old-form
product URL paths; plain-text ASIN extraction (lenient on /import
only); defensive input filter for /search; ASIN extract-and-dispatch
(including multi-ASIN paste); smart UPC/EAN/ISBN identifier mode; silent
Amazon-side query relaxation; and observability parity with the
workspace’s recent Sentry conventions (including retrofitting
/api/amazon/import if it falls short). All work lands in a single PR
(#836) on
the existing jmpicnic/amazon-import-search branch.
Decomposition
Section titled “Decomposition”Task List
Section titled “Task List”Tasks are grouped by phase; phases reflect the dependency graph. All tasks
use persona front-end-engineer.
Phase 1 — Audit
Section titled “Phase 1 — Audit”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 1 | Verification pass | — | Complete | Read existing /api/amazon/import route, creators-client, MSW handlers, env.ts, observability. Output: short audit note appended to this file (see Audit Outputs). Resolves I1, I2, I3 before implementation. |
Phase 2 — URL/ASIN input normalisation
Section titled “Phase 2 — URL/ASIN input normalisation”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 2 | Extend extractAsin (strict) in src/lib/shared/amazon/asin.ts | 1 | Complete | Case-fold bare ASIN; add m./smile./read.amazon.com to US allow-list; add /exec/obidos/ASIN/ and /o/ASIN/ to path regex; scheme-prepend retry; path-only matching with or without leading /. Existing tests pass except flipped m./smile./read. expectations; ~22 new unit-test cases. |
| 3 | Add extractAsinLenient (plain-text fallback) | 2 | Complete | New sibling export. Runs strict extractAsin first; only falls through to ASIN-in-text extraction when no authoritative Amazon URL was parsed (i.e. the input is plain text). A US Amazon URL that parsed but pointed at a non-product path is preserved as a recognised rejection and is not scanned for bare ASINs. Plain-text scan uses \b(B[A-Za-z0-9]{9}|\d{9}[\dXx])\b with digit-presence guard for the B-branch; requires exactly one distinct match. Unit tests cover the 8 plain-text cases. |
| 4 | Switch /api/amazon/import route to extractAsinLenient | 3 | Complete | Update src/server/routes/amazon/import.ts to call extractAsinLenient instead of extractAsin. Rewrite the UNRECOGNIZED_AMAZON_URL user-facing message to “We could not identify an Amazon Reference in your input.” Existing route tests + new tests for the broader acceptance set. Response contract preserved verbatim. |
Phase 3 — Foundation
Section titled “Phase 3 — Foundation”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 5 | Server-side constants module | 1 | Complete | Declare all MAX_* / RELAXATION_* / BATCH_ASIN_MAX constants in one place with the values from spec. |
| 6 | Shared resource selector + resourcesForMode | 1 | Complete | Factor BASE_ITEM_RESOURCES out of existing getItems path; add resourcesForMode("default" | "identifier"). |
Phase 4 — Pure helpers
Section titled “Phase 4 — Pure helpers”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 7 | Defensive input filter | 1, 5 | Complete | Pure function per spec; unit tests for every filter step + the “at-least-one-search-term” rule. |
| 8 | Category resolver | 1, 5 | Complete | resolveCategory(label) + curated synonym table (n:1) + unit tests; covers Q1 option (a) for multi-category. |
| 9 | ASIN multi-token extraction (strict) | 1, 2, 5 | Complete | Tokeniser + per-token strict extractAsin (Phase 2 Task 2 output); batch-cap enforcement; unit tests including mixed-token fall-through; verifies plain-text-ASIN extraction is NOT used here. |
| 10 | Identifier classifier + filter + dedup | 1, 5, 6 | Complete | UPC/EAN/ISBN patterns, all-tokens-identifier check, filterByExternalIds, ASIN dedup; unit tests. |
Phase 5 — Composition
Section titled “Phase 5 — Composition”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 11 | BFF→SDK request builder | 6, 8, 10 | Complete | buildSearchRequest(filtered) in search-request-builder.ts; pure; 24 unit tests covering default mode (query, keywords, categories, primeOnly, sortBy), identifier mode (pipe-join, searchIndex=All, deliveryFlags/categories ignored), and edge cases. |
Phase 6 — Client
Section titled “Phase 6 — Client”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 12 | creatorsClient.searchItems wrapper | 6, 11 | Complete | Async wrapper mirroring getItems shape; error→AMAZON_API_ERROR; Layer-2 tests using the existing SDK-mock pattern. |
Phase 7 — Orchestration
Section titled “Phase 7 — Orchestration”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 13 | Silent Amazon-side relaxation orchestrator | 12 | Complete | Bounded retry ladder (drop deliveryFlags → drop category); RELAXATION_MAX_RETRIES + RELAXATION_TIME_BUDGET_MS; unit tests. |
Phase 8 — Route
Section titled “Phase 8 — Route”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 14 | Route handler src/server/routes/amazon/search.ts | 7, 8, 9, 11, 13 | Complete | Validates input; dispatches ASIN shortcut / identifier mode / default; returns response envelope. Shared item-mapper.ts extracted. 30 unit tests. |
| 15 | Next.js POST handler src/app/api/amazon/search/route.ts | 14 | Complete | Thin POST handler; auth wired identically to /api/amazon/import. 12 unit tests. |
Phase 9 — MSW
Section titled “Phase 9 — MSW”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 16 | MSW Layer-1 handlers + fixtures | 14, 15 | Complete | src/mocks/handlers/amazon.ts + src/mocks/data/: success multi-item, zero results, INVALID_SEARCH_INPUT, AMAZON_API_ERROR, identifier mode. |
Phase 10 — Tests
Section titled “Phase 10 — Tests”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 17 | Layer-1 consumer tests | 16 | Complete | 1–2 jest tests that fetch('/api/amazon/search', body) through MSW; double as PDEV-477 reference. |
| 18 | Route-level tests (full matrix) | 14, 15 | Complete | Per-branch coverage of the test matrix (see Acceptance Criteria). |
Phase 11 — Observability
Section titled “Phase 11 — Observability”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 19 | Observability audit + retrofit | 14, 15 | Complete | Option (a) chosen — spans + breadcrumbs + captureException + relaxation metric landed in commit 2ec2f9f3. 7 files modified (creators-client.ts, search.ts, import.ts, their 3 test files, __mocks__/@sentry/nextjs.ts). 32 new test assertions. No follow-up ticket required. See decision I6. |
Phase 12 — Integration
Section titled “Phase 12 — Integration”| # | Task | Depends On | Status | Notes |
|---|---|---|---|---|
| 20 | Final integration + local gates + CHANGELOG roll-up | 1–19 | Complete | Local gates: eslint clean, tsc clean, jest 5300/310 suites passing, npm run build succeeds. PR #836 title + body rewritten to consolidate the project-setup drive-bys, PDEV-318 AGENTS.md shim, URL/ASIN normalisation, new /api/amazon/search route, and Sentry observability into a single ### Added block (plus the existing ### Fixed for the Playwright tsc fix). The 27 pre-existing tsc errors and the npm run build failure observed earlier were resolved by aligning node_modules to the lockfile via npm install (the lockfile already pinned design-system 5.3.0; node_modules had been left at the older 5.2.1). |
Worktree Strategy
Section titled “Worktree Strategy”Single directory — no new worktrees needed. All work lands on the
existing jmpicnic/amazon-import-search branch in the
/Users/jmp/code/arda/projects/amazon-import-search-worktrees/arda-frontend-app
worktree, extending PR #836. Documentation updates land in the
sibling documentation worktree on the same branch name, extending
PR #83. No parallel agents.
Base branch: main (in Arda-cards/arda-frontend-app and
Arda-cards/documentation).
Parallelization
Section titled “Parallelization”Single agent — tasks execute strictly in dependency order. No concurrent work. The phases shown in the task list above reflect the dependency graph; within a phase, tasks are still serialised because there is only one agent. If the project is later multi-agent, Phase 4’s four pure helpers (Tasks 7–10) and Phase 8’s two route artifacts (Tasks 14–15) are the natural parallelisation seams.
Idle Agent Strategy
Section titled “Idle Agent Strategy”Accept idle time — single-agent plan, no idleness to manage.
Personas Required
Section titled “Personas Required”| Persona | Tasks Assigned | Worktree | Spawn Order |
|---|---|---|---|
| front-end-engineer | 1–20 | /Users/jmp/code/arda/projects/amazon-import-search-worktrees/arda-frontend-app (+ documentation) | First |
Open Questions and Decisions
Section titled “Open Questions and Decisions”All scope-level questions resolved during exploration (see
spec-analysis.md — Open questions).
Implementation-detail questions deferred to Task 1’s verification
output:
| # | Question | Options | Recommendation | Decision |
|---|---|---|---|---|
| I1 | Existing error envelope shape on /api/amazon/import | Read from code | Match exactly | Resolved: success wire shape is { ok: true, data: <body> }; error wire shape is { ok: false, code, message }. Next.js handler renames route module’s internal field to data. Status codes per statusMap in src/app/api/amazon/import/route.ts:77-86. Success status is 200 when name+image+price+productUrl all non-null, 206 otherwise. For /search, items are list-shaped so partial-completeness 206 does not apply — always 200 on success. |
| I2 | Existing Sentry / observability primitives used in this repo | Read from code | Match exactly, retrofit /import if behind | Resolved: repo uses addBreadcrumb + metrics.count + captureException directly at call sites. Sentry.startSpan is NOT used in production code today (only a demo page). /api/amazon/import is NOT wrapped in any span; creators-client.ts does NOT wrap Amazon SDK calls. The “retrofit” decision in Phase 11 becomes: introduce spans (new pattern) or match existing breadcrumbs+metrics. Surface to user. |
| I3 | Existing Amazon-API mocking pattern in creators-client.test.ts | SDK-method mock vs. msw/node vs. transport-level | Match the existing pattern verbatim | Resolved: jest.mock('amazon-creators-api', () => { class MockApiClient ... }, { virtual: true }). Class mocks for ApiClient, TypedDefaultApi, GetItemsRequestContent with per-method jest.fn(). virtual: true because the package is not installed locally. __resetApiClientCacheForTests() in beforeEach. Match verbatim for searchItems tests. |
| I4 | Coverage thresholds actually enforced | Read from jest.config.js | Confirmed: jest.config.js coverageThreshold.global is lines: 84, statements: 84, functions: 81, branches: 72 (global, not per-file). README’s 11–18% numbers refer to merged Jest+E2E thresholds (a different gate) and are stale. The new code targets are higher; see Acceptance Criteria. | Resolved |
| I5 | API reference page in current-system/ | Skip / inline / follow-up | Postpone until after merge; capture as Linear comment | Resolved by user |
| I6 | /api/amazon/import observability retrofit scope | (a) retrofit in this PR / (b) follow-on PR / (c) no retrofit | Option (a) for Medium scope | Resolved (user-authorized): Option (a) chosen. Retrofit landed in commit 2ec2f9f3 alongside the new /search observability. Both routes now ship at parity: outer Sentry.startSpan (op function.bff), dispatch + validation breadcrumbs, captureException on Amazon API errors, and amazon.search.relaxation metric when relaxation fires. creators-client.ts wraps both SDK calls (getItems, searchItems) in http.client spans. 7 files modified, 32 new test assertions, no follow-up ticket required. |
Acceptance Criteria
Section titled “Acceptance Criteria”The Team Lead (or single agent) knows the work is complete when every item below is checked.
URL/ASIN input normalisation
Section titled “URL/ASIN input normalisation”-
extractAsin(strict) accepts schemeless URLs (www.amazon.com/dp/<ASIN>,amazon.com/dp/<ASIN>). -
extractAsinaccepts path-only inputs both with and without leading/(e.g.,/dp/<ASIN>,dp/<ASIN>,Some-Product/dp/<ASIN>,gp/product/<ASIN>,gp/aw/d/<ASIN>). -
extractAsinaccepts lowercase / mixed-case bare ASINs (case-folded before pattern test). -
extractAsinacceptsm.amazon.com,smile.amazon.com,read.amazon.com(added to US allow-list). -
extractAsinaccepts old-form paths/exec/obidos/ASIN/<ASIN>and/o/ASIN/<ASIN>(with or without leading/). -
extractAsinreturnsUNRECOGNIZED_AMAZON_URL(not falling through) when a URL parses with a US Amazon host but the path is non-product (search/cart/homepage). -
extractAsinLenientcallsextractAsinfirst and only falls back to plain-text ASIN extraction when no authoritative Amazon URL was parsed (i.e. the input is plain text). A URL that parsed but pointed at a non-product US Amazon path returnsUNRECOGNIZED_AMAZON_URLwithout scanning for bare ASINs.UNSUPPORTED_SHORT_LINKandUNSUPPORTED_AMAZON_LOCALEshort-circuit. - Plain-text ASIN extraction uses
\b(B[A-Za-z0-9]{9}\|\d{9}[\dXx])\bwith a digit-presence guard for theB-branch; rejects 10-letter English words. - Plain-text ASIN extraction requires exactly one distinct match; zero or ≥2 matches →
UNRECOGNIZED_AMAZON_URL. -
/api/amazon/importroute handler usesextractAsinLenient. -
/api/amazon/searchASIN-shortcut dispatcher (multi-token tokeniser) uses strictextractAsin— verified by a test that a search query likeB08N5WRWNW alternativesdoes NOT trigger the ASIN shortcut.
Routing and contract
Section titled “Routing and contract”-
POST /api/amazon/importpreserves its response contract verbatim (DTO shape, error codes, HTTP statuses). Previously accepted inputs still succeed; the broadened acceptance set (per the criteria above) succeeds on inputs that previously returnedUNRECOGNIZED_AMAZON_URL. -
POST /api/amazon/searchaccepts{ query?, keywords?, categories?, primeOnly?, sortBy? }and returns{ items: AmazonImportDto[], totalResultsHint? }on success (200). - Server-side constants module exports
MAX_QUERY_LENGTH,MAX_KEYWORDS,MAX_KEYWORD_LENGTH,MAX_CATEGORIES,MAX_CATEGORY_LENGTH,MAX_RESULTS,RELAXATION_MAX_RETRIES,RELAXATION_TIME_BUDGET_MS,BATCH_ASIN_MAXwith the values fromspec-analysis.md— Constants. -
BASE_ITEM_RESOURCESis shared betweengetItemsandsearchItemscall sites (no duplicate resource list).
Validation
Section titled “Validation”- Over-length
query→INVALID_SEARCH_INPUT(400). - Over-cardinality
keywords[]orcategories[]→INVALID_SEARCH_INPUT. - No search terms (
queryempty/absent andkeywords[]empty/absent post-filter) →INVALID_SEARCH_INPUT. - Unknown
sortByvalue →INVALID_SEARCH_INPUT. - Multi-ASIN paste exceeds
BATCH_ASIN_MAX→INVALID_SEARCH_INPUT. - Empty
keywords: []andcategories: []arrays treated as absent (not malformed).
Dispatch paths
Section titled “Dispatch paths”- Single bare ASIN →
getItemsshortcut, returns one-item list. - Single Amazon product URL on
amazon.com→getItemsshortcut. - Multiple ASINs/URLs (≤10) separated by whitespace, commas,
semicolons, or newlines → single batched
getItemscall. - ASIN embedded in surrounding free text → no shortcut; passes
through to
SearchItemsas keywords. - Short-link URL (
a.co/,amzn.to/) →UNSUPPORTED_SHORT_LINK. - Non-US-locale Amazon URL →
UNSUPPORTED_AMAZON_LOCALE. - Pure-identifier list (all tokens UPC/EAN/ISBN-10/ISBN-13) →
identifier mode (
SearchIndex=All, pipe-joined keywords,ItemInfo.ExternalIdsin resources, response filtered + deduped). - Mixed identifier + keyword tokens → falls through to plain keyword search.
Silent relaxation
Section titled “Silent relaxation”- Zero result → drop
deliveryFlagsand retry (if Prime was set). - Still zero result → drop
searchIndex/browseNodeIdand retry (if category was set). - At most
1 + RELAXATION_MAX_RETRIESAmazon S2S calls per request. - Total wall-clock for relaxation respects
RELAXATION_TIME_BUDGET_MS(early-exit on overshoot). - Relaxation never mutates
keywordscontent. - Zero results post-relaxation →
200withitems: [](not an error).
Identifier mode specifics
Section titled “Identifier mode specifics”- Amazon “adjacent products” filtered out via
ItemInfo.ExternalIds.{EANs,UPCs,ISBNs}.DisplayValuesexact-match. - Items echoed by multiple input identifiers deduped by ASIN (first occurrence preserved).
- Output ordered as Amazon returned them, with non-matches removed and ASIN duplicates collapsed.
Upstream errors
Section titled “Upstream errors”- Amazon SDK throws / rejects / 5xx / throttle →
AMAZON_API_ERROR(502).
-
src/mocks/handlers/amazon.tsadds handlers for/api/amazon/searchcovering: success (multi-item), zero results (200+ empty),INVALID_SEARCH_INPUT,AMAZON_API_ERROR, identifier-mode success. - Layer-1 consumer tests (1–2) fetch through MSW and assert the response shape.
- No live Amazon calls run in CI.
- All defensive-filter steps unit-tested independently.
-
resolveCategorycovers identity matches, synonym matches, and unresolved labels. -
filterByExternalIdscovers exact match, no-match, multiple identifier types per item. - ASIN dedup tested with multi-identifier input pointing to the same ASIN.
- Layer-2 tests cover
creatorsClient.searchItemshappy paths per mode and each error class. - Route-level tests cover the full matrix above.
- Coverage gates pass:
jest.config.jsenforces global thresholdslines: 84,statements: 84,functions: 81,branches: 72. New code must keep the global aggregates above these values, and new modules should individually exceed them by a safety margin (target ≥ 90% lines / statements, ≥ 85% branches on new files, since the new code is mostly pure functions).
Observability
Section titled “Observability”- Sentry user-span wraps the route handler.
- Each Amazon S2S call (search + relaxation retries + identifier resolution) carries its own timed span as a child of the request span.
- Errors caught at the route boundary are reported to Sentry with correlation to the request span.
- If the Task 1 audit flagged any of the above missing in
/api/amazon/import, the retrofit lands in this PR.
Constraints from goal.md
Section titled “Constraints from goal.md”- No new external dependencies, server secrets, env vars, or operations-backend changes.
- Reuses existing
creatorsClient, OAuth2 credentials, marketplace header, affiliate-tag helper. - No UI/UX changes; no React component, page, hook, or Storybook story modified beyond keeping existing tests green.
Local gates and PR
Section titled “Local gates and PR”-
npx eslint .clean. -
npx tsc --noEmitclean. -
npx jest --no-coverage --watchAll=false --forceExitgreen. -
npm run buildsucceeds locally (with the placeholderAMAZON_CREATORS_*env vars fromknowledge-base/amazon-creators-local-env.md). - PR #836 body has a single consolidated
## CHANGELOGsection rolling up the project-setup, AGENTS.md shim, and BFF additions into one### Addedblock (plus the existing### Fixed).
Risks and Blockers
Section titled “Risks and Blockers”| Risk / Blocker | Impact | Mitigation |
|---|---|---|
| Task 1 audit surfaces an existing error-envelope or auth pattern that conflicts with the spec’s informal shape | Forces a contract revision late in the project | Task 1 explicitly outputs an audit note before Task 2 starts. Any mismatch with the spec is escalated to the user before committing implementation. |
/api/amazon/import is materially behind on Sentry conventions and the retrofit is large | Inflates PR #836 scope and review time | Task 19 produces a sized estimate of the retrofit and surfaces it to the user with options and trade-offs (see Retrofit decision protocol). User decides scope; decision recorded in this file before Task 19 proceeds. |
Coverage thresholds (jest.config.js: 84/84/81/72 global) | Global aggregates could dip if large new code lands sparsely tested | New modules are pure functions with deterministic input/output. Target ≥ 90% lines/statements / ≥ 85% branches on new files, well above the global gates. |
| Amazon SDK quirks (e.g. response shape variations across modes) | Identifier-mode filtering or default-mode mapping silently mishandles edge cases | Layer-2 tests use realistic fixtures captured from the SDK’s documented types; identifier-mode “adjacent products” case is an explicit test scenario. |
Branch divergence from main while implementation is in flight (significant refactors land that touch BFF / Sentry / mocks / shared helpers, likely outside this project’s scope) | Conflict resolution cost; risk of silently inheriting a contract or pattern change without noticing | Check origin/main staleness at every phase boundary. Run git -C <fe-worktree> fetch origin && git -C <fe-worktree> log --oneline HEAD..origin/main -- <touched-paths> (see Staleness-check command). If commits land that touch the route, the client wrapper, MSW handlers, env, observability, or any helper this project depends on, pause and either rebase or surface the conflict to the user before continuing. Force-push (with --force-with-lease) after each rebase. |
| Smart-identifier work uncovers further sub-bits not documented | Implementation paused for spec edits | Spec already documents the sub-bits (conditional resource selector, response filter, dedup, ordering). New findings get flagged to the user, not silenced. |
Mid-flight protocols
Section titled “Mid-flight protocols”Retrofit decision protocol
Section titled “Retrofit decision protocol”Task 19 begins with an audit phase only — read every observability
touchpoint in /api/amazon/import and the surrounding stack, then
compare against the workspace’s current Sentry conventions. The output
is a one-paragraph summary recorded in
Audit Outputs (under a Task 19 subheading,
alongside Task 1’s audit) with:
- A list of probes present today.
- A list of probes the conventions expect but that are missing.
- A sized estimate (Small / Medium / Large) of how much code change the retrofit would require.
The implementation pauses there. Three options are presented to the user, with the recommendation:
| Option | Description | Trade-off |
|---|---|---|
(a) Retrofit /import in this PR (recommended for Small) | Apply the same observability envelope to /import as part of PR #836. Both routes ship at parity. | PR grows by N lines; review surface grows. |
(b) Retrofit /import in a follow-on PR | Ship /search with full observability; file a separate ticket for /import retrofit, link to it from PDEV-457’s completion notes. | Parity gap exists between merges; ticket may drift if not picked up promptly. |
| (c) No retrofit | Ship /search matching /import’s current (lower) observability bar. | Codifies the gap; harder to argue for retrofit later when both routes look the same. |
The user’s decision is recorded as a row in
Open Questions and Decisions (new
row I6 — /api/amazon/import observability retrofit scope) before
Task 19 proceeds beyond the audit. Default if no response within the
work window: option (b) — file the follow-on ticket and continue.
Staleness-check command
Section titled “Staleness-check command”At every phase boundary, before starting the next phase’s first task, run:
git -C /Users/jmp/code/arda/projects/amazon-import-search-worktrees/arda-frontend-app fetch origingit -C /Users/jmp/code/arda/projects/amazon-import-search-worktrees/arda-frontend-app log --oneline HEAD..origin/main -- \ 'src/app/api/amazon/**' \ 'src/server/routes/amazon/**' \ 'src/server/lib/amazon/**' \ 'src/lib/env.ts' \ 'src/lib/shared/amazon/**' \ 'src/mocks/handlers/amazon.ts' \ 'src/mocks/data/**' \ 'instrumentation.ts' \ 'instrumentation-client.ts' \ 'sentry.*.config.ts' \ 'jest.config.js' \ 'package.json' \ 'package-lock.json'If the output is non-empty, stop and triage before continuing:
- Inspect each commit. Most edits in adjacent areas are safe to inherit via rebase.
- If a commit changes a contract this plan depends on (error envelope, Sentry primitive, MSW pattern, route conventions, jest thresholds), surface it to the user with the commit SHA and a one-line summary. Decide whether the plan needs an amendment before proceeding.
- Rebase the branch (
git -C <worktree> rebase origin/main), reconcile any conflicts, re-run the local gates, force-push with--force-with-lease.
Refresh the staleness check at every phase boundary, not just on errors — the smaller the increment, the cheaper the rebase.
Project Completion Artifacts
Section titled “Project Completion Artifacts”When the work is complete, the following artifacts should exist:
| Artifact | Status |
|---|---|
arda-frontend-app PR #836 includes the full BFF implementation (route handler, Next.js handler, client wrapper, helpers, constants, MSW handlers, tests). | Pending |
All local gates green; PR-body ## CHANGELOG consolidated. | Pending |
documentation PR #83 includes this task-plan.md and any verification-pass output that warrants archival. | Pending |
roadmap/in-progress/amazon-import-search/ moves to roadmap/completed/amazon-import-search/ after the PRs merge. | Complete |
| PDEV-457 marked Done in Linear. | Pending |
Audit Outputs
Section titled “Audit Outputs”Holds the audit notes for the two audit-phase tasks in this project:
Task 1 (verification pass — locks the existing /api/amazon/import
shape, auth wiring, Sentry primitives, MSW conventions, and per-file
coverage thresholds before implementation begins) and Task 19
(observability retrofit audit — compares the existing /import
observability surface against the workspace’s Sentry conventions and
estimates retrofit scope before the Phase 11 implementation continues).
Task 1 — Verification pass
Section titled “Task 1 — Verification pass”Intentionally blank at plan-time. Task 1’s output goes here as a short audit note covering:
- Existing error-envelope shape on
/api/amazon/import - Existing auth wiring (Cognito JWT verification path)
- Existing Sentry integration primitives used in the repo
- Existing Amazon-API mocking pattern in
creators-client.test.ts - Existing MSW handler conventions in
src/mocks/handlers/amazon.ts - Where
BASE_ITEM_RESOURCESshould be factored out of - Per-file coverage threshold actually enforced
- Anything else that should be locked before implementation
Task 19 — Observability retrofit audit
Section titled “Task 19 — Observability retrofit audit”Intentionally blank at plan-time. Task 19’s audit summary goes here per the Retrofit decision protocol:
- Probes present today on
/api/amazon/import(spans, breadcrumbs, metrics,captureExceptionsites). - Probes the current Sentry conventions expect but that are missing.
- Sized estimate (Small / Medium / Large) of the retrofit code change.
Decision recorded against this audit goes as a row in Open Questions and Decisions (row I6).
Copyright: (c) Arda Systems 2025-2026, All rights reserved
Copyright: © Arda Systems 2025-2026, All rights reserved