@fayz-ai/orders 0.0.0-stage → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +38 -2
- package/dist/chunk-A4AGOZHO.js +168 -0
- package/dist/chunk-A4AGOZHO.js.map +1 -0
- package/dist/components/CommercialOrderCard.d.ts +7 -0
- package/dist/components/CommercialOrderCard.d.ts.map +1 -0
- package/dist/components/CommercialOrderCard.js +18 -0
- package/dist/components/CommercialOrderCard.js.map +1 -0
- package/dist/components/OrderBoardCard.d.ts +10 -0
- package/dist/components/OrderBoardCard.d.ts.map +1 -0
- package/dist/components/OrderBoardCard.js +35 -0
- package/dist/components/OrderBoardCard.js.map +1 -0
- package/dist/components/OrderStatusDot.d.ts +8 -0
- package/dist/components/OrderStatusDot.d.ts.map +1 -0
- package/dist/components/OrderStatusDot.js +22 -0
- package/dist/components/OrderStatusDot.js.map +1 -0
- package/dist/components/PaymentStateBadge.d.ts +6 -0
- package/dist/components/PaymentStateBadge.d.ts.map +1 -0
- package/dist/components/PaymentStateBadge.js +27 -0
- package/dist/components/PaymentStateBadge.js.map +1 -0
- package/dist/data/mock.d.ts +3 -0
- package/dist/data/mock.d.ts.map +1 -0
- package/dist/data/mock.js +208 -0
- package/dist/data/mock.js.map +1 -0
- package/dist/data/platform.d.ts +19 -0
- package/dist/data/platform.d.ts.map +1 -0
- package/dist/data/platform.js +362 -0
- package/dist/data/platform.js.map +1 -0
- package/dist/data/provider.d.ts +14 -0
- package/dist/data/provider.d.ts.map +1 -0
- package/dist/data/provider.js +3 -0
- package/dist/data/provider.js.map +1 -0
- package/dist/data/supabase.d.ts +19 -0
- package/dist/data/supabase.d.ts.map +1 -0
- package/dist/data/supabase.js +316 -0
- package/dist/data/supabase.js.map +1 -0
- package/dist/domain/order.d.ts +172 -0
- package/dist/domain/order.d.ts.map +1 -0
- package/dist/domain/order.js +3 -0
- package/dist/domain/order.js.map +1 -0
- package/dist/store.d.ts +30 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +146 -0
- package/dist/store.js.map +1 -0
- package/package.json +52 -3
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
export type OrderKind = 'dine_in' | 'takeout' | 'delivery';
|
|
2
|
+
export type DineInStatus = 'draft' | 'new' | 'confirmed' | 'preparing' | 'ready' | 'served' | 'completed' | 'cancelled';
|
|
3
|
+
export type TakeoutStatus = 'draft' | 'new' | 'confirmed' | 'preparing' | 'ready' | 'picked_up' | 'completed' | 'cancelled';
|
|
4
|
+
export type DeliveryStatus = 'draft' | 'new' | 'confirmed' | 'preparing' | 'ready' | 'dispatched' | 'delivered' | 'completed' | 'cancelled';
|
|
5
|
+
export type OrderStatus = DineInStatus | TakeoutStatus | DeliveryStatus;
|
|
6
|
+
export type KanbanColumn = 'new' | 'confirmed' | 'preparing' | 'ready' | 'out' | 'completed' | 'cancelled';
|
|
7
|
+
export interface RestaurantOrder {
|
|
8
|
+
id: string;
|
|
9
|
+
referenceNumber: string;
|
|
10
|
+
kind: OrderKind;
|
|
11
|
+
status: OrderStatus;
|
|
12
|
+
partyId?: string;
|
|
13
|
+
partyName?: string;
|
|
14
|
+
assigneeId?: string;
|
|
15
|
+
assigneeName?: string;
|
|
16
|
+
locationId?: string;
|
|
17
|
+
subtotal: number;
|
|
18
|
+
discount: number;
|
|
19
|
+
tax: number;
|
|
20
|
+
total: number;
|
|
21
|
+
currency: string;
|
|
22
|
+
notes?: string;
|
|
23
|
+
tags: string[];
|
|
24
|
+
source: string;
|
|
25
|
+
tableId?: string;
|
|
26
|
+
tableName?: string;
|
|
27
|
+
estimatedMinutes?: number;
|
|
28
|
+
items: RestaurantOrderItem[];
|
|
29
|
+
metadata?: Record<string, unknown>;
|
|
30
|
+
tenantId: string;
|
|
31
|
+
unitId?: string;
|
|
32
|
+
createdAt: string;
|
|
33
|
+
updatedAt: string;
|
|
34
|
+
completedAt?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface RestaurantOrderItem {
|
|
37
|
+
id: string;
|
|
38
|
+
orderId: string;
|
|
39
|
+
productId?: string;
|
|
40
|
+
name: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
quantity: number;
|
|
43
|
+
unitPrice: number;
|
|
44
|
+
discount: number;
|
|
45
|
+
total: number;
|
|
46
|
+
sortOrder: number;
|
|
47
|
+
modifiers?: string;
|
|
48
|
+
kitchenNotes?: string;
|
|
49
|
+
metadata?: Record<string, unknown>;
|
|
50
|
+
createdAt: string;
|
|
51
|
+
}
|
|
52
|
+
export interface CreateOrderInput {
|
|
53
|
+
kind: OrderKind;
|
|
54
|
+
source?: string;
|
|
55
|
+
tableId?: string;
|
|
56
|
+
partyId?: string;
|
|
57
|
+
assigneeId?: string;
|
|
58
|
+
notes?: string;
|
|
59
|
+
estimatedMinutes?: number;
|
|
60
|
+
items: CreateOrderItemInput[];
|
|
61
|
+
}
|
|
62
|
+
export interface CreateOrderItemInput {
|
|
63
|
+
productId?: string;
|
|
64
|
+
name: string;
|
|
65
|
+
quantity: number;
|
|
66
|
+
unitPrice: number;
|
|
67
|
+
discount?: number;
|
|
68
|
+
modifiers?: string;
|
|
69
|
+
kitchenNotes?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface UpdateOrderStatusInput {
|
|
72
|
+
orderId: string;
|
|
73
|
+
status: OrderStatus;
|
|
74
|
+
}
|
|
75
|
+
export interface OrderQuery {
|
|
76
|
+
kind?: OrderKind | OrderKind[] | (string & {}) | string[];
|
|
77
|
+
status?: OrderStatus | OrderStatus[] | (string & {}) | string[];
|
|
78
|
+
source?: string;
|
|
79
|
+
/** Sales channel as `orders.channel` holds it (balcao · shop · delivery…). */
|
|
80
|
+
channel?: string;
|
|
81
|
+
/** unfulfilled · partially_fulfilled · fulfilled */
|
|
82
|
+
fulfillmentStatus?: string;
|
|
83
|
+
/** Kinds left out — the sales list drops `purchase`, which shares the table. */
|
|
84
|
+
excludeKinds?: string[];
|
|
85
|
+
/** `false` skips the lines — a list row does not draw them. Default true. */
|
|
86
|
+
withItems?: boolean;
|
|
87
|
+
tableId?: string;
|
|
88
|
+
assigneeId?: string;
|
|
89
|
+
dateRange?: DateRange;
|
|
90
|
+
search?: string;
|
|
91
|
+
page?: number;
|
|
92
|
+
pageSize?: number;
|
|
93
|
+
}
|
|
94
|
+
export interface DateRange {
|
|
95
|
+
from: string;
|
|
96
|
+
to: string;
|
|
97
|
+
}
|
|
98
|
+
export interface PaginatedResult<T> {
|
|
99
|
+
data: T[];
|
|
100
|
+
total: number;
|
|
101
|
+
}
|
|
102
|
+
export interface OrdersSummary {
|
|
103
|
+
todayOrderCount: number;
|
|
104
|
+
todayRevenue: number;
|
|
105
|
+
averageTicket: number;
|
|
106
|
+
activeOrderCount: number;
|
|
107
|
+
ordersByKind: Record<OrderKind, number>;
|
|
108
|
+
ordersByStatus: Record<string, number>;
|
|
109
|
+
topItems: Array<{
|
|
110
|
+
name: string;
|
|
111
|
+
quantity: number;
|
|
112
|
+
revenue: number;
|
|
113
|
+
}>;
|
|
114
|
+
}
|
|
115
|
+
export interface OrderStatusConfig {
|
|
116
|
+
value: string;
|
|
117
|
+
label: string;
|
|
118
|
+
color: string;
|
|
119
|
+
icon?: string;
|
|
120
|
+
}
|
|
121
|
+
export declare const DEFAULT_STATUS_CONFIGS: OrderStatusConfig[];
|
|
122
|
+
export declare const STATUS_FLOW: Record<OrderKind, OrderStatus[]>;
|
|
123
|
+
/** The food has left the kitchen: one step, a different word per kind. */
|
|
124
|
+
export declare const OUT_STATUSES: readonly OrderStatus[];
|
|
125
|
+
/** Work in progress: on the board until it is completed or cancelled. */
|
|
126
|
+
export declare const ACTIVE_STATUSES: readonly OrderStatus[];
|
|
127
|
+
export declare const KANBAN_COLUMNS: KanbanColumn[];
|
|
128
|
+
/** The verb on the advance button, keyed by the status it moves to. */
|
|
129
|
+
export declare const ADVANCE_VERB: Record<OrderStatus, string>;
|
|
130
|
+
export declare function isActive(status: string): boolean;
|
|
131
|
+
/** Completed or cancelled: nothing is added to it, advanced or cancelled again. */
|
|
132
|
+
export declare function isClosed(status: string | undefined): boolean;
|
|
133
|
+
export declare function getNextStatus(kind: OrderKind, current: OrderStatus): OrderStatus | null;
|
|
134
|
+
export declare function getPreviousStatus(kind: OrderKind, current: OrderStatus): OrderStatus | null;
|
|
135
|
+
/** Cancelling is always allowed; otherwise the order stays put or takes the next step of its flow. */
|
|
136
|
+
export declare function canMoveTo(kind: OrderKind, from: OrderStatus, to: OrderStatus): boolean;
|
|
137
|
+
export declare function mapToKanbanColumn(status: OrderStatus): KanbanColumn;
|
|
138
|
+
/** Which board an order runs on: the dining room pays after eating, delivery and takeout before. */
|
|
139
|
+
export type OrderService = 'salao' | 'delivery';
|
|
140
|
+
export declare function serviceOf(order: Pick<RestaurantOrder, 'kind'>): OrderService;
|
|
141
|
+
/** The dining room has no "new" column: a comanda is open from the moment a waiter opens it. */
|
|
142
|
+
export declare function boardColumns(service: OrderService): KanbanColumn[];
|
|
143
|
+
export declare function boardColumnOf(service: OrderService, status: OrderStatus): KanbanColumn;
|
|
144
|
+
/** The column this order sits in on `service`'s board, or null when it runs on the other board. */
|
|
145
|
+
export declare function boardColumnFor(service: OrderService, order: Pick<RestaurantOrder, 'kind' | 'status'>): KanbanColumn | null;
|
|
146
|
+
export declare function nextBoardColumn(service: OrderService, order: Pick<RestaurantOrder, 'kind' | 'status'>): KanbanColumn | null;
|
|
147
|
+
export declare function lineTotal(item: {
|
|
148
|
+
quantity: number;
|
|
149
|
+
unitPrice: number;
|
|
150
|
+
discount?: number;
|
|
151
|
+
}): number;
|
|
152
|
+
export declare function orderTotals(items: ReadonlyArray<{
|
|
153
|
+
total: number;
|
|
154
|
+
}>, adjustments?: {
|
|
155
|
+
discount?: number;
|
|
156
|
+
tax?: number;
|
|
157
|
+
}): {
|
|
158
|
+
subtotal: number;
|
|
159
|
+
total: number;
|
|
160
|
+
};
|
|
161
|
+
export declare function withCancellationNote(notes: string | undefined, reason?: string): string | undefined;
|
|
162
|
+
export declare function isoDay(date?: Date | string): string;
|
|
163
|
+
export declare function matchesQuery(order: RestaurantOrder, query: OrderQuery): boolean;
|
|
164
|
+
export declare function paginate<T>(items: T[], page?: number, pageSize?: number): PaginatedResult<T>;
|
|
165
|
+
/** Counts orders created in the range (today by default); revenue and top items leave cancelled ones out. */
|
|
166
|
+
export declare function summarizeOrders(orders: RestaurantOrder[], dateRange?: DateRange, today?: string): OrdersSummary;
|
|
167
|
+
/** Whether a sale produced a receivable (título), and how far it is paid. */
|
|
168
|
+
export type PaymentState = 'none' | 'pending' | 'partial' | 'paid' | 'overdue' | 'cancelled';
|
|
169
|
+
export declare function paymentStateOf(order: Pick<RestaurantOrder, 'metadata'>): PaymentState;
|
|
170
|
+
export type CommercialColumn = 'open' | 'no_invoice' | 'paid' | 'cancelled';
|
|
171
|
+
export declare function commercialColumnOf(order: Pick<RestaurantOrder, 'status' | 'metadata'>): CommercialColumn;
|
|
172
|
+
//# sourceMappingURL=order.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.d.ts","sourceRoot":"","sources":["../../src/domain/order.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { ACTIVE_STATUSES, ADVANCE_VERB, DEFAULT_STATUS_CONFIGS, KANBAN_COLUMNS, OUT_STATUSES, STATUS_FLOW, boardColumnFor, boardColumnOf, boardColumns, canMoveTo, commercialColumnOf, getNextStatus, getPreviousStatus, isActive, isClosed, isoDay, lineTotal, mapToKanbanColumn, matchesQuery, nextBoardColumn, orderTotals, paginate, paymentStateOf, serviceOf, summarizeOrders, withCancellationNote } from '../chunk-A4AGOZHO.js';
|
|
2
|
+
//# sourceMappingURL=order.js.map
|
|
3
|
+
//# sourceMappingURL=order.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"order.js"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type StoreApi } from 'zustand/vanilla';
|
|
2
|
+
import type { OrdersDataProvider } from './data/provider';
|
|
3
|
+
import { type CreateOrderInput, type CreateOrderItemInput, type DateRange, type OrderQuery, type OrdersSummary, type RestaurantOrder, type UpdateOrderStatusInput } from './domain/order';
|
|
4
|
+
export interface OrdersUIState {
|
|
5
|
+
orders: RestaurantOrder[];
|
|
6
|
+
ordersTotal: number;
|
|
7
|
+
ordersLoading: boolean;
|
|
8
|
+
orderQuery: OrderQuery;
|
|
9
|
+
activeOrders: RestaurantOrder[];
|
|
10
|
+
activeOrdersLoading: boolean;
|
|
11
|
+
summary: OrdersSummary | null;
|
|
12
|
+
summaryLoading: boolean;
|
|
13
|
+
selectedOrderId: string | null;
|
|
14
|
+
fetchOrders(query: OrderQuery): Promise<void>;
|
|
15
|
+
fetchActiveOrders(): Promise<void>;
|
|
16
|
+
fetchSummary(dateRange?: DateRange): Promise<void>;
|
|
17
|
+
selectOrder(id: string | null): void;
|
|
18
|
+
createOrder(input: CreateOrderInput): Promise<RestaurantOrder>;
|
|
19
|
+
advanceOrderStatus(orderId: string): Promise<void>;
|
|
20
|
+
updateOrderStatus(input: UpdateOrderStatusInput): Promise<void>;
|
|
21
|
+
cancelOrder(id: string, reason?: string): Promise<void>;
|
|
22
|
+
addOrderItem(orderId: string, item: CreateOrderItemInput): Promise<void>;
|
|
23
|
+
removeOrderItem(itemId: string): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export interface OrdersLifecycleHooks {
|
|
26
|
+
onOrderCompleted?: (order: RestaurantOrder) => Promise<void>;
|
|
27
|
+
onOrderCancelled?: (order: RestaurantOrder) => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export declare function createOrdersStore(provider: OrdersDataProvider, hooks?: OrdersLifecycleHooks): StoreApi<OrdersUIState>;
|
|
30
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAEL,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EACrG,KAAK,eAAe,EAAE,KAAK,sBAAsB,EAClD,MAAM,gBAAgB,CAAA;AAEvB,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,eAAe,EAAE,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,UAAU,CAAA;IAEtB,YAAY,EAAE,eAAe,EAAE,CAAA;IAC/B,mBAAmB,EAAE,OAAO,CAAA;IAE5B,OAAO,EAAE,aAAa,GAAG,IAAI,CAAA;IAC7B,cAAc,EAAE,OAAO,CAAA;IAEvB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAE9B,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7C,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,YAAY,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IACpC,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC9D,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/D,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxE,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/C;AAED,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7D;AAuCD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,KAAK,GAAE,oBAAyB,GAAG,QAAQ,CAAC,aAAa,CAAC,CA6HzH"}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { ACTIVE_STATUSES, getNextStatus } from './chunk-A4AGOZHO.js';
|
|
2
|
+
import { createStore } from 'zustand/vanilla';
|
|
3
|
+
import { errorMessage, emitDomainEvent } from '@fayz-ai/core';
|
|
4
|
+
import { toast } from '@fayz-ai/ui';
|
|
5
|
+
|
|
6
|
+
function emitLifecycleEvent(key, order) {
|
|
7
|
+
emitDomainEvent(key, {
|
|
8
|
+
order_id: order.id,
|
|
9
|
+
reference_number: order.referenceNumber,
|
|
10
|
+
total: order.total,
|
|
11
|
+
item_count: order.items.length,
|
|
12
|
+
source: order.source
|
|
13
|
+
}, {
|
|
14
|
+
tenantId: order.tenantId,
|
|
15
|
+
subject: { type: "order", id: order.id }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async function runLifecycleHook(label, order, hook) {
|
|
19
|
+
if (!hook) return;
|
|
20
|
+
try {
|
|
21
|
+
await hook(order);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw new Error(`Order was ${label}, but downstream synchronization is pending: ${errorMessage(error)}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function withToast(success, failure, run) {
|
|
27
|
+
try {
|
|
28
|
+
const result = await run();
|
|
29
|
+
toast.success(success);
|
|
30
|
+
return result;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
toast.error(failure, { description: errorMessage(error) });
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function createOrdersStore(provider, hooks = {}) {
|
|
37
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
38
|
+
function shared(key, read) {
|
|
39
|
+
const running = inflight.get(key);
|
|
40
|
+
if (running) return running;
|
|
41
|
+
const promise = read().finally(() => inflight.delete(key));
|
|
42
|
+
inflight.set(key, promise);
|
|
43
|
+
return promise;
|
|
44
|
+
}
|
|
45
|
+
const readActive = () => provider.getOrders({ status: [...ACTIVE_STATUSES] });
|
|
46
|
+
return createStore((set, get) => {
|
|
47
|
+
async function refreshList(withSummary) {
|
|
48
|
+
const query = get().orderQuery;
|
|
49
|
+
const [result, summary] = await Promise.all([
|
|
50
|
+
provider.getOrders(query),
|
|
51
|
+
withSummary ? provider.getSummary() : Promise.resolve(get().summary)
|
|
52
|
+
]);
|
|
53
|
+
set({ orders: result.data, ordersTotal: result.total, summary });
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
orders: [],
|
|
57
|
+
ordersTotal: 0,
|
|
58
|
+
ordersLoading: false,
|
|
59
|
+
orderQuery: {},
|
|
60
|
+
activeOrders: [],
|
|
61
|
+
activeOrdersLoading: false,
|
|
62
|
+
summary: null,
|
|
63
|
+
summaryLoading: false,
|
|
64
|
+
selectedOrderId: null,
|
|
65
|
+
async fetchOrders(query) {
|
|
66
|
+
set({ ordersLoading: true, orderQuery: query });
|
|
67
|
+
try {
|
|
68
|
+
const result = await shared(`orders:list:${JSON.stringify(query)}`, () => provider.getOrders(query));
|
|
69
|
+
set({ orders: result.data, ordersTotal: result.total });
|
|
70
|
+
} finally {
|
|
71
|
+
set({ ordersLoading: false });
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
async fetchActiveOrders() {
|
|
75
|
+
set({ activeOrdersLoading: true });
|
|
76
|
+
try {
|
|
77
|
+
const result = await shared("orders:active", readActive);
|
|
78
|
+
set({ activeOrders: result.data });
|
|
79
|
+
} finally {
|
|
80
|
+
set({ activeOrdersLoading: false });
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
async fetchSummary(dateRange) {
|
|
84
|
+
set({ summaryLoading: true });
|
|
85
|
+
try {
|
|
86
|
+
set({ summary: await shared(`orders:summary:${JSON.stringify(dateRange ?? null)}`, () => provider.getSummary(dateRange)) });
|
|
87
|
+
} finally {
|
|
88
|
+
set({ summaryLoading: false });
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
selectOrder(id) {
|
|
92
|
+
set({ selectedOrderId: id });
|
|
93
|
+
},
|
|
94
|
+
createOrder: (input) => withToast("Pedido criado", "N\xE3o foi poss\xEDvel criar o pedido", async () => {
|
|
95
|
+
const order = await provider.createOrder(input);
|
|
96
|
+
await refreshList(true);
|
|
97
|
+
return order;
|
|
98
|
+
}),
|
|
99
|
+
advanceOrderStatus: (orderId) => withToast("Pedido avan\xE7ado", "N\xE3o foi poss\xEDvel avan\xE7ar o pedido", async () => {
|
|
100
|
+
const { orders, activeOrders } = get();
|
|
101
|
+
const order = orders.find((o) => o.id === orderId) ?? activeOrders.find((o) => o.id === orderId);
|
|
102
|
+
if (!order) throw new Error("Order not found");
|
|
103
|
+
const nextStatus = getNextStatus(order.kind, order.status);
|
|
104
|
+
if (!nextStatus) throw new Error("No next status available");
|
|
105
|
+
const updated = await provider.updateOrderStatus({ orderId, status: nextStatus });
|
|
106
|
+
if (updated.status === "completed") {
|
|
107
|
+
emitLifecycleEvent("orders.order_completed", updated);
|
|
108
|
+
await runLifecycleHook("completed", updated, hooks.onOrderCompleted);
|
|
109
|
+
}
|
|
110
|
+
set({ activeOrders: (await readActive()).data });
|
|
111
|
+
}),
|
|
112
|
+
updateOrderStatus: (input) => withToast("Status atualizado", "N\xE3o foi poss\xEDvel atualizar o status", async () => {
|
|
113
|
+
const before = await provider.getOrderById(input.orderId);
|
|
114
|
+
const updated = await provider.updateOrderStatus(input);
|
|
115
|
+
if (updated.status === "completed") {
|
|
116
|
+
if (before?.status !== "completed") emitLifecycleEvent("orders.order_completed", updated);
|
|
117
|
+
await runLifecycleHook("completed", updated, hooks.onOrderCompleted);
|
|
118
|
+
}
|
|
119
|
+
await refreshList(true);
|
|
120
|
+
}),
|
|
121
|
+
cancelOrder: (id, reason) => withToast("Pedido cancelado", "N\xE3o foi poss\xEDvel cancelar o pedido", async () => {
|
|
122
|
+
const before = await provider.getOrderById(id);
|
|
123
|
+
await provider.cancelOrder(id, reason);
|
|
124
|
+
const cancelled = await provider.getOrderById(id);
|
|
125
|
+
const order = cancelled ?? (before ? { ...before, status: "cancelled" } : null);
|
|
126
|
+
if (order) {
|
|
127
|
+
if (before?.status !== "cancelled") emitLifecycleEvent("orders.order_cancelled", order);
|
|
128
|
+
await runLifecycleHook("cancelled", order, hooks.onOrderCancelled);
|
|
129
|
+
}
|
|
130
|
+
await refreshList(true);
|
|
131
|
+
}),
|
|
132
|
+
addOrderItem: (orderId, item) => withToast("Item adicionado", "N\xE3o foi poss\xEDvel adicionar o item", async () => {
|
|
133
|
+
await provider.addOrderItem(orderId, item);
|
|
134
|
+
await refreshList(false);
|
|
135
|
+
}),
|
|
136
|
+
removeOrderItem: (itemId) => withToast("Item removido", "N\xE3o foi poss\xEDvel remover o item", async () => {
|
|
137
|
+
await provider.removeOrderItem(itemId);
|
|
138
|
+
await refreshList(false);
|
|
139
|
+
})
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export { createOrdersStore };
|
|
145
|
+
//# sourceMappingURL=store.js.map
|
|
146
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"names":[],"mappings":"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","file":"store.js","sourcesContent":["import { createStore, type StoreApi } from 'zustand/vanilla'\nimport { emitDomainEvent, errorMessage } from '@fayz-ai/core'\nimport { toast } from '@fayz-ai/ui'\nimport type { OrdersDataProvider } from './data/provider'\nimport {\n ACTIVE_STATUSES, getNextStatus,\n type CreateOrderInput, type CreateOrderItemInput, type DateRange, type OrderQuery, type OrdersSummary,\n type RestaurantOrder, type UpdateOrderStatusInput,\n} from './domain/order'\n\nexport interface OrdersUIState {\n orders: RestaurantOrder[]\n ordersTotal: number\n ordersLoading: boolean\n orderQuery: OrderQuery\n\n activeOrders: RestaurantOrder[]\n activeOrdersLoading: boolean\n\n summary: OrdersSummary | null\n summaryLoading: boolean\n\n selectedOrderId: string | null\n\n fetchOrders(query: OrderQuery): Promise<void>\n fetchActiveOrders(): Promise<void>\n fetchSummary(dateRange?: DateRange): Promise<void>\n selectOrder(id: string | null): void\n createOrder(input: CreateOrderInput): Promise<RestaurantOrder>\n advanceOrderStatus(orderId: string): Promise<void>\n updateOrderStatus(input: UpdateOrderStatusInput): Promise<void>\n cancelOrder(id: string, reason?: string): Promise<void>\n addOrderItem(orderId: string, item: CreateOrderItemInput): Promise<void>\n removeOrderItem(itemId: string): Promise<void>\n}\n\nexport interface OrdersLifecycleHooks {\n onOrderCompleted?: (order: RestaurantOrder) => Promise<void>\n onOrderCancelled?: (order: RestaurantOrder) => Promise<void>\n}\n\nfunction emitLifecycleEvent(key: 'orders.order_completed' | 'orders.order_cancelled', order: RestaurantOrder): void {\n emitDomainEvent(key, {\n order_id: order.id,\n reference_number: order.referenceNumber,\n total: order.total,\n item_count: order.items.length,\n source: order.source,\n }, {\n tenantId: order.tenantId,\n subject: { type: 'order', id: order.id },\n })\n}\n\nasync function runLifecycleHook(\n label: 'completed' | 'cancelled',\n order: RestaurantOrder,\n hook?: (order: RestaurantOrder) => Promise<void>,\n): Promise<void> {\n if (!hook) return\n try {\n await hook(order)\n } catch (error) {\n throw new Error(`Order was ${label}, but downstream synchronization is pending: ${errorMessage(error)}`)\n }\n}\n\nasync function withToast<T>(success: string, failure: string, run: () => Promise<T>): Promise<T> {\n try {\n const result = await run()\n toast.success(success)\n return result\n } catch (error) {\n toast.error(failure, { description: errorMessage(error) })\n throw error\n }\n}\n\nexport function createOrdersStore(provider: OrdersDataProvider, hooks: OrdersLifecycleHooks = {}): StoreApi<OrdersUIState> {\n // Per store: a store rebuilt for another tenant must not be handed the previous store's read.\n const inflight = new Map<string, Promise<unknown>>()\n function shared<T>(key: string, read: () => Promise<T>): Promise<T> {\n const running = inflight.get(key) as Promise<T> | undefined\n if (running) return running\n const promise = read().finally(() => inflight.delete(key))\n inflight.set(key, promise)\n return promise\n }\n\n const readActive = () => provider.getOrders({ status: [...ACTIVE_STATUSES] })\n\n return createStore<OrdersUIState>((set, get) => {\n async function refreshList(withSummary: boolean): Promise<void> {\n const query = get().orderQuery\n const [result, summary] = await Promise.all([\n provider.getOrders(query),\n withSummary ? provider.getSummary() : Promise.resolve(get().summary),\n ])\n set({ orders: result.data, ordersTotal: result.total, summary })\n }\n\n return {\n orders: [],\n ordersTotal: 0,\n ordersLoading: false,\n orderQuery: {},\n\n activeOrders: [],\n activeOrdersLoading: false,\n\n summary: null,\n summaryLoading: false,\n\n selectedOrderId: null,\n\n async fetchOrders(query) {\n set({ ordersLoading: true, orderQuery: query })\n try {\n const result = await shared(`orders:list:${JSON.stringify(query)}`, () => provider.getOrders(query))\n set({ orders: result.data, ordersTotal: result.total })\n } finally {\n set({ ordersLoading: false })\n }\n },\n\n async fetchActiveOrders() {\n set({ activeOrdersLoading: true })\n try {\n const result = await shared('orders:active', readActive)\n set({ activeOrders: result.data })\n } finally {\n set({ activeOrdersLoading: false })\n }\n },\n\n async fetchSummary(dateRange) {\n set({ summaryLoading: true })\n try {\n set({ summary: await shared(`orders:summary:${JSON.stringify(dateRange ?? null)}`, () => provider.getSummary(dateRange)) })\n } finally {\n set({ summaryLoading: false })\n }\n },\n\n selectOrder(id) {\n set({ selectedOrderId: id })\n },\n\n createOrder: (input) => withToast('Pedido criado', 'Não foi possível criar o pedido', async () => {\n const order = await provider.createOrder(input)\n await refreshList(true)\n return order\n }),\n\n advanceOrderStatus: (orderId) => withToast('Pedido avançado', 'Não foi possível avançar o pedido', async () => {\n const { orders, activeOrders } = get()\n const order = orders.find((o) => o.id === orderId) ?? activeOrders.find((o) => o.id === orderId)\n if (!order) throw new Error('Order not found')\n const nextStatus = getNextStatus(order.kind, order.status)\n if (!nextStatus) throw new Error('No next status available')\n\n const updated = await provider.updateOrderStatus({ orderId, status: nextStatus })\n if (updated.status === 'completed') {\n emitLifecycleEvent('orders.order_completed', updated)\n await runLifecycleHook('completed', updated, hooks.onOrderCompleted)\n }\n set({ activeOrders: (await readActive()).data })\n }),\n\n updateOrderStatus: (input) => withToast('Status atualizado', 'Não foi possível atualizar o status', async () => {\n const before = await provider.getOrderById(input.orderId)\n const updated = await provider.updateOrderStatus(input)\n if (updated.status === 'completed') {\n if (before?.status !== 'completed') emitLifecycleEvent('orders.order_completed', updated)\n // Replaying `completed` retries the idempotent downstream hook without a second event.\n await runLifecycleHook('completed', updated, hooks.onOrderCompleted)\n }\n await refreshList(true)\n }),\n\n cancelOrder: (id, reason) => withToast('Pedido cancelado', 'Não foi possível cancelar o pedido', async () => {\n const before = await provider.getOrderById(id)\n await provider.cancelOrder(id, reason)\n const cancelled = await provider.getOrderById(id)\n const order = cancelled ?? (before ? { ...before, status: 'cancelled' as const } : null)\n if (order) {\n if (before?.status !== 'cancelled') emitLifecycleEvent('orders.order_cancelled', order)\n await runLifecycleHook('cancelled', order, hooks.onOrderCancelled)\n }\n await refreshList(true)\n }),\n\n addOrderItem: (orderId, item) => withToast('Item adicionado', 'Não foi possível adicionar o item', async () => {\n await provider.addOrderItem(orderId, item)\n await refreshList(false)\n }),\n\n removeOrderItem: (itemId) => withToast('Item removido', 'Não foi possível remover o item', async () => {\n await provider.removeOrderItem(itemId)\n await refreshList(false)\n }),\n }\n })\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fayz-ai/orders",
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
"fayz": {
|
|
4
|
+
"status": "beta"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"description": "Fayz SDK orders context — the order domain and its status flow, the repository port and adapters, the store and UI pieces",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
"./*": {
|
|
12
|
+
"types": "./dist/*.d.ts",
|
|
13
|
+
"import": "./dist/*.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@supabase/supabase-js": "^2.45.0",
|
|
21
|
+
"lucide-react": ">=0.400.0 <1.0.0",
|
|
22
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
23
|
+
"zustand": "^4.5.0 || ^5.0.0"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@fayz-ai/core": "^0.48.0",
|
|
27
|
+
"@fayz-ai/sdk": "^0.48.0",
|
|
28
|
+
"@fayz-ai/ui": "^0.48.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@supabase/supabase-js": "^2.45.0",
|
|
32
|
+
"@types/react": "^18.3.0",
|
|
33
|
+
"lucide-react": "^0.400.0",
|
|
34
|
+
"react": "^18.3.0",
|
|
35
|
+
"tsup": "^8.2.0",
|
|
36
|
+
"typescript": "^5.5.0",
|
|
37
|
+
"vitest": "^4.1.5",
|
|
38
|
+
"zustand": "^4.5.0"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"keywords": [
|
|
42
|
+
"fayz",
|
|
43
|
+
"orders"
|
|
44
|
+
],
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsup && tsc -b --force",
|
|
50
|
+
"dev": "tsup --watch",
|
|
51
|
+
"typecheck": "tsc -b tsconfig.test.json",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"clean": "rm -rf dist .tsbuildinfo"
|
|
54
|
+
}
|
|
6
55
|
}
|