HOCO B2B
Team tasksImad

MRA-10 — Reseller app — returns & live order updates

Return request from a delivered order (lines, quantities, reason, photos) and its tracking; the SSE client that keeps order screens live while the app is open.

FieldDetails
Task codeMRA-10
PhaseP1 — V1 build & integration
Product scopeV1
StatusPlanned
StartMon 23 Nov 2026
DueTue 24 Nov 2026
ResponsibleImad — Mobile developer (Flutter)
Co-responsible—
Effort1 person-day(s) planned · 3 from scratch · size S
Area · appReseller app · mobile
Depends onMRA-05
UnblocksMRA-11
Milestones—

Summary

Return request from a delivered order (lines, quantities, reason, photos) and its tracking; the SSE client that keeps order screens live while the app is open.

Description

Two 17 Oct decisions land here: returns are V1 (ORD-13) and every order status change must reach the reseller live while the app is open (ORD-15). Scope: return request RA-40 from a delivered order (lines, quantities, reason, photos) and its tracking through ReturnStatus up to the credit note; and the SSE client on GET /v1/events (events.stream) that keeps RA-21/RA-22 and the inbox badge live, plus ticket replies and return status changes, with push (MOB-08) covering the app in background. The SSE client connects only while the app is foregrounded and signed in, resumes with Last-Event-ID and falls back to refetching on gaps. It needs returns.create|list|get (SRV-20) and the user event stream (SRV-26) from Anis, and Akram's DES-09 return frame. It plugs into the OrdersRepository hook from MRA-05 and the ticket screens of MRA-08.

Subtasks

#SubtaskOwner
1EventStreamClient in hoco_core: dio streaming GET /v1/events with the bearer token, text/event-stream parser (id, event, data, retry, comment heartbeats), Last-Event-ID on reconnectImad
2Connection lifecycle: open on AppLifecycleState.resumed when signed in, close on pause and sign-out, reconnect with backoff 1 s → 30 s plus jitter, honour the server retry field; no stream for guestsImad
3Event router: order.status_changed and order.modified → OrdersRepository.applyOrderEvent; assisted_order.awaiting_confirmation → banner to RA-23; ticket.replied → conversation refresh; return.status_changed → returns refresh; notification.created → badgeImad
4In-app toast « Votre commande CMD-2026-000158 est Expédiée » when the event concerns an order not on screen; foreground push for the same event id suppressedImad
5Gap handling: if the server cannot resume from Last-Event-ID or the app was paused, refetch orders.summary and the visible order instead of trusting the streamImad
6ReturnRequestScreen RA-40 from RA-22 when allowedActions includes return: select lines and quantities (capped at delivered minus already returned), reason, comment, photos via MOB-11 → POST /orders/{orderId}/returns with an Idempotency-KeyImad
7Returns list and detail (GET /returns, GET /returns/{id}): status timeline « Demandé », « Accepté », « En retour », « Reçu », « Remboursé / avoir émis », « Refusé » with reason; credit note PDF when issuedImad
8Return and claim cross-links: a RETURN resolution of an after-sales claim (MRA-08) opens the corresponding returnImad

Deliverables

  • packages/hoco_core/lib/src/realtime/event_stream_client.dart and sse_parser.dart
  • apps/reseller/lib/src/app/live_updates.dart (event router)
  • apps/reseller/lib/src/features/returns/ (request, list, detail)
  • Unit tests of the SSE parser and reconnection policy

Acceptance criteria

  • With the order detail open, a back-office status change (e.g. VALIDATED → PREPARING) appears in the app within 5 s without user action (ORD-15)
  • After network loss the stream reconnects with Last-Event-ID and no status change is missed; after a long pause the screens are refetched
  • With the app in background no SSE connection is kept; the push notification covers the change
  • A return can be requested only on a delivered order, only for returnable quantities, and appears as « Demandé » with its lines and photos (ORD-13)
  • When the back-office receives the return, the reseller sees « Reçu » and then the credit note (FIN-08 via ORD-13)
  • A retried return request creates a single RET- record (Idempotency-Key)

Requirements covered

RequirementTitleRelease
ORD-13Returns: request on a delivered order, back-office approval, reception; returned quantities re-enter stock automaticallyV1
ORD-15Order status changes reach the reseller in real time (live update in the app and web) and as a notificationV1

Screens

ScreenNameApp
RA-40Return requestRA
RA-21OrdersRA
RA-22Order detail & trackingRA

API surface

Test measures

  • Unit tests of the SSE parser (multi-line data, comments, retry field, partial chunks)
  • Unit tests of reconnection with fake clock and Last-Event-ID propagation
  • Integration test on staging: change an order status in the dashboard → app updates live; toggle airplane mode mid-stream
  • Widget tests of the return line selector caps

Risks

  • Mobile proxies or carrier networks buffer or cut long-lived HTTP streams — heartbeats every 25 s from the server, client timeout and reconnect, and push as the guaranteed channel
  • Battery cost of a stream — connect only in foreground and drop it on pause

KPI

  • Delivered by Tue 24 Nov 2026 within 1 person-day(s).
  • Every acceptance criterion above demonstrated before hand-off; linked requirements' acceptance criteria pass.
  • Zero open critical defects, permission gaps or data-integrity regressions at sign-off.

Generated from content/plan/tasks.json by scripts/generate-team-tasks.mjs. Dates are computed by the scheduler (Sunday–Thursday weeks, holidays excluded) — change the plan, not this page.

On this page