@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.
Files changed (176) hide show
  1. package/README.md +42 -15
  2. package/dist/AddressAutocomplete-CjcqPElD.d.mts +46 -0
  3. package/dist/AddressAutocomplete-CvJHuRkf.d.ts +46 -0
  4. package/dist/components/index.d.mts +497 -0
  5. package/dist/components/index.d.ts +497 -0
  6. package/dist/components/index.js +4217 -0
  7. package/dist/components/index.js.map +1 -0
  8. package/dist/components/index.mjs +4194 -0
  9. package/dist/components/index.mjs.map +1 -0
  10. package/dist/config/server.d.mts +26 -0
  11. package/dist/config/server.d.ts +26 -0
  12. package/dist/config/server.js +38 -0
  13. package/dist/config/server.js.map +1 -0
  14. package/dist/config/server.mjs +13 -0
  15. package/dist/config/server.mjs.map +1 -0
  16. package/dist/hooks/index.d.mts +393 -160
  17. package/dist/hooks/index.d.ts +393 -160
  18. package/dist/hooks/index.js +2792 -2137
  19. package/dist/hooks/index.js.map +1 -1
  20. package/dist/hooks/index.mjs +2734 -2121
  21. package/dist/hooks/index.mjs.map +1 -1
  22. package/dist/index-CNW_LINy.d.mts +578 -0
  23. package/dist/index-CNW_LINy.d.ts +578 -0
  24. package/dist/{index-C1chUA3P.d.mts → index-F7N6UItS.d.mts} +1 -1
  25. package/dist/{index-C1chUA3P.d.ts → index-F7N6UItS.d.ts} +1 -1
  26. package/dist/index-NkI10J_E.d.mts +40 -0
  27. package/dist/index-NkI10J_E.d.ts +40 -0
  28. package/dist/index.d.mts +20437 -103
  29. package/dist/index.d.ts +20437 -103
  30. package/dist/index.js +2111 -1802
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.mjs +2006 -1786
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/media.service-Cx7dQjzX.d.mts +1393 -0
  35. package/dist/media.service-mrBFJ2UQ.d.ts +1393 -0
  36. package/dist/services/index.d.mts +908 -2
  37. package/dist/services/index.d.ts +908 -2
  38. package/dist/services/index.js +1492 -1686
  39. package/dist/services/index.js.map +1 -1
  40. package/dist/services/index.mjs +1431 -1670
  41. package/dist/services/index.mjs.map +1 -1
  42. package/package.json +46 -6
  43. package/src/components/bespoke/BespokeAvailabilityBadge.tsx +32 -0
  44. package/src/components/bespoke/BespokeProgressTracker.tsx +58 -0
  45. package/src/components/bespoke/index.ts +3 -0
  46. package/src/components/booking/SlotPicker.tsx +97 -0
  47. package/src/components/booking/index.ts +1 -0
  48. package/src/components/cart/CartItem.tsx +81 -0
  49. package/src/components/cart/CartSidebar.tsx +115 -0
  50. package/src/components/cart/CartTypeMismatchBanner.tsx +55 -0
  51. package/src/components/cart/index.ts +3 -0
  52. package/src/components/index.ts +8 -0
  53. package/src/components/orders/DeliverableReviewer.tsx +139 -0
  54. package/src/components/orders/index.ts +1 -0
  55. package/src/components/product/ProductCard.tsx +350 -0
  56. package/src/components/product/ProductGrid.tsx +84 -0
  57. package/src/components/product/index.ts +2 -0
  58. package/src/components/shared/AddressAutocomplete.tsx +212 -0
  59. package/src/components/shared/AnalyticsScripts.tsx +56 -0
  60. package/src/components/shared/CookieConsentBanner.tsx +98 -0
  61. package/src/components/shared/ImageEditorModal.tsx +1066 -0
  62. package/src/components/shared/ImageViewerModal.tsx +598 -0
  63. package/src/components/shared/LucideReactIcon.tsx +52 -0
  64. package/src/components/shared/MapPinDrop.tsx +101 -0
  65. package/src/components/shared/MultiSelectPicker.tsx +193 -0
  66. package/src/components/shared/OfflineBanner.tsx +46 -0
  67. package/src/components/shared/SearchableInput.tsx +153 -0
  68. package/src/components/shared/SearchablePopover.tsx +166 -0
  69. package/src/components/shared/SmartImage.tsx +311 -0
  70. package/src/components/shared/TruncatedValue.tsx +27 -0
  71. package/src/components/shared/UnsavedChangesGuard.tsx +138 -0
  72. package/src/components/shared/index.ts +15 -0
  73. package/src/components/skeletons/CardSkeleton.tsx +26 -0
  74. package/src/components/skeletons/CartItemSkeleton.tsx +26 -0
  75. package/src/components/skeletons/OrderItemSkeleton.tsx +26 -0
  76. package/src/components/skeletons/ProductCardSkeleton.tsx +26 -0
  77. package/src/components/skeletons/TableSkeleton.tsx +42 -0
  78. package/src/components/skeletons/index.ts +5 -0
  79. package/src/config/index.ts +22 -4
  80. package/src/config/server.ts +45 -0
  81. package/src/context/sdk-context.tsx +5 -2
  82. package/src/generated/auth-openapi.ts +2935 -0
  83. package/src/generated/cart-openapi.ts +652 -0
  84. package/src/generated/cms-openapi.ts +1668 -0
  85. package/src/generated/crm-openapi.ts +986 -0
  86. package/src/generated/graphql.ts +126 -0
  87. package/src/generated/index.ts +11 -0
  88. package/src/generated/media-openapi.ts +613 -0
  89. package/src/generated/notification-openapi.ts +862 -0
  90. package/src/generated/payment-openapi.ts +2713 -0
  91. package/src/generated/store-openapi.ts +9510 -0
  92. package/src/graphql/operations/collections.graphql +32 -0
  93. package/src/graphql/operations/products.graphql +197 -0
  94. package/src/graphql/operations/wishlist.graphql +25 -0
  95. package/src/hooks/index.ts +9 -2
  96. package/src/hooks/use-auth.ts +163 -69
  97. package/src/hooks/use-bespoke-availability.ts +39 -22
  98. package/src/hooks/use-business-config.ts +51 -0
  99. package/src/hooks/use-cart.ts +310 -238
  100. package/src/hooks/use-cms.ts +107 -127
  101. package/src/hooks/use-collections.ts +35 -55
  102. package/src/hooks/use-consultations.ts +9 -136
  103. package/src/hooks/use-countries.ts +19 -28
  104. package/src/hooks/use-currencies.ts +8 -20
  105. package/src/hooks/use-customer-address.ts +64 -0
  106. package/src/hooks/use-feedback.ts +34 -0
  107. package/src/hooks/use-languages.ts +26 -39
  108. package/src/hooks/use-media-upload.ts +23 -0
  109. package/src/hooks/use-notification-stream.ts +88 -0
  110. package/src/hooks/use-notifications.ts +163 -0
  111. package/src/hooks/use-order-stream.ts +29 -29
  112. package/src/hooks/use-orders.ts +91 -73
  113. package/src/hooks/use-payment.ts +116 -84
  114. package/src/hooks/use-products.ts +65 -269
  115. package/src/hooks/use-push-notifications.ts +122 -0
  116. package/src/hooks/use-reviews.ts +175 -0
  117. package/src/hooks/use-service-booking.ts +109 -132
  118. package/src/hooks/use-states.ts +16 -30
  119. package/src/hooks/use-wishlist.ts +44 -69
  120. package/src/index.ts +15 -11
  121. package/src/services/auth.service.ts +422 -132
  122. package/src/services/bespoke.service.ts +69 -10
  123. package/src/services/cart.service.ts +155 -186
  124. package/src/services/cms.service.ts +41 -50
  125. package/src/services/collection.service.ts +25 -63
  126. package/src/services/config.service.ts +10 -21
  127. package/src/services/consultation.service.ts +36 -93
  128. package/src/services/feedback.service.ts +76 -0
  129. package/src/services/index.ts +7 -1
  130. package/src/services/legal.service.ts +62 -0
  131. package/src/services/logistics.service.ts +235 -53
  132. package/src/services/media.service.ts +115 -0
  133. package/src/services/notifications.service.ts +204 -20
  134. package/src/services/order.service.ts +498 -127
  135. package/src/services/payment.service.ts +149 -100
  136. package/src/services/product.service.ts +157 -814
  137. package/src/services/review.service.ts +211 -0
  138. package/src/services/service-booking.service.ts +198 -99
  139. package/src/services/wishlist.service.ts +27 -74
  140. package/src/types/auth/index.ts +161 -18
  141. package/src/types/business/index.ts +9 -1
  142. package/src/types/cms/index.ts +91 -6
  143. package/src/types/cms/legal.ts +18 -0
  144. package/src/types/consultations/index.ts +60 -68
  145. package/src/types/index.ts +5 -3
  146. package/src/types/media/index.ts +35 -3
  147. package/src/types/payments/index.ts +80 -16
  148. package/src/types/reviews/index.ts +116 -0
  149. package/src/types/services/index.ts +113 -38
  150. package/src/types/store/checkout.ts +53 -0
  151. package/src/types/store/index.ts +273 -52
  152. package/src/types/store/invoice.ts +31 -0
  153. package/src/types/store/shipping.ts +84 -3
  154. package/src/types/ui/index.ts +1 -1
  155. package/src/utils/checkout.ts +19 -3
  156. package/src/utils/cookieConsent.ts +34 -0
  157. package/src/utils/format.ts +408 -0
  158. package/src/utils/geolocation.ts +134 -0
  159. package/src/utils/graphql-url.ts +47 -0
  160. package/src/utils/guest-session.ts +59 -0
  161. package/src/utils/http-client.ts +147 -0
  162. package/src/utils/index.ts +11 -4
  163. package/src/utils/status-colors.ts +79 -0
  164. package/src/utils/token-refresh.ts +115 -0
  165. package/src/utils/validators.ts +13 -0
  166. package/src/utils/youtube.ts +18 -0
  167. package/dist/index-C5YO9gTl.d.mts +0 -507
  168. package/dist/index-C5YO9gTl.d.ts +0 -507
  169. package/dist/index-CefG7_xq.d.mts +0 -793
  170. package/dist/index-DeHCf3zI.d.ts +0 -793
  171. package/src/graphql/collections.graphql.ts +0 -48
  172. package/src/graphql/index.ts +0 -7
  173. package/src/graphql/products.graphql.ts +0 -860
  174. package/src/graphql/wishlist.graphql.ts +0 -34
  175. package/src/hooks/use-consultation-stream.ts +0 -142
  176. package/src/types/bespoke/index.ts +0 -39
