-
Notifications
You must be signed in to change notification settings - Fork 1
backlog(B-0610): amazon-orders-extract v3 design pass #4020
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
AceHack
merged 2 commits into
main
from
feat/b0610-amazon-orders-extract-v3-design-pass-2026-05-16
May 17, 2026
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
185 changes: 185 additions & 0 deletions
185
docs/backlog/P2/B-0610-amazon-orders-extract-v3-design-pass-2026-05-16.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,185 @@ | ||
| --- | ||
| id: B-0610 | ||
| status: open | ||
| priority: P2 | ||
| created: 2026-05-16 | ||
| type: feature | ||
| composes_with: | ||
| - B-0600 # family-distributed AI interface (per-relative AI on miner fleet — different consumer of the same inventory substrate) | ||
| - B-0590 # fleet replication + hardware inventory substrate (consumer of this script's output) | ||
| depends_on: [] | ||
| --- | ||
|
|
||
| # Amazon orders extract — v3 design pass (8 deferred reviewer-thread findings) | ||
|
|
||
| ## Substrate-honest context | ||
|
|
||
| The personal Amazon order-history extractor (`tools/inventory/amazon-orders-extract.ts`) | ||
| landed via [PR #3993](https://github.com/Lucent-Financial-Group/Zeta/pull/3993) | ||
| in five iterative batches (v1 → v2 → v2.3 → v2.4 → v2.4.1 → v2.5) addressing | ||
| 19 of 27 reviewer-thread findings. This row captures the **8 remaining | ||
| findings** that require substantive design work — they are legitimate but | ||
| do not fit a 1-line patch. | ||
|
|
||
| This is NOT scope-creep on the original PR. The v1-v2.5 script is | ||
| functional for the immediate use case (hardware-inventory audit + accountant | ||
| data preservation per the maintainer's operational need). The v3 design | ||
| pass refines it into a more robust general-purpose extractor. | ||
|
|
||
| ## 8 deferred findings | ||
|
|
||
| ### 1. Dedupe drops duplicate purchases (P0/P1) | ||
|
|
||
| **Threads**: chatgpt-codex-connector (line 207) + copilot-pull-request-reviewer (P0 dedupe key) | ||
|
|
||
| The current per-page dedupe key is `href.split("?")[0]` (URL only). When | ||
| the same product is purchased multiple times on the same orders page, | ||
| later occurrences are dropped — undercounting actual purchase volume. | ||
|
|
||
| **Design**: track items by `(url, occurrenceIndex)` or by combining | ||
| url + nearby date + nearby price as the dedupe key. Need to distinguish | ||
| "same product link rendered twice on the page" (a true duplicate to | ||
| dedupe) from "same product purchased twice on different orders shown | ||
| on the page" (a real duplicate to preserve). | ||
|
|
||
| ### 2. Filter links without order-context metadata (P1) | ||
|
|
||
| **Thread**: chatgpt-codex-connector (line 216) | ||
|
|
||
| The extractor pushes every qualifying `/dp/` or `/gp/product/` link to | ||
| the items array even when no nearby date + nearby price is found. Some | ||
| of these are "Buy it again" widgets, recommendations, or sidebar | ||
| suggestions — not actual orders. | ||
|
|
||
| **Design**: require at least one of {date, price} to be present before | ||
| classifying a link as an order item. OR walk the DOM more precisely to | ||
| find the "Order #" container and only extract links within it. | ||
|
|
||
| ### 3. Auto-install mutates tracked repo state (P1) | ||
|
|
||
| **Thread**: copilot-pull-request-reviewer | ||
|
|
||
| `bun install playwright` (in `installIfMissing`) writes to the caller's | ||
| `package.json` + `bun.lock`. For a one-off personal extractor this is a | ||
| surprising side effect; for users who copy the script to their own repos | ||
| it pollutes their dependency manifest. | ||
|
|
||
| **Design**: use `bun install --no-save playwright` or detect-then-install | ||
| in a script-local node_modules-equivalent. OR remove auto-install and | ||
| document the one-time setup explicitly. | ||
|
|
||
| ### 4. Empty-order-year timeout handling (P1) | ||
|
|
||
| **Thread**: chatgpt-codex-connector | ||
|
|
||
| For years with zero orders, the original v1 script could wait the full | ||
| 5-minute selector timeout. v2's press-Enter pattern mitigates this | ||
| partially (the human-in-the-loop confirms the page loaded), but a fully | ||
| empty year still produces 0 detected pages and 0 items, which may not | ||
| be the substrate-honest outcome the user expected. | ||
|
|
||
| **Design**: explicit "no orders found for year X" path with early-exit | ||
| and a clear message instead of silent zero-results. | ||
|
|
||
| ### 5. Parse order total explicitly (P2) | ||
|
|
||
| **Thread**: chatgpt-codex-connector | ||
|
|
||
| Currently `text.match(/\$[\d,]+\.\d{2}/)` matches the FIRST currency | ||
| token in the container — could be a subtotal, savings amount, or | ||
| shipping cost rather than the order total. | ||
|
|
||
| **Design**: walk to a specific "Order total" / "Grand total" element | ||
| or use Amazon's `[data-test-id="orderTotalAmount"]` or equivalent | ||
| attribute. | ||
|
|
||
| ### 6. `main(argv)` export pattern (P1) | ||
|
|
||
| **Thread**: copilot-pull-request-reviewer | ||
|
|
||
| Most `tools/**.ts` scripts in the repo expose `export function main(argv)` | ||
| and only execute on `import.meta.main`. The current extractor calls | ||
| `main()` unconditionally at module load, blocking any future test or | ||
| import. | ||
|
|
||
| **Design**: refactor to: | ||
| ```ts | ||
| export async function main(argv: string[]): Promise<void> { ... } | ||
| if (import.meta.main) main(process.argv.slice(2)); | ||
| ``` | ||
|
|
||
| ### 7. Fail-run-when-page-fails (deliberate design choice) | ||
|
|
||
| **Thread**: chatgpt-codex-connector | ||
|
|
||
| The current v2.3 design is "continue-on-skip" — a page navigation | ||
| timeout logs a warning and continues. The reviewer suggested failing | ||
| the run instead. | ||
|
|
||
| **Design**: this is a substrate-honest design choice (v2.3 chose | ||
| continue-on-skip explicitly so partial extraction is preserved when | ||
| one page fails). The v3 pass should make this CONFIGURABLE — flag | ||
| `--fail-on-page-error` for users who want fail-fast behavior, default | ||
| to continue-on-skip for the audit use case. | ||
|
|
||
| ### 8. Hardware-filter regex too narrow (operator finding, not in reviewer threads) | ||
|
|
||
| The current `HARDWARE_KEYWORDS` regex matched 1 of 90 items in the | ||
| maintainer's 2026 partial extract and surfaced fewer-than-expected | ||
| items in the 2025 audit. Brands missing from the regex but present in | ||
| the actual orders include: FLUMINER, Goldshell, Bitaxe, NerdMiner, | ||
| Canaan, Avalon, Ledger, Trezor, Blockstream, Raspberry Pi, ESP32, | ||
| LILYGO, Heltec, Meshtastic, LoRa, MSI, Razer, Seagate, Crucial. | ||
|
|
||
| **Design**: widen the regex based on the actual hardware-inventory | ||
| substrate (see Otto-Desktop's audit at user-scope memory | ||
| `aaron_amazon_2025_hardware_audit_for_zeta_215_orders_107_hardware_77k_spend_2026_05_17.md`). | ||
| Risk: too-wide regex catches false positives (e.g., "fan" matching | ||
| kitchen fans). Mitigation: narrower brand-anchored patterns rather | ||
| than generic terms. | ||
|
|
||
| ## Acceptance | ||
|
|
||
| - [ ] Dedupe preserves duplicate purchases via composite key | ||
| - [ ] Order-context filter excludes Buy-it-again / recommendations | ||
| - [ ] Auto-install no longer mutates tracked package.json | ||
| - [ ] Empty-year case has explicit early-exit message | ||
| - [ ] Order total parsed from specific Amazon element, not first $-match | ||
| - [ ] `main(argv)` export pattern with `import.meta.main` guard | ||
| - [ ] `--fail-on-page-error` flag (default off, preserves continue-on-skip) | ||
| - [ ] Hardware-filter regex widened with brand-anchored patterns from | ||
| actual 2025 audit substrate | ||
| - [ ] Each change verified locally + tsc clean | ||
|
|
||
| ## Composes with | ||
|
|
||
| - [PR #3993](https://github.com/Lucent-Financial-Group/Zeta/pull/3993) — v1-v2.5 substrate this row refines | ||
| - [B-0590](B-0590-fleet-replication-20-machines-bare-metal-os-install-kvm-mini-pcs-2026-05-16.md) | ||
| — consumer of the hardware-filtered output | ||
| - [B-0600](B-0600-family-distributed-ai-interface-miner-fleet-mom-dad-2026-05-16.md) | ||
| — different consumer (mom/dad AI uses the inventory substrate) | ||
| - User-scope: `aaron_amazon_2025_hardware_audit_for_zeta_215_orders_107_hardware_77k_spend_2026_05_17.md` | ||
| (the 2025 audit; reference data for the hardware-regex widening) | ||
| - Future B-NNNN — multi-account/multi-vendor consolidation | ||
| (the maintainer's "killer feature" framing 2026-05-16; v3 extractor | ||
| is the natural substrate to build that on) | ||
|
|
||
| ## Substrate-honest framing | ||
|
|
||
| This row exists because reviewer-thread triage on the parent PR | ||
| distinguished "addressable in 1-3 lines" (the 19 resolved) from "needs | ||
| design work" (these 8). Filing as P2 — v1-v2.5 works for the immediate | ||
| use case; v3 is the refinement. | ||
|
|
||
| Per `.claude/rules/no-directives.md`: this is not committed work; it's | ||
| captured intent. Implementation timing is at the maintainer's + AI-team's | ||
| discretion. The row exists so the thread substrate doesn't decay into | ||
| weather per `substrate-or-it-didn't-happen`. | ||
|
|
||
| ## Out of scope | ||
|
|
||
| - Per-item price detail (Amazon's order-summary page; ~107 × 4s = 7 min | ||
| per Otto-Desktop's audit note) — separate decomposition slice if needed | ||
| - Multi-vendor / multi-account consolidation — separate backlog row | ||
| - Tax-prep integration — separate concern; this script's output may | ||
| feed into it | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.