@kasuvia/sdk 0.0.8 → 0.0.9
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/README.md +42 -15
- package/dist/AddressAutocomplete-CjcqPElD.d.mts +46 -0
- package/dist/AddressAutocomplete-CvJHuRkf.d.ts +46 -0
- package/dist/components/index.d.mts +497 -0
- package/dist/components/index.d.ts +497 -0
- package/dist/components/index.js +4217 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +4194 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/server.d.mts +26 -0
- package/dist/config/server.d.ts +26 -0
- package/dist/config/server.js +38 -0
- package/dist/config/server.js.map +1 -0
- package/dist/config/server.mjs +13 -0
- package/dist/config/server.mjs.map +1 -0
- package/dist/hooks/index.d.mts +393 -160
- package/dist/hooks/index.d.ts +393 -160
- package/dist/hooks/index.js +2792 -2137
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +2734 -2121
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index-CNW_LINy.d.mts +578 -0
- package/dist/index-CNW_LINy.d.ts +578 -0
- package/dist/{index-C1chUA3P.d.mts → index-F7N6UItS.d.mts} +1 -1
- package/dist/{index-C1chUA3P.d.ts → index-F7N6UItS.d.ts} +1 -1
- package/dist/index-NkI10J_E.d.mts +40 -0
- package/dist/index-NkI10J_E.d.ts +40 -0
- package/dist/index.d.mts +20437 -103
- package/dist/index.d.ts +20437 -103
- package/dist/index.js +2111 -1802
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2006 -1786
- package/dist/index.mjs.map +1 -1
- package/dist/media.service-Cx7dQjzX.d.mts +1393 -0
- package/dist/media.service-mrBFJ2UQ.d.ts +1393 -0
- package/dist/services/index.d.mts +908 -2
- package/dist/services/index.d.ts +908 -2
- package/dist/services/index.js +1492 -1686
- package/dist/services/index.js.map +1 -1
- package/dist/services/index.mjs +1431 -1670
- package/dist/services/index.mjs.map +1 -1
- package/package.json +46 -6
- package/src/components/bespoke/BespokeAvailabilityBadge.tsx +32 -0
- package/src/components/bespoke/BespokeProgressTracker.tsx +58 -0
- package/src/components/bespoke/index.ts +3 -0
- package/src/components/booking/SlotPicker.tsx +97 -0
- package/src/components/booking/index.ts +1 -0
- package/src/components/cart/CartItem.tsx +81 -0
- package/src/components/cart/CartSidebar.tsx +115 -0
- package/src/components/cart/CartTypeMismatchBanner.tsx +55 -0
- package/src/components/cart/index.ts +3 -0
- package/src/components/index.ts +8 -0
- package/src/components/orders/DeliverableReviewer.tsx +139 -0
- package/src/components/orders/index.ts +1 -0
- package/src/components/product/ProductCard.tsx +350 -0
- package/src/components/product/ProductGrid.tsx +84 -0
- package/src/components/product/index.ts +2 -0
- package/src/components/shared/AddressAutocomplete.tsx +212 -0
- package/src/components/shared/AnalyticsScripts.tsx +56 -0
- package/src/components/shared/CookieConsentBanner.tsx +98 -0
- package/src/components/shared/ImageEditorModal.tsx +1066 -0
- package/src/components/shared/ImageViewerModal.tsx +598 -0
- package/src/components/shared/LucideReactIcon.tsx +52 -0
- package/src/components/shared/MapPinDrop.tsx +101 -0
- package/src/components/shared/MultiSelectPicker.tsx +193 -0
- package/src/components/shared/OfflineBanner.tsx +46 -0
- package/src/components/shared/SearchableInput.tsx +153 -0
- package/src/components/shared/SearchablePopover.tsx +166 -0
- package/src/components/shared/SmartImage.tsx +311 -0
- package/src/components/shared/TruncatedValue.tsx +27 -0
- package/src/components/shared/UnsavedChangesGuard.tsx +138 -0
- package/src/components/shared/index.ts +15 -0
- package/src/components/skeletons/CardSkeleton.tsx +26 -0
- package/src/components/skeletons/CartItemSkeleton.tsx +26 -0
- package/src/components/skeletons/OrderItemSkeleton.tsx +26 -0
- package/src/components/skeletons/ProductCardSkeleton.tsx +26 -0
- package/src/components/skeletons/TableSkeleton.tsx +42 -0
- package/src/components/skeletons/index.ts +5 -0
- package/src/config/index.ts +22 -4
- package/src/config/server.ts +45 -0
- package/src/context/sdk-context.tsx +5 -2
- package/src/generated/auth-openapi.ts +2935 -0
- package/src/generated/cart-openapi.ts +652 -0
- package/src/generated/cms-openapi.ts +1668 -0
- package/src/generated/crm-openapi.ts +986 -0
- package/src/generated/graphql.ts +126 -0
- package/src/generated/index.ts +11 -0
- package/src/generated/media-openapi.ts +613 -0
- package/src/generated/notification-openapi.ts +862 -0
- package/src/generated/payment-openapi.ts +2713 -0
- package/src/generated/store-openapi.ts +9510 -0
- package/src/graphql/operations/collections.graphql +32 -0
- package/src/graphql/operations/products.graphql +197 -0
- package/src/graphql/operations/wishlist.graphql +25 -0
- package/src/hooks/index.ts +9 -2
- package/src/hooks/use-auth.ts +163 -69
- package/src/hooks/use-bespoke-availability.ts +39 -22
- package/src/hooks/use-business-config.ts +51 -0
- package/src/hooks/use-cart.ts +310 -238
- package/src/hooks/use-cms.ts +107 -127
- package/src/hooks/use-collections.ts +35 -55
- package/src/hooks/use-consultations.ts +9 -136
- package/src/hooks/use-countries.ts +19 -28
- package/src/hooks/use-currencies.ts +8 -20
- package/src/hooks/use-customer-address.ts +64 -0
- package/src/hooks/use-feedback.ts +34 -0
- package/src/hooks/use-languages.ts +26 -39
- package/src/hooks/use-media-upload.ts +23 -0
- package/src/hooks/use-notification-stream.ts +88 -0
- package/src/hooks/use-notifications.ts +163 -0
- package/src/hooks/use-order-stream.ts +29 -29
- package/src/hooks/use-orders.ts +91 -73
- package/src/hooks/use-payment.ts +116 -84
- package/src/hooks/use-products.ts +65 -269
- package/src/hooks/use-push-notifications.ts +122 -0
- package/src/hooks/use-reviews.ts +175 -0
- package/src/hooks/use-service-booking.ts +109 -132
- package/src/hooks/use-states.ts +16 -30
- package/src/hooks/use-wishlist.ts +44 -69
- package/src/index.ts +15 -11
- package/src/services/auth.service.ts +422 -132
- package/src/services/bespoke.service.ts +69 -10
- package/src/services/cart.service.ts +155 -186
- package/src/services/cms.service.ts +41 -50
- package/src/services/collection.service.ts +25 -63
- package/src/services/config.service.ts +10 -21
- package/src/services/consultation.service.ts +36 -93
- package/src/services/feedback.service.ts +76 -0
- package/src/services/index.ts +7 -1
- package/src/services/legal.service.ts +62 -0
- package/src/services/logistics.service.ts +235 -53
- package/src/services/media.service.ts +115 -0
- package/src/services/notifications.service.ts +204 -20
- package/src/services/order.service.ts +498 -127
- package/src/services/payment.service.ts +149 -100
- package/src/services/product.service.ts +157 -814
- package/src/services/review.service.ts +211 -0
- package/src/services/service-booking.service.ts +198 -99
- package/src/services/wishlist.service.ts +27 -74
- package/src/types/auth/index.ts +161 -18
- package/src/types/business/index.ts +9 -1
- package/src/types/cms/index.ts +91 -6
- package/src/types/cms/legal.ts +18 -0
- package/src/types/consultations/index.ts +60 -68
- package/src/types/index.ts +5 -3
- package/src/types/media/index.ts +35 -3
- package/src/types/payments/index.ts +80 -16
- package/src/types/reviews/index.ts +116 -0
- package/src/types/services/index.ts +113 -38
- package/src/types/store/checkout.ts +53 -0
- package/src/types/store/index.ts +273 -52
- package/src/types/store/invoice.ts +31 -0
- package/src/types/store/shipping.ts +84 -3
- package/src/types/ui/index.ts +1 -1
- package/src/utils/checkout.ts +19 -3
- package/src/utils/cookieConsent.ts +34 -0
- package/src/utils/format.ts +408 -0
- package/src/utils/geolocation.ts +134 -0
- package/src/utils/graphql-url.ts +47 -0
- package/src/utils/guest-session.ts +59 -0
- package/src/utils/http-client.ts +147 -0
- package/src/utils/index.ts +11 -4
- package/src/utils/status-colors.ts +79 -0
- package/src/utils/token-refresh.ts +115 -0
- package/src/utils/validators.ts +13 -0
- package/src/utils/youtube.ts +18 -0
- package/dist/index-C5YO9gTl.d.mts +0 -507
- package/dist/index-C5YO9gTl.d.ts +0 -507
- package/dist/index-CefG7_xq.d.mts +0 -793
- package/dist/index-DeHCf3zI.d.ts +0 -793
- package/src/graphql/collections.graphql.ts +0 -48
- package/src/graphql/index.ts +0 -7
- package/src/graphql/products.graphql.ts +0 -860
- package/src/graphql/wishlist.graphql.ts +0 -34
- package/src/hooks/use-consultation-stream.ts +0 -142
- package/src/types/bespoke/index.ts +0 -39
package/src/types/store/index.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import type { DeliveryAddress } from "./shipping";
|
|
2
2
|
|
|
3
3
|
export * from "./shipping";
|
|
4
|
+
export * from "./invoice";
|
|
5
|
+
export * from "./checkout";
|
|
4
6
|
export type { DeliveryAddress };
|
|
5
7
|
|
|
6
|
-
export
|
|
8
|
+
export enum ProductTypeEnum {
|
|
9
|
+
PHYSICAL = "physical",
|
|
10
|
+
DIGITAL = "digital",
|
|
11
|
+
SERVICE = "service",
|
|
12
|
+
BESPOKE = "bespoke",
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type ProductType = ProductTypeEnum | "physical" | "digital" | "service" | "bespoke";
|
|
7
16
|
|
|
8
17
|
export enum ServiceTypeEnum {
|
|
9
18
|
APPOINTMENT = 'appointment',
|
|
@@ -13,13 +22,18 @@ export enum ServiceTypeEnum {
|
|
|
13
22
|
|
|
14
23
|
export type ServiceType = ServiceTypeEnum | 'appointment' | 'project' | 'recurring'
|
|
15
24
|
|
|
25
|
+
// REAL BUG FIXED (2026-09-21): these values didn't match anything the real
|
|
26
|
+
// backend ever stores — kasuvia-store-management's Product.service_location_type
|
|
27
|
+
// (app/models/catalog.py) is validated against exactly "remote" |
|
|
28
|
+
// "at_business" | "customer_location". The old "physical"/"both" values
|
|
29
|
+
// would never match a real product's actual value.
|
|
16
30
|
export enum ServiceLocationTypeEnum {
|
|
17
31
|
REMOTE = 'remote',
|
|
18
|
-
|
|
19
|
-
|
|
32
|
+
AT_BUSINESS = 'at_business',
|
|
33
|
+
CUSTOMER_LOCATION = 'customer_location',
|
|
20
34
|
}
|
|
21
35
|
|
|
22
|
-
export type ServiceLocationType = ServiceLocationTypeEnum | 'remote' | '
|
|
36
|
+
export type ServiceLocationType = ServiceLocationTypeEnum | 'remote' | 'at_business' | 'customer_location'
|
|
23
37
|
|
|
24
38
|
export enum ServiceRecurringIntervalEnum {
|
|
25
39
|
WEEKLY = 'weekly',
|
|
@@ -43,9 +57,11 @@ export interface Collection {
|
|
|
43
57
|
name: string
|
|
44
58
|
slug: string
|
|
45
59
|
description?: string
|
|
46
|
-
image?: string
|
|
47
60
|
collection_type?: string
|
|
48
|
-
rules
|
|
61
|
+
/** Raw JSON string of smart-collection matching rules (kasuvia-store-management's own evaluation detail, never parsed client-side) — the real backend GraphQL field is a String scalar, not a structured object. */
|
|
62
|
+
rules?: string
|
|
63
|
+
image_url?: string
|
|
64
|
+
image_id?: string
|
|
49
65
|
status?: string
|
|
50
66
|
sort_order?: number
|
|
51
67
|
created_at: string
|
|
@@ -62,9 +78,9 @@ export interface Inventory {
|
|
|
62
78
|
reorder_quantity: number
|
|
63
79
|
track_quantity: boolean
|
|
64
80
|
allow_backorder: boolean
|
|
65
|
-
available
|
|
66
|
-
is_in_stock
|
|
67
|
-
is_low_stock
|
|
81
|
+
available?: number
|
|
82
|
+
is_in_stock?: boolean
|
|
83
|
+
is_low_stock?: boolean
|
|
68
84
|
updated_at: string
|
|
69
85
|
}
|
|
70
86
|
|
|
@@ -76,33 +92,47 @@ export interface ProductVariant {
|
|
|
76
92
|
price?: number
|
|
77
93
|
images: string[]
|
|
78
94
|
weight_kg?: number
|
|
95
|
+
length_cm?: number
|
|
96
|
+
width_cm?: number
|
|
97
|
+
height_cm?: number
|
|
79
98
|
is_active: boolean
|
|
80
99
|
inventory?: Inventory
|
|
81
|
-
created_at: string
|
|
82
|
-
updated_at: string
|
|
83
100
|
}
|
|
84
101
|
|
|
85
102
|
export interface CustomField {
|
|
86
103
|
label: string
|
|
87
104
|
unit?: string
|
|
88
105
|
required: boolean
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
/** "text" (free text/number input) or "choice" (customer picks from
|
|
107
|
+
* `options`) — matches kasuvia-store-management's CustomFieldSchema. */
|
|
108
|
+
field_type: "text" | "choice"
|
|
109
|
+
/** Only meaningful when field_type is "choice" - the pick list a
|
|
110
|
+
* merchant configured. Always [] for a "text" field. */
|
|
111
|
+
options: string[]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** One file of a DIGITAL/MIXED product (kasuvia-store-management's ProductDigitalFile) — replaces the old dropped single `digital_file_key` scalar. */
|
|
115
|
+
export interface ProductDigitalFile {
|
|
116
|
+
id: string
|
|
117
|
+
file_key: string
|
|
118
|
+
display_name: string
|
|
119
|
+
sort_order: number
|
|
92
120
|
}
|
|
93
121
|
|
|
94
122
|
export interface Product {
|
|
95
123
|
id: string
|
|
96
124
|
business_id: string
|
|
97
125
|
name: string
|
|
98
|
-
slug
|
|
126
|
+
slug?: string
|
|
99
127
|
description?: string
|
|
100
128
|
brand?: string
|
|
101
129
|
product_type: ProductType
|
|
102
130
|
requires_shipping: boolean
|
|
103
131
|
is_consumable: boolean
|
|
104
132
|
is_bespoke: boolean
|
|
105
|
-
is_physical?: boolean
|
|
133
|
+
is_physical?: boolean
|
|
134
|
+
is_non_returnable?: boolean
|
|
135
|
+
deposit_percentage?: number
|
|
106
136
|
base_price: number
|
|
107
137
|
currency: string
|
|
108
138
|
sale_price?: number
|
|
@@ -110,42 +140,67 @@ export interface Product {
|
|
|
110
140
|
sale_end?: string
|
|
111
141
|
images: string[]
|
|
112
142
|
tags: string[]
|
|
113
|
-
custom_fields
|
|
143
|
+
custom_fields?: CustomField[]
|
|
114
144
|
is_published: boolean
|
|
115
145
|
is_featured: boolean
|
|
116
146
|
is_popular: boolean
|
|
117
147
|
is_new: boolean
|
|
118
148
|
is_temporary: boolean
|
|
119
|
-
|
|
149
|
+
/** Real fields (kasuvia-crm's review pipeline syncs into these). */
|
|
150
|
+
average_rating?: number | null
|
|
151
|
+
rating_count: number
|
|
152
|
+
/** "kasuvia" for organic products, a real channel key ("whatsapp", etc.) for channel-imported products. */
|
|
153
|
+
source_channel: string
|
|
154
|
+
source_channel_ref_id?: string | null
|
|
155
|
+
digital_files: ProductDigitalFile[]
|
|
120
156
|
download_limit?: number
|
|
121
157
|
download_expires_at?: string
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
service_location_type
|
|
158
|
+
service_type?: ServiceType
|
|
159
|
+
service_duration_minutes?: number
|
|
160
|
+
service_location_type?: ServiceLocationType
|
|
161
|
+
/** Only meaningful when service_location_type === "customer_location". */
|
|
162
|
+
service_coverage_radius_km?: number | null
|
|
126
163
|
service_requires_consultation?: boolean
|
|
127
|
-
service_max_capacity_per_slot?: number
|
|
164
|
+
service_max_capacity_per_slot?: number
|
|
128
165
|
service_buffer_minutes?: number
|
|
129
166
|
service_is_recurring?: boolean
|
|
130
|
-
service_recurring_interval?: ServiceRecurringInterval
|
|
167
|
+
service_recurring_interval?: ServiceRecurringInterval
|
|
131
168
|
service_project_based?: boolean
|
|
132
|
-
weight_kg
|
|
169
|
+
weight_kg?: number
|
|
133
170
|
length_cm?: number
|
|
134
171
|
width_cm?: number
|
|
135
172
|
height_cm?: number
|
|
173
|
+
variants?: ProductVariant[]
|
|
174
|
+
collections?: Collection[]
|
|
175
|
+
inventory?: Inventory
|
|
136
176
|
created_at: string
|
|
137
177
|
updated_at: string
|
|
138
|
-
|
|
139
|
-
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export interface ProductListResponse {
|
|
181
|
+
items: Product[]
|
|
182
|
+
total: number
|
|
183
|
+
page: number
|
|
184
|
+
page_size: number
|
|
185
|
+
total_pages: number
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface CollectionListResponse {
|
|
189
|
+
items: Collection[]
|
|
190
|
+
total: number
|
|
191
|
+
page: number
|
|
192
|
+
page_size: number
|
|
193
|
+
total_pages: number
|
|
140
194
|
}
|
|
141
195
|
|
|
142
196
|
export interface ListParams {
|
|
143
197
|
page?: number
|
|
144
198
|
pageSize?: number
|
|
145
|
-
search?: string
|
|
146
|
-
ordering?: string
|
|
147
199
|
collectionSlug?: string
|
|
200
|
+
search?: string
|
|
148
201
|
excludeProductId?: string
|
|
202
|
+
/** One of physical/digital/service/bespoke — omit to browse the whole catalog. */
|
|
203
|
+
productType?: ProductType
|
|
149
204
|
}
|
|
150
205
|
|
|
151
206
|
export interface PaginatedResponse<T> {
|
|
@@ -165,23 +220,29 @@ export interface CartItem {
|
|
|
165
220
|
product_id: string
|
|
166
221
|
product_slug: string
|
|
167
222
|
product_name: string
|
|
168
|
-
|
|
223
|
+
image_url?: string
|
|
169
224
|
variant_id?: string
|
|
170
225
|
variant_attributes?: string | Record<string, string>
|
|
171
226
|
unit_price: number
|
|
172
227
|
quantity: number
|
|
173
228
|
custom_measurements?: string
|
|
174
229
|
is_bespoke: boolean
|
|
230
|
+
product_type?: ProductType
|
|
175
231
|
created_at: string
|
|
176
232
|
updated_at: string
|
|
177
233
|
}
|
|
178
234
|
|
|
179
235
|
export interface CartResponse {
|
|
236
|
+
/**
|
|
237
|
+
* The Redis cart key returned by kasuvia-cart-management on every cart operation.
|
|
238
|
+
* Used to correlate a cart with a shipping-rate quote and checkout session.
|
|
239
|
+
*/
|
|
240
|
+
id?: string
|
|
180
241
|
items: CartItem[]
|
|
181
242
|
subtotal: number
|
|
182
243
|
total: number
|
|
183
244
|
item_count: number
|
|
184
|
-
product_type?:
|
|
245
|
+
product_type?: ProductType
|
|
185
246
|
}
|
|
186
247
|
|
|
187
248
|
// ============================================================================
|
|
@@ -196,7 +257,17 @@ export interface WishlistItem {
|
|
|
196
257
|
product_name?: string
|
|
197
258
|
product_slug?: string
|
|
198
259
|
product_price?: number
|
|
199
|
-
|
|
260
|
+
/**
|
|
261
|
+
* REAL BUG FIXED (2026-09-21): was typed as an object
|
|
262
|
+
* (`Record<string, unknown> | null`) but the real GraphQL resolver
|
|
263
|
+
* (kasuvia-store-management's queries.py storefront wishlist query)
|
|
264
|
+
* returns a plain image URL string — a live consumer's `typeof === 'object'`
|
|
265
|
+
* check against this field was always false, silently hiding every
|
|
266
|
+
* wishlist item's image.
|
|
267
|
+
*/
|
|
268
|
+
product_image?: string | null
|
|
269
|
+
/** Real field (queries.py's `item.product.currency`) — the SDK's own GET_STOREFRONT_WISHLIST query already fetches it. */
|
|
270
|
+
currency?: string
|
|
200
271
|
}
|
|
201
272
|
|
|
202
273
|
export interface WishlistListResponse {
|
|
@@ -216,40 +287,111 @@ export type OrderStatus =
|
|
|
216
287
|
| 'confirmed'
|
|
217
288
|
| 'processing'
|
|
218
289
|
| 'packed'
|
|
219
|
-
| 'picked_up'
|
|
290
|
+
| 'picked_up' // Carrier pickup (for carrier shipping)
|
|
291
|
+
| 'ready_for_pickup' // Customer self-pickup: order ready for customer collection
|
|
292
|
+
| 'picked_up_by_customer' // Customer self-pickup: customer has collected the order
|
|
220
293
|
| 'in_transit'
|
|
221
294
|
| 'shipped'
|
|
222
295
|
| 'delivered'
|
|
223
296
|
| 'voided'
|
|
224
297
|
| 'refunded'
|
|
225
298
|
| 'failed';
|
|
226
|
-
export type BespokeStageKey = "received" | "development" | "finished" | "dispatched";
|
|
227
299
|
|
|
228
300
|
export interface OrderItem {
|
|
229
301
|
id: string;
|
|
230
|
-
|
|
231
|
-
|
|
302
|
+
order_id?: string;
|
|
303
|
+
product_id?: string;
|
|
304
|
+
variant_id?: string;
|
|
305
|
+
product_name: string;
|
|
232
306
|
quantity: number;
|
|
233
|
-
|
|
307
|
+
unit_price: number;
|
|
308
|
+
variant_details?: Record<string, unknown>;
|
|
309
|
+
custom_measurements?: Record<string, unknown>;
|
|
310
|
+
image_url?: string;
|
|
234
311
|
}
|
|
235
312
|
|
|
236
313
|
export interface Order {
|
|
237
314
|
id: string;
|
|
238
|
-
display_id
|
|
239
|
-
|
|
240
|
-
|
|
315
|
+
display_id: string;
|
|
316
|
+
business_id: string;
|
|
317
|
+
customer_id?: string;
|
|
241
318
|
status: OrderStatus;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
319
|
+
payment_status: string;
|
|
320
|
+
product_type?: ProductType;
|
|
321
|
+
subtotal_amount?: number;
|
|
322
|
+
discount_amount?: number;
|
|
323
|
+
discount_code?: string;
|
|
324
|
+
tax_amount?: number;
|
|
325
|
+
shipping_amount?: number;
|
|
326
|
+
total_amount: number;
|
|
327
|
+
currency: string;
|
|
328
|
+
customer_name?: string;
|
|
329
|
+
customer_email?: string;
|
|
330
|
+
carrier_name?: string;
|
|
331
|
+
carrier_slug?: string;
|
|
332
|
+
terminal_rate_id?: string;
|
|
333
|
+
tracking_number?: string;
|
|
334
|
+
delivery_status?: string;
|
|
335
|
+
guest_token?: string;
|
|
336
|
+
guest_email?: string;
|
|
337
|
+
guest_phone?: string;
|
|
338
|
+
guest_name?: string;
|
|
339
|
+
|
|
340
|
+
// Weight discrepancy & surcharge fields (Task 2)
|
|
341
|
+
shipping_surcharge_amount?: number;
|
|
342
|
+
shipping_surcharge_reason?: string;
|
|
343
|
+
shipping_surcharge_description?: string;
|
|
344
|
+
shipping_surcharge_applied_at?: string;
|
|
345
|
+
declared_weight_kg?: number;
|
|
346
|
+
actual_weight_kg?: number;
|
|
347
|
+
|
|
348
|
+
// Self-pickup verification fields (Task 3)
|
|
349
|
+
pickup_verification_code?: string;
|
|
350
|
+
pickup_verification_code_generated_at?: string;
|
|
351
|
+
pickup_verification_code_used_at?: string;
|
|
352
|
+
pickup_verification_failed_attempts?: number;
|
|
353
|
+
pickup_verification_locked_until?: string;
|
|
354
|
+
pickup_qr_payload?: string;
|
|
355
|
+
|
|
356
|
+
// Bespoke fields (Batch 4)
|
|
357
|
+
bespoke_brief?: string;
|
|
358
|
+
bespoke_reference_images?: string[];
|
|
359
|
+
bespoke_measurements?: Record<string, unknown>;
|
|
360
|
+
bespoke_preferred_timeline?: string;
|
|
361
|
+
bespoke_special_instructions?: string;
|
|
362
|
+
bespoke_deposit_ratio?: number;
|
|
363
|
+
bespoke_deposit_amount?: number;
|
|
364
|
+
bespoke_balance_amount?: number;
|
|
365
|
+
/** BespokeFulfillmentStatus: "processing" | "awaiting_approval" | "under_review" | "confirmed". */
|
|
366
|
+
bespoke_status?: string;
|
|
367
|
+
bespoke_deliverable_submitted_at?: string;
|
|
368
|
+
bespoke_deliverable_url?: string;
|
|
369
|
+
bespoke_deliverable_notes?: string;
|
|
370
|
+
bespoke_buyer_approved_at?: string;
|
|
371
|
+
bespoke_revision_count?: number;
|
|
372
|
+
bespoke_revision_notes?: string;
|
|
373
|
+
|
|
374
|
+
items: OrderItem[];
|
|
375
|
+
buyer_country?: string;
|
|
376
|
+
withdrawal_consent_given_at?: string;
|
|
377
|
+
created_at: string;
|
|
378
|
+
updated_at: string;
|
|
379
|
+
|
|
380
|
+
// Optional SDK legacy compatibility aliases for existing component consumers
|
|
381
|
+
total?: number;
|
|
382
|
+
shippingAmount?: number;
|
|
383
|
+
discountAmount?: number;
|
|
384
|
+
customerEmail?: string;
|
|
385
|
+
customerName?: string;
|
|
386
|
+
createdAt?: number;
|
|
387
|
+
updatedAt?: number;
|
|
246
388
|
deliveryMethod?: string;
|
|
247
389
|
trackingNumber?: string;
|
|
248
390
|
deliveryAddress?: string;
|
|
249
391
|
shippingAddress?: DeliveryAddress;
|
|
250
392
|
cancellationReason?: string;
|
|
251
393
|
hasBespoke?: boolean;
|
|
252
|
-
bespokeStage?:
|
|
394
|
+
bespokeStage?: string;
|
|
253
395
|
bespokeBrief?: string;
|
|
254
396
|
deliveryStatus?: string;
|
|
255
397
|
carrierName?: string;
|
|
@@ -278,6 +420,11 @@ export interface ShippingLocation {
|
|
|
278
420
|
lga: string;
|
|
279
421
|
country: string;
|
|
280
422
|
postal: string;
|
|
423
|
+
// Task: Plus Codes + Interactive Map Pin-Drop - Geolocation fields
|
|
424
|
+
latitude?: number | null;
|
|
425
|
+
longitude?: number | null;
|
|
426
|
+
plus_code?: string | null;
|
|
427
|
+
coordinate_source?: 'pin_drop' | 'plus_code' | 'manual' | null;
|
|
281
428
|
}
|
|
282
429
|
|
|
283
430
|
// ============================================================================
|
|
@@ -289,12 +436,81 @@ export interface FindOrderParams {
|
|
|
289
436
|
order_id: string;
|
|
290
437
|
}
|
|
291
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Mirrors kasuvia-store-management's real PhysicalFulfillmentCreate schema
|
|
441
|
+
* exactly (app/schemas/order.py) — the ONLY place these fields are actually
|
|
442
|
+
* read from on OrderCreate. See CreateOrderParams's own doc comment for the
|
|
443
|
+
* real bug this replaced (they used to be declared flat on CreateOrderParams
|
|
444
|
+
* itself, which OrderBase's `extra: "allow"` config accepted with no
|
|
445
|
+
* validation error, then silently discarded — order_in.physical stayed None
|
|
446
|
+
* regardless of what was sent).
|
|
447
|
+
*/
|
|
448
|
+
export interface CreateOrderPhysicalParams {
|
|
449
|
+
shipping_address?: DeliveryAddress;
|
|
450
|
+
shipping_latitude?: number | null;
|
|
451
|
+
shipping_longitude?: number | null;
|
|
452
|
+
shipping_plus_code?: string | null;
|
|
453
|
+
shipping_coordinate_source?: 'pin_drop' | 'plus_code' | 'manual' | null;
|
|
454
|
+
/**
|
|
455
|
+
* A quote_id from getShippingRates' per-rate "quote_id" field (carrier
|
|
456
|
+
* shipments only). Required for any nonzero shipping fee — the backend
|
|
457
|
+
* reads shipping_amount/terminal_rate_id/carrier_name from this stored
|
|
458
|
+
* quote. self_pickup orders need one too (a real zero-fee quote, see
|
|
459
|
+
* logisticsService.getShippingRates' self_pickup branch) — the backend
|
|
460
|
+
* derives resolved_location_id from it, required for both shipping_method.
|
|
461
|
+
*/
|
|
462
|
+
shipping_quote_id?: string;
|
|
463
|
+
/** A ShippingQuoteGroup id when the cart needed splitting across multiple locations — mutually exclusive with shipping_quote_id. */
|
|
464
|
+
shipping_plan_id?: string;
|
|
465
|
+
/**
|
|
466
|
+
* Client-repeated for documentation only — the backend derives the REAL
|
|
467
|
+
* shipping method from the quote itself (resolved_terminal_rate_id is
|
|
468
|
+
* None for a self_pickup quote), never trusts this field. Safe to omit.
|
|
469
|
+
*/
|
|
470
|
+
shipping_method?: 'carrier' | 'self_pickup';
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/** Mirrors kasuvia-store-management's real DigitalFulfillmentCreate schema exactly. */
|
|
474
|
+
export interface CreateOrderDigitalParams {
|
|
475
|
+
/** ISO-3166-1 alpha-2 country code (e.g. "NG"). Required for digital orders — the backend's VAT lookup refuses to guess a tax jurisdiction. */
|
|
476
|
+
buyer_country?: string;
|
|
477
|
+
withdrawal_consent_given_at?: string;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* REAL BUG FIXED (2026-09-24), live-reported ("digital checkout still does
|
|
482
|
+
* not work" / the [FlatRateVAT] error persisting even after buyer_country
|
|
483
|
+
* was correctly collected in the UI): shipping_address, shipping_quote_id,
|
|
484
|
+
* shipping_latitude/longitude/plus_code/coordinate_source, buyer_country,
|
|
485
|
+
* withdrawal_consent_given_at, and shipping_rate_id used to be declared
|
|
486
|
+
* FLAT on this interface. kasuvia-store-management's real OrderCreate
|
|
487
|
+
* schema never had flat equivalents of any of these — confirmed against
|
|
488
|
+
* app/schemas/order.py directly - they only ever existed nested under
|
|
489
|
+
* `physical`/`digital` (see CreateOrderPhysicalParams/
|
|
490
|
+
* CreateOrderDigitalParams above). OrderBase's `extra: "allow"` config
|
|
491
|
+
* meant sending them flat produced no validation error at all - Pydantic
|
|
492
|
+
* silently accepted and discarded them, so order_in.physical/order_in.digital
|
|
493
|
+
* stayed None regardless of what the checkout form collected. Every real
|
|
494
|
+
* physical order's shipping_address/quote and every real digital order's
|
|
495
|
+
* buyer_country has been silently lost this way. shipping_rate_id and
|
|
496
|
+
* pickup_location_id (also previously flat) never existed on the backend
|
|
497
|
+
* schema in ANY shape - both removed outright as confirmed-dead.
|
|
498
|
+
*/
|
|
292
499
|
export interface CreateOrderParams {
|
|
293
500
|
customer_id?: string | null;
|
|
294
501
|
status?: string;
|
|
295
|
-
shipping_address?: DeliveryAddress;
|
|
296
502
|
checkout_session_id?: string;
|
|
297
|
-
|
|
503
|
+
physical?: CreateOrderPhysicalParams;
|
|
504
|
+
digital?: CreateOrderDigitalParams;
|
|
505
|
+
/**
|
|
506
|
+
* Line items for the order.
|
|
507
|
+
*
|
|
508
|
+
* @important DASHBOARD-ONLY — For the merchant dashboard path (POST /sales/orders),
|
|
509
|
+
* these items are used directly. For storefront checkout (POST /orders/storefront),
|
|
510
|
+
* the backend IGNORES this field entirely and reads items from the customer's
|
|
511
|
+
* server-side Redis cart instead. Do NOT rely on this field for storefront orders.
|
|
512
|
+
*/
|
|
513
|
+
items?: Array<{
|
|
298
514
|
product_id: string;
|
|
299
515
|
product_name: string;
|
|
300
516
|
quantity: number;
|
|
@@ -303,16 +519,21 @@ export interface CreateOrderParams {
|
|
|
303
519
|
variant_details?: Record<string, unknown>;
|
|
304
520
|
custom_measurements?: Record<string, unknown>;
|
|
305
521
|
}>;
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
522
|
+
subtotal_amount?: number;
|
|
523
|
+
/** @deprecated Ignored by the backend when discount_code is set (recomputed server-side from the real Discount row); rejected outright if sent without a code. */
|
|
524
|
+
discount_amount?: number;
|
|
525
|
+
discount_code?: string;
|
|
526
|
+
promo_code?: string;
|
|
527
|
+
/** @deprecated Ignored by the backend — tax is always recomputed server-side from the DB VAT rate for the buyer's country. */
|
|
528
|
+
tax_amount?: number;
|
|
529
|
+
/** @deprecated Ignored by the backend for carrier shipments once physical.shipping_quote_id is set; rejected outright if sent nonzero without one. */
|
|
530
|
+
shipping_amount?: number;
|
|
309
531
|
payment_method?: string;
|
|
310
|
-
shipping_rate_id?: string;
|
|
311
532
|
guest_token?: string;
|
|
312
533
|
guest_email?: string;
|
|
313
534
|
guest_phone?: string;
|
|
314
535
|
guest_name?: string;
|
|
315
|
-
product_type?:
|
|
536
|
+
product_type?: ProductType;
|
|
316
537
|
bespoke_brief?: string;
|
|
317
538
|
bespoke_reference_images?: string[];
|
|
318
539
|
bespoke_measurements?: Record<string, string>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invoice Types for Kasuvia Storefront & SDK
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface InvoiceLineItem {
|
|
6
|
+
product_name: string;
|
|
7
|
+
quantity: number;
|
|
8
|
+
unit_price: number;
|
|
9
|
+
total_price?: number;
|
|
10
|
+
variant_details?: Record<string, string | number>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface Invoice {
|
|
14
|
+
id: string;
|
|
15
|
+
invoice_number: string;
|
|
16
|
+
status: "paid" | "issued" | "overdue" | "voided" | "cancelled";
|
|
17
|
+
subtotal_amount: number;
|
|
18
|
+
tax_amount: number;
|
|
19
|
+
discount_amount: number;
|
|
20
|
+
total_amount: number;
|
|
21
|
+
currency: string;
|
|
22
|
+
issued_at?: string | null;
|
|
23
|
+
due_date?: string | null;
|
|
24
|
+
paid_at?: string | null;
|
|
25
|
+
payment_link_url?: string | null;
|
|
26
|
+
customer_name?: string | null;
|
|
27
|
+
customer_email?: string | null;
|
|
28
|
+
customer_phone?: string | null;
|
|
29
|
+
notes_and_terms?: string | null;
|
|
30
|
+
line_items_snapshot?: InvoiceLineItem[];
|
|
31
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
export interface ShippingRate {
|
|
6
6
|
id: string;
|
|
7
7
|
carrier_name: string;
|
|
8
|
-
carrier_logo: string;
|
|
8
|
+
carrier_logo: string | null;
|
|
9
9
|
carrier_rate_description: string;
|
|
10
10
|
carrier_slug: string;
|
|
11
11
|
amount: number;
|
|
@@ -17,6 +17,13 @@ export interface ShippingRate {
|
|
|
17
17
|
pickup_available: boolean;
|
|
18
18
|
dropoff_available?: boolean;
|
|
19
19
|
dropoff_required?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Persisted, single-use, ~45min-TTL quote id — pass this (not `amount`)
|
|
22
|
+
* as `shipping_quote_id` at order creation. The backend re-reads the
|
|
23
|
+
* amount/carrier from the stored quote itself; a client-submitted
|
|
24
|
+
* shipping amount with no valid quote_id is rejected.
|
|
25
|
+
*/
|
|
26
|
+
quote_id?: string;
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
export interface ShippingRatesResponse {
|
|
@@ -32,9 +39,14 @@ export interface DeliveryAddress {
|
|
|
32
39
|
street: string;
|
|
33
40
|
city: string;
|
|
34
41
|
state: string;
|
|
35
|
-
lga
|
|
42
|
+
lga?: string;
|
|
36
43
|
country: string;
|
|
37
|
-
postal
|
|
44
|
+
postal?: string;
|
|
45
|
+
// Task: Plus Codes + Interactive Map Pin-Drop - Geolocation fields
|
|
46
|
+
latitude?: number | null;
|
|
47
|
+
longitude?: number | null;
|
|
48
|
+
plus_code?: string | null;
|
|
49
|
+
coordinate_source?: CoordinateSource;
|
|
38
50
|
}
|
|
39
51
|
|
|
40
52
|
// ============================================================================
|
|
@@ -47,3 +59,72 @@ export interface AddressValidationErrorData {
|
|
|
47
59
|
cities?: Array<{ name: string; city_id: string; stateCode: string; countryCode: string }>;
|
|
48
60
|
states?: Array<{ name: string; code: string; countryCode: string }>;
|
|
49
61
|
}
|
|
62
|
+
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// GEOLOCATION TYPES (Task: Plus Codes + Interactive Map Pin-Drop)
|
|
65
|
+
// ============================================================================
|
|
66
|
+
|
|
67
|
+
export type CoordinateSource = 'pin_drop' | 'plus_code' | 'manual' | null;
|
|
68
|
+
|
|
69
|
+
export interface GeolocationData {
|
|
70
|
+
latitude?: number | null;
|
|
71
|
+
longitude?: number | null;
|
|
72
|
+
plus_code?: string | null;
|
|
73
|
+
coordinate_source?: CoordinateSource;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface ReverseGeocodeRequest {
|
|
77
|
+
latitude: number;
|
|
78
|
+
longitude: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface ReverseGeocodeResponse {
|
|
82
|
+
city: string | null;
|
|
83
|
+
state: string | null;
|
|
84
|
+
country: string | null;
|
|
85
|
+
country_code: string | null;
|
|
86
|
+
display_name: string | null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface PlusCodeDecodeRequest {
|
|
90
|
+
plus_code: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface PlusCodeDecodeResponse {
|
|
94
|
+
latitude: number;
|
|
95
|
+
longitude: number;
|
|
96
|
+
latitude_lo: number;
|
|
97
|
+
longitude_hi: number;
|
|
98
|
+
plus_code: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface AddressSuggestion {
|
|
102
|
+
place_id: string;
|
|
103
|
+
display_name: string;
|
|
104
|
+
line1: string;
|
|
105
|
+
city: string | null;
|
|
106
|
+
state: string | null;
|
|
107
|
+
postal_code: string | null;
|
|
108
|
+
country: string | null;
|
|
109
|
+
country_code: string | null;
|
|
110
|
+
latitude: number | null;
|
|
111
|
+
longitude: number | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface AddressAutocompleteResponse {
|
|
115
|
+
results: AddressSuggestion[];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface ShippingAddressPayload extends GeolocationData {
|
|
119
|
+
first_name: string;
|
|
120
|
+
last_name: string;
|
|
121
|
+
phone: string;
|
|
122
|
+
address_line1: string;
|
|
123
|
+
address_line2?: string | null;
|
|
124
|
+
city: string;
|
|
125
|
+
state: string;
|
|
126
|
+
country: string;
|
|
127
|
+
postal_code?: string | null;
|
|
128
|
+
is_residential?: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
package/src/types/ui/index.ts
CHANGED