@@ -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 (consultations feature)
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
- * - bespoke: kasuvia-store-management (bespoke slot booking feature)
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 './bespoke'
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'
@@ -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: string
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?: string
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?: string
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
- amount: number;
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
- amount: number;
63
- currency: string;
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 AppointmentStatus =
6
- | "pending"
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
- export interface AvailableSlot {
25
+ /** GET /catalog/products/{product_id}/available-slots response. */
26
+ export interface AvailableSlotsResponse {
27
+ product_id: string;
14
28
  date: string;
15
- start_time: string;
16
- end_time: string;
17
- slots_remaining: number;
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
- status: AppointmentStatus;
26
- appointment_date: string;
27
- start_time: string;
28
- end_time: string;
29
- location_type: import("../store").ServiceLocationType;
30
- customer_address: Record<string, unknown> | null;
31
- meeting_link: string | null;
32
- customer_notes: string | null;
33
- price: number;
34
- created_at: string;
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
- location_type?: import("../store").ServiceLocationType;
46
- customer_address?: Record<string, unknown>;
47
- customer_notes?: string;
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
- export interface DeliverableStatus {
51
- pending: "pending";
52
- in_progress: "in_progress";
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
- export type DeliverableStatusType = DeliverableStatus[keyof DeliverableStatus];
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
- export interface ServiceDeliverable {
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
- order_id: string;
118
+ booking_id: string;
63
119
  title: string;
64
- description: string;
65
- status: DeliverableStatusType;
66
- due_date: string | null;
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
- attachments: string[];
69
- customer_feedback: string | null;
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
- export interface DeliverableApprovalPayload {
75
- approved: boolean;
76
- feedback?: string;
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
+ }