@fayz-ai/shop 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +18 -1
  2. package/dist/admin.d.ts +2 -0
  3. package/dist/admin.d.ts.map +1 -0
  4. package/dist/catalog.d.ts +1 -3
  5. package/dist/catalog.d.ts.map +1 -1
  6. package/dist/catalog.js +2 -2
  7. package/dist/{chunk-IYQHKMLB.js → chunk-2WACO2TG.js} +4 -4
  8. package/dist/chunk-2WACO2TG.js.map +1 -0
  9. package/dist/chunk-3GERSY5F.js +526 -0
  10. package/dist/chunk-3GERSY5F.js.map +1 -0
  11. package/dist/chunk-6BO2TMZ5.js +93 -0
  12. package/dist/chunk-6BO2TMZ5.js.map +1 -0
  13. package/dist/chunk-FQPGE3YN.js +3 -0
  14. package/dist/{chunk-JR25TISO.js.map → chunk-FQPGE3YN.js.map} +1 -1
  15. package/dist/{chunk-CTKZ6O2J.js → chunk-IKNGCRUM.js} +41 -15
  16. package/dist/chunk-IKNGCRUM.js.map +1 -0
  17. package/dist/chunk-KLDS7IPU.js +17 -0
  18. package/dist/chunk-KLDS7IPU.js.map +1 -0
  19. package/dist/chunk-NWW3WJ7Y.js +136 -0
  20. package/dist/chunk-NWW3WJ7Y.js.map +1 -0
  21. package/dist/chunk-STRNMFC4.js +1438 -0
  22. package/dist/chunk-STRNMFC4.js.map +1 -0
  23. package/dist/chunk-U6HV3LVP.js +1170 -0
  24. package/dist/chunk-U6HV3LVP.js.map +1 -0
  25. package/dist/client.d.ts +2 -0
  26. package/dist/client.d.ts.map +1 -0
  27. package/dist/data/customer-search.d.ts +3 -0
  28. package/dist/data/customer-search.d.ts.map +1 -0
  29. package/dist/data/functions.d.ts +9 -0
  30. package/dist/data/functions.d.ts.map +1 -0
  31. package/dist/data/media.d.ts +37 -0
  32. package/dist/data/media.d.ts.map +1 -0
  33. package/dist/{mock-catalog.d.ts → data/mock-catalog.d.ts} +21 -1
  34. package/dist/data/mock-catalog.d.ts.map +1 -0
  35. package/dist/data/mock-provider.d.ts +165 -0
  36. package/dist/data/mock-provider.d.ts.map +1 -0
  37. package/dist/data/mock.d.ts +3 -0
  38. package/dist/data/mock.d.ts.map +1 -0
  39. package/dist/data/provider.d.ts +335 -0
  40. package/dist/data/provider.d.ts.map +1 -0
  41. package/dist/data/supabase-provider.d.ts +208 -0
  42. package/dist/data/supabase-provider.d.ts.map +1 -0
  43. package/dist/data/tables.d.ts +38 -0
  44. package/dist/data/tables.d.ts.map +1 -0
  45. package/dist/data/tenant.d.ts.map +1 -0
  46. package/dist/entities/entity-reconcile.d.ts +32 -0
  47. package/dist/entities/entity-reconcile.d.ts.map +1 -0
  48. package/dist/entities/entity-sql.d.ts +50 -0
  49. package/dist/entities/entity-sql.d.ts.map +1 -0
  50. package/dist/entities/entity-store.d.ts +58 -0
  51. package/dist/entities/entity-store.d.ts.map +1 -0
  52. package/dist/entities/index.d.ts +10 -0
  53. package/dist/entities/index.d.ts.map +1 -0
  54. package/dist/entities/mock-entity-store.d.ts +17 -0
  55. package/dist/entities/mock-entity-store.d.ts.map +1 -0
  56. package/dist/entities/supabase-entity-store.d.ts +8 -0
  57. package/dist/entities/supabase-entity-store.d.ts.map +1 -0
  58. package/dist/entities.js +159 -0
  59. package/dist/entities.js.map +1 -0
  60. package/dist/index.d.ts +28 -12
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +1558 -40
  63. package/dist/index.js.map +1 -1
  64. package/dist/inventory/allocation.d.ts +98 -0
  65. package/dist/inventory/allocation.d.ts.map +1 -0
  66. package/dist/inventory/index.d.ts +13 -0
  67. package/dist/inventory/index.d.ts.map +1 -0
  68. package/dist/inventory/mock-stock-store.d.ts +89 -0
  69. package/dist/inventory/mock-stock-store.d.ts.map +1 -0
  70. package/dist/inventory/postgrest-double.d.ts +65 -0
  71. package/dist/inventory/postgrest-double.d.ts.map +1 -0
  72. package/dist/inventory/shopify-mapping.d.ts +67 -0
  73. package/dist/inventory/shopify-mapping.d.ts.map +1 -0
  74. package/dist/inventory/stock-contract.d.ts +46 -0
  75. package/dist/inventory/stock-contract.d.ts.map +1 -0
  76. package/dist/inventory/stock-store.d.ts +96 -0
  77. package/dist/inventory/stock-store.d.ts.map +1 -0
  78. package/dist/inventory/stock-types.d.ts +351 -0
  79. package/dist/inventory/stock-types.d.ts.map +1 -0
  80. package/dist/inventory/supabase-stock-store.d.ts +60 -0
  81. package/dist/inventory/supabase-stock-store.d.ts.map +1 -0
  82. package/dist/inventory/vocabulary.d.ts +86 -0
  83. package/dist/inventory/vocabulary.d.ts.map +1 -0
  84. package/dist/inventory.js +4 -0
  85. package/dist/inventory.js.map +1 -0
  86. package/dist/lib/catalog.d.ts +4 -0
  87. package/dist/lib/catalog.d.ts.map +1 -0
  88. package/dist/{commerce.d.ts → lib/commerce.d.ts} +2 -2
  89. package/dist/lib/commerce.d.ts.map +1 -0
  90. package/dist/lib/document.d.ts +13 -0
  91. package/dist/lib/document.d.ts.map +1 -0
  92. package/dist/lib/emails.d.ts +50 -0
  93. package/dist/lib/emails.d.ts.map +1 -0
  94. package/dist/lib/message-events.d.ts +4 -0
  95. package/dist/lib/message-events.d.ts.map +1 -0
  96. package/dist/lib/runtime.d.ts +5 -0
  97. package/dist/lib/runtime.d.ts.map +1 -0
  98. package/dist/lib/variant-matrix.d.ts +120 -0
  99. package/dist/lib/variant-matrix.d.ts.map +1 -0
  100. package/dist/mock.d.ts +1 -2
  101. package/dist/mock.d.ts.map +1 -1
  102. package/dist/mock.js +4 -2
  103. package/dist/provider.d.ts +1 -88
  104. package/dist/provider.d.ts.map +1 -1
  105. package/dist/providers/checkout.d.ts +129 -0
  106. package/dist/providers/checkout.d.ts.map +1 -0
  107. package/dist/providers/index.d.ts +5 -0
  108. package/dist/providers/index.d.ts.map +1 -0
  109. package/dist/providers/shipping.d.ts +43 -0
  110. package/dist/providers/shipping.d.ts.map +1 -0
  111. package/dist/providers.js +70 -0
  112. package/dist/providers.js.map +1 -0
  113. package/dist/rules/adapter.d.ts +36 -0
  114. package/dist/rules/adapter.d.ts.map +1 -0
  115. package/dist/rules/attributes.d.ts +64 -0
  116. package/dist/rules/attributes.d.ts.map +1 -0
  117. package/dist/rules/context.d.ts +43 -0
  118. package/dist/rules/context.d.ts.map +1 -0
  119. package/dist/rules/evaluator.d.ts +37 -0
  120. package/dist/rules/evaluator.d.ts.map +1 -0
  121. package/dist/rules/index.d.ts +13 -0
  122. package/dist/rules/index.d.ts.map +1 -0
  123. package/dist/rules/prices.d.ts +25 -0
  124. package/dist/rules/prices.d.ts.map +1 -0
  125. package/dist/rules/rule-types.d.ts +160 -0
  126. package/dist/rules/rule-types.d.ts.map +1 -0
  127. package/dist/rules.js +22 -0
  128. package/dist/rules.js.map +1 -0
  129. package/dist/runtime.d.ts +1 -4
  130. package/dist/runtime.d.ts.map +1 -1
  131. package/dist/runtime.js +5 -3
  132. package/dist/shipping/label-provider.d.ts +43 -0
  133. package/dist/shipping/label-provider.d.ts.map +1 -0
  134. package/dist/types.d.ts +688 -0
  135. package/dist/types.d.ts.map +1 -1
  136. package/package.json +30 -20
  137. package/dist/chunk-CTKZ6O2J.js.map +0 -1
  138. package/dist/chunk-IYQHKMLB.js.map +0 -1
  139. package/dist/chunk-JR25TISO.js +0 -3
  140. package/dist/chunk-SVTCJ6HP.js +0 -440
  141. package/dist/chunk-SVTCJ6HP.js.map +0 -1
  142. package/dist/commerce.d.ts.map +0 -1
  143. package/dist/mock-catalog.d.ts.map +0 -1
  144. package/dist/mock-provider.d.ts +0 -60
  145. package/dist/mock-provider.d.ts.map +0 -1
  146. package/dist/supabase-provider.d.ts +0 -56
  147. package/dist/supabase-provider.d.ts.map +0 -1
  148. package/dist/tables.d.ts +0 -12
  149. package/dist/tables.d.ts.map +0 -1
  150. package/dist/tenant.d.ts.map +0 -1
  151. package/src/catalog.ts +0 -3
  152. package/src/commerce.ts +0 -120
  153. package/src/index.ts +0 -40
  154. package/src/mock-catalog.ts +0 -266
  155. package/src/mock-provider.ts +0 -480
  156. package/src/mock.ts +0 -2
  157. package/src/provider.ts +0 -117
  158. package/src/runtime.ts +0 -20
  159. package/src/supabase-provider.ts +0 -754
  160. package/src/tables.ts +0 -17
  161. package/src/tenant.ts +0 -21
  162. package/src/types.ts +0 -623
  163. /package/dist/{tenant.d.ts → data/tenant.d.ts} +0 -0
