@kasuvia/sdk 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +112 -0
- package/dist/index.d.mts +1891 -0
- package/dist/index.d.ts +1891 -0
- package/dist/index.js +3540 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3314 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +59 -0
- package/src/client/authClient.ts +135 -0
- package/src/client/graphqlClient.ts +53 -0
- package/src/client/httpClient.ts +298 -0
- package/src/config/index.ts +102 -0
- package/src/graphql/collections.graphql.ts +56 -0
- package/src/graphql/index.ts +7 -0
- package/src/graphql/products.graphql.ts +710 -0
- package/src/graphql/wishlist.graphql.ts +33 -0
- package/src/hooks/index.ts +26 -0
- package/src/hooks/use-auth.ts +182 -0
- package/src/hooks/use-bespoke-availability.ts +20 -0
- package/src/hooks/use-cart.ts +207 -0
- package/src/hooks/use-cms.ts +165 -0
- package/src/hooks/use-collections.ts +40 -0
- package/src/hooks/use-consultation-stream.ts +141 -0
- package/src/hooks/use-consultations.ts +76 -0
- package/src/hooks/use-countries.ts +24 -0
- package/src/hooks/use-currencies.ts +27 -0
- package/src/hooks/use-google-translate.ts +164 -0
- package/src/hooks/use-is-mounted.ts +9 -0
- package/src/hooks/use-languages.ts +33 -0
- package/src/hooks/use-order-stream.ts +195 -0
- package/src/hooks/use-orders.ts +64 -0
- package/src/hooks/use-payment.ts +68 -0
- package/src/hooks/use-products.ts +113 -0
- package/src/hooks/use-service-booking.ts +118 -0
- package/src/hooks/use-states.ts +28 -0
- package/src/hooks/use-wishlist.ts +121 -0
- package/src/index.ts +65 -0
- package/src/services/app.service.ts +17 -0
- package/src/services/auth.service.ts +332 -0
- package/src/services/bespoke.service.ts +17 -0
- package/src/services/cart.service.ts +245 -0
- package/src/services/cms.service.ts +112 -0
- package/src/services/collection.service.ts +77 -0
- package/src/services/config.service.ts +42 -0
- package/src/services/consultation.service.ts +51 -0
- package/src/services/index.ts +21 -0
- package/src/services/logistics.service.ts +95 -0
- package/src/services/notifications.service.ts +50 -0
- package/src/services/order.service.ts +169 -0
- package/src/services/payment.service.ts +127 -0
- package/src/services/product.service.ts +678 -0
- package/src/services/service-booking.service.ts +86 -0
- package/src/services/wishlist.service.ts +84 -0
- package/src/types/auth/index.ts +126 -0
- package/src/types/bespoke/index.ts +39 -0
- package/src/types/business/index.ts +6 -0
- package/src/types/cms/index.ts +77 -0
- package/src/types/consultations/index.ts +79 -0
- package/src/types/index.ts +27 -0
- package/src/types/media/index.ts +41 -0
- package/src/types/payments/index.ts +120 -0
- package/src/types/services/index.ts +80 -0
- package/src/types/store/index.ts +282 -0
- package/src/types/store/shipping.ts +38 -0
- package/src/types/ui/index.ts +32 -0
- package/src/utils/cache.ts +33 -0
- package/src/utils/checkout.ts +39 -0
- package/src/utils/customer.ts +20 -0
- package/src/utils/error-handler.ts +14 -0
- package/src/utils/index.ts +10 -0
- package/src/utils/logger.ts +79 -0
- package/src/utils/sanitize-url.ts +55 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Booking Service
|
|
3
|
+
*
|
|
4
|
+
* Handles service appointments and deliverables.
|
|
5
|
+
*/
|
|
6
|
+
import { storeManagementAxios } from '../client/httpClient'
|
|
7
|
+
import type {
|
|
8
|
+
ServiceAppointment,
|
|
9
|
+
ServiceAppointmentCreatePayload,
|
|
10
|
+
AvailableSlot,
|
|
11
|
+
ServiceDeliverable,
|
|
12
|
+
DeliverableApprovalPayload,
|
|
13
|
+
} from '../types/services'
|
|
14
|
+
|
|
15
|
+
export async function getAvailableSlots(
|
|
16
|
+
product_id: string,
|
|
17
|
+
date_from: string,
|
|
18
|
+
date_to: string
|
|
19
|
+
): Promise<AvailableSlot[]> {
|
|
20
|
+
const { data } = await storeManagementAxios.get<AvailableSlot[]>(
|
|
21
|
+
`service/available-slots/${product_id}`,
|
|
22
|
+
{ params: { date_from, date_to } }
|
|
23
|
+
)
|
|
24
|
+
return data
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function bookAppointment(
|
|
28
|
+
payload: ServiceAppointmentCreatePayload
|
|
29
|
+
): Promise<ServiceAppointment> {
|
|
30
|
+
const { data } = await storeManagementAxios.post<ServiceAppointment>('service/appointments/', payload)
|
|
31
|
+
return data
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function getAppointments(): Promise<ServiceAppointment[]> {
|
|
35
|
+
const { data } = await storeManagementAxios.get<ServiceAppointment[]>('service/bookings/my')
|
|
36
|
+
return data
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function getAppointment(id: string): Promise<ServiceAppointment> {
|
|
40
|
+
const { data } = await storeManagementAxios.get<ServiceAppointment>(`service/bookings/${id}`)
|
|
41
|
+
return data
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function cancelAppointment(id: string): Promise<void> {
|
|
45
|
+
await storeManagementAxios.delete(`service/bookings/${id}`)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function getDeliverables(order_id: string): Promise<ServiceDeliverable[]> {
|
|
49
|
+
const { data } = await storeManagementAxios.get<ServiceDeliverable[]>(`service/projects/${order_id}/deliverables/`)
|
|
50
|
+
return data
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function approveDeliverable(
|
|
54
|
+
order_id: string,
|
|
55
|
+
deliverable_id: string
|
|
56
|
+
): Promise<ServiceDeliverable> {
|
|
57
|
+
const { data } = await storeManagementAxios.post<ServiceDeliverable>(
|
|
58
|
+
`service/projects/${order_id}/deliverables/${deliverable_id}/approve`,
|
|
59
|
+
{ approved: true }
|
|
60
|
+
)
|
|
61
|
+
return data
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function requestRevision(
|
|
65
|
+
order_id: string,
|
|
66
|
+
deliverable_id: string,
|
|
67
|
+
feedback: string
|
|
68
|
+
): Promise<ServiceDeliverable> {
|
|
69
|
+
const { data } = await storeManagementAxios.post<ServiceDeliverable>(
|
|
70
|
+
`service/projects/${order_id}/deliverables/${deliverable_id}/revision`,
|
|
71
|
+
{ approved: false, feedback }
|
|
72
|
+
)
|
|
73
|
+
return data
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Service object export for backward compatibility
|
|
77
|
+
export const serviceBookingService = {
|
|
78
|
+
getAvailableSlots,
|
|
79
|
+
bookAppointment,
|
|
80
|
+
getAppointments,
|
|
81
|
+
getAppointment,
|
|
82
|
+
cancelAppointment,
|
|
83
|
+
getDeliverables,
|
|
84
|
+
approveDeliverable,
|
|
85
|
+
requestRevision,
|
|
86
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wishlist Service
|
|
3
|
+
*
|
|
4
|
+
* Handles wishlist operations.
|
|
5
|
+
*/
|
|
6
|
+
import { storeManagementAxios } from '../client/httpClient'
|
|
7
|
+
import { getGraphQLClient } from '../client/graphqlClient'
|
|
8
|
+
import type { WishlistItem, WishlistListResponse, WishlistCheckResponse } from '../types/store'
|
|
9
|
+
|
|
10
|
+
const GET_WISHLIST = `
|
|
11
|
+
query GetWishlist($page: Int!, $pageSize: Int!) {
|
|
12
|
+
wishlist(page: $page, pageSize: $pageSize) {
|
|
13
|
+
items {
|
|
14
|
+
id
|
|
15
|
+
product_id
|
|
16
|
+
notes
|
|
17
|
+
created_at
|
|
18
|
+
product_name
|
|
19
|
+
product_slug
|
|
20
|
+
product_price
|
|
21
|
+
product_image
|
|
22
|
+
}
|
|
23
|
+
total
|
|
24
|
+
page
|
|
25
|
+
page_size
|
|
26
|
+
total_pages
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`
|
|
30
|
+
|
|
31
|
+
const CHECK_IN_WISHLIST = `
|
|
32
|
+
query CheckInWishlist($productId: String!) {
|
|
33
|
+
check_in_wishlist(productId: $productId) {
|
|
34
|
+
in_wishlist
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
`
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Fetch the customer's wishlist for the current business.
|
|
41
|
+
*/
|
|
42
|
+
export async function getWishlist(params?: { page?: number; pageSize?: number }): Promise<WishlistListResponse> {
|
|
43
|
+
const client = getGraphQLClient()
|
|
44
|
+
const variables = {
|
|
45
|
+
page: params?.page || 1,
|
|
46
|
+
pageSize: params?.pageSize || 20,
|
|
47
|
+
}
|
|
48
|
+
const data = await client.request(GET_WISHLIST, variables)
|
|
49
|
+
return data.wishlist
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Check if a product is in the customer's wishlist.
|
|
54
|
+
*/
|
|
55
|
+
export async function checkInWishlist(productId: string): Promise<WishlistCheckResponse> {
|
|
56
|
+
const client = getGraphQLClient()
|
|
57
|
+
const data = await client.request(CHECK_IN_WISHLIST, { productId })
|
|
58
|
+
return data.check_in_wishlist
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Add a product to the customer's wishlist.
|
|
63
|
+
*/
|
|
64
|
+
export async function addToWishlist(productId: string, notes?: string): Promise<WishlistItem> {
|
|
65
|
+
const { data } = await storeManagementAxios.post<WishlistItem>("wishlist/", {
|
|
66
|
+
product_id: productId,
|
|
67
|
+
notes: notes || undefined,
|
|
68
|
+
})
|
|
69
|
+
return data
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Remove an item from the customer's wishlist by item ID.
|
|
74
|
+
*/
|
|
75
|
+
export async function removeFromWishlist(itemId: string): Promise<void> {
|
|
76
|
+
await storeManagementAxios.delete(`wishlist/${itemId}`)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Remove a product from the customer's wishlist by product ID.
|
|
81
|
+
*/
|
|
82
|
+
export async function removeProductFromWishlist(productId: string): Promise<void> {
|
|
83
|
+
await storeManagementAxios.delete(`wishlist/product/${productId}`)
|
|
84
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simplified customer auth types for luxe-storefront.
|
|
3
|
+
* Customers only need enough to track their orders — no RBAC, MFA, or complex profiles.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ── Customer Identity ─────────────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Media System response object for avatar/profile picture.
|
|
10
|
+
* Stored as JSON in the backend Profile model.
|
|
11
|
+
*/
|
|
12
|
+
export interface AvatarObject {
|
|
13
|
+
id: string;
|
|
14
|
+
alt: string;
|
|
15
|
+
url: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CustomerProfileFields {
|
|
19
|
+
firstname: string;
|
|
20
|
+
lastname: string;
|
|
21
|
+
phone: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface CustomerUser {
|
|
25
|
+
id: string;
|
|
26
|
+
email: string;
|
|
27
|
+
firstname?: string;
|
|
28
|
+
lastname?: string;
|
|
29
|
+
phone?: string;
|
|
30
|
+
/** Derived display name — prefer firstname + lastname when available */
|
|
31
|
+
full_name?: string;
|
|
32
|
+
avatar: string | null;
|
|
33
|
+
provider: 'google' | 'facebook' | 'email';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** GET/PUT /auth/profile/ — matches luxe-auth UserSerializer */
|
|
37
|
+
export interface AuthUserResponse {
|
|
38
|
+
id: string;
|
|
39
|
+
email: string;
|
|
40
|
+
is_google_auth_enabled?: boolean;
|
|
41
|
+
is_facebook_auth_enabled?: boolean;
|
|
42
|
+
profile?: {
|
|
43
|
+
firstname?: string;
|
|
44
|
+
lastname?: string;
|
|
45
|
+
phone?: string;
|
|
46
|
+
profile_picture?: string | null;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface UpdateProfilePayload {
|
|
51
|
+
firstname?: string;
|
|
52
|
+
lastname?: string;
|
|
53
|
+
phone?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ── Business Context (storefront is scoped to one business) ──────────────────
|
|
57
|
+
|
|
58
|
+
export interface BusinessContext {
|
|
59
|
+
id: string; // UUID
|
|
60
|
+
business_id: string; // B-XXXXXXXX — permanent, never changes
|
|
61
|
+
name: string;
|
|
62
|
+
logo_picture?: string | null;
|
|
63
|
+
display_currency?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ── API Responses ─────────────────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
export interface CustomerAuthResponse {
|
|
69
|
+
access: string;
|
|
70
|
+
refresh: string;
|
|
71
|
+
user: CustomerUser;
|
|
72
|
+
business: BusinessContext;
|
|
73
|
+
is_new?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface RefreshTokenResponse {
|
|
77
|
+
access: string;
|
|
78
|
+
refresh?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ── Request Payloads ──────────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
/** POST /auth/login/customer/ — field name is `tenant_id` (the business_id) */
|
|
84
|
+
export interface CustomerLoginPayload {
|
|
85
|
+
tenant_id: string; // config.api.storefrontBusinessId
|
|
86
|
+
email: string;
|
|
87
|
+
password: string;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** POST /auth/register/customer/ */
|
|
91
|
+
export interface CustomerRegisterPayload {
|
|
92
|
+
tenant_id: string; // config.api.storefrontBusinessId
|
|
93
|
+
/** Full name — backend splits this into firstname and lastname on the Profile */
|
|
94
|
+
full_name: string;
|
|
95
|
+
email: string;
|
|
96
|
+
password: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** POST /auth/verify-otp/ */
|
|
100
|
+
export interface OTPVerifyPayload {
|
|
101
|
+
email: string;
|
|
102
|
+
code: string;
|
|
103
|
+
purpose?: 'verify' | 'password_reset';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** POST /auth/resend-otp/ */
|
|
107
|
+
export interface ResendOTPPayload {
|
|
108
|
+
email: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** POST /auth/logout/ */
|
|
112
|
+
export interface LogoutPayload {
|
|
113
|
+
refresh?: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ── Auth Context ──────────────────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
export interface AuthContextValue {
|
|
119
|
+
customer: CustomerUser | null;
|
|
120
|
+
isLoading: boolean;
|
|
121
|
+
isModalOpen: boolean;
|
|
122
|
+
openModal: () => void;
|
|
123
|
+
closeModal: () => void;
|
|
124
|
+
setCustomer: (user: CustomerUser | null) => void;
|
|
125
|
+
logout: () => Promise<void>;
|
|
126
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bespoke slot booking types for customer-facing storefront
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type SlotBookingStatus = "reserved" | "confirmed" | "completed" | "voided";
|
|
6
|
+
|
|
7
|
+
export interface BespokeSlotBooking {
|
|
8
|
+
id: string;
|
|
9
|
+
product_id: string;
|
|
10
|
+
capacity_config_id: string | null;
|
|
11
|
+
consultation_id: string | null;
|
|
12
|
+
order_id: string | null;
|
|
13
|
+
customer_id: string;
|
|
14
|
+
status: SlotBookingStatus;
|
|
15
|
+
preferred_start_date: string | null;
|
|
16
|
+
preferred_end_date: string | null;
|
|
17
|
+
estimated_completion_date: string | null;
|
|
18
|
+
notes: string | null;
|
|
19
|
+
created_at: string;
|
|
20
|
+
updated_at: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface BespokeCapacityConfig {
|
|
24
|
+
id: string;
|
|
25
|
+
business_id: string;
|
|
26
|
+
product_id: string;
|
|
27
|
+
slot_period: "weekly" | "monthly" | "yearly";
|
|
28
|
+
total_slots: number;
|
|
29
|
+
slots_used: number;
|
|
30
|
+
period_start_date: string;
|
|
31
|
+
period_end_date: string;
|
|
32
|
+
production_days_per_order: number;
|
|
33
|
+
buffer_days_between_orders: number;
|
|
34
|
+
blocked_dates: string[];
|
|
35
|
+
auto_reset: boolean;
|
|
36
|
+
is_active: boolean;
|
|
37
|
+
created_at: string;
|
|
38
|
+
updated_at: string;
|
|
39
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CMS Types
|
|
3
|
+
*
|
|
4
|
+
* Types for kasuvia-cms integration - dynamic content models and entries
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface CmsField {
|
|
8
|
+
name: string
|
|
9
|
+
label: string
|
|
10
|
+
type: string
|
|
11
|
+
required: boolean
|
|
12
|
+
config: Record<string, any>
|
|
13
|
+
sub_fields?: CmsField[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface CmsModelPermissions {
|
|
17
|
+
read: boolean
|
|
18
|
+
create: boolean
|
|
19
|
+
update: boolean
|
|
20
|
+
delete: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface CmsModelPublicApiPermissions {
|
|
24
|
+
public_api: CmsModelPermissions
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface CmsModel {
|
|
28
|
+
id: string
|
|
29
|
+
business_id: string
|
|
30
|
+
model_slug: string
|
|
31
|
+
display_name: string
|
|
32
|
+
description: string | null
|
|
33
|
+
fields: CmsField[]
|
|
34
|
+
permissions: CmsModelPublicApiPermissions
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface CmsEntry {
|
|
38
|
+
id: string
|
|
39
|
+
business_id: string
|
|
40
|
+
model_slug: string
|
|
41
|
+
data: Record<string, any>
|
|
42
|
+
created_at: string
|
|
43
|
+
updated_at: string
|
|
44
|
+
created_by: string | null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface CmsEntryListResponse {
|
|
48
|
+
entries: CmsEntry[]
|
|
49
|
+
total: number
|
|
50
|
+
page: number
|
|
51
|
+
page_size: number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface CmsIcon {
|
|
55
|
+
id: string
|
|
56
|
+
name: string
|
|
57
|
+
category: string
|
|
58
|
+
tags: string[]
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface CmsIconListResponse {
|
|
62
|
+
icons: CmsIcon[]
|
|
63
|
+
total: number
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ListCmsEntriesParams {
|
|
67
|
+
page?: number
|
|
68
|
+
page_size?: number
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface CreateCmsEntryParams {
|
|
72
|
+
data: Record<string, any>
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface UpdateCmsEntryParams {
|
|
76
|
+
data: Record<string, any>
|
|
77
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consultation types for customer-facing storefront
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type ConsultationStatus =
|
|
6
|
+
| "pending"
|
|
7
|
+
| "quoted"
|
|
8
|
+
| "negotiating"
|
|
9
|
+
| "deposit_pending"
|
|
10
|
+
| "deposit_paid"
|
|
11
|
+
| "converting"
|
|
12
|
+
| "converted"
|
|
13
|
+
| "rejected";
|
|
14
|
+
|
|
15
|
+
export type ConsultationProductType = "bespoke" | "service";
|
|
16
|
+
|
|
17
|
+
export interface ConsultationMessage {
|
|
18
|
+
id: string;
|
|
19
|
+
consultation_id: string;
|
|
20
|
+
sender_id: string;
|
|
21
|
+
sender_role: "customer" | "merchant" | "system";
|
|
22
|
+
message: string;
|
|
23
|
+
attachments: string[];
|
|
24
|
+
is_read: boolean;
|
|
25
|
+
created_at: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface Consultation {
|
|
29
|
+
id: string;
|
|
30
|
+
business_id: string;
|
|
31
|
+
customer_id: string;
|
|
32
|
+
product_id: string | null;
|
|
33
|
+
title: string;
|
|
34
|
+
status: ConsultationStatus;
|
|
35
|
+
product_type: ConsultationProductType;
|
|
36
|
+
quote_amount: number | null;
|
|
37
|
+
agreed_price: number | null;
|
|
38
|
+
deposit_amount: number | null;
|
|
39
|
+
deposit_required: boolean;
|
|
40
|
+
is_physical_delivery: boolean;
|
|
41
|
+
expected_delivery_type: string | null;
|
|
42
|
+
structured_details: Record<string, unknown>;
|
|
43
|
+
rejection_reason: string | null;
|
|
44
|
+
converted_order_id: string | null;
|
|
45
|
+
slot_booking_id: string | null;
|
|
46
|
+
capacity_config_id: string | null;
|
|
47
|
+
created_at: string;
|
|
48
|
+
updated_at: string;
|
|
49
|
+
messages: ConsultationMessage[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ConsultationCreatePayload {
|
|
53
|
+
product_id?: string;
|
|
54
|
+
title: string;
|
|
55
|
+
description: string;
|
|
56
|
+
reference_images?: string[];
|
|
57
|
+
custom_measurements?: Record<string, string | number>;
|
|
58
|
+
preferred_timeline?: string;
|
|
59
|
+
special_instructions?: string;
|
|
60
|
+
product_type?: ConsultationProductType;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ConsultationMessagePayload {
|
|
64
|
+
message: string;
|
|
65
|
+
attachments?: string[];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface ConsultationQuoteAcceptPayload {
|
|
69
|
+
agreed_price: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface BespokeAvailability {
|
|
73
|
+
available_slots: number;
|
|
74
|
+
next_available_date: string | null;
|
|
75
|
+
period_end: string;
|
|
76
|
+
blocked_dates: string[];
|
|
77
|
+
production_days: number;
|
|
78
|
+
is_available: boolean;
|
|
79
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK Types Barrel Export
|
|
3
|
+
*
|
|
4
|
+
* Central export point for all domain types.
|
|
5
|
+
* Organized by backend service:
|
|
6
|
+
* - auth: kasuvia-auth
|
|
7
|
+
* - store: kasuvia-store-management
|
|
8
|
+
* - payments: kasuvia-payment-system
|
|
9
|
+
* - cms: kasuvia-cms
|
|
10
|
+
* - media: kasuvia-media-system
|
|
11
|
+
* - consultations: kasuvia-store-management (consultations feature)
|
|
12
|
+
* - services: kasuvia-store-management (service booking feature)
|
|
13
|
+
* - bespoke: kasuvia-store-management (bespoke slot booking feature)
|
|
14
|
+
* - business: business configuration
|
|
15
|
+
* - ui: UI/app state types
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export * from './auth'
|
|
19
|
+
export * from './store'
|
|
20
|
+
export * from './payments'
|
|
21
|
+
export * from './consultations'
|
|
22
|
+
export * from './services'
|
|
23
|
+
export * from './bespoke'
|
|
24
|
+
export * from './cms'
|
|
25
|
+
export * from './media'
|
|
26
|
+
export * from './business'
|
|
27
|
+
export * from './ui'
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media types for the storefront
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface MediaAsset {
|
|
6
|
+
id: string
|
|
7
|
+
url: string
|
|
8
|
+
filename: string
|
|
9
|
+
content_type: string
|
|
10
|
+
size: number
|
|
11
|
+
business_id: string
|
|
12
|
+
affiliation: string
|
|
13
|
+
created_at: string
|
|
14
|
+
alt?: string
|
|
15
|
+
description?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface MediaUploadParams {
|
|
19
|
+
business_id?: string
|
|
20
|
+
owner_id?: string
|
|
21
|
+
uploaded_by_name?: string
|
|
22
|
+
affiliation?: string
|
|
23
|
+
context: string // Required for security: describes the upload context (e.g., product, user, business)
|
|
24
|
+
entity_id: string // Required for security: ID of the entity this file belongs to
|
|
25
|
+
alt?: string
|
|
26
|
+
description?: string
|
|
27
|
+
idempotency_key?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface MediaAssetUpdatePayload {
|
|
31
|
+
alt?: string
|
|
32
|
+
description?: string
|
|
33
|
+
affiliation?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface StorageStats {
|
|
37
|
+
total_bytes: number
|
|
38
|
+
used_bytes: number
|
|
39
|
+
available_bytes: number
|
|
40
|
+
asset_count: number
|
|
41
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file types/payments/index.ts
|
|
3
|
+
* @description All customer-facing payment types for the Luxe Payment System.
|
|
4
|
+
*
|
|
5
|
+
* Auth model:
|
|
6
|
+
* - X-Storefront-Key → identifies the business storefront
|
|
7
|
+
* - X-Business-ID → tenant context
|
|
8
|
+
* No business-owner JWT used here — these are CUSTOMER-facing types.
|
|
9
|
+
*
|
|
10
|
+
* Payment flow:
|
|
11
|
+
* Customer → Business Owner : Monnify (NGN) | Flutterwave (non-NGN)
|
|
12
|
+
* Business Owner → Luxe : Subscription (separate, JWT-auth)
|
|
13
|
+
* Luxe → Business Owner : Payout (separate, JWT-auth)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// ── Configuration Types ─────────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
export interface Currency {
|
|
19
|
+
code: string; // ISO 4217 currency code (e.g., USD, NGN, EUR)
|
|
20
|
+
name: string; // Full currency name (e.g., US Dollar, Nigerian Naira)
|
|
21
|
+
symbol: string; // Currency symbol (e.g., $, ₦, €)
|
|
22
|
+
decimals: number; // Number of decimal places (e.g., 2 for USD, 0 for JPY)
|
|
23
|
+
is_active: boolean; // Whether this currency is active
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface SupportedCurrenciesResponse {
|
|
27
|
+
currencies: Currency[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface BackendLanguage {
|
|
31
|
+
code: string; // Language code (e.g., en, ar, fr)
|
|
32
|
+
label: string; // Language label (e.g., English, Arabic, French)
|
|
33
|
+
flag: string; // Flag emoji or icon
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface SupportedLang {
|
|
37
|
+
code: string; // Google Translate code
|
|
38
|
+
appCode: string; // Internal app code
|
|
39
|
+
label: string;
|
|
40
|
+
native: string;
|
|
41
|
+
flag: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface SupportedLanguagesResponse {
|
|
45
|
+
languages: BackendLanguage[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ── Request Types ─────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
export interface DVACreateRequest {
|
|
51
|
+
order_id?: string;
|
|
52
|
+
amount: number;
|
|
53
|
+
customer_email: string;
|
|
54
|
+
customer_name?: string;
|
|
55
|
+
/** Defaults to NGN — DVA is Monnify-only */
|
|
56
|
+
currency?: string;
|
|
57
|
+
/** Idempotency key to prevent duplicate DVA creation */
|
|
58
|
+
idempotency_key?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface PaymentInitiateRequest {
|
|
62
|
+
amount: number;
|
|
63
|
+
currency: string;
|
|
64
|
+
customer_email: string;
|
|
65
|
+
customer_name?: string;
|
|
66
|
+
order_id?: string;
|
|
67
|
+
quote_id?: string;
|
|
68
|
+
/** Window origin of the storefront — used as gateway redirect base URL */
|
|
69
|
+
storefront_origin?: string;
|
|
70
|
+
metadata?: Record<string, string | number | boolean>;
|
|
71
|
+
/** Idempotency key to prevent duplicate payment initiation */
|
|
72
|
+
idempotency_key?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
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
|
+
// ── Response Types ─────────────────────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
export interface DVADetails {
|
|
91
|
+
account_number: string;
|
|
92
|
+
bank_name: string;
|
|
93
|
+
account_name: string;
|
|
94
|
+
reference: string;
|
|
95
|
+
amount: number;
|
|
96
|
+
transaction_id: string;
|
|
97
|
+
expires_at: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface PaymentInitiateResponse {
|
|
101
|
+
id: string;
|
|
102
|
+
gateway_ref: string;
|
|
103
|
+
gateway: string;
|
|
104
|
+
status: string;
|
|
105
|
+
/** Normalised top-level checkout URL for gateway redirect */
|
|
106
|
+
checkout_url: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface TransactionVerifyResponse {
|
|
110
|
+
id: string;
|
|
111
|
+
status: string;
|
|
112
|
+
amount: number;
|
|
113
|
+
currency: string;
|
|
114
|
+
gateway_ref: string;
|
|
115
|
+
gateway?: string;
|
|
116
|
+
order_id?: string;
|
|
117
|
+
escrow_status?: string;
|
|
118
|
+
escrow_release_date?: string;
|
|
119
|
+
metadata_json?: Record<string, unknown>;
|
|
120
|
+
}
|