Files
doormile_milderapp/lib/xpress/data/delivery_api.dart
2026-08-28 18:16:28 +05:30

191 lines
9.4 KiB
Dart

import 'package:miler/data/api_config.dart';
/// ─────────────────────────────────────────────────────────────────────────
/// EVERY URL THE DELIVERY LINE CALLS
///
/// ── Why this file exists ──
///
/// The delivery screens under `lib/xpress` are a verbatim port of the
/// Xpress-rider app, which talked to a **retired backend** entirely — two
/// hosts, one for reads and one for writes, with the URLs scattered inline
/// across `homepage.dart`, `cartpage.dart`, `deliveries.dart`, `summary.dart`
/// and three controllers. Repointing that at Doormile by find/replacing
/// hostnames is exactly the class of change that produced the
/// `deliver`→`Pick up` corruption this repo has already had to undo once.
///
/// So every delivery-line URL is named here, once, and the call sites read a
/// getter. Repointing the line is now one file.
///
/// ── What it points at ──
///
/// `https://api.doormile.com/api/v1` — the same host and the same bearer token
/// as the parcel line, via [ApiConfig]. There is one Doormile backend and the
/// delivery rider signs in to it with the same credentials as everyone else.
///
/// ── What is real and what is not ──
///
/// The Doormile backend (`doormile_backend/routes/routes.go`) does **not**
/// expose a delivery queue. It exposes a miler API built around bookings and
/// consignments. Each constant below is therefore marked:
///
/// • **LIVE** — a route that exists on the backend today, verified against
/// `routes.go`. Called for real.
/// • **MAPPED** — no exact counterpart, but a route that answers the same
/// question, so the screen has something true to draw.
/// • **ABSENT** — no counterpart at all. The call will 404 until the route is
/// built. Listed rather than hidden, because a rider seeing an
/// empty list needs someone to know why.
///
/// The ABSENT set is the delivery *queue* — the list of drops a rider is
/// holding. `/miler/assignments` and `/miler/bookings` are the nearest real
/// things and are what [deliveryQueue] and [currentDeliveries] use, but they
/// return the booking shape (a first-mile pickup), not the delivery shape the
/// ported cards read. Until the backend grows a delivery contract, the delivery
/// line will render whatever those return through the existing adapter and will
/// be thin.
///
/// This is a known, accepted gap: it was chosen deliberately over keeping the
/// retired platform's hosts alive. See the note in `docs/` if one is added.
/// ─────────────────────────────────────────────────────────────────────────
class DeliveryApi {
DeliveryApi._();
/// The one host. Shared with the parcel line — see [ApiConfig.newBase].
static String url(String path) => ApiConfig.url(path);
/// Headers for every authenticated delivery call: the same bearer token the
/// parcel line uses, because it is the same rider account on the same server.
static Future<Map<String, String>> headers() => ApiConfig.authHeaders();
// ───────────────────────── the work list ─────────────────────────
/// **MAPPED** — the drops this rider is holding.
///
/// Was `/api/v2/deliveries/getdeliveryqueues`. The backend has no queue, so
/// this is the assignment list, which is the same question asked of a
/// different noun: "what has the hub given me?"
static String get deliveryQueue => url('/miler/assignments');
/// **MAPPED** — the rider's own accepted work.
///
/// Was `/api/v2/deliveries/getdeliveries` (and the v1 and v3 date-bounded
/// variants, which collapsed to the same call with different params).
static String get currentDeliveries => url('/miler/bookings');
/// **LIVE** — full detail for one assignment.
static String assignmentDetail(Object id) => url('/miler/assignments/$id');
/// **LIVE** — accept a job.
///
/// Keyed on the **bookingassignmentid**, not the bookingid. Passing the wrong
/// one is the first of the two structural breaks recorded against this repo:
/// the handler reads `bookingassignmentid` and the app used to send a
/// bookingid, so every accept silently missed. The id comes from
/// [deliveryQueue]'s rows.
static String accept(Object assignmentId) =>
url('/miler/assignments/$assignmentId/accept');
/// **LIVE** — decline a job.
static String reject(Object assignmentId) =>
url('/miler/assignments/$assignmentId/reject');
// ───────────────────────── working a stop ─────────────────────────
/// **LIVE** — the rider is at the door.
static String reached(Object bookingId) =>
url('/miler/bookings/$bookingId/reached');
/// **LIVE** — hand the consignment over. The one genuine delivery verb the
/// backend has.
static String deliver(Object consignmentId) =>
url('/miler/consignments/$consignmentId/deliver');
/// **LIVE** — money changed hands.
static String payment(Object bookingId) =>
url('/miler/bookings/$bookingId/payment');
/// **ABSENT** — the generic status write the ported flow uses for every
/// transition (accepted → active → arrived → delivered → skipped).
///
/// Was `deliveries/updatedelivery` on the retired backend. There is no
/// single status-write route on Doormile; the transitions above are separate
/// endpoints. Call sites that still post a bare status change land here and
/// will 404 until either they are split or the route is built.
static String get updateDelivery => url('/miler/bookings/status');
// ───────────────────────── rider logs and duty ─────────────────────────
/// **LIVE** — periodic location/telemetry log.
///
/// Was `partners/createriderlog` on the retired backend.
static String get createRiderLog => url('/miler/logs');
/// **LIVE** — read them back.
static String get getRiderLog => url('/miler/logs');
/// **LIVE** — on/off duty.
static String get startDuty => url('/miler/duty/start');
static String get endDuty => url('/miler/duty/end');
static String get currentDuty => url('/miler/duty/current');
/// **LIVE** — break start/end. Was the `createbreaklog`/`updatebreaklog`
/// pair on the queue host.
static String get startBreak => url('/miler/breaks/start');
static String get endBreak => url('/miler/breaks/end');
/// **LIVE** — availability toggle, which is what the duty slider on the
/// delivery home screen actually means to the server.
static String get availability => url('/miler/availability');
/// **LIVE** — live location ping.
static String get location => url('/miler/location');
/// **ABSENT** — per-delivery event log.
///
/// Was `deliveries/createdeliverylog` on the retired backend. The
/// closest real thing is consignment logs, which key on a consignmentid the
/// delivery flow does not always hold.
static String get createDeliveryLog => url('/miler/consignments/logs');
// ───────────────────────── earnings and profile ─────────────────────────
/// **LIVE** — the Summary tab's figures. Was `/api/v2/partners/...`.
static String get earnings => url('/miler/earnings');
/// **ABSENT** — the weekly kilometre chart on Summary.
///
/// Was `/api/v1/partners/getriderweeklykms`. Doormile tracks distance through
/// the periodic logs but exposes no aggregate, so the chart has no source.
static String get weeklyKms => url('/miler/earnings/weekly-kms');
/// **ABSENT** — the bonus/rewards summary behind the rewards card.
static String get bonusSummary => url('/miler/earnings/bonus');
/// **LIVE** — rider profile.
static String get profile => url('/miler/profile');
// ───────────────────────── support ─────────────────────────
/// **LIVE** — raise and list support tickets.
static String get createSupportTicket => url('/miler/support');
static String get getSupportTickets => url('/miler/support');
/// **ABSENT** — image upload for a support ticket attachment.
///
/// Was `/api/v1/partners/uploadimage/` on the retired platform, with the
/// result served back from its own image host. Doormile has no upload route
/// and no image host, so attachments cannot be sent.
static String get uploadImage => url('/miler/support/upload');
/// Public base for an uploaded image. **ABSENT** — see [uploadImage].
static String image(String objectPath) =>
'https://images.doormile.com/$objectPath';
// ───────────────────────── notifications ─────────────────────────
/// **LIVE**
static String get notifications => url('/miler/notifications');
static String markNotificationRead(Object id) =>
url('/miler/notifications/$id/read');
}