package/src/tables.ts DELETED
@@ -1,17 +0,0 @@
1
- // Physical table names for @fayz-ai/shop. Renamed to the plg_shop_* industry-pool
2
- // prefix (was shop_*) when the core DB moved into the public schema. RPC function
3
- // names (shop_place_order, shop_get_order, shop_resolve_customer) are unchanged.
4
- export const T = {
5
- products: 'plg_shop_products',
6
- productImages: 'plg_shop_product_images',
7
- categories: 'plg_shop_categories',
8
- orders: 'plg_shop_orders',
9
- orderItems: 'plg_shop_order_items',
10
- customers: 'plg_shop_customers',
11
- discounts: 'plg_shop_discounts',
12
- salesChannels: 'plg_shop_channels',
13
- // Core, not plg_shop_*: a delivery zone is a fact about the business, and
14
- // fulfilment and financial read it too. Same reasoning as addresses and
15
- // orders — see migration 0021.
16
- shippingZones: 'shipping_zones',
17
- } as const
package/src/tenant.ts DELETED
@@ -1,21 +0,0 @@
1
- // Tenant scoping for shop queries. @fayz-ai/shop has no dependency on @fayz-ai/saas —
2
- // the host app (or @fayz-ai/plugin-shop) registers a resolver that returns the
3
- // current tenant id. When no resolver is set, queries are unscoped (RLS still
4
- // applies server-side).
5
-
6
- export type TenantResolver = () => string | undefined
7
-
8
- let _resolver: TenantResolver | null = null
9
-
10
- export function setShopTenantResolver(resolver: TenantResolver): void {
11
- _resolver = resolver
12
- }
13
-
14
- export function getShopTenantId(): string | undefined {
15
- if (!_resolver) return undefined
16
- try {
17
- return _resolver()
18
- } catch {
19
- return undefined
20
- }
21
- }
package/src/types.ts DELETED
@@ -1,623 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Product
3
- // ---------------------------------------------------------------------------
4
-
5
- export type ProductStatus = 'draft' | 'active' | 'archived'
6
-
7
- export interface Product {
8
- id: string
9
- tenantId: string
10
- name: string
11
- slug: string
12
- description: string | null
13
- price: number
14
- compareAtPrice: number | null
15
- currency: string
16
- status: ProductStatus
17
- inventoryCount: number
18
- sku: string | null
19
- sortOrder: number
20
- metadata: Record<string, unknown>
21
- images: ProductImage[]
22
- categoryId: string | null
23
- categoryName: string | null
24
- isPhysical: boolean
25
- weight: number | null
26
- weightUnit: string
27
- createdAt: string
28
- updatedAt: string
29
- }
30
-
31
- export interface ProductImage {
32
- id: string
33
- productId: string
34
- url: string
35
- altText: string | null
36
- sortOrder: number
37
- isPrimary: boolean
38
- createdAt: string
39
- }
40
-
41
- export interface CreateProductInput {
42
- name: string
43
- slug?: string
44
- description?: string
45
- price: number
46
- compareAtPrice?: number
47
- currency?: string
48
- status?: ProductStatus
49
- inventoryCount?: number
50
- sku?: string
51
- sortOrder?: number
52
- metadata?: Record<string, unknown>
53
- categoryId?: string
54
- isPhysical?: boolean
55
- weight?: number
56
- weightUnit?: string
57
- }
58
-
59
- export interface UpdateProductInput {
60
- name?: string
61
- slug?: string
62
- description?: string
63
- price?: number
64
- compareAtPrice?: number | null
65
- currency?: string
66
- status?: ProductStatus
67
- inventoryCount?: number
68
- sku?: string | null
69
- sortOrder?: number
70
- metadata?: Record<string, unknown>
71
- categoryId?: string | null
72
- isPhysical?: boolean
73
- weight?: number | null
74
- weightUnit?: string
75
- }
76
-
77
- export interface ListProductsOptions {
78
- status?: ProductStatus
79
- categoryId?: string
80
- search?: string
81
- /** Exact-match slug lookup (storefront product-detail routing) */
82
- slug?: string
83
- limit?: number
84
- offset?: number
85
- orderBy?: 'name' | 'price' | 'created_at' | 'sort_order'
86
- order?: 'asc' | 'desc'
87
- }
88
-
89
- // ---------------------------------------------------------------------------
90
- // Product enquiry
91
- // ---------------------------------------------------------------------------
92
-
93
- export type ProductEnquiryStatus = 'new' | 'contacted' | 'closed'
94
-
95
- export interface ProductEnquiry {
96
- id: string
97
- tenantId: string
98
- productId: string | null
99
- productName: string
100
- productSlug: string | null
101
- customerName: string
102
- customerEmail: string
103
- customerPhone: string | null
104
- subject: string | null
105
- message: string
106
- sourceUrl: string | null
107
- status: ProductEnquiryStatus
108
- metadata: Record<string, unknown>
109
- createdAt: string
110
- updatedAt: string
111
- }
112
-
113
- export interface CreateProductEnquiryInput {
114
- productId?: string
115
- productName: string
116
- productSlug?: string
117
- customerName: string
118
- customerEmail: string
119
- customerPhone?: string
120
- subject?: string
121
- message: string
122
- sourceUrl?: string
123
- metadata?: Record<string, unknown>
124
- }
125
-
126
- export interface ListProductEnquiriesOptions {
127
- productId?: string
128
- customerEmail?: string
129
- status?: ProductEnquiryStatus
130
- limit?: number
131
- offset?: number
132
- }
133
-
134
- // ---------------------------------------------------------------------------
135
- // Category
136
- // ---------------------------------------------------------------------------
137
-
138
- export interface Category {
139
- id: string
140
- tenantId: string
141
- name: string
142
- slug: string
143
- description: string | null
144
- parentId: string | null
145
- sortOrder: number
146
- /** Showcase image (storefront category tiles). Not yet a shop_categories column. */
147
- imageUrl?: string | null
148
- children?: Category[]
149
- createdAt: string
150
- }
151
-
152
- export interface CreateCategoryInput {
153
- name: string
154
- slug?: string
155
- description?: string
156
- parentId?: string
157
- sortOrder?: number
158
- }
159
-
160
- export interface UpdateCategoryInput {
161
- name?: string
162
- slug?: string
163
- description?: string | null
164
- parentId?: string | null
165
- sortOrder?: number
166
- }
167
-
168
- // ---------------------------------------------------------------------------
169
- // Order
170
- // ---------------------------------------------------------------------------
171
-
172
- export type OrderStatus = 'open' | 'archived' | 'cancelled'
173
- export type FinancialStatus = 'pending' | 'paid' | 'partially_paid' | 'refunded' | 'partially_refunded' | 'voided'
174
- export type FulfillmentStatus = 'unfulfilled' | 'partially_fulfilled' | 'fulfilled'
175
-
176
- export interface Order {
177
- id: string
178
- tenantId: string
179
- orderNumber: number
180
- status: OrderStatus
181
- financialStatus: FinancialStatus
182
- fulfillmentStatus: FulfillmentStatus
183
- currency: string
184
- subtotal: number
185
- taxTotal: number
186
- discountTotal: number
187
- shippingTotal: number
188
- total: number
189
- customerId: string | null
190
- customerName: string | null
191
- customerEmail: string | null
192
- discountCode: string | null
193
- notes: string | null
194
- /** Frozen delivery address captured at purchase time (0010/0012). */
195
- shippingAddress: ShippingAddressSnapshot | null
196
- /** How the buyer paid — opens the ledger row in public.transactions. */
197
- paymentMethodKind: PaymentMethodKind | null
198
- paidAt: string | null
199
- items: OrderItem[]
200
- createdAt: string
201
- updatedAt: string
202
- }
203
-
204
- export interface OrderItem {
205
- id: string
206
- orderId: string
207
- productId: string | null
208
- name: string
209
- sku: string | null
210
- quantity: number
211
- unitPrice: number
212
- total: number
213
- imageUrl: string | null
214
- }
215
-
216
- export interface CreateOrderInput {
217
- customerId?: string
218
- customerName?: string
219
- customerEmail?: string
220
- currency?: string
221
- notes?: string
222
- discountCode?: string
223
- discountTotal?: number
224
- shippingTotal?: number
225
- items: Array<{
226
- productId?: string
227
- name: string
228
- sku?: string
229
- quantity: number
230
- unitPrice: number
231
- imageUrl?: string
232
- }>
233
- }
234
-
235
- export interface UpdateOrderInput {
236
- status?: OrderStatus
237
- financialStatus?: FinancialStatus
238
- fulfillmentStatus?: FulfillmentStatus
239
- notes?: string
240
- }
241
-
242
- export interface ListOrdersOptions {
243
- status?: OrderStatus
244
- financialStatus?: FinancialStatus
245
- fulfillmentStatus?: FulfillmentStatus
246
- customerId?: string
247
- customerEmail?: string
248
- search?: string
249
- limit?: number
250
- offset?: number
251
- }
252
-
253
- // ---------------------------------------------------------------------------
254
- // Order placement (server-trust primitive)
255
- // ---------------------------------------------------------------------------
256
-
257
- /**
258
- * A single line in a trusted order-placement request. Carries NO price — the
259
- * server re-reads the product price from the catalog so the browser can never
260
- * set what it pays.
261
- */
262
- export interface PlaceOrderLine {
263
- productId: string
264
- quantity: number
265
- /** Variant/options label appended to the stored item name (display only). */
266
- optionsLabel?: string
267
- }
268
-
269
- /**
270
- * Input for {@link ShopProvider.placeOrder} — the only trusted path to create a
271
- * storefront order. Prices, discount math, and inventory are resolved
272
- * server-side; the client supplies product ids, quantities, and intent only.
273
- */
274
- /** Structured delivery address. Mirrors public.addresses so the RPC can both
275
- * freeze it on the order and save it to the customer's address book. */
276
- export interface ShippingAddressInput {
277
- postalCode: string
278
- street: string
279
- number?: string
280
- complement?: string
281
- district?: string
282
- city: string
283
- state: string
284
- country?: string
285
- recipient?: string
286
- phone?: string
287
- label?: string
288
- }
289
-
290
- export type PaymentMethodKind = 'pix' | 'credit_card' | 'debit_card' | 'boleto' | 'cash' | 'other'
291
-
292
- /**
293
- * A range of postal codes the store delivers to, with its own price and ETA.
294
- *
295
- * `postalFrom`/`postalTo` are 8 digits, no punctuation. Ranges may overlap: the
296
- * cheapest match wins, which is how a merchant layers a promotional zone over a
297
- * broader one without deleting anything.
298
- */
299
- export interface ShippingZone {
300
- id: string
301
- tenantId: string
302
- name: string
303
- carrier?: string | null
304
- postalFrom: string
305
- postalTo: string
306
- rate: number
307
- /** Overrides the store-wide free-delivery threshold inside this zone. */
308
- freeAbove?: number | null
309
- etaMinDays?: number | null
310
- etaMaxDays?: number | null
311
- active: boolean
312
- sortOrder: number
313
- }
314
-
315
- export type CreateShippingZoneInput = Omit<ShippingZone, 'id' | 'tenantId'>
316
- export type UpdateShippingZoneInput = Partial<CreateShippingZoneInput>
317
-
318
- /**
319
- * One delivery option for a postal code, as quoted by shop_quote_shipping.
320
- *
321
- * `rate` already has the zone's free-above threshold applied, so the caller
322
- * never re-derives a price — the number shown is the number charged. An EMPTY
323
- * list of options is the meaningful answer "we do not deliver there", not an
324
- * error condition.
325
- */
326
- export interface ShippingQuoteOption {
327
- zoneId: string
328
- name: string
329
- carrier?: string
330
- /** Resolved against the subtotal the quote was requested for. */
331
- rate: number
332
- /** The zone's price before any free-above rule — lets a caller re-resolve
333
- * `rate` for a changed cart without another round trip, using the same rule
334
- * the server applies. Without it a stale quote had to fall back to the
335
- * store-wide flat rate, which is a different zone's price. */
336
- baseRate: number
337
- freeAbove?: number | null
338
- etaMinDays?: number
339
- etaMaxDays?: number
340
- /** True when the rate is 0 because the order cleared the zone's threshold. */
341
- free: boolean
342
- }
343
-
344
- /**
345
- * A row from the customer's address book (public.addresses).
346
- *
347
- * Only reachable with a signed-in shopper: the addresses_self_read policy joins
348
- * plg_shop_customers.auth_user_id to auth.uid(), so an anonymous request sees
349
- * nothing. Guests get an empty book and type their address, which is correct —
350
- * the alternative is showing them somebody else's.
351
- */
352
- export interface CustomerAddress extends ShippingAddressInput {
353
- id: string
354
- isDefault?: boolean
355
- }
356
-
357
- /** Address as stored on the order: snake_case, mirroring public.addresses. */
358
- export interface ShippingAddressSnapshot {
359
- postal_code?: string
360
- street?: string
361
- number?: string
362
- complement?: string
363
- district?: string
364
- city?: string
365
- state?: string
366
- country?: string
367
- recipient?: string
368
- phone?: string
369
- label?: string
370
- raw?: string
371
- source?: string
372
- }
373
-
374
- export interface PlaceOrderInput {
375
- /** Tenant/store id. The Supabase provider falls back to the resolved shop tenant. */
376
- tenantId?: string
377
- /** Existing customer id (preferred when the session already resolved one). */
378
- customerId?: string
379
- /** Customer identity for find-or-create when {@link PlaceOrderInput.customerId} is absent. */
380
- customer?: { name?: string; email?: string }
381
- currency?: string
382
- notes?: string
383
- /** Discount code to validate + apply server-side (never trust a client total). */
384
- discountCode?: string
385
- /** Shipping cost from the store's shipping policy. Clamped to >= 0 server-side. */
386
- shippingTotal?: number
387
- /** Structured delivery address. Without it the address survives only as free
388
- * text in `notes`, which logistics cannot read. */
389
- shippingAddress?: ShippingAddressInput
390
- /** How the buyer is paying. Opens the ledger row in public.transactions. */
391
- paymentMethod?: PaymentMethodKind
392
- items: PlaceOrderLine[]
393
- }
394
-
395
- // ---------------------------------------------------------------------------
396
- // Customer
397
- // ---------------------------------------------------------------------------
398
-
399
- export interface ShopCustomer {
400
- id: string
401
- tenantId: string
402
- firstName: string
403
- lastName: string
404
- email: string | null
405
- phone: string | null
406
- notes: string | null
407
- ordersCount: number
408
- totalSpent: number
409
- createdAt: string
410
- updatedAt: string
411
- }
412
-
413
- export interface CreateCustomerInput {
414
- firstName: string
415
- lastName?: string
416
- email?: string
417
- phone?: string
418
- notes?: string
419
- }
420
-
421
- export interface UpdateCustomerInput {
422
- firstName?: string
423
- lastName?: string
424
- email?: string | null
425
- phone?: string | null
426
- notes?: string | null
427
- }
428
-
429
- export interface ListCustomersOptions {
430
- search?: string
431
- limit?: number
432
- offset?: number
433
- }
434
-
435
- /**
436
- * Input for {@link ShopProvider.resolveCustomer} — find-or-create a customer by
437
- * email and (on Supabase) link it to the authenticated user (auth.uid) so
438
- * "my orders" can be enforced by RLS. Runs server-side; the browser never
439
- * supplies the auth id.
440
- */
441
- export interface ResolveCustomerInput {
442
- email: string
443
- name?: string
444
- /** Tenant/store id. The Supabase provider falls back to the resolved shop tenant. */
445
- tenantId?: string
446
- }
447
-
448
- // ---------------------------------------------------------------------------
449
- // Discount
450
- // ---------------------------------------------------------------------------
451
-
452
- export type DiscountType = 'percentage' | 'fixed_amount' | 'free_shipping' | 'buy_x_get_y'
453
- export type DiscountMethod = 'code' | 'automatic'
454
- export type DiscountStatus = 'active' | 'expired' | 'scheduled' | 'draft'
455
-
456
- /** What subset of the cart a discount applies to. 'all' = order-wide (default). */
457
- export type DiscountScope = 'all' | 'products' | 'categories'
458
-
459
- export interface Discount {
460
- id: string
461
- tenantId: string
462
- title: string
463
- code: string | null
464
- type: DiscountType
465
- method: DiscountMethod
466
- value: number
467
- usageLimit: number | null
468
- oncePerCustomer: boolean
469
- /** Minimum order subtotal for the coupon to apply (pedido mínimo). Null = none. */
470
- minSubtotal: number | null
471
- /** Scope of the discount. 'products'/'categories' restrict it to the eligible
472
- * line items; the %/valor then applies to that eligible subtotal only. */
473
- appliesTo: DiscountScope
474
- /** When appliesTo='products', the eligible product ids. */
475
- productIds: string[]
476
- /** When appliesTo='categories', the eligible category ids. */
477
- categoryIds: string[]
478
- startsAt: string
479
- endsAt: string | null
480
- status: DiscountStatus
481
- timesUsed: number
482
- createdAt: string
483
- updatedAt: string
484
- }
485
-
486
- export interface CreateDiscountInput {
487
- title: string
488
- code?: string
489
- type: DiscountType
490
- method?: DiscountMethod
491
- value: number
492
- usageLimit?: number
493
- oncePerCustomer?: boolean
494
- minSubtotal?: number | null
495
- appliesTo?: DiscountScope
496
- productIds?: string[]
497
- categoryIds?: string[]
498
- startsAt?: string
499
- endsAt?: string
500
- status?: DiscountStatus
501
- }
502
-
503
- export interface UpdateDiscountInput {
504
- title?: string
505
- code?: string | null
506
- type?: DiscountType
507
- method?: DiscountMethod
508
- value?: number
509
- usageLimit?: number | null
510
- oncePerCustomer?: boolean
511
- minSubtotal?: number | null
512
- appliesTo?: DiscountScope
513
- productIds?: string[]
514
- categoryIds?: string[]
515
- startsAt?: string
516
- endsAt?: string | null
517
- status?: DiscountStatus
518
- }
519
-
520
- export interface ListDiscountsOptions {
521
- status?: DiscountStatus
522
- type?: DiscountType
523
- search?: string
524
- limit?: number
525
- offset?: number
526
- }
527
-
528
- // ---------------------------------------------------------------------------
529
- // Sales channels — the store's points of sale (Loja Online, WhatsApp, TikTok…).
530
- // A channel is per-tenant (the store IS the tenant). The 'online_store' channel
531
- // points at the merchant's fayz storefront; the rest are external links the
532
- // merchant maintains. Surfaced as a "Canais de venda" group in the admin nav.
533
- // ---------------------------------------------------------------------------
534
-
535
- export type SalesChannelKind =
536
- | 'online_store'
537
- | 'whatsapp'
538
- | 'instagram'
539
- | 'tiktok_shop'
540
- | 'marketplace'
541
- | 'physical'
542
- | 'custom'
543
-
544
- export interface SalesChannel {
545
- id: string
546
- tenantId: string
547
- kind: SalesChannelKind
548
- label: string
549
- /** External URL opened from the sidebar / channels page. Null while unconfigured
550
- * (e.g. the Loja Online channel before the storefront address is set). */
551
- url: string | null
552
- enabled: boolean
553
- /** Sidebar/list ordering (lower first). */
554
- position: number
555
- createdAt: string
556
- updatedAt: string
557
- }
558
-
559
- export interface CreateSalesChannelInput {
560
- kind: SalesChannelKind
561
- label: string
562
- url?: string | null
563
- enabled?: boolean
564
- position?: number
565
- }
566
-
567
- export interface UpdateSalesChannelInput {
568
- kind?: SalesChannelKind
569
- label?: string
570
- url?: string | null
571
- enabled?: boolean
572
- position?: number
573
- }
574
-
575
- // ---------------------------------------------------------------------------
576
- // Commerce primitives (FAY-1193) — provider-agnostic helpers for custom workflows
577
- // ---------------------------------------------------------------------------
578
-
579
- export interface DiscountValidation {
580
- valid: boolean
581
- code: string | null
582
- type: DiscountType | null
583
- /** Percentage points for 'percentage'; absolute amount for 'fixed_amount'. */
584
- value: number
585
- /** Machine-readable reason when invalid: not_found | expired | not_started | usage_limit | unsupported | empty */
586
- reason?: string
587
- }
588
-
589
- export interface InventoryLine {
590
- productId: string
591
- quantity: number
592
- }
593
-
594
- export interface InventoryIssue {
595
- productId: string
596
- name: string
597
- requested: number
598
- available: number
599
- }
600
-
601
- export interface InventoryCheck {
602
- ok: boolean
603
- issues: InventoryIssue[]
604
- }
605
-
606
- export interface CartTotalLine {
607
- productId: string
608
- name: string
609
- sku: string | null
610
- unitPrice: number
611
- quantity: number
612
- lineTotal: number
613
- }
614
-
615
- export interface CartTotals {
616
- lines: CartTotalLine[]
617
- subtotal: number
618
- discountTotal: number
619
- discountCode: string | null
620
- taxTotal: number
621
- shippingTotal: number
622
- total: number
623
- }
File without changes