Skip to content

1.8.6

⚙️ Patch 1.8.6 — Tiered Nettospanne EK & full-watchlist analyze

🚀 Summary

  • Tiered target EK — Amazon Nettospanne margin by avg VK (30d): 13% when VK < 25 EUR, 10% at or above (replaces single configurable margin %).
  • Analyze (by EAN) — one API call processes all non-archived watchlist rows in internal 500-row DB batches; always recomputes and writes EK/margin (no skip-write / reanalyze pagination).
  • Watchlist UI — removed manual Margin % inputs (analyze toolbar + cron); info text explains tier rules; Target EK column shows per-row % Nettospanne from analyze.
  • Broader analyze scope — no longer limited to source=keepa or ASIN: stub exclusion; ~all table rows are eligible (rows without Keepa fetch data are skipped_analyze).

✨ Improvements

Tiered Nettospanne (pricing.py)

Avg VK (30d) brutto Target margin
< 25 EUR 13%
≥ 25 EUR 10%
  • margin_percent_for_sell_price_eur() — tier selection from avg30 sell price.
  • analyze_from_stored_row() / analyze_product() — always use tiered margin (no per-run override).
  • margin_percent stored on each watchlist row; Target EK and tiered margin drive are_targets_met / wholesale targets.

Example: VK 19.14 EUR, fees 2.87 EUR → 13% → target EK ~10.72 EUR (was ~11.30 EUR at flat 10%).

Analyze pipeline — simplified

Before: frontend looped offset / limit / reanalyze=true; backend could skip DB writes when EK unchanged (ek_skipped_write).

After:

  • POST /keepa/analyze-products body: { target_quantity?, asins? } only.
  • Server loads all eligible rows (archived_at IS NULL), batches of KEEPA_ANALYZE_BATCH_SIZE (500).
  • Every row with valid Keepa metrics is written (tier refresh, catalog targets, in_qogita_catalog).
  • Response: requested, stored, batches, ek_changed, margin_changed, skipped_analyze, pipeline counts.

Logs:

Keepa analyze start: margin=tiered(<25→13%,≥25→10%) eligible=1450 with_keepa_fetch=239 batch_size=500
Keepa analyze complete: … batches=3 margin_changed=… ek_changed=…
  • eligible — all non-archived watchlist rows.
  • with_keepa_fetch — subset that completed Fetch Products (have keepa_product_fetched_at); only those can get tiered EK until fetched.

CRUD — analyze eligibility

  • _analyze_eligible_query() — non-archived rows only (no source=keepa, no ASIN: GTIN filter).
  • count_items_with_keepa_fetch() — diagnostic count for logging.

Frontend

  • Removed Margin % (Nettospanne) from analyze toolbar and scheduled jobs.
  • Margin tier info above table and under Scheduled jobs.
  • Single analyzeProducts() call (no client-side batch loop).
  • Success toast includes margin_changed when tier updates apply.

🐛 Bug Fixes

Reanalyze skipped tier migration

  • Flat 10% rows were not updated after tier rules shipped because ek_skipped_write treated them as unchanged.
  • Analyze now always persists on each run; tier mismatches show up as margin_changed / ek_changed in logs.

✨ Tests

  • test_keepa_pricing.py — tier thresholds, analyze_from_stored_row at 19.14 EUR → 13% / EK 10.72.
  • Updated analyze API models (KeepaAnalyzeProductsRequest / Response).
cd backend/service_omni
pytest app/tests/test_keepa_pricing.py::TestTieredMargin -v

📁 Files changed

Backend (service_omni)

  • app/services/keepa/pricing.py — tiered margin constants + helpers
  • app/services/keepa/scanner.py — simplified analyze_products()
  • app/services/keepa/constants.pyKEEPA_ANALYZE_BATCH_SIZE
  • app/crud/qogita.py_analyze_eligible_query(), count_items_with_keepa_fetch()
  • app/models/keepa.py — analyze request/response shape
  • app/api/v1/endpoints/keepa.py
  • app/tests/test_keepa_pricing.py, test_keepa_workflow_integration.py, test_keepa_scanner_mocked.py

Frontend

  • src/pages/Statistics/Tabs/QogitaWatchlistTab.jsx
  • src/pages/Statistics/Tabs/qogitaWatchlistPrefs.jsKEEPA_NETTOPANNE_MARGIN_SUMMARY, formatTargetEkMarginCaption()

🔧 Deploy

Restart service-omni. Rebuild frontend. No database migration.

After deploy:

  1. Run 2. Fetch Products for any rows still missing Keepa metrics (with_keepa_fetch < eligible).
  2. Run 3. Analyze (by EAN) once — expect margin_changed > 0 for VK < 25 EUR rows still on old 10%.

Usage notes

Why analyze total ≠ table row count

Count Meaning
Table total (~1453) All rows including archived / stubs
eligible Non-archived rows analyze iterates
with_keepa_fetch Rows with Keepa product data (can compute EK)
skipped_analyze Eligible but missing avg30 / fees (run Fetch Products first)

Cron margin

  • Qogita / Keepa crons no longer send margin_percent; tier rules apply automatically on analyze paths.

SQL — rows still on 10% below 25 EUR VK

SELECT gtin, name, avg30_new_price_cents / 100.0 AS vk_eur,
       margin_percent, calculated_ek_price
FROM qogita_watchlist_items
WHERE archived_at IS NULL
  AND avg30_new_price_cents IS NOT NULL
  AND avg30_new_price_cents >= 0
  AND (avg30_new_price_cents / 100.0) < 25
  AND margin_percent = 10
ORDER BY gtin;

Run Analyze (by EAN) after deploy to refresh these rows.