@final-commerce/command-frame 0.12.0 → 0.13.0

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.
@@ -1,3 +1,4 @@
1
+ import { applyAssignment } from '@final-commerce/common';
1
2
  import { MOCK_ORDERS, MOCK_PARKED_ORDERS, MOCK_USERS, mockPublishEvent } from '../../demo/database';
2
3
  export const mockAssignOrderUser = async (params) => {
3
4
  console.log('[Mock] assignOrderUser called', params);
@@ -11,20 +12,19 @@ export const mockAssignOrderUser = async (params) => {
11
12
  if (!order) {
12
13
  throw new Error(`Order with ID ${params.orderId} not found`);
13
14
  }
14
- if (params.userId === null) {
15
- order.assignedUser = null;
16
- }
17
- else if (order.assignedUser?.userId !== params.userId) {
18
- if (!MOCK_USERS.some((u) => u.id === params.userId)) {
19
- throw new Error(`User with ID ${params.userId} not found`);
20
- }
21
- order.assignedUser = { userId: params.userId, assignedAt: new Date().toISOString() };
15
+ if (params.userId !== null && !MOCK_USERS.some((u) => u.id === params.userId)) {
16
+ throw new Error(`User with ID ${params.userId} not found`);
22
17
  }
18
+ order.assignedUser = applyAssignment(order, {
19
+ userId: params.userId,
20
+ label: params.label,
21
+ at: new Date().toISOString(),
22
+ });
23
23
  mockPublishEvent('orders', 'order-updated', { order });
24
24
  return {
25
25
  success: true,
26
26
  orderId: order._id,
27
- assignedUser: order.assignedUser ?? null,
27
+ assignedUser: order.assignedUser,
28
28
  timestamp: new Date().toISOString(),
29
29
  };
30
30
  };
@@ -2,14 +2,25 @@ import type { CFOrderAssignedUser } from '../../CommonTypes';
2
2
  export interface AssignOrderUserParams {
3
3
  /** Order to assign. Omit to target the live cart's order — it must already exist (parked, paid or transitioned). */
4
4
  orderId?: string;
5
- /** User to assign (e.g. the driver), or null to unassign. Replaces any current assignee. */
5
+ /**
6
+ * User to assign (e.g. the driver), or null to unassign. Assigning replaces the current
7
+ * assignee with the same `label`; the replaced one stays in the order's record, ended.
8
+ */
6
9
  userId: string | null;
10
+ /**
11
+ * Why the user is assigned, free text — e.g. 'delivery'. Omit for an unlabeled assignment.
12
+ * When unassigning, ends only this label's assignee; omit it to end every current assignment.
13
+ */
14
+ label?: string | null;
7
15
  }
8
16
  export interface AssignOrderUserResponse {
9
17
  success: boolean;
10
18
  orderId: string;
11
- /** The order's assignee after the call; null when unassigned. */
12
- assignedUser: CFOrderAssignedUser | null;
19
+ /**
20
+ * Everyone who has had the order after the call, oldest first. Entries without
21
+ * `unassignedAt` are the current assignees.
22
+ */
23
+ assignedUser: CFOrderAssignedUser[];
13
24
  timestamp: string;
14
25
  }
15
26
  export type AssignOrderUser = (params: AssignOrderUserParams) => Promise<AssignOrderUserResponse>;
@@ -1,3 +1,4 @@
1
+ import { currentAssignees } from '@final-commerce/common';
1
2
  import { MOCK_ORDERS, MOCK_PARKED_ORDERS, MOCK_USERS, MOCK_STATIONS, MOCK_OUTLETS, safeSerialize, } from '../../demo/database';
2
3
  export const mockGetOrders = async (params) => {
3
4
  console.log('[Mock] getOrders called', params);
@@ -5,7 +6,7 @@ export const mockGetOrders = async (params) => {
5
6
  let orders = safeSerialize([...MOCK_ORDERS, ...MOCK_PARKED_ORDERS]);
6
7
  // Filter simulation
7
8
  if (params) {
8
- const { customerId, status, sessionId, paymentState, fulfillmentState, outletId, assignedUserId, inCart, orderType, customStatusId, customStatusKey, scheduled, scheduledFrom, scheduledTo, searchValue, limit, offset, sortBy, sortDirection, } = params;
9
+ const { customerId, status, sessionId, paymentState, fulfillmentState, outletId, assignedUserId, assignedUserLabel, inCart, orderType, customStatusId, customStatusKey, scheduled, scheduledFrom, scheduledTo, searchValue, limit, offset, sortBy, sortDirection, } = params;
9
10
  // 1. Filtering
10
11
  if (customerId) {
11
12
  orders = orders.filter((o) => o.customer && '_id' in o.customer && o.customer._id === customerId);
@@ -27,11 +28,13 @@ export const mockGetOrders = async (params) => {
27
28
  if (outletId) {
28
29
  orders = orders.filter((o) => o.posData?.outlet === outletId);
29
30
  }
30
- if (assignedUserId) {
31
- orders = orders.filter((o) => o.assignedUser?.userId === assignedUserId);
32
- }
33
- else if (assignedUserId === null) {
34
- orders = orders.filter((o) => o.assignedUser == null);
31
+ if (assignedUserId || assignedUserId === null || assignedUserLabel !== undefined) {
32
+ orders = orders.filter((o) => {
33
+ const holders = currentAssignees(o, assignedUserLabel);
34
+ if (assignedUserId === null)
35
+ return holders.length === 0;
36
+ return assignedUserId ? holders.some((a) => a.userId === assignedUserId) : holders.length > 0;
37
+ });
35
38
  }
36
39
  if (orderType !== undefined) {
37
40
  const types = Array.isArray(orderType) ? orderType : [orderType];
@@ -11,10 +11,16 @@ export interface GetOrdersParams {
11
11
  /** Only orders placed at this outlet (`posData.outlet`). Without it, orders from every outlet in the company are returned. */
12
12
  outletId?: string;
13
13
  /**
14
- * Only orders assigned to this user (`assignedUser.userId`), e.g. a driver's deliveries.
15
- * `null`: only orders nobody is assigned to yet (e.g. deliveries awaiting a driver).
14
+ * Only orders this user is assigned to now (a current `assignedUser` entry), e.g. a driver's deliveries.
15
+ * `null`: only orders nobody is assigned to now (e.g. deliveries awaiting a driver).
16
16
  */
17
17
  assignedUserId?: string | null;
18
+ /**
19
+ * Narrows the assignee test to assignments with this label, e.g. 'delivery': with `assignedUserId`, that
20
+ * user must hold the order under this label; with `assignedUserId: null`, nobody holds it under this label;
21
+ * alone, someone holds it under this label. `null` means unlabeled assignments.
22
+ */
23
+ assignedUserLabel?: string | null;
18
24
  /**
19
25
  * true: only orders loaded in a cart; false: only orders that aren't. Reads `order.inCart` when the order
20
26
  * carries it, otherwise the legacy reading (fulfillment 'draft' / status 'in-cart').
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@final-commerce/command-frame",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Commands Frame library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -57,7 +57,7 @@
57
57
  "ignoreBranchesMissingTickets": true
58
58
  },
59
59
  "dependencies": {
60
- "@final-commerce/common": "2.9.0"
60
+ "@final-commerce/common": "2.10.0"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@commitlint/cli": "^19.0.0",