assign option

This commit is contained in:
2026-09-04 11:31:07 +05:30
parent 743aa93e20
commit 416c50755b
8 changed files with 450 additions and 785 deletions

View File

@@ -10,6 +10,29 @@ import type { DeliveryDraft } from '@/features/store-admin/assignDelivery';
* these three change it.
*/
/**
* The rider has no device registered.
*
* Its own error type because the remedy differs from a transport failure: the
* rider must open the app and sign in, not retry. Collapsed into a generic
* "notification failed", an operator assumes the network is at fault and tries
* again forever.
*/
export class RiderNotReachableError extends Error {
constructor(message = 'This rider has no device registered, so they were not told.') {
super(message);
this.name = 'RiderNotReachableError';
}
}
/** What the rider is told. Kept together so the wording stays consistent. */
export const RIDER_MESSAGE = {
assigned: (count: number) =>
count === 1
? 'An order has been assigned to you. Kindly accept and process the delivery.'
: `${count} orders have been assigned to you. Kindly accept and process the deliveries.`,
} as const;
export interface RiderQuery {
/**
* The delivery region. This is the scope that works.
@@ -51,6 +74,29 @@ export const deliveriesApi = {
assign: (rows: DeliveryDraft[]) =>
api.post<unknown>(`${WEB}/deliveries/createdeliveries`, rows),
/**
* Tell a rider they have work.
*
* Deliberately NOT chained into `assign` — the deliveries are committed by
* the time this runs, so a failed push must not read as a failed assignment.
* Callers fire it afterwards and report the two outcomes separately: a rider
* who was never told has work sitting unseen, which the operator needs to
* know without being told the assignment failed.
*
* The backend holds the Firebase credentials; this only relays.
*/
notify: (token: string, body: string) => {
// Checked here rather than at the server: posting an empty token returns
// FCM's "exactly one of token, topic or condition must be specified",
// which reads as a server fault rather than as a rider who has never
// opened the app. Verified against the live endpoint.
if (!token.trim()) throw new RiderNotReachableError();
return api.post<unknown>(`${WEB}/utils/notifyuser`, {
token: token.trim(),
notification: { title: 'NearleXpress', body },
});
},
/**
* Move a delivery along its ladder, or hand it to a different rider.
*

View File

@@ -518,6 +518,8 @@ export interface RiderInfo {
vehiclename?: string;
vehicleno?: string;
licenseno?: string;
/** The device to push to. Empty for a rider who has never opened the app. */
userfcmtoken?: string;
shiftid?: number;
/** Shift window, as `HH:MM:SS`. */
starttime?: string;