2026-05-04 on prod. Two follow-ups to the May-03 R5 ship: per-session
cards re-added to the daily report (the data was already there in
aggregateNativeDailyReport.sessions; just needed a UI to
surface it), and a sync dead-letter banner on /cafe/orders
so operators see when the every-minute sync worker has given up on
pushing an order to Odoo. Retry button resets the counter so the next
cron firing picks the order back up.
listSessionsForDay with aggregateNativeDailyReport.sessions on the cafe.sessions UUID. Each card shows opener / closer / beginning + ending cash / diff + reason / paid-order count + gross. Mirrors what Pro had pre-R5.3 (which was dropped when the Pro daily-report page collapsed onto the Starter client).SyncDeadLetterBanner component on /cafe/orders. Hidden when the queue is empty (no banner in the happy path). Shows when cafe.orders WHERE odoo_sync_retries >= 5 AND odoo_order_id IS NULL AND source = 'native' has rows. Click toggles a table with the odoo_sync_error message + per-row Retry button.retryDeadLetterOrderAction gated on nix_cafe.orders.refund (owner / manager). Resets odoo_sync_retries=0, clears odoo_next_attempt_at + odoo_sync_error, then revalidates /orders so the banner disappears immediately.listDeadLetterOrders now wraps in db.transaction() to bypass the 60s SELECT cache — without it, a freshly-stuck order could take a minute+ to surface in the banner. Same pattern that bit M3, R1.1, and the close-shift expected-cash query.