Skip to content

QC-69: End-to-end delivery workflow — agent actions, cancellations, OTP UI, status gaps #151

@DarshanCode2005

Description

@DarshanCode2005

Summary

The order lifecycle is only half-wired: backend pieces exist for assign-agent, geolocation relay, OTP generate/verify, and customer stepper (QC-56), but critical agent and cancellation flows have no UI or API, and one status transition (agent_assignedout_for_delivery) is never performed in production code. Customers see the stepper stall on Agent assigned; agents see a map + chat but cannot start delivery, complete delivery, or cancel from the app.

This issue tracks the missing work to complete the delivery workflow across agent, customer, and owner roles.


What existing open issues cover (and what they do not)

Issue Covers Does not cover
#58 QC-56 Customer order detail stepper UI (read-only) Status transitions, agent actions
#59 QC-57 Customer live tracking map (subscribe to agent-location) Agent start/complete/cancel; out_for_delivery transition
#60 QC-58 Customer stepper live updates via Pusher order-status Creating status changes; agent OTP UI
#127 QC-68 Post-checkout navigation, cart clear, links on order detail Agent delivery panel, OTP, cancel
#141 Vague “workflow polish” No concrete delivery spec
#46–47 QC-44/45 (done) POST /api/otp/generate, POST /api/otp/verify APIs No agent frontend calling these routes
#43–45 QC-41–43 (done) Assign agent, delivery map, location relay Start delivery, complete delivery UI, cancel

Conclusion: None of the open issues fully close the gap described below. Implement this epic (or split into sub-issues) after QC-56 merges; coordinate with QC-57/58 for customer-side updates.


Canonical status flow (intended)

placed → confirmed → awaiting_agent → agent_assigned → out_for_delivery → delivered
                                                              ↘ cancelled (terminal)

Owner early cancel: placed|confirmedcancelled (already via PATCH /api/orders/[id]/status, owner-only).

Defined in lib/order-status-transitions.ts:

  • Owner: placed/confirmedcancelled; confirmedawaiting_agent (request agent).
  • Agent: awaiting_agentagent_assigned (assign); agent_assignedout_for_delivery; out_for_deliverydelivered (via OTP verify today).

Gap analysis (current repo state)

1. agent_assignedout_for_deliverynot implemented

  • Transition exists in AGENT_ORDER_TRANSITIONS but no API route or UI sets out_for_delivery.
  • Customer stepper stays on Agent assigned until manual DB edit or jump to delivered.
  • Owner Kanban groups both statuses in “Out for Delivery” column, which masks the gap.

Needed:

  • PATCH /api/orders/[id]/status or dedicated POST /api/orders/[id]/start-delivery (agent-only, assigned agent, from agent_assigned only).
  • Agent delivery page: primary “Start delivery” button → transitions status + emits order-status Pusher event.
  • Optional: auto-start when agent opens map (product decision — document choice).

2. Mark delivered — API only, no agent UI

Needed:

  • AgentDeliveryActions (or sheet/drawer on delivery page):
    • Generate OTP → calls generate API; show “OTP sent to customer email” / handle email_unavailable.
    • Verify delivery → 6-digit input + submit → verify API; success toast + redirect to /agent/orders or history.
  • Disable verify until OTP generated (or show clear error from API).
  • Show order status badge on delivery header; reflect out_for_delivery / delivered.
  • Handle errors: wrong OTP, expired, already delivered.

3. Cancel delivery — not available to agent or customer mid-flight

  • Owner can cancel only from placed or confirmed (OWNER_ORDER_TRANSITIONS).
  • No path to cancel after awaiting_agent, agent_assigned, or out_for_delivery.
  • Customer order detail shows cancelled alert (QC-56) but no cancel button.

Needed (product rules — pick and document):

Actor Suggested cancel rules
Customer Cancel while placed (before shop confirms)? Or until agent_assigned? Refund policy for Stripe?
Owner Cancel through awaiting_agent / before agent starts? Force cancel with reason?
Agent Abort delivery (unassign): agent_assigned/out_for_deliveryawaiting_agent, clear agentId? Or → cancelled?

Implementation:

  • Extend transition map + validators (separate from owner-only PATCH or role-aware PATCH).
  • APIs: e.g. POST /api/orders/[id]/cancel with { reason? } (role-scoped).
  • UI: customer “Cancel order” on detail when allowed; owner Kanban action; agent “Can’t deliver” / “Release order”.
  • Pusher order-status on all cancel paths; stepper + Kanban update (QC-58).

