Skip to content

1.8.7

⚙️ Patch 1.8.7 — Multi-EAN watchlist, row actions & PrepBusiness package split

🚀 Summary

  • Multi-EAN per ASIN — Keepa eanList stored 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 UIPackages column; dark-mode fix for Raw Response Debug JSON panel.

✨ Improvements

Multi-EAN architecture

  • New column keepa_ean_list (JSONB) on qogita_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_list and 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 ASINPOST /keepa/add-asin registers/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 qid missing 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 OK with timing; serialization errors logged with sample GTINs.
  • keepa_ean_list coercion 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:

  1. API — row_package_splits: [{ "row_index": 5, "packages": 4 }]
  2. Sheet columns — Packages, Pakete, Teilungen, Bundles, …

Response includes package_splits_applied.

🐛 Bug Fixes

Discord “targets met” spam

  • upsert_from_api no longer overwrites local are_targets_met from 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 readable text.primary.

✨ Tests

  • test_catalog_targets.pyare_targets_met preserved 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, analyze gtins filter
  • app/services/keepa/scanner.pyadd_asin_and_fetch, push upsert, gtins on analyze/push
  • app/services/qogita/catalog_ean_resolve.py, ean_keys.py, watchlist_present.py, watchlist_sync.py
  • app/services/qogita/qogita_client.pyupsert_watchlist_targets, PATCH item fetch
  • app/services/price_alerts/watchlist_cron.py — catalog EAN sibling refresh
  • app/services/bundling/package_split.py — new
  • app/api/v1/endpoints/keepa.py, qogita.py, prepbusiness.py
  • app/models/keepa.py, qogita.py, prepbusiness.py
  • app/schemas/qogita.py
  • docker/postgres/migrations/add_keepa_ean_list.sql

Frontend

  • src/pages/Statistics/Tabs/QogitaWatchlistTab.jsx — row actions, Add ASIN, EANs dialog
  • src/services/api/omni/keepa.js, qogita.js
  • src/pages/Prepbusiness/Tabs/SimulatorTab.jsx — Packages column, dark-mode debug panel

🔧 Deploy

  1. Apply migration:
-- docker/postgres/migrations/add_keepa_ean_list.sql
ALTER TABLE qogita_watchlist_items
    ADD COLUMN IF NOT EXISTS keepa_ean_list JSONB;
  1. Restart service-omni.
  2. Rebuild frontend.

After deploy:

  1. Run Sync from Qogita once if local qid values are stale.
  2. Re-Fetch / Analyze ASINs with multiple EANs to populate sibling rows.
  3. 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.