Skip to content

1.9.1

⚙️ Patch 1.9.1 — Analysis 1:1 bundles & fast qty sort; Sentry triage

🚀 Summary

  • Analysis: 1:1 bundle aliases are detected correctly, rolled into the live parent SKU, and shown as chips in the table and sales-stats dialog; sales/return qty sort uses a fast SQL path.
  • Qogita (LAGE-DASHBOARD-57, 9, 58): production was missing last_targets_met_alert_price; omni now applies the column + backfill on startup (create_all cannot alter existing tables).
  • Plenty Sheets (LAGE-DASHBOARD-5A, 59): @retry_on_429 was ineffective because 429s were wrapped as HTTPException(400) before retry; metadata / values / updates now re-raise 429 for exponential backoff.
  • Multi-repricer (LAGE-DASHBOARD-56): enable pool_pre_ping + pool_recycle to recover stale Postgres connections.

✨ Improvements

Analysis — 1:1 bundles & qty sort

Area Behavior
Detection Live parent lists historical SKUs in child_skus; each alias with bundle_packages exactly [{sku: parent, quantity: 1}] is a 1:1 link (qty ≥ 2 ignored).
KPI rollup Alias sales / returns / profit / ads merge into the parent for the selected period.
Table Parent row shows chips for all linked SKUs (one_to_one_linked_skus); rolled-up qty/profit columns.
Sales stats dialog Same linked-SKU chips; KPIs include alias sales for the chosen window.
Fast sort Sorting/filtering by sales_qty or retour_qty ranks via SQL aggregates (+ 1:1 rollup), then fee-aware stats only for the current page.
API GET /articles/analytics and sales-stats responses expose is_one_to_one_bundle, one_to_one_linked_skus, one_to_one_component_sku.

Example: RitualsJingGeschenkSetM2025 with children …M2024 / …2023M that package back to M2025 qty 1 → both aliases appear on the M2025 row and their sales count toward its KPIs.

Sentry triage run — 23.07.2026

Issue Root cause Fix
LAGE-DASHBOARD-57 Watchlist cron selected missing column Startup ensure_qogita_watchlist_columns
LAGE-DASHBOARD-9 Same column on Qogita webhook Same
LAGE-DASHBOARD-58 Same column on Keepa price cron Same
LAGE-DASHBOARD-5A Sheets append → metadata 429 wrapped Re-raise 429 + retry decorator
LAGE-DASHBOARD-59 Sheets ensure headers → metadata 429 Same
LAGE-DASHBOARD-56 Stale DB connection on articles list pool_pre_ping / pool_recycle

🔧 Deploy

  1. Redeploy service-multi-repricer + frontend (Analysis 1:1 + fast qty sort; DB pool).
  2. Redeploy service-omni (schema patch runs on startup; optional manual SQL still OK: docker/postgres/updates/qogita_last_targets_met_alert_price.sql).
  3. Redeploy service-plenty.
  4. Confirm Qogita watchlist / Keepa crons stop erroring; Sheets bulk updates survive brief quota spikes.

✅ Verify

  1. Analysis: open a 1:1 parent (e.g. Jing Geschenkset M2025) → chips for linked aliases; sales qty includes alias sales; sort by Sales qty / Return qty is responsive.
  2. Sales stats dialog on that SKU → same linked chips + rolled-up KPIs.
  3. pytest backend/service_multi-repricer/app/tests/test_article_stats.py
  4. Omni logs: Added qogita_watchlist_items.last_targets_met_alert_price (or skip if already present).
  5. pytest backend/service_omni/app/tests/test_schema_patches.py
  6. PYTHONPATH=app;<repo>/backend pytest backend/service_plenty/app/tests/test_sheets_retry.py

⚠️ Notes

  • Analysis table uses a 10-minute localStorage cache — hit Refresh after deploy to see 1:1 chips.
  • Manual SQL from 1.8.20 remains valid and idempotent with the Qogita startup patch.

Files touched

service-multi-repricer

  • app/services/article_stats.py — 1:1 resolve/rollup, fast qty SQL sort
  • app/api/v1/endpoints/article_stats.py — analytics + sales-stats linked-SKU fields
  • app/core/database.py — pool_pre_ping / pool_recycle
  • app/tests/test_article_stats.py

frontend

  • src/pages/Analysis/AnalysisArticles.jsx — 1:1 chips in table
  • src/pages/MultiRepricer/components/ArticleSalesStatsDialog.jsx — linked SKUs in dialog

service-omni

  • app/core/schema_patches.py
  • app/main.py
  • app/tests/test_schema_patches.py

service-plenty

  • app/services/sheets.py
  • app/tests/test_sheets_retry.py

docs

  • docs/docs/patchnotes/1.9/1.9.1.md