@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/index.ts
CHANGED
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
* - payments: kasuvia-payment-system
|
|
9
9
|
* - cms: kasuvia-cms
|
|
10
10
|
* - media: kasuvia-media-system
|
|
11
|
-
* - consultations: kasuvia-store-management (
|
|
11
|
+
* - consultations: kasuvia-store-management (real bespoke commission types only — the file's
|
|
12
|
+
* name is historical; the fictional "Consultation" resource it used to also hold was removed)
|
|
12
13
|
* - services: kasuvia-store-management (service booking feature)
|
|
13
|
-
* -
|
|
14
|
+
* - reviews: kasuvia-crm (reviews and comments feature)
|
|
14
15
|
* - business: business configuration
|
|
15
16
|
* - ui: UI/app state types
|
|
16
17
|
*/
|
|
@@ -20,8 +21,9 @@ export * from './store'
|
|
|
20
21
|
export * from './payments'
|
|
21
22
|
export * from './consultations'
|
|
22
23
|
export * from './services'
|
|
23
|
-
export * from './
|
|
24
|
+
export * from './reviews'
|
|
24
25
|
export * from './cms'
|
|
26
|
+
export * from './cms/legal'
|
|
25
27
|
export * from './media'
|
|
26
28
|
export * from './business'
|
|
27
29
|
export * from './ui'
|
package/src/types/media/index.ts
CHANGED
|
@@ -1,7 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Media types for the storefront
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `Affiliation` in `kasuvia-media-system/app/models/media.py`, the real
|
|
5
|
+
* source of truth. Re-synced 2026-09-04 (media affiliation recheck): this mirror
|
|
6
|
+
* was missing `Business` and `Review` entirely, and wrongly described
|
|
7
|
+
* `BusinessOwner` as covering logos too.
|
|
8
|
+
*
|
|
9
|
+
* Canonical affiliations:
|
|
10
|
+
* - Content: CMS and website builder content — the ONE shared tag for both
|
|
11
|
+
* - Product: Product images
|
|
12
|
+
* - Collection: Collection images
|
|
13
|
+
* - Chat: AI/customer chat interactions
|
|
14
|
+
* - Review: photos a customer attaches to a product review (kasuvia-crm) —
|
|
15
|
+
* distinct from Customer (a person's own identity photo, not
|
|
16
|
+
* customer-GENERATED content)
|
|
17
|
+
* - Business: a business's own logo
|
|
18
|
+
* - BusinessOwner: the business owner's OWN personal avatar — distinct from
|
|
19
|
+
* Business (the business's logo); never the same asset
|
|
20
|
+
* - Staff: staff avatars
|
|
21
|
+
* - Customer: customer avatars
|
|
22
|
+
* - General: General use cases
|
|
3
23
|
*/
|
|
4
24
|
|
|
25
|
+
export type MediaAffiliation =
|
|
26
|
+
| 'Content'
|
|
27
|
+
| 'Product'
|
|
28
|
+
| 'Collection'
|
|
29
|
+
| 'Chat'
|
|
30
|
+
| 'Review'
|
|
31
|
+
| 'Business'
|
|
32
|
+
| 'BusinessOwner'
|
|
33
|
+
| 'Staff'
|
|
34
|
+
| 'Customer'
|
|
35
|
+
| 'General'
|
|
36
|
+
|
|
5
37
|
export interface MediaAsset {
|
|
6
38
|
id: string
|
|
7
39
|
url: string
|
|
@@ -9,7 +41,7 @@ export interface MediaAsset {
|
|
|
9
41
|
content_type: string
|
|
10
42
|
size: number
|
|
11
43
|
business_id: string
|
|
12
|
-
affiliation:
|
|
44
|
+
affiliation: MediaAffiliation
|
|
13
45
|
created_at: string
|
|
14
46
|
alt?: string
|
|
15
47
|
description?: string
|
|
@@ -19,7 +51,7 @@ export interface MediaUploadParams {
|
|
|
19
51
|
business_id?: string
|
|
20
52
|
owner_id?: string
|
|
21
53
|
uploaded_by_name?: string
|
|
22
|
-
affiliation?:
|
|
54
|
+
affiliation?: MediaAffiliation
|
|
23
55
|
context: string // Required for security: describes the upload context (e.g., product, user, business)
|
|
24
56
|
entity_id: string // Required for security: ID of the entity this file belongs to
|
|
25
57
|
alt?: string
|
|
@@ -30,7 +62,7 @@ export interface MediaUploadParams {
|
|
|
30
62
|
export interface MediaAssetUpdatePayload {
|
|
31
63
|
alt?: string
|
|
32
64
|
description?: string
|
|
33
|
-
affiliation?:
|
|
65
|
+
affiliation?: MediaAffiliation
|
|
34
66
|
}
|
|
35
67
|
|
|
36
68
|
export interface StorageStats {
|
|
@@ -45,26 +45,103 @@ export interface SupportedLanguagesResponse {
|
|
|
45
45
|
languages: BackendLanguage[];
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
export enum PaymentGatewayEnum {
|
|
49
|
+
MONNIFY = "monnify",
|
|
50
|
+
FLUTTERWAVE = "flutterwave",
|
|
51
|
+
PAYSTACK = "paystack",
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type PaymentGateway = PaymentGatewayEnum | "monnify" | "flutterwave" | "paystack";
|
|
55
|
+
|
|
56
|
+
export enum PaymentMethodTypeEnum {
|
|
57
|
+
CARD = "card",
|
|
58
|
+
TRANSFER = "transfer",
|
|
59
|
+
BANK_TRANSFER = "bank_transfer",
|
|
60
|
+
ACCOUNT = "account",
|
|
61
|
+
USSD = "ussd",
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export type PaymentMethodType = PaymentMethodTypeEnum | "card" | "transfer" | "bank_transfer" | "account" | "ussd";
|
|
65
|
+
|
|
66
|
+
export interface PaymentMethodOption {
|
|
67
|
+
method: PaymentMethodType | string;
|
|
68
|
+
display_name: string;
|
|
69
|
+
description: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface GatewayMethods {
|
|
73
|
+
gateway: PaymentGateway | string;
|
|
74
|
+
display_name: string;
|
|
75
|
+
methods: PaymentMethodOption[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ── Wallet Types ───────────────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
export interface WalletBalanceResponse {
|
|
81
|
+
balance: number;
|
|
82
|
+
currency: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface WalletLedgerEntry {
|
|
86
|
+
id: string;
|
|
87
|
+
entry_type: string;
|
|
88
|
+
amount: number;
|
|
89
|
+
currency: string;
|
|
90
|
+
refund_id?: string | null;
|
|
91
|
+
transaction_id?: string | null;
|
|
92
|
+
balance_after: number;
|
|
93
|
+
created_at: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface WalletLedgerResponse {
|
|
97
|
+
items: WalletLedgerEntry[];
|
|
98
|
+
total: number;
|
|
99
|
+
page: number;
|
|
100
|
+
page_size: number;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface ClaimWalletCreditRequest {
|
|
104
|
+
claim_token: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface OutstandingClaimResponse {
|
|
108
|
+
wallet_id: string;
|
|
109
|
+
claim_email: string;
|
|
110
|
+
balance: number;
|
|
111
|
+
currency: string;
|
|
112
|
+
created_at: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
48
115
|
// ── Request Types ─────────────────────────────────────────────────────────────
|
|
49
116
|
|
|
50
117
|
export interface DVACreateRequest {
|
|
51
118
|
order_id?: string;
|
|
52
|
-
|
|
119
|
+
/** Ignored by the backend — the real order total is always charged instead. Only meaningful (and required) if order_id is omitted. */
|
|
120
|
+
amount?: number;
|
|
53
121
|
customer_email: string;
|
|
54
122
|
customer_name?: string;
|
|
55
123
|
/** Defaults to NGN — DVA is Monnify-only */
|
|
56
124
|
currency?: string;
|
|
125
|
+
/** Gateway identifier — the backend requires this explicitly, no default */
|
|
126
|
+
gateway: string;
|
|
127
|
+
/** Window origin of the storefront */
|
|
128
|
+
storefront_origin?: string;
|
|
57
129
|
/** Idempotency key to prevent duplicate DVA creation */
|
|
58
130
|
idempotency_key?: string;
|
|
59
131
|
}
|
|
60
132
|
|
|
61
133
|
export interface PaymentInitiateRequest {
|
|
62
|
-
|
|
63
|
-
|
|
134
|
+
/** Ignored by the backend when order_id is set — the real order total is always charged instead. Required only if order_id is omitted. */
|
|
135
|
+
amount?: number;
|
|
136
|
+
currency?: string;
|
|
64
137
|
customer_email: string;
|
|
65
138
|
customer_name?: string;
|
|
66
139
|
order_id?: string;
|
|
67
140
|
quote_id?: string;
|
|
141
|
+
/** ISO 2-letter country code (defaults to 'NG') */
|
|
142
|
+
country_code?: string;
|
|
143
|
+
/** Gateway chosen by customer (e.g., 'monnify', 'flutterwave', 'paystack') — the backend requires this explicitly, no default */
|
|
144
|
+
gateway: string;
|
|
68
145
|
/** Window origin of the storefront — used as gateway redirect base URL */
|
|
69
146
|
storefront_origin?: string;
|
|
70
147
|
metadata?: Record<string, string | number | boolean>;
|
|
@@ -72,19 +149,6 @@ export interface PaymentInitiateRequest {
|
|
|
72
149
|
idempotency_key?: string;
|
|
73
150
|
}
|
|
74
151
|
|
|
75
|
-
export interface ConversionQuote {
|
|
76
|
-
id: string;
|
|
77
|
-
business_id: string;
|
|
78
|
-
from_currency: string;
|
|
79
|
-
to_currency: string;
|
|
80
|
-
rate: number;
|
|
81
|
-
original_amount: number;
|
|
82
|
-
converted_amount: number;
|
|
83
|
-
is_used: boolean;
|
|
84
|
-
expires_at: string;
|
|
85
|
-
created_at: string;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
152
|
// ── Response Types ─────────────────────────────────────────────────────────────
|
|
89
153
|
|
|
90
154
|
export interface DVADetails {
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review and Comment types for CRM service
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export enum ModerationStatus {
|
|
6
|
+
PENDING = 'pending',
|
|
7
|
+
APPROVED = 'approved',
|
|
8
|
+
REJECTED = 'rejected'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface Review {
|
|
12
|
+
id: string
|
|
13
|
+
business_id: string
|
|
14
|
+
product_id: string
|
|
15
|
+
order_id?: string
|
|
16
|
+
customer_id: string
|
|
17
|
+
/** Real field (kasuvia-crm-go's ReviewResponse.customer_name_masked) — the raw customer_id is never exposed to other storefront visitors. */
|
|
18
|
+
customer_name_masked: string
|
|
19
|
+
rating: number
|
|
20
|
+
body: string
|
|
21
|
+
media: string[]
|
|
22
|
+
media_ids: string[]
|
|
23
|
+
verified_purchase: boolean
|
|
24
|
+
moderation_status: ModerationStatus
|
|
25
|
+
merchant_reply?: string
|
|
26
|
+
merchant_reply_at?: string
|
|
27
|
+
created_at: string
|
|
28
|
+
edited_at?: string
|
|
29
|
+
edit_count: number
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface Comment {
|
|
33
|
+
id: string
|
|
34
|
+
business_id: string
|
|
35
|
+
product_id: string
|
|
36
|
+
customer_id?: string
|
|
37
|
+
/** Real field (kasuvia-crm-go's CommentResponse.customer_name_masked). */
|
|
38
|
+
customer_name_masked: string
|
|
39
|
+
body: string
|
|
40
|
+
parent_comment_id?: string
|
|
41
|
+
moderation_status: ModerationStatus
|
|
42
|
+
is_merchant_reply: boolean
|
|
43
|
+
created_at: string
|
|
44
|
+
updated_at: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ReviewCreate {
|
|
48
|
+
product_id: string
|
|
49
|
+
/** Required: reviews are purchase-verified — must reference a completed order for this product. */
|
|
50
|
+
order_id: string
|
|
51
|
+
rating: number
|
|
52
|
+
body: string
|
|
53
|
+
/**
|
|
54
|
+
* `media` (asset URLs) and `media_ids` (the matching MediaAsset ids) must
|
|
55
|
+
* be two parallel, order-paired arrays of the SAME length — the real
|
|
56
|
+
* backend (kasuvia-crm-go's validateMediaPairing) 400s otherwise. Omit
|
|
57
|
+
* both together, or populate both together in the same order.
|
|
58
|
+
*/
|
|
59
|
+
media?: string[]
|
|
60
|
+
media_ids?: string[]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ReviewUpdate {
|
|
64
|
+
rating?: number
|
|
65
|
+
body?: string
|
|
66
|
+
/** See ReviewCreate's identical doc comment — media/media_ids must be order-paired, same length. */
|
|
67
|
+
media?: string[]
|
|
68
|
+
media_ids?: string[]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface CommentCreate {
|
|
72
|
+
product_id: string
|
|
73
|
+
body: string
|
|
74
|
+
parent_comment_id?: string
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface CommentUpdate {
|
|
78
|
+
body?: string
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface MerchantReplyCreate {
|
|
82
|
+
body: string
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface ReviewModerationAction {
|
|
86
|
+
status: ModerationStatus
|
|
87
|
+
reason?: string
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface CommentModerationAction {
|
|
91
|
+
status: ModerationStatus
|
|
92
|
+
reason?: string
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// REAL BUG FIXED (2026-09-21): these used `reviews`/`comments`/`total` —
|
|
96
|
+
// kasuvia-crm-go's real GET /products/{id}/reviews and .../comments
|
|
97
|
+
// (reviews.go) return the platform's standard pagination shape instead
|
|
98
|
+
// (`results`/`count`/`page`/`page_size`/`total_pages`), same convention as
|
|
99
|
+
// every other paginated Kasuvia endpoint.
|
|
100
|
+
export interface ProductReviewsResponse {
|
|
101
|
+
results: Review[]
|
|
102
|
+
count: number
|
|
103
|
+
page: number
|
|
104
|
+
page_size: number
|
|
105
|
+
total_pages: number
|
|
106
|
+
average_rating: number | null
|
|
107
|
+
rating_distribution: Record<number, number>
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface ProductCommentsResponse {
|
|
111
|
+
results: Comment[]
|
|
112
|
+
count: number
|
|
113
|
+
page: number
|
|
114
|
+
page_size: number
|
|
115
|
+
total_pages: number
|
|
116
|
+
}
|
|
@@ -1,77 +1,152 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Service booking types for customer-facing storefront
|
|
2
|
+
* Service booking types for customer-facing storefront.
|
|
3
|
+
*
|
|
4
|
+
* REAL BUG FIXED (2026-09-20): this entire file used to describe a fictional
|
|
5
|
+
* API shape that never matched kasuvia-store-management's real service-
|
|
6
|
+
* booking backend (`app/schemas/service.py`, `app/api/v1/endpoints/service/
|
|
7
|
+
* bookings.py`) — wrong field names (`appointment_date` vs the real
|
|
8
|
+
* `scheduled_date`), a status enum with values the backend never emits
|
|
9
|
+
* ("pending" vs the real "scheduled"), fields that don't exist on the real
|
|
10
|
+
* response (`location_type`, `customer_address`, `meeting_link`, `price`),
|
|
11
|
+
* and a whole "deliverables" concept (`ServiceDeliverable`,
|
|
12
|
+
* `DeliverableApprovalPayload`) that has no backend counterpart at all — the
|
|
13
|
+
* real analogous feature is the milestone/escrow system below, a different
|
|
14
|
+
* shape entirely. Rebuilt field-for-field against the real Pydantic schemas.
|
|
3
15
|
*/
|
|
4
16
|
|
|
5
|
-
export type
|
|
6
|
-
| "
|
|
17
|
+
export type ServiceBookingStatus =
|
|
18
|
+
| "scheduled"
|
|
7
19
|
| "confirmed"
|
|
8
20
|
| "in_progress"
|
|
9
21
|
| "completed"
|
|
10
22
|
| "voided"
|
|
11
23
|
| "no_show";
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
/** GET /catalog/products/{product_id}/available-slots response. */
|
|
26
|
+
export interface AvailableSlotsResponse {
|
|
27
|
+
product_id: string;
|
|
14
28
|
date: string;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
29
|
+
staff_id: string | null;
|
|
30
|
+
duration_minutes: number | null;
|
|
31
|
+
/** false when the business has no/ambiguous location config for this
|
|
32
|
+
* product — check `reason` for why, `available_slots` is always empty. */
|
|
33
|
+
serviceable: boolean;
|
|
34
|
+
reason: string | null;
|
|
35
|
+
/** ISO time strings (e.g. "14:30:00"), not slot objects. */
|
|
36
|
+
available_slots: string[];
|
|
18
37
|
}
|
|
19
38
|
|
|
39
|
+
/** Matches ServiceBookingResponse exactly (kasuvia-store-management/app/schemas/service.py:66-90). */
|
|
20
40
|
export interface ServiceAppointment {
|
|
21
41
|
id: string;
|
|
42
|
+
business_id: string;
|
|
22
43
|
product_id: string;
|
|
23
44
|
customer_id: string;
|
|
24
45
|
order_id: string | null;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
updated_at: string;
|
|
46
|
+
transaction_id: string | null;
|
|
47
|
+
scheduled_date: string;
|
|
48
|
+
scheduled_time: string;
|
|
49
|
+
duration_minutes: number | null;
|
|
50
|
+
status: ServiceBookingStatus;
|
|
51
|
+
notes: string | null;
|
|
52
|
+
reminder_sent: boolean;
|
|
53
|
+
reminder_scheduled_at: string | null;
|
|
54
|
+
location_id: string | null;
|
|
55
|
+
started_at: string | null;
|
|
36
56
|
completed_at: string | null;
|
|
57
|
+
buyer_confirmed_at: string | null;
|
|
58
|
+
no_show_at: string | null;
|
|
37
59
|
voided_at: string | null;
|
|
38
60
|
cancellation_reason: string | null;
|
|
61
|
+
cancellation_window_hours: number;
|
|
62
|
+
refund_due: boolean | null;
|
|
63
|
+
refund_processed_at: string | null;
|
|
64
|
+
is_milestone_based: boolean;
|
|
65
|
+
assigned_staff_id: string | null;
|
|
66
|
+
assigned_at: string | null;
|
|
67
|
+
assignment_method: string | null;
|
|
68
|
+
created_at: string;
|
|
69
|
+
updated_at: string;
|
|
39
70
|
}
|
|
40
71
|
|
|
72
|
+
/** POST /service/bookings/schedule payload (ScheduleServiceRequest). */
|
|
41
73
|
export interface ServiceAppointmentCreatePayload {
|
|
42
74
|
product_id: string;
|
|
43
75
|
scheduled_date: string;
|
|
44
76
|
scheduled_time: string;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
77
|
+
notes?: string;
|
|
78
|
+
staff_id?: string;
|
|
79
|
+
/** Required when the product is service_location_type='at_business' and the business runs more than one active location (see useAvailableSlots/logisticsService.listBusinessLocations). */
|
|
80
|
+
location_id?: string;
|
|
48
81
|
}
|
|
49
82
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
review: "review";
|
|
54
|
-
approved: "approved";
|
|
55
|
-
rejected: "rejected";
|
|
83
|
+
/** POST /service/bookings/{id}/cancel payload (CustomerCancelBookingRequest). */
|
|
84
|
+
export interface CancelAppointmentPayload {
|
|
85
|
+
reason?: string;
|
|
56
86
|
}
|
|
57
87
|
|
|
58
|
-
|
|
88
|
+
/** POST /service/bookings/{id}/reschedule payload (CustomerRescheduleBookingRequest). */
|
|
89
|
+
export interface RescheduleAppointmentPayload {
|
|
90
|
+
scheduled_date: string;
|
|
91
|
+
scheduled_time: string;
|
|
92
|
+
staff_id?: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** POST /service/bookings/{id}/dispute payload (CustomerOpenDisputeRequest). */
|
|
96
|
+
export interface DisputeAppointmentPayload {
|
|
97
|
+
reason: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** POST /service/bookings/{id}/confirm payload (BuyerConfirmRequest). */
|
|
101
|
+
export interface ConfirmAppointmentPayload {
|
|
102
|
+
notes?: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type MilestoneStatus =
|
|
106
|
+
| "pending"
|
|
107
|
+
| "funded"
|
|
108
|
+
| "submitted"
|
|
109
|
+
| "approved"
|
|
110
|
+
| "released"
|
|
111
|
+
| "disputed"
|
|
112
|
+
| "refunded";
|
|
59
113
|
|
|
60
|
-
|
|
114
|
+
/** Matches ServiceMilestoneResponse + its ServiceMilestoneBase parent
|
|
115
|
+
* (kasuvia-store-management/app/schemas/service.py:169-173,208-222). */
|
|
116
|
+
export interface ServiceMilestone {
|
|
61
117
|
id: string;
|
|
62
|
-
|
|
118
|
+
booking_id: string;
|
|
63
119
|
title: string;
|
|
64
|
-
description: string;
|
|
65
|
-
|
|
66
|
-
|
|
120
|
+
description: string | null;
|
|
121
|
+
/**
|
|
122
|
+
* Milestone amount in the order currency.
|
|
123
|
+
*
|
|
124
|
+
* REAL BUG FIXED (2026-09-23) via the REST codegen initiative: this was
|
|
125
|
+
* typed `number`, but the real backend field (ServiceMilestoneBase.amount,
|
|
126
|
+
* kasuvia-store-management's app/schemas/service.py) is a Pydantic
|
|
127
|
+
* `Decimal`, which serializes to JSON as a STRING (e.g. "150000.00"), not
|
|
128
|
+
* a number - confirmed against the generated OpenAPI schema
|
|
129
|
+
* (`ServiceMilestoneResponse.amount: string`). The one real consumer
|
|
130
|
+
* (ProjectDeliverables.tsx) called `.toLocaleString()` directly on it,
|
|
131
|
+
* which on a string just returns the string unchanged (no thousands
|
|
132
|
+
* separators) rather than the number-formatted value it looked like it
|
|
133
|
+
* was producing for any amount under 4 digits.
|
|
134
|
+
*/
|
|
135
|
+
amount: string;
|
|
136
|
+
sequence: number;
|
|
137
|
+
status: MilestoneStatus;
|
|
138
|
+
funded_at: string | null;
|
|
67
139
|
submitted_at: string | null;
|
|
68
|
-
|
|
69
|
-
|
|
140
|
+
approved_at: string | null;
|
|
141
|
+
completion_event_at: string | null;
|
|
142
|
+
released_at: string | null;
|
|
143
|
+
dispute_reason: string | null;
|
|
144
|
+
transaction_id: string | null;
|
|
70
145
|
created_at: string;
|
|
71
146
|
updated_at: string;
|
|
72
147
|
}
|
|
73
148
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
149
|
+
/** POST /service/bookings/{id}/milestones/{milestone_id}/approve payload. */
|
|
150
|
+
export interface ApproveMilestonePayload {
|
|
151
|
+
notes?: string;
|
|
77
152
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkout Session Types
|
|
3
|
+
*
|
|
4
|
+
* Mirrors kasuvia-cart-management's public CheckoutSessionResponse shape
|
|
5
|
+
* (internal/models/checkout_session.go → ToResponse()).
|
|
6
|
+
* NEVER include internal fields (cart_key, reservation_id, customer_id,
|
|
7
|
+
* business_id) — those are stripped by ToResponse() and must not appear here.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* One price-locked line in a checkout session.
|
|
12
|
+
* Matches CheckoutLine in kasuvia-cart-management/internal/models/checkout_session.go.
|
|
13
|
+
*/
|
|
14
|
+
export interface CheckoutLine {
|
|
15
|
+
cart_item_id: string;
|
|
16
|
+
product_id: string;
|
|
17
|
+
variant_id?: string;
|
|
18
|
+
product_name: string;
|
|
19
|
+
product_slug: string;
|
|
20
|
+
image_url?: string;
|
|
21
|
+
sku: string;
|
|
22
|
+
quantity: number;
|
|
23
|
+
/** Price confirmed by store-management at session-creation time — locked for session TTL. */
|
|
24
|
+
unit_price: number;
|
|
25
|
+
line_total: number;
|
|
26
|
+
reserved_units: number;
|
|
27
|
+
product_type: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Public checkout session returned by:
|
|
32
|
+
* POST /api/v1/checkout/session
|
|
33
|
+
* GET /api/v1/checkout/session/{session_id}
|
|
34
|
+
*
|
|
35
|
+
* Matches CheckoutSessionResponse in kasuvia-cart-management/internal/models/checkout_session.go.
|
|
36
|
+
* Do NOT use `id` — the backend field is `session_id`.
|
|
37
|
+
*/
|
|
38
|
+
export interface CheckoutSession {
|
|
39
|
+
session_id: string;
|
|
40
|
+
items: CheckoutLine[];
|
|
41
|
+
subtotal: number;
|
|
42
|
+
shipping_cost: number;
|
|
43
|
+
discount_amount: number;
|
|
44
|
+
tax_amount: number;
|
|
45
|
+
total: number;
|
|
46
|
+
currency: string;
|
|
47
|
+
/** Derived from cart lines — "physical" | "digital" | "service" | "bespoke" | "mixed" | null */
|
|
48
|
+
product_type?: string | null;
|
|
49
|
+
/** "pending" | "consumed" | "abandoned" */
|
|
50
|
+
status: 'pending' | 'consumed' | 'abandoned';
|
|
51
|
+
/** RFC3339 timestamp */
|
|
52
|
+
expires_at: string;
|
|
53
|
+
}
|