@teincfood/core 0.10.17 → 0.10.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,7 +36,7 @@ export declare const sellerService: {
36
36
  }>;
37
37
  };
38
38
  export declare const kioskService: {
39
- assignKioskOrderToRider: (_orderId: string, _riderId: string) => Promise<unknown>;
39
+ assignKioskOrderToRider: (_orderId: string, _riderId: string, _idempotencyKey?: string) => Promise<unknown>;
40
40
  };
41
41
  export declare const menuService: {
42
42
  fetchBusinessMenuItems: (_businessId: string, _page: number) => Promise<unknown>;
@@ -54,7 +54,7 @@ export const sellerService = {
54
54
  };
55
55
  // kiosk.service
56
56
  export const kioskService = {
57
- assignKioskOrderToRider: async (_orderId, _riderId) => {
57
+ assignKioskOrderToRider: async (_orderId, _riderId, _idempotencyKey) => {
58
58
  notImpl("kioskService.assignKioskOrderToRider");
59
59
  },
60
60
  };
@@ -141,8 +141,12 @@ export const orderRepository = {
141
141
  commandType: "delivery:assign",
142
142
  businessId: input.businessId,
143
143
  entityId: input.orderId,
144
- payload: { rider_id: input.riderId },
144
+ payload: { rider_id: input.riderId, idempotency_key: "" },
145
145
  });
146
+ // One user action = one stable key. Replays of this command (timeout,
147
+ // reconnect, LAN relay) must converge on the same delivery instead of
148
+ // creating another one.
149
+ command.payload.idempotency_key = command.command_id;
146
150
  const events = await syncEngine.execute(command);
147
151
  const event = events[0];
148
152
  if (!event) {
@@ -217,7 +217,12 @@ async function tryRest(businessId, payload, commandType) {
217
217
  const riderId = (payload.rider_id ?? payload.riderId);
218
218
  if (!riderId)
219
219
  return { ok: false, status: 422, code: "MISSING_RIDER", message: "Assign rider job has no rider_id — re-assign from the app" };
220
- await http.post(`/deliveries/assign`, { order_id: orderId, rider_id: riderId });
220
+ const idempotencyKey = (payload.idempotency_key ?? payload.idempotencyKey);
221
+ await http.post(`/deliveries/assign`, {
222
+ order_id: orderId,
223
+ rider_id: riderId,
224
+ ...(idempotencyKey ? { idempotency_key: idempotencyKey } : {}),
225
+ });
221
226
  return { ok: true };
222
227
  }
223
228
  // POST /deliveries/:deliveryId/confirm-handover — resolve the delivery
@@ -84,7 +84,8 @@ export class RestTransport {
84
84
  return this.executeOrderTransition(command, "cancel", timestamp, () => sellerService.cancelOrder(entity_id));
85
85
  }
86
86
  case "delivery:assign": {
87
- const response = await kioskService.assignKioskOrderToRider(entity_id, payload.rider_id);
87
+ const assignPayload = payload;
88
+ const response = await kioskService.assignKioskOrderToRider(entity_id, assignPayload.rider_id, assignPayload.idempotency_key ?? command.command_id);
88
89
  return this.wrapResponse("delivery.assigned", response, entity_id, timestamp, command);
89
90
  }
90
91
  case "delivery:confirm_handover": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@teincfood/core",
3
- "version": "0.10.17",
4
- "description": "TeincFood shared offline-first core — types, sync engine, local DB, reference data, and repositories for mobile + desktop",
3
+ "version": "0.10.18",
4
+ "description": "TeincFood shared offline-first core \u2014 types, sync engine, local DB, reference data, and repositories for mobile + desktop",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",