4. Agent release / reassignment (optional but common)

  • Today: first accept wins (assign-agent); no release.
  • If agent abandons, order may stay agent_assigned forever.

Needed:

  • POST /api/orders/[id]/release-agent (assigned agent only) → awaiting_agent, agentId: null, notify presence-agents again?
  • Owner override to unassign (edge case).

5. Customer tracking UX (ties to QC-57/58)

  • Location relay works from agent map (DeliveryMap POSTs every 3s).
  • Customer page has stepper but no map until QC-57.
  • Stepper does not live-update until QC-58.

Needed (cross-link, not duplicate QC-57/58):

  • Ensure start-delivery and delivered transitions emit notifyOrderStatusUpdated (already pattern in verify/assign).
  • QC-58 client wrapper reads order-status and updates OrderStepper + badge.

6. Payment / COD clarity on completion

  • COD stays pending until OTP verify (QC-54/45) — good.
  • Agent UI should show: “Collect ₹X cash” for COD before verify.
  • Stripe orders: verify only marks delivered (payment already paid via webhook).

Proposed implementation phases

Phase A — Agent happy path (minimum viable delivery)

  1. Start delivery API + button (out_for_delivery).
  2. OTP generate + verify UI on agent delivery page.
  3. Manual QA: accept → start → generate OTP → verify → customer stepper shows delivered.

Phase B — Cancellations & release

  1. Transition rules + cancel/release APIs per table above.
  2. Customer + owner + agent cancel/release UI.
  3. Refund note for Stripe (document or stub webhook reversal out of scope).

Phase C — Polish (can parallel QC-57/58)

  1. Customer tracking map when out_for_delivery.
  2. Live stepper (QC-58).
  3. Agent orders list: CTA labels (“Continue delivery”, “Start delivery”).

Files likely touched

Area Files
Transitions lib/order-status-transitions.ts, new lib/agent-order-status.ts or extend owner PATCH with role checks
APIs app/api/orders/[id]/status/route.ts (or new routes under app/api/orders/[id]/)
Agent UI app/(agent)/agent/delivery/[orderId]/page.tsx, new components/agent/AgentDeliveryPanel.tsx
Customer UI app/(customer)/customer/orders/[orderId]/page.tsx, optional cancel modal
Owner UI components/owner/OwnerOrdersKanban.tsx, components/order/OrderCard.tsx
Realtime lib/pusher-server.ts (reuse notifyOrderStatusUpdated)
Docs docs/IMPLEMENTATION_CONTEXT.md, scripts/test-*-api.mts

Acceptance criteria

Agent

  • Assigned agent can start delivery from delivery page; DB status out_for_delivery; customer stepper advances (after refresh or QC-58).
  • Agent can generate OTP and verify OTP from delivery page; order becomes delivered; COD → paid.
  • Agent sees clear errors for SMTP missing, wrong/expired OTP.

Customer

  • Stepper reflects out_for_delivery and delivered without manual DB edits.
  • (Phase B) Cancel order when policy allows; sees cancelled alert.

Owner

  • (Phase B) Can cancel or unassign per defined rules; Kanban updates.

System

  • All status changes emit order-status on private-order-{orderId} and owner shop channel where applicable.
  • Integration tests for new transitions (extend scripts/test-*-api.mts).

Test plan

npm run lint && npx tsc --noEmit
# API scripts (add as built):
npx tsx --env-file=.env.local scripts/test-agent-delivery-flow.mts

# Manual E2E
# 1. Customer places COD order
# 2. Owner confirms → request agent
# 3. Agent accepts → agent_assigned
# 4. Agent opens delivery → Start delivery → out_for_delivery
# 5. Customer order detail: stepper on Out for delivery; map moves (QC-57)
# 6. Agent Generate OTP → customer email
# 7. Agent Verify OTP → delivered; customer stepper complete; COD paid
# 8. (Phase B) Cancel paths per role

Depends on

Suggested follow-up splits (optional child issues)

  1. QC-69a Agent start-delivery API + UI
  2. QC-69b Agent OTP panel on delivery page
  3. QC-69c Cancel / release order APIs + multi-role UI

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentDelivery agent featuresbackendAPI routes and server logiccustomerCustomer role featuresenhancementNew feature or requestfrontendUI pages and componentsownerShop owner featurespusherPusher-specific setuprealtimePusher real-time events

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions