@rovela-ai/sdk 0.1.24 → 0.1.26

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 (48) hide show
  1. package/dist/admin/components/ProductTable.d.ts.map +1 -1
  2. package/dist/admin/components/ProductTable.js +7 -2
  3. package/dist/admin/components/ProductTable.js.map +1 -1
  4. package/dist/admin/components/VariantManager.d.ts.map +1 -1
  5. package/dist/admin/components/VariantManager.js +4 -2
  6. package/dist/admin/components/VariantManager.js.map +1 -1
  7. package/dist/admin/server/admin-service.d.ts +3 -3
  8. package/dist/admin/server/admin-service.d.ts.map +1 -1
  9. package/dist/admin/server/admin-service.js +12 -22
  10. package/dist/admin/server/admin-service.js.map +1 -1
  11. package/dist/auth/server/customer-service.d.ts +2 -2
  12. package/dist/auth/server/customer-service.d.ts.map +1 -1
  13. package/dist/auth/server/customer-service.js +11 -20
  14. package/dist/auth/server/customer-service.js.map +1 -1
  15. package/dist/auth/server/password-reset-service.d.ts +1 -0
  16. package/dist/auth/server/password-reset-service.d.ts.map +1 -1
  17. package/dist/auth/server/password-reset-service.js +5 -7
  18. package/dist/auth/server/password-reset-service.js.map +1 -1
  19. package/dist/auth/server/verification-service.d.ts +1 -0
  20. package/dist/auth/server/verification-service.d.ts.map +1 -1
  21. package/dist/auth/server/verification-service.js +6 -9
  22. package/dist/auth/server/verification-service.js.map +1 -1
  23. package/dist/core/db/client.d.ts +2 -44
  24. package/dist/core/db/client.d.ts.map +1 -1
  25. package/dist/core/db/client.js +2 -106
  26. package/dist/core/db/client.js.map +1 -1
  27. package/dist/core/db/index.d.ts +1 -1
  28. package/dist/core/db/index.d.ts.map +1 -1
  29. package/dist/core/db/index.js +2 -2
  30. package/dist/core/db/index.js.map +1 -1
  31. package/dist/core/db/queries.d.ts +20 -37
  32. package/dist/core/db/queries.d.ts.map +1 -1
  33. package/dist/core/db/queries.js +69 -110
  34. package/dist/core/db/queries.js.map +1 -1
  35. package/dist/core/db/schema.d.ts +1 -137
  36. package/dist/core/db/schema.d.ts.map +1 -1
  37. package/dist/core/db/schema.js +6 -23
  38. package/dist/core/db/schema.js.map +1 -1
  39. package/dist/core/server/index.d.ts +1 -1
  40. package/dist/core/server/index.d.ts.map +1 -1
  41. package/dist/core/server/index.js +1 -3
  42. package/dist/core/server/index.js.map +1 -1
  43. package/dist/core/types.d.ts +0 -5
  44. package/dist/core/types.d.ts.map +1 -1
  45. package/dist/emails/config.d.ts.map +1 -1
  46. package/dist/emails/config.js +11 -17
  47. package/dist/emails/config.js.map +1 -1
  48. package/package.json +1 -1
@@ -1,20 +1,18 @@
1
1
  /**
2
2
  * @rovela/sdk/core/db/queries
3
3
  *
4
- * Type-safe query helpers with automatic tenant isolation
5
- * All queries are scoped to the current tenant
4
+ * Type-safe query helpers for e-commerce stores
5
+ * Each store has its own database (via Neon branches) - no tenant filtering needed
6
6
  */
7
7
  import { eq, and, desc, asc, ilike, sql, inArray } from 'drizzle-orm';
8
- import { getDb, getTenantId } from './client';
8
+ import { getDb } from './client';
9
9
  import * as schema from './schema';
10
10
  /**
11
11
  * Find products with filtering, sorting, and pagination
12
- * Automatically scoped to current tenant
13
12
  */
14
13
  export async function findProducts(options = {}) {
15
14
  const db = getDb();
16
- const tenantId = getTenantId();
17
- const conditions = [eq(schema.products.tenantId, tenantId)];
15
+ const conditions = [];
18
16
  if (options.categoryId) {
19
17
  conditions.push(eq(schema.products.categoryId, options.categoryId));
20
18
  }
@@ -43,7 +41,7 @@ export async function findProducts(options = {}) {
43
41
  const query = db
44
42
  .select()
45
43
  .from(schema.products)
46
- .where(and(...conditions))
44
+ .where(conditions.length > 0 ? and(...conditions) : undefined)
47
45
  .orderBy(orderBy);
48
46
  if (options.limit) {
49
47
  query.limit(options.limit);
@@ -58,11 +56,10 @@ export async function findProducts(options = {}) {
58
56
  */
59
57
  export async function findProductBySlug(slug) {
60
58
  const db = getDb();
61
- const tenantId = getTenantId();
62
59
  const result = await db
63
60
  .select()
64
61
  .from(schema.products)
65
- .where(and(eq(schema.products.tenantId, tenantId), eq(schema.products.slug, slug)))
62
+ .where(eq(schema.products.slug, slug))
66
63
  .limit(1);
67
64
  return result[0] || null;
68
65
  }
@@ -71,11 +68,10 @@ export async function findProductBySlug(slug) {
71
68
  */
72
69
  export async function findProductById(id) {
73
70
  const db = getDb();
74
- const tenantId = getTenantId();
75
71
  const result = await db
76
72
  .select()
77
73
  .from(schema.products)
78
- .where(and(eq(schema.products.tenantId, tenantId), eq(schema.products.id, id)))
74
+ .where(eq(schema.products.id, id))
79
75
  .limit(1);
80
76
  return result[0] || null;
81
77
  }
@@ -94,8 +90,7 @@ export async function findProductVariants(productId) {
94
90
  */
95
91
  export async function countProducts(options = {}) {
96
92
  const db = getDb();
97
- const tenantId = getTenantId();
98
- const conditions = [eq(schema.products.tenantId, tenantId)];
93
+ const conditions = [];
99
94
  if (options.categoryId) {
100
95
  conditions.push(eq(schema.products.categoryId, options.categoryId));
101
96
  }
@@ -108,22 +103,20 @@ export async function countProducts(options = {}) {
108
103
  const result = await db
109
104
  .select({ count: sql `count(*)` })
110
105
  .from(schema.products)
111
- .where(and(...conditions));
106
+ .where(conditions.length > 0 ? and(...conditions) : undefined);
112
107
  return Number(result[0]?.count || 0);
113
108
  }
114
109
  // =============================================================================
115
110
  // Categories
116
111
  // =============================================================================
117
112
  /**
118
- * Find all categories for the current tenant
113
+ * Find all categories
119
114
  */
120
115
  export async function findCategories() {
121
116
  const db = getDb();
122
- const tenantId = getTenantId();
123
117
  return db
124
118
  .select()
125
119
  .from(schema.categories)
126
- .where(eq(schema.categories.tenantId, tenantId))
127
120
  .orderBy(asc(schema.categories.order), asc(schema.categories.name));
128
121
  }
129
122
  /**
@@ -131,11 +124,10 @@ export async function findCategories() {
131
124
  */
132
125
  export async function findCategoryBySlug(slug) {
133
126
  const db = getDb();
134
- const tenantId = getTenantId();
135
127
  const result = await db
136
128
  .select()
137
129
  .from(schema.categories)
138
- .where(and(eq(schema.categories.tenantId, tenantId), eq(schema.categories.slug, slug)))
130
+ .where(eq(schema.categories.slug, slug))
139
131
  .limit(1);
140
132
  return result[0] || null;
141
133
  }
@@ -144,8 +136,7 @@ export async function findCategoryBySlug(slug) {
144
136
  */
145
137
  export async function findOrders(options = {}) {
146
138
  const db = getDb();
147
- const tenantId = getTenantId();
148
- const conditions = [eq(schema.orders.tenantId, tenantId)];
139
+ const conditions = [];
149
140
  if (options.status) {
150
141
  conditions.push(eq(schema.orders.status, options.status));
151
142
  }
@@ -155,7 +146,7 @@ export async function findOrders(options = {}) {
155
146
  const query = db
156
147
  .select()
157
148
  .from(schema.orders)
158
- .where(and(...conditions))
149
+ .where(conditions.length > 0 ? and(...conditions) : undefined)
159
150
  .orderBy(desc(schema.orders.createdAt));
160
151
  if (options.limit) {
161
152
  query.limit(options.limit);
@@ -170,11 +161,10 @@ export async function findOrders(options = {}) {
170
161
  */
171
162
  export async function findOrderById(id) {
172
163
  const db = getDb();
173
- const tenantId = getTenantId();
174
164
  const order = await db
175
165
  .select()
176
166
  .from(schema.orders)
177
- .where(and(eq(schema.orders.tenantId, tenantId), eq(schema.orders.id, id)))
167
+ .where(eq(schema.orders.id, id))
178
168
  .limit(1);
179
169
  if (!order[0])
180
170
  return null;
@@ -205,11 +195,10 @@ export async function findOrderItems(orderId) {
205
195
  */
206
196
  export async function findCustomerByEmail(email) {
207
197
  const db = getDb();
208
- const tenantId = getTenantId();
209
198
  const result = await db
210
199
  .select()
211
200
  .from(schema.customers)
212
- .where(and(eq(schema.customers.tenantId, tenantId), eq(schema.customers.email, email.toLowerCase())))
201
+ .where(eq(schema.customers.email, email.toLowerCase()))
213
202
  .limit(1);
214
203
  return result[0] || null;
215
204
  }
@@ -218,11 +207,10 @@ export async function findCustomerByEmail(email) {
218
207
  */
219
208
  export async function findCustomerById(id) {
220
209
  const db = getDb();
221
- const tenantId = getTenantId();
222
210
  const result = await db
223
211
  .select()
224
212
  .from(schema.customers)
225
- .where(and(eq(schema.customers.tenantId, tenantId), eq(schema.customers.id, id)))
213
+ .where(eq(schema.customers.id, id))
226
214
  .limit(1);
227
215
  return result[0] || null;
228
216
  }
@@ -231,15 +219,14 @@ export async function findCustomerById(id) {
231
219
  */
232
220
  export async function findCustomers(options = {}) {
233
221
  const db = getDb();
234
- const tenantId = getTenantId();
235
- const conditions = [eq(schema.customers.tenantId, tenantId)];
222
+ const conditions = [];
236
223
  if (options.search) {
237
224
  conditions.push(ilike(schema.customers.email, `%${options.search}%`));
238
225
  }
239
226
  const query = db
240
227
  .select()
241
228
  .from(schema.customers)
242
- .where(and(...conditions))
229
+ .where(conditions.length > 0 ? and(...conditions) : undefined)
243
230
  .orderBy(desc(schema.customers.createdAt));
244
231
  if (options.limit) {
245
232
  query.limit(options.limit);
@@ -257,11 +244,10 @@ export async function findCustomers(options = {}) {
257
244
  */
258
245
  export async function findAdminByEmail(email) {
259
246
  const db = getDb();
260
- const tenantId = getTenantId();
261
247
  const result = await db
262
248
  .select()
263
249
  .from(schema.storeAdmins)
264
- .where(and(eq(schema.storeAdmins.tenantId, tenantId), eq(schema.storeAdmins.email, email.toLowerCase())))
250
+ .where(eq(schema.storeAdmins.email, email.toLowerCase()))
265
251
  .limit(1);
266
252
  return result[0] || null;
267
253
  }
@@ -273,28 +259,25 @@ export async function findAdminByEmail(email) {
273
259
  */
274
260
  export async function getStoreStats() {
275
261
  const db = getDb();
276
- const tenantId = getTenantId();
277
262
  const [productCount, orderCount, customerCount, revenue] = await Promise.all([
278
263
  // Total products
279
264
  db
280
265
  .select({ count: sql `count(*)` })
281
266
  .from(schema.products)
282
- .where(and(eq(schema.products.tenantId, tenantId), eq(schema.products.status, 'active'))),
267
+ .where(eq(schema.products.status, 'active')),
283
268
  // Total orders
284
269
  db
285
270
  .select({ count: sql `count(*)` })
286
- .from(schema.orders)
287
- .where(eq(schema.orders.tenantId, tenantId)),
271
+ .from(schema.orders),
288
272
  // Total customers
289
273
  db
290
274
  .select({ count: sql `count(*)` })
291
- .from(schema.customers)
292
- .where(eq(schema.customers.tenantId, tenantId)),
275
+ .from(schema.customers),
293
276
  // Total revenue (paid orders only)
294
277
  db
295
278
  .select({ total: sql `COALESCE(SUM(total), 0)` })
296
279
  .from(schema.orders)
297
- .where(and(eq(schema.orders.tenantId, tenantId), inArray(schema.orders.status, ['paid', 'shipped', 'delivered']))),
280
+ .where(inArray(schema.orders.status, ['paid', 'shipped', 'delivered'])),
298
281
  ]);
299
282
  return {
300
283
  products: Number(productCount[0]?.count || 0),
@@ -308,7 +291,6 @@ export async function getStoreStats() {
308
291
  */
309
292
  export async function getLowStockProducts(threshold = 10) {
310
293
  const db = getDb();
311
- const tenantId = getTenantId();
312
294
  // Get products with variants that have low stock
313
295
  const lowStockVariants = await db
314
296
  .select({
@@ -317,7 +299,7 @@ export async function getLowStockProducts(threshold = 10) {
317
299
  })
318
300
  .from(schema.productVariants)
319
301
  .innerJoin(schema.products, eq(schema.productVariants.productId, schema.products.id))
320
- .where(and(eq(schema.products.tenantId, tenantId), eq(schema.products.status, 'active'), sql `${schema.productVariants.inventory} < ${threshold}`))
302
+ .where(and(eq(schema.products.status, 'active'), sql `${schema.productVariants.inventory} < ${threshold}`))
321
303
  .orderBy(asc(schema.productVariants.inventory));
322
304
  return lowStockVariants;
323
305
  }
@@ -326,11 +308,9 @@ export async function getLowStockProducts(threshold = 10) {
326
308
  */
327
309
  export async function getRecentOrders(limit = 5) {
328
310
  const db = getDb();
329
- const tenantId = getTenantId();
330
311
  return db
331
312
  .select()
332
313
  .from(schema.orders)
333
- .where(eq(schema.orders.tenantId, tenantId))
334
314
  .orderBy(desc(schema.orders.createdAt))
335
315
  .limit(limit);
336
316
  }
@@ -342,10 +322,9 @@ export async function getRecentOrders(limit = 5) {
342
322
  */
343
323
  export async function createOrder(data) {
344
324
  const db = getDb();
345
- const tenantId = getTenantId();
346
325
  const [order] = await db
347
326
  .insert(schema.orders)
348
- .values({ ...data, tenantId })
327
+ .values(data)
349
328
  .returning();
350
329
  return order;
351
330
  }
@@ -364,11 +343,10 @@ export async function createOrderItems(items) {
364
343
  */
365
344
  export async function updateOrderStatus(orderId, status) {
366
345
  const db = getDb();
367
- const tenantId = getTenantId();
368
346
  const [order] = await db
369
347
  .update(schema.orders)
370
348
  .set({ status, updatedAt: new Date() })
371
- .where(and(eq(schema.orders.tenantId, tenantId), eq(schema.orders.id, orderId)))
349
+ .where(eq(schema.orders.id, orderId))
372
350
  .returning();
373
351
  return order || null;
374
352
  }
@@ -378,11 +356,10 @@ export async function updateOrderStatus(orderId, status) {
378
356
  */
379
357
  export async function findOrderByPaymentIntent(paymentIntentId) {
380
358
  const db = getDb();
381
- const tenantId = getTenantId();
382
359
  const [order] = await db
383
360
  .select()
384
361
  .from(schema.orders)
385
- .where(and(eq(schema.orders.tenantId, tenantId), eq(schema.orders.stripePaymentIntentId, paymentIntentId)))
362
+ .where(eq(schema.orders.stripePaymentIntentId, paymentIntentId))
386
363
  .limit(1);
387
364
  return order || null;
388
365
  }
@@ -394,10 +371,9 @@ export async function findOrderByPaymentIntent(paymentIntentId) {
394
371
  */
395
372
  export async function createProduct(data) {
396
373
  const db = getDb();
397
- const tenantId = getTenantId();
398
374
  const [product] = await db
399
375
  .insert(schema.products)
400
- .values({ ...data, tenantId })
376
+ .values(data)
401
377
  .returning();
402
378
  return product;
403
379
  }
@@ -406,11 +382,10 @@ export async function createProduct(data) {
406
382
  */
407
383
  export async function updateProduct(id, data) {
408
384
  const db = getDb();
409
- const tenantId = getTenantId();
410
385
  const [product] = await db
411
386
  .update(schema.products)
412
387
  .set({ ...data, updatedAt: new Date() })
413
- .where(and(eq(schema.products.tenantId, tenantId), eq(schema.products.id, id)))
388
+ .where(eq(schema.products.id, id))
414
389
  .returning();
415
390
  return product || null;
416
391
  }
@@ -430,10 +405,9 @@ export async function deleteProduct(id) {
430
405
  */
431
406
  export async function hardDeleteProduct(id) {
432
407
  const db = getDb();
433
- const tenantId = getTenantId();
434
408
  const result = await db
435
409
  .delete(schema.products)
436
- .where(and(eq(schema.products.tenantId, tenantId), eq(schema.products.id, id)))
410
+ .where(eq(schema.products.id, id))
437
411
  .returning({ id: schema.products.id });
438
412
  return result.length > 0;
439
413
  }
@@ -504,11 +478,10 @@ export async function findVariantById(id) {
504
478
  */
505
479
  export async function findCategoryById(id) {
506
480
  const db = getDb();
507
- const tenantId = getTenantId();
508
481
  const [category] = await db
509
482
  .select()
510
483
  .from(schema.categories)
511
- .where(and(eq(schema.categories.tenantId, tenantId), eq(schema.categories.id, id)))
484
+ .where(eq(schema.categories.id, id))
512
485
  .limit(1);
513
486
  return category || null;
514
487
  }
@@ -517,10 +490,9 @@ export async function findCategoryById(id) {
517
490
  */
518
491
  export async function createCategory(data) {
519
492
  const db = getDb();
520
- const tenantId = getTenantId();
521
493
  const [category] = await db
522
494
  .insert(schema.categories)
523
- .values({ ...data, tenantId })
495
+ .values(data)
524
496
  .returning();
525
497
  return category;
526
498
  }
@@ -529,11 +501,10 @@ export async function createCategory(data) {
529
501
  */
530
502
  export async function updateCategory(id, data) {
531
503
  const db = getDb();
532
- const tenantId = getTenantId();
533
504
  const [category] = await db
534
505
  .update(schema.categories)
535
506
  .set(data)
536
- .where(and(eq(schema.categories.tenantId, tenantId), eq(schema.categories.id, id)))
507
+ .where(eq(schema.categories.id, id))
537
508
  .returning();
538
509
  return category || null;
539
510
  }
@@ -542,42 +513,38 @@ export async function updateCategory(id, data) {
542
513
  */
543
514
  export async function deleteCategory(id) {
544
515
  const db = getDb();
545
- const tenantId = getTenantId();
546
516
  const result = await db
547
517
  .delete(schema.categories)
548
- .where(and(eq(schema.categories.tenantId, tenantId), eq(schema.categories.id, id)))
518
+ .where(eq(schema.categories.id, id))
549
519
  .returning({ id: schema.categories.id });
550
520
  return result.length > 0;
551
521
  }
552
522
  /**
553
- * Count categories for the current tenant
523
+ * Count categories
554
524
  */
555
525
  export async function countCategories() {
556
526
  const db = getDb();
557
- const tenantId = getTenantId();
558
527
  const result = await db
559
528
  .select({ count: sql `count(*)` })
560
- .from(schema.categories)
561
- .where(eq(schema.categories.tenantId, tenantId));
529
+ .from(schema.categories);
562
530
  return Number(result[0]?.count || 0);
563
531
  }
564
532
  // =============================================================================
565
533
  // Customer Queries (for admin module)
566
534
  // =============================================================================
567
535
  /**
568
- * Count customers for the current tenant with optional search
536
+ * Count customers with optional search
569
537
  */
570
538
  export async function countCustomers(options = {}) {
571
539
  const db = getDb();
572
- const tenantId = getTenantId();
573
- const conditions = [eq(schema.customers.tenantId, tenantId)];
540
+ const conditions = [];
574
541
  if (options.search) {
575
542
  conditions.push(ilike(schema.customers.email, `%${options.search}%`));
576
543
  }
577
544
  const result = await db
578
545
  .select({ count: sql `count(*)` })
579
546
  .from(schema.customers)
580
- .where(and(...conditions));
547
+ .where(conditions.length > 0 ? and(...conditions) : undefined);
581
548
  return Number(result[0]?.count || 0);
582
549
  }
583
550
  /**
@@ -585,11 +552,10 @@ export async function countCustomers(options = {}) {
585
552
  */
586
553
  export async function findCustomerOrders(customerId) {
587
554
  const db = getDb();
588
- const tenantId = getTenantId();
589
555
  return db
590
556
  .select()
591
557
  .from(schema.orders)
592
- .where(and(eq(schema.orders.tenantId, tenantId), eq(schema.orders.customerId, customerId)))
558
+ .where(eq(schema.orders.customerId, customerId))
593
559
  .orderBy(desc(schema.orders.createdAt));
594
560
  }
595
561
  /**
@@ -609,7 +575,6 @@ export async function findCustomerOrders(customerId) {
609
575
  */
610
576
  export async function deleteCustomer(id) {
611
577
  const db = getDb();
612
- const tenantId = getTenantId();
613
578
  // Anonymize customer data instead of hard delete
614
579
  const result = await db
615
580
  .update(schema.customers)
@@ -620,7 +585,7 @@ export async function deleteCustomer(id) {
620
585
  emailVerified: null,
621
586
  stripeCustomerId: null,
622
587
  })
623
- .where(and(eq(schema.customers.tenantId, tenantId), eq(schema.customers.id, id)))
588
+ .where(eq(schema.customers.id, id))
624
589
  .returning({ id: schema.customers.id });
625
590
  return result.length > 0;
626
591
  }
@@ -632,15 +597,14 @@ export async function deleteCustomer(id) {
632
597
  */
633
598
  export async function countOrders(options = {}) {
634
599
  const db = getDb();
635
- const tenantId = getTenantId();
636
- const conditions = [eq(schema.orders.tenantId, tenantId)];
600
+ const conditions = [];
637
601
  if (options.status) {
638
602
  conditions.push(eq(schema.orders.status, options.status));
639
603
  }
640
604
  const result = await db
641
605
  .select({ count: sql `count(*)` })
642
606
  .from(schema.orders)
643
- .where(and(...conditions));
607
+ .where(conditions.length > 0 ? and(...conditions) : undefined);
644
608
  return Number(result[0]?.count || 0);
645
609
  }
646
610
  /**
@@ -648,7 +612,6 @@ export async function countOrders(options = {}) {
648
612
  */
649
613
  export async function getRevenueByPeriod(days) {
650
614
  const db = getDb();
651
- const tenantId = getTenantId();
652
615
  const startDate = new Date();
653
616
  startDate.setDate(startDate.getDate() - days);
654
617
  const result = await db
@@ -657,7 +620,7 @@ export async function getRevenueByPeriod(days) {
657
620
  revenue: sql `COALESCE(SUM(${schema.orders.total}), 0)`,
658
621
  })
659
622
  .from(schema.orders)
660
- .where(and(eq(schema.orders.tenantId, tenantId), inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), sql `${schema.orders.createdAt} >= ${startDate.toISOString()}`))
623
+ .where(and(inArray(schema.orders.status, ['paid', 'shipped', 'delivered']), sql `${schema.orders.createdAt} >= ${startDate.toISOString()}`))
661
624
  .groupBy(sql `DATE(${schema.orders.createdAt})`)
662
625
  .orderBy(sql `DATE(${schema.orders.createdAt})`);
663
626
  return result.map((r) => ({
@@ -670,14 +633,12 @@ export async function getRevenueByPeriod(days) {
670
633
  */
671
634
  export async function getOrdersByStatus() {
672
635
  const db = getDb();
673
- const tenantId = getTenantId();
674
636
  const result = await db
675
637
  .select({
676
638
  status: schema.orders.status,
677
639
  count: sql `count(*)`,
678
640
  })
679
641
  .from(schema.orders)
680
- .where(eq(schema.orders.tenantId, tenantId))
681
642
  .groupBy(schema.orders.status);
682
643
  return result.map((r) => ({
683
644
  status: r.status,
@@ -685,16 +646,15 @@ export async function getOrdersByStatus() {
685
646
  }));
686
647
  }
687
648
  /**
688
- * Find store settings for the current tenant.
649
+ * Find store settings.
689
650
  * Returns null if no settings exist (first time access).
651
+ * Each store has only one settings row.
690
652
  */
691
653
  export async function findSettings() {
692
654
  const db = getDb();
693
- const tenantId = getTenantId();
694
655
  const [settings] = await db
695
656
  .select()
696
657
  .from(schema.storeSettings)
697
- .where(eq(schema.storeSettings.tenantId, tenantId))
698
658
  .limit(1);
699
659
  if (!settings)
700
660
  return null;
@@ -712,15 +672,17 @@ export async function findSettings() {
712
672
  };
713
673
  }
714
674
  /**
715
- * Upsert (create or update) store settings for the current tenant.
716
- * Uses ON CONFLICT to update if row already exists.
675
+ * Upsert (create or update) store settings.
676
+ * Each store has only one settings row.
717
677
  */
718
678
  export async function upsertSettings(data) {
719
679
  const db = getDb();
720
- const tenantId = getTenantId();
721
- // Build the values object
680
+ // Check if settings exist
681
+ const existing = await db
682
+ .select({ id: schema.storeSettings.id })
683
+ .from(schema.storeSettings)
684
+ .limit(1);
722
685
  const values = {
723
- tenantId,
724
686
  storeName: data.storeName ?? undefined,
725
687
  storeEmail: data.storeEmail ?? undefined,
726
688
  storeCurrency: data.storeCurrency ?? undefined,
@@ -735,25 +697,22 @@ export async function upsertSettings(data) {
735
697
  : undefined,
736
698
  updatedAt: new Date(),
737
699
  };
738
- // Use raw SQL for upsert since Drizzle's onConflict syntax varies
739
- const [result] = await db
740
- .insert(schema.storeSettings)
741
- .values(values)
742
- .onConflictDoUpdate({
743
- target: schema.storeSettings.tenantId,
744
- set: {
745
- storeName: sql `COALESCE(EXCLUDED.store_name, ${schema.storeSettings.storeName})`,
746
- storeEmail: sql `COALESCE(EXCLUDED.store_email, ${schema.storeSettings.storeEmail})`,
747
- storeCurrency: sql `COALESCE(EXCLUDED.store_currency, ${schema.storeSettings.storeCurrency})`,
748
- storeTimezone: sql `COALESCE(EXCLUDED.store_timezone, ${schema.storeSettings.storeTimezone})`,
749
- taxEnabled: sql `COALESCE(EXCLUDED.tax_enabled, ${schema.storeSettings.taxEnabled})`,
750
- taxRate: sql `COALESCE(EXCLUDED.tax_rate, ${schema.storeSettings.taxRate})`,
751
- shippingEnabled: sql `COALESCE(EXCLUDED.shipping_enabled, ${schema.storeSettings.shippingEnabled})`,
752
- freeShippingThreshold: sql `COALESCE(EXCLUDED.free_shipping_threshold, ${schema.storeSettings.freeShippingThreshold})`,
753
- updatedAt: new Date(),
754
- },
755
- })
756
- .returning();
700
+ let result;
701
+ if (existing.length > 0) {
702
+ // Update existing
703
+ [result] = await db
704
+ .update(schema.storeSettings)
705
+ .set(values)
706
+ .where(eq(schema.storeSettings.id, existing[0].id))
707
+ .returning();
708
+ }
709
+ else {
710
+ // Insert new
711
+ [result] = await db
712
+ .insert(schema.storeSettings)
713
+ .values(values)
714
+ .returning();
715
+ }
757
716
  return {
758
717
  storeName: result.storeName,
759
718
  storeEmail: result.storeEmail,