1.8.7
⚙️ Patch 1.8.7 — Multi-EAN watchlist, row actions & PrepBusiness package split¶
🚀 Summary¶
- Multi-EAN per ASIN — Keepa
eanListstored on watchlist rows; one row per catalog-matched GTIN; analyze/push/cron fan out across sibling EANs. - Watchlist row actions — per-row Fetch, Analyze, Push, Sync Qogita; toolbar Add ASIN (Keepa fetch + analyze).
- Qogita push — existing watchlist items are updated (target EK/qty) instead of failing with “already watchlisted”; uses Qogita PATCH API (no GET on item path).
- Watchlist load fix — catalog EAN keys loaded once per page (fixes slow/empty watchlist UI).
- PrepBusiness batch — optional per-row package split (e.g. 200 units → 4×50) before bundling.
- Simulator UI — Packages column; dark-mode fix for Raw Response Debug JSON panel.
✨ Improvements¶
Multi-EAN architecture¶
- New column
keepa_ean_list(JSONB) onqogita_watchlist_items. - Fetch Products creates one watchlist row per catalog-matched EAN from Keepa
eanList(shared Keepa metrics, per-GTIN wholesale targets). - Analyze runs per catalog EAN sibling; Push expands to all catalog GTINs for an ASIN.
- Cron refreshes new catalog EAN siblings after catalog download; ASIN stubs archived after fetch (rows never auto-deleted).
- Frontend EANs column + dialog listing
keepa_ean_listand catalog matches.
Watchlist — row-wise manual actions¶
| Action | Scope |
|---|---|
| Fetch (cloud) | Row ASIN → POST /keepa/fetch-products { asins } |
| Analyze (calculator) | Row GTIN → POST /keepa/analyze-products { gtins } |
| Push (upload) | Row GTIN → POST /keepa/push-to-qogita { gtins } |
| Sync (sync) | Row GTIN → POST /qogita/watchlist/{gtin}/sync-from-qogita |
- Add ASIN —
POST /keepa/add-asinregisters/refreshes ASIN, fetches Keepa data, analyzes catalog EANs.
Qogita push & sync — API alignment¶
upsert_watchlist_targets()— PATCH first; on 404 → POST create → PATCH; on “already watchlisted” → PATCH.get_watchlist_item()— uses PATCH with empty body (Qogita returns 405 for GET on/watchlist/items/{gtin}/).- Local
qidmissing no longer causes duplicate-create failures when item already exists on Qogita.
Watchlist list performance¶
watchlist_items_to_responses()loads wholesale catalog EAN keys once per request (was N× full catalog scan per row).- Endpoint logs:
Watchlist list DB/Watchlist list OKwith timing; serialization errors logged with sample GTINs. keepa_ean_listcoercion on API model for malformed JSONB.
PrepBusiness — per-row package split¶
Split a sheet row into N evenly sized packages before hazmat bundling and €2500 value split.
Example: 200 units, 4 packages → 4 chunks of 50 (203 ÷ 4 → 51+51+51+50).
Configure via:
- API —
row_package_splits: [{ "row_index": 5, "packages": 4 }] - Sheet columns —
Packages,Pakete,Teilungen,Bundles, …
Response includes package_splits_applied.
🐛 Bug Fixes¶
Discord “targets met” spam¶
upsert_from_apino longer overwrites localare_targets_metfrom Qogita API — alerts only on false→true transition.
Watchlist empty / hanging load¶
- Per-row catalog key reload caused multi-minute requests; fixed with single shared catalog key set per page.
Qogita push 400 / 405¶
- 400 “already watchlisted” when pushing without local
qid→ update path. - 405 Method Not Allowed on GET item → PATCH-only flow per Qogita OpenAPI.
PrepBusiness simulator — dark mode¶
- Raw Response Debug used inverted
grey[900](light in this theme) →grey[50]background with readabletext.primary.
✨ Tests¶
test_catalog_targets.py—are_targets_metpreserved on Qogita sync merge.test_keepa_scanner_mocked.py— push upsert / already-on-Qogita paths.test_package_split.py— even split, remainder, sheet column parse.
cd backend/service_omni
pytest app/tests/test_package_split.py app/tests/test_catalog_targets.py -v
📁 Files changed¶
Backend (service_omni)
app/crud/qogita.py— multi-EAN fetch/analyze/push,keepa_ean_list, analyzegtinsfilterapp/services/keepa/scanner.py—add_asin_and_fetch, push upsert,gtinson analyze/pushapp/services/qogita/catalog_ean_resolve.py,ean_keys.py,watchlist_present.py,watchlist_sync.pyapp/services/qogita/qogita_client.py—upsert_watchlist_targets, PATCH item fetchapp/services/price_alerts/watchlist_cron.py— catalog EAN sibling refreshapp/services/bundling/package_split.py— newapp/api/v1/endpoints/keepa.py,qogita.py,prepbusiness.pyapp/models/keepa.py,qogita.py,prepbusiness.pyapp/schemas/qogita.pydocker/postgres/migrations/add_keepa_ean_list.sql
Frontend
src/pages/Statistics/Tabs/QogitaWatchlistTab.jsx— row actions, Add ASIN, EANs dialogsrc/services/api/omni/keepa.js,qogita.jssrc/pages/Prepbusiness/Tabs/SimulatorTab.jsx— Packages column, dark-mode debug panel
🔧 Deploy¶
- Apply migration:
-- docker/postgres/migrations/add_keepa_ean_list.sql
ALTER TABLE qogita_watchlist_items
ADD COLUMN IF NOT EXISTS keepa_ean_list JSONB;
- Restart
service-omni. - Rebuild frontend.
After deploy:
- Run Sync from Qogita once if local
qidvalues are stale. - Re-Fetch / Analyze ASINs with multiple EANs to populate sibling rows.
- Use row Push to update target EK on items already on the Qogita watchlist.
Usage notes¶
Why multiple rows per ASIN
Keepa’s first eanList entry is often not the Qogita catalog GTIN. Fetch now creates rows for all catalog-matched EANs so analyze and push target the correct wholesale SKU.
Package split vs bundling
Package split divides one sheet line into equal chunks first; the existing bundler then combines chunks with other articles under hazmat/volume/€2500 rules.