feat(flow): map SKU + auto-retry consolidated banner

After saving a SKU mapping, check for SKIPPED orders containing that
SKU and show a floating banner with count + "Importa" button. Batch
retries up to 20 orders and shows result feedback.

Backend:
- get_skipped_orders_with_sku() in sqlite_service.py
- GET /api/orders/by-sku/{sku}/pending endpoint
- POST /api/orders/batch-retry endpoint (max 20, sequential)

Frontend:
- Auto-retry banner after quickMap save with batch import button
- Success/error feedback, auto-dismiss after 15s

Cache-bust: shared.js?v=19

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-03-27 12:38:10 +00:00
parent 7a789b4fe7
commit b52313faf6
4 changed files with 90 additions and 2 deletions

View File

@@ -960,6 +960,24 @@ async def set_app_setting(key: str, value: str):
await db.close()
# ── SKU-based order lookup ────────────────────────
async def get_skipped_orders_with_sku(sku: str) -> list[str]:
"""Get order_numbers of SKIPPED orders that contain the given SKU."""
db = await get_sqlite()
try:
cursor = await db.execute("""
SELECT DISTINCT oi.order_number
FROM order_items oi
JOIN orders o ON o.order_number = oi.order_number
WHERE oi.sku = ? AND o.status = 'SKIPPED'
""", (sku,))
rows = await cursor.fetchall()
return [row[0] for row in rows]
finally:
await db.close()
# ── Price Sync Runs ───────────────────────────────
async def get_price_sync_runs(page: int = 1, per_page: int = 20):