@stacksjs/defaults 0.70.355 → 0.70.356

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 (155) hide show
  1. package/ai/skills/stacks-email/SKILL.md +38 -1
  2. package/app/Actions/ContactAction.ts +2 -2
  3. package/app/Actions/Dashboard/Analytics/EventAnalyticsAction.ts +2 -3
  4. package/app/Actions/Dashboard/Analytics/MarketingAnalyticsAction.ts +2 -3
  5. package/app/Actions/Dashboard/Analytics/SalesAnalyticsAction.ts +2 -3
  6. package/app/Actions/Dashboard/Analytics/WebAnalyticsAction.ts +9 -3
  7. package/app/Actions/Dashboard/Auth/MeAction.ts +4 -7
  8. package/app/Actions/Dashboard/Buddy/BuddyChatAction.ts +2 -3
  9. package/app/Actions/Dashboard/Cloud/CloudIndexAction.ts +8 -1
  10. package/app/Actions/Dashboard/Cloud/ServerlessIndexAction.ts +15 -8
  11. package/app/Actions/Dashboard/Commerce/CommerceCategoriesAction.ts +2 -4
  12. package/app/Actions/Dashboard/Commerce/CommerceCouponsAction.ts +2 -4
  13. package/app/Actions/Dashboard/Commerce/CommerceCustomersAction.ts +2 -4
  14. package/app/Actions/Dashboard/Commerce/CommerceDashboardAction.ts +2 -4
  15. package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +2 -4
  16. package/app/Actions/Dashboard/Commerce/CommerceGiftCardsAction.ts +2 -4
  17. package/app/Actions/Dashboard/Commerce/CommerceOrdersAction.ts +2 -4
  18. package/app/Actions/Dashboard/Commerce/CommercePaymentsAction.ts +2 -4
  19. package/app/Actions/Dashboard/Commerce/CommercePosAction.ts +2 -4
  20. package/app/Actions/Dashboard/Commerce/CommercePosCheckoutAction.ts +75 -61
  21. package/app/Actions/Dashboard/Commerce/CommercePrintDevicesAction.ts +2 -4
  22. package/app/Actions/Dashboard/Commerce/CommercePrintLogsAction.ts +2 -4
  23. package/app/Actions/Dashboard/Commerce/CommerceProductDetailAction.ts +3 -4
  24. package/app/Actions/Dashboard/Commerce/CommerceProductsAction.ts +2 -4
  25. package/app/Actions/Dashboard/Commerce/CommerceTaxesAction.ts +2 -4
  26. package/app/Actions/Dashboard/Commerce/DeliveryRouteIndexAction.ts +2 -4
  27. package/app/Actions/Dashboard/Commerce/DigitalDeliveryIndexAction.ts +2 -4
  28. package/app/Actions/Dashboard/Commerce/DriverIndexAction.ts +2 -4
  29. package/app/Actions/Dashboard/Commerce/LicenseKeyIndexAction.ts +2 -4
  30. package/app/Actions/Dashboard/Commerce/LicenseKeyOptionsAction.ts +2 -4
  31. package/app/Actions/Dashboard/Commerce/ManufacturerIndexAction.ts +2 -4
  32. package/app/Actions/Dashboard/Commerce/ProductUnitIndexAction.ts +2 -4
  33. package/app/Actions/Dashboard/Commerce/ProductVariantIndexAction.ts +2 -4
  34. package/app/Actions/Dashboard/Commerce/ProductWaitlistIndexAction.ts +2 -4
  35. package/app/Actions/Dashboard/Commerce/RestaurantWaitlistIndexAction.ts +2 -4
  36. package/app/Actions/Dashboard/Commerce/ReviewIndexAction.ts +2 -4
  37. package/app/Actions/Dashboard/Commerce/ShippingMethodIndexAction.ts +2 -4
  38. package/app/Actions/Dashboard/Commerce/ShippingRateIndexAction.ts +2 -4
  39. package/app/Actions/Dashboard/Commerce/ShippingZoneIndexAction.ts +2 -4
  40. package/app/Actions/Dashboard/DashboardActivityAction.ts +2 -5
  41. package/app/Actions/Dashboard/Data/ActivityIndexAction.ts +2 -5
  42. package/app/Actions/Dashboard/Data/SubscriberIndexAction.ts +2 -5
  43. package/app/Actions/Dashboard/Data/TeamIndexAction.ts +2 -5
  44. package/app/Actions/Dashboard/Data/UserIndexAction.ts +2 -5
  45. package/app/Actions/Dashboard/Deployments/CreateDeployment.ts +23 -19
  46. package/app/Actions/Dashboard/Deployments/GetAverageDeploymentTime.ts +8 -2
  47. package/app/Actions/Dashboard/Deployments/GetDeployScript.ts +3 -6
  48. package/app/Actions/Dashboard/Deployments/GetDeployment.ts +4 -5
  49. package/app/Actions/Dashboard/Deployments/GetDeploymentCount.ts +7 -1
  50. package/app/Actions/Dashboard/Deployments/GetDeploymentLiveTerminalOutput.ts +10 -9
  51. package/app/Actions/Dashboard/Deployments/GetDeployments.ts +2 -4
  52. package/app/Actions/Dashboard/Deployments/GetRecentDeployments.ts +8 -2
  53. package/app/Actions/Dashboard/Deployments/UpdateDeployScript.ts +18 -5
  54. package/app/Actions/Dashboard/Email/CapturedMailIndexAction.ts +2 -4
  55. package/app/Actions/Dashboard/Email/CapturedMailShowAction.ts +3 -4
  56. package/app/Actions/Dashboard/Infrastructure/InsightsAction.ts +15 -14
  57. package/app/Actions/Dashboard/Infrastructure/LogIndexAction.ts +2 -8
  58. package/app/Actions/Dashboard/Jobs/JobIndexAction.ts +2 -4
  59. package/app/Actions/Dashboard/Jobs/JobShowAction.ts +13 -8
  60. package/app/Actions/Dashboard/Jobs/JobStatsAction.ts +2 -4
  61. package/app/Actions/Dashboard/Kanban/BoardDestroyAction.ts +2 -3
  62. package/app/Actions/Dashboard/Kanban/BoardShowAction.ts +2 -3
  63. package/app/Actions/Dashboard/Kanban/BoardStoreAction.ts +2 -3
  64. package/app/Actions/Dashboard/Kanban/BoardUpdateAction.ts +2 -3
  65. package/app/Actions/Dashboard/Kanban/BoardsIndexAction.ts +2 -3
  66. package/app/Actions/Dashboard/Kanban/BoardsReorderAction.ts +2 -3
  67. package/app/Actions/Dashboard/Kanban/CardAssigneesSyncAction.ts +2 -3
  68. package/app/Actions/Dashboard/Kanban/CardCommentDestroyAction.ts +2 -3
  69. package/app/Actions/Dashboard/Kanban/CardCommentStoreAction.ts +2 -3
  70. package/app/Actions/Dashboard/Kanban/CardCommentUpdateAction.ts +2 -3
  71. package/app/Actions/Dashboard/Kanban/CardDestroyAction.ts +2 -3
  72. package/app/Actions/Dashboard/Kanban/CardLabelsSyncAction.ts +2 -3
  73. package/app/Actions/Dashboard/Kanban/CardShowAction.ts +2 -3
  74. package/app/Actions/Dashboard/Kanban/CardStoreAction.ts +2 -3
  75. package/app/Actions/Dashboard/Kanban/CardUpdateAction.ts +2 -3
  76. package/app/Actions/Dashboard/Kanban/CardsReorderAction.ts +2 -3
  77. package/app/Actions/Dashboard/Kanban/ColumnDestroyAction.ts +2 -3
  78. package/app/Actions/Dashboard/Kanban/ColumnStoreAction.ts +2 -3
  79. package/app/Actions/Dashboard/Kanban/ColumnUpdateAction.ts +2 -3
  80. package/app/Actions/Dashboard/Kanban/ColumnsReorderAction.ts +2 -3
  81. package/app/Actions/Dashboard/Kanban/LabelDestroyAction.ts +2 -3
  82. package/app/Actions/Dashboard/Kanban/LabelStoreAction.ts +2 -3
  83. package/app/Actions/Dashboard/Kanban/LabelUpdateAction.ts +2 -3
  84. package/app/Actions/Dashboard/Kanban/UsersListAction.ts +2 -3
  85. package/app/Actions/Dashboard/Kanban/kanban-response.ts +5 -0
  86. package/app/Actions/Dashboard/Library/CreateComponent.ts +15 -6
  87. package/app/Actions/Dashboard/Library/CreateFunction.ts +15 -6
  88. package/app/Actions/Dashboard/Library/DependencyIndexAction.ts +88 -77
  89. package/app/Actions/Dashboard/Library/GetAverageReleaseTime.ts +21 -15
  90. package/app/Actions/Dashboard/Library/GetComponents.ts +14 -7
  91. package/app/Actions/Dashboard/Library/GetDownloadCount.ts +14 -5
  92. package/app/Actions/Dashboard/Library/GetFunctions.ts +12 -5
  93. package/app/Actions/Dashboard/Library/GetReleaseCount.ts +14 -5
  94. package/app/Actions/Dashboard/Library/GetReleases.ts +17 -10
  95. package/app/Actions/Dashboard/Library/PackageIndexAction.ts +14 -7
  96. package/app/Actions/Dashboard/Models/ModelDestroyAction.ts +7 -5
  97. package/app/Actions/Dashboard/Models/ModelShowAction.ts +82 -174
  98. package/app/Actions/Dashboard/Models/ModelStoreAction.ts +6 -4
  99. package/app/Actions/Dashboard/Models/ModelUpdateAction.ts +9 -7
  100. package/app/Actions/Dashboard/Models/ModelsIndexAction.ts +47 -17
  101. package/app/Actions/Dashboard/Models/model-write.ts +20 -5
  102. package/app/Actions/Dashboard/Notifications/NotificationDeliveryHistoryAction.ts +46 -36
  103. package/app/Actions/Dashboard/Notifications/NotificationDeliveryIndexAction.ts +14 -6
  104. package/app/Actions/Dashboard/Notifications/NotificationDeliveryOverviewAction.ts +96 -84
  105. package/app/Actions/Dashboard/Notifications/NotificationDeliveryRetryAction.ts +34 -21
  106. package/app/Actions/Dashboard/Queries/QueryDashboardAction.ts +2 -4
  107. package/app/Actions/Dashboard/Queries/QueryShowAction.ts +2 -3
  108. package/app/Actions/Dashboard/Queue/QueueStatsAction.ts +2 -4
  109. package/app/Actions/Dashboard/Queue/QueueWorkersAction.ts +2 -4
  110. package/app/Actions/Dashboard/Rbac/PermissionDestroyAction.ts +2 -2
  111. package/app/Actions/Dashboard/Rbac/PermissionStoreAction.ts +2 -2
  112. package/app/Actions/Dashboard/Rbac/PermissionsIndexAction.ts +2 -3
  113. package/app/Actions/Dashboard/Rbac/RoleDestroyAction.ts +2 -2
  114. package/app/Actions/Dashboard/Rbac/RolePermissionsShowAction.ts +2 -2
  115. package/app/Actions/Dashboard/Rbac/RolePermissionsSyncAction.ts +2 -6
  116. package/app/Actions/Dashboard/Rbac/RoleStoreAction.ts +2 -2
  117. package/app/Actions/Dashboard/Rbac/RolesIndexAction.ts +4 -6
  118. package/app/Actions/Dashboard/Rbac/UserRolesShowAction.ts +2 -2
  119. package/app/Actions/Dashboard/Rbac/UserRolesSyncAction.ts +2 -9
  120. package/app/Actions/Dashboard/Rbac/UsersListAction.ts +2 -3
  121. package/app/Actions/Dashboard/Rbac/rbac-response.ts +10 -0
  122. package/app/Actions/Dashboard/Realtime/RealtimeStatsAction.ts +2 -4
  123. package/app/Actions/Dashboard/Search/GlobalSearchAction.ts +68 -55
  124. package/app/Actions/Dashboard/Teams/TeamInvitationDestroyAction.ts +34 -16
  125. package/app/Actions/Dashboard/Teams/TeamInvitationResendAction.ts +52 -29
  126. package/app/Actions/Dashboard/Teams/TeamInviteAction.ts +102 -71
  127. package/app/Actions/Dashboard/Teams/TeamMemberDestroyAction.ts +36 -17
  128. package/app/Actions/Dashboard/Teams/TeamMemberUpdateAction.ts +39 -26
  129. package/app/Actions/Dashboard/Teams/TeamPeopleIndexAction.ts +71 -58
  130. package/app/Actions/Dashboard/Teams/team-invitation-delivery.ts +29 -7
  131. package/app/Actions/Dashboard/Teams/team-member-count.ts +4 -2
  132. package/app/Actions/Dashboard/Teams/team-records.test.ts +2 -0
  133. package/app/Actions/Dashboard/Teams/team-records.ts +2 -0
  134. package/app/Actions/Dashboard/dashboard-response.ts +16 -0
  135. package/app/Actions/SendWelcomeEmail.ts +1 -1
  136. package/app/Actions/Teams/AcceptInvitationAction.ts +74 -51
  137. package/app/Actions/Teams/ShowInvitationAction.ts +21 -14
  138. package/app/Actions/Teams/team-response.ts +23 -0
  139. package/app/Mail/OrderConfirmation.ts +1 -1
  140. package/app/Mail/SubscriptionConfirmation.ts +1 -1
  141. package/app/Mail/TeamInvitation.ts +1 -1
  142. package/app/Models/EmailIdempotency.ts +64 -0
  143. package/app/Models/EmailSuppression.ts +52 -0
  144. package/app/Models/EmailWebhookEvent.ts +51 -0
  145. package/app/Models/TeamInvitation.ts +13 -0
  146. package/functions/data.ts +0 -1
  147. package/functions/jobs.ts +0 -1
  148. package/ide/vscode/package.json +1 -1
  149. package/package.json +1 -1
  150. package/resources/components/Dashboard/Data/DataRecords.stx +0 -4
  151. package/resources/components/Dashboard/Jobs/JobDetail.stx +3 -2
  152. package/resources/components/Dashboard/Models/ModelRecordsDashboard.stx +7 -13
  153. package/resources/components/Dashboard/Models/ModelsOverview.stx +1 -1
  154. package/views/dashboard/.discovered-models.json +30 -0
  155. package/views/dashboard/stores/auth.ts +15 -14
@@ -6,6 +6,7 @@ import { config } from '@stacksjs/config'
6
6
  import { log } from '@stacksjs/logging'
7
7
  import { Category, Customer, Manufacturer, OrderItem, Payment, Product, TaxRate } from '@stacksjs/orm'
8
8
  import { response } from '@stacksjs/router'
9
+ import { dashboardOperationalError } from '../dashboard-response'
9
10
  import {
10
11
  calculateCommercePosSale,
11
12
  CommercePosAvailabilityError,
@@ -165,7 +166,13 @@ export default new Action({
165
166
  if (idempotencyKey.length < 8 || idempotencyKey.length > 255)
166
167
  return response.json({ message: 'A valid checkout idempotency key is required.' }, 422)
167
168
 
168
- const existing = await orders.findOrderByIdempotencyKey(idempotencyKey)
169
+ let existing
170
+ try {
171
+ existing = await orders.findOrderByIdempotencyKey(idempotencyKey)
172
+ }
173
+ catch (error) {
174
+ return dashboardOperationalError(error, 'Checkout records could not be read.', 'CommercePosCheckoutAction')
175
+ }
169
176
  if (existing) {
170
177
  try {
171
178
  return {
@@ -175,9 +182,7 @@ export default new Action({
175
182
  }
176
183
  }
177
184
  catch (error) {
178
- return response.json({
179
- message: error instanceof Error ? error.message : 'Existing receipt records could not be read.',
180
- }, 503)
185
+ return dashboardOperationalError(error, 'Existing receipt records could not be read.', 'CommercePosCheckoutAction')
181
186
  }
182
187
  }
183
188
 
@@ -211,7 +216,13 @@ export default new Action({
211
216
  : Number.NaN
212
217
  if (customerId && (!Number.isInteger(customerId) || customerId <= 0))
213
218
  return response.json({ message: 'Select a valid customer.' }, 422)
214
- const customer = customerId ? await Customer.find(customerId) : null
219
+ let customer
220
+ try {
221
+ customer = customerId ? await Customer.find(customerId) : null
222
+ }
223
+ catch (error) {
224
+ return dashboardOperationalError(error, 'Customer records could not be read.', 'CommercePosCheckoutAction')
225
+ }
215
226
  if (customerId && !customer)
216
227
  return response.json({ message: 'The selected customer no longer exists.' }, 422)
217
228
 
@@ -227,17 +238,18 @@ export default new Action({
227
238
  return response.json({ message: 'Order instructions must be 1,000 characters or fewer.' }, 422)
228
239
 
229
240
  const productIds = parsed.lines.map(line => line.productId)
230
- const [productRows, categories, manufacturers, taxRates] = await Promise.all([
231
- Product.where('id', 'in', productIds).get(),
232
- Category.orderBy('name', 'asc').limit(500).get(),
233
- Manufacturer.orderBy('manufacturer', 'asc').limit(500).get(),
234
- TaxRate.orderBy('id', 'asc').limit(500).get(),
235
- ])
236
- const categoryMap = new Map(categories.map(normalizeProductOption).map(option => [option.id, option.label]))
237
- const manufacturerMap = new Map(manufacturers.map(normalizeManufacturerOption).map(option => [option.id, option.label]))
238
- const emptyCounts = new Map<string, number>()
239
241
  let products
242
+ let taxRates
240
243
  try {
244
+ const [productRows, categories, manufacturers, persistedTaxRates] = await Promise.all([
245
+ Product.where('id', 'in', productIds).get(),
246
+ Category.orderBy('name', 'asc').limit(500).get(),
247
+ Manufacturer.orderBy('manufacturer', 'asc').limit(500).get(),
248
+ TaxRate.orderBy('id', 'asc').limit(500).get(),
249
+ ])
250
+ const categoryMap = new Map(categories.map(normalizeProductOption).map(option => [option.id, option.label]))
251
+ const manufacturerMap = new Map(manufacturers.map(normalizeManufacturerOption).map(option => [option.id, option.label]))
252
+ const emptyCounts = new Map<string, number>()
241
253
  products = productRows.map(product => normalizeCommercePosProduct(normalizeCommerceProductRecord(
242
254
  product,
243
255
  categoryMap,
@@ -246,11 +258,10 @@ export default new Action({
246
258
  emptyCounts,
247
259
  emptyCounts,
248
260
  )))
261
+ taxRates = persistedTaxRates
249
262
  }
250
263
  catch (error) {
251
- return response.json({
252
- message: error instanceof Error ? error.message : 'Product records could not be read.',
253
- }, 503)
264
+ return dashboardOperationalError(error, 'Product records could not be read.', 'CommercePosCheckoutAction')
254
265
  }
255
266
  if (products.length !== productIds.length)
256
267
  return response.json({ message: 'One or more products no longer exist.' }, 422)
@@ -260,9 +271,7 @@ export default new Action({
260
271
  taxRate = selectCommercePosTaxRate(taxRates)
261
272
  }
262
273
  catch (error) {
263
- return response.json({
264
- message: error instanceof Error ? error.message : 'Tax rate records could not be read.',
265
- }, 503)
274
+ return dashboardOperationalError(error, 'Tax rate records could not be read.', 'CommercePosCheckoutAction')
266
275
  }
267
276
 
268
277
  let sale
@@ -270,48 +279,54 @@ export default new Action({
270
279
  sale = calculateCommercePosSale(products, parsed.lines, taxRate)
271
280
  }
272
281
  catch (error) {
273
- return response.json(
274
- { message: error instanceof Error ? error.message : String(error) },
275
- error instanceof CommercePosAvailabilityError ? 409 : 422,
276
- )
282
+ if (error instanceof CommercePosAvailabilityError)
283
+ return response.json({ message: error.message }, 409)
284
+
285
+ return dashboardOperationalError(error, 'Sale totals could not be calculated.', 'CommercePosCheckoutAction')
277
286
  }
278
287
 
279
288
  const currency = normalizeCommerceCurrency((config as any).commerce?.currency)
280
289
  const transactionId = randomUUIDv7()
281
290
  const referenceNumber = `POS-${transactionId.slice(0, 12).toUpperCase()}`
282
- const result = await orders.placeOrder({
283
- idempotencyKey,
284
- order: {
285
- customer_id: customerId || null,
286
- status: 'DELIVERED',
287
- total_amount: sale.totalAmount,
288
- currency,
289
- tax_amount: sale.taxAmount,
290
- discount_amount: 0,
291
- delivery_fee: 0,
292
- tip_amount: 0,
293
- order_type: orderType,
294
- special_instructions: specialInstructions || null,
295
- } as any,
296
- items: sale.lines.map(line => ({
297
- productId: line.productId,
298
- quantity: line.quantity,
299
- price: line.unitPrice,
300
- specialInstructions: line.specialInstructions,
301
- })),
302
- payment: {
303
- customer_id: customerId || null,
304
- amount: sale.totalAmount,
305
- method: 'cash',
306
- status: 'completed',
307
- currency,
308
- reference_number: referenceNumber,
309
- transaction_id: transactionId,
310
- payment_provider: 'pos',
311
- notes: specialInstructions || null,
312
- } as any,
313
- inventory: sale.lines.map(line => ({ id: line.productId, delta: -line.quantity })),
314
- })
291
+ let result
292
+ try {
293
+ result = await orders.placeOrder({
294
+ idempotencyKey,
295
+ order: {
296
+ customer_id: customerId || null,
297
+ status: 'DELIVERED',
298
+ total_amount: sale.totalAmount,
299
+ currency,
300
+ tax_amount: sale.taxAmount,
301
+ discount_amount: 0,
302
+ delivery_fee: 0,
303
+ tip_amount: 0,
304
+ order_type: orderType,
305
+ special_instructions: specialInstructions || null,
306
+ } as any,
307
+ items: sale.lines.map(line => ({
308
+ productId: line.productId,
309
+ quantity: line.quantity,
310
+ price: line.unitPrice,
311
+ specialInstructions: line.specialInstructions,
312
+ })),
313
+ payment: {
314
+ customer_id: customerId || null,
315
+ amount: sale.totalAmount,
316
+ method: 'cash',
317
+ status: 'completed',
318
+ currency,
319
+ reference_number: referenceNumber,
320
+ transaction_id: transactionId,
321
+ payment_provider: 'pos',
322
+ notes: specialInstructions || null,
323
+ } as any,
324
+ inventory: sale.lines.map(line => ({ id: line.productId, delta: -line.quantity })),
325
+ })
326
+ }
327
+ catch (error) {
328
+ return dashboardOperationalError(error, 'The sale could not be completed atomically.', 'CommercePosCheckoutAction', 500)
329
+ }
315
330
 
316
331
  if (!result.ok) {
317
332
  if (result.reason === 'unknown') {
@@ -325,7 +340,8 @@ export default new Action({
325
340
  : result.reason === 'duplicate-idempotency-key'
326
341
  ? 'This checkout is already being processed. Retry once.'
327
342
  : 'The sale could not be completed atomically.'
328
- return response.json({ message }, result.reason === 'out-of-stock' ? 409 : 422)
343
+ const status = result.reason === 'unknown' ? 500 : 409
344
+ return response.json({ message }, status)
329
345
  }
330
346
 
331
347
  const order = result.order as any
@@ -340,9 +356,7 @@ export default new Action({
340
356
  )
341
357
  }
342
358
  catch (error) {
343
- return response.json({
344
- message: error instanceof Error ? error.message : 'Created order record could not be read.',
345
- }, 503)
359
+ return dashboardOperationalError(error, 'Created order record could not be read.', 'CommercePosCheckoutAction', 500)
346
360
  }
347
361
  return {
348
362
  ok: true,
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { PrintDevice } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import { normalizePrintDeviceRecord, summarizePrintDevices } from './print-device-records'
5
5
 
6
6
  export default new Action({
@@ -19,9 +19,7 @@ export default new Action({
19
19
  }
20
20
  }
21
21
  catch (error) {
22
- return response.json({
23
- message: error instanceof Error ? error.message : 'Print device records could not be read.',
24
- }, 503)
22
+ return dashboardOperationalError(error, 'Print device records could not be read.', 'CommercePrintDevicesAction')
25
23
  }
26
24
  },
27
25
  })
@@ -2,7 +2,7 @@ import type { RequestInstance } from '@stacksjs/types'
2
2
  import { Action } from '@stacksjs/actions'
3
3
  import { db } from '@stacksjs/database'
4
4
  import { formatDate, PrintDevice } from '@stacksjs/orm'
5
- import { response } from '@stacksjs/router'
5
+ import { dashboardOperationalError } from '../dashboard-response'
6
6
  import { dashboardRequestValue } from '../dashboard-request'
7
7
  import {
8
8
  commerceEnum,
@@ -115,9 +115,7 @@ export default new Action({
115
115
  }
116
116
  }
117
117
  catch (error) {
118
- return response.json({
119
- message: error instanceof Error ? error.message : 'Print log records could not be read.',
120
- }, 503)
118
+ return dashboardOperationalError(error, 'Print log records could not be read.', 'CommercePrintLogsAction')
121
119
  }
122
120
  },
123
121
  })
@@ -3,6 +3,7 @@ import { Action } from '@stacksjs/actions'
3
3
  import { config } from '@stacksjs/config'
4
4
  import { Category, Manufacturer, Product, ProductUnit, ProductVariant, Review } from '@stacksjs/orm'
5
5
  import { response } from '@stacksjs/router'
6
+ import { dashboardOperationalError } from '../dashboard-response'
6
7
  import {
7
8
  countProductRelations,
8
9
  normalizeCommerceCurrency,
@@ -22,7 +23,7 @@ export default new Action({
22
23
 
23
24
  async handle(request: RequestInstance) {
24
25
  const id = Number(request.getParam('id'))
25
- if (!Number.isFinite(id) || id <= 0)
26
+ if (!Number.isSafeInteger(id) || id <= 0)
26
27
  return response.notFound({ error: 'Product not found' })
27
28
 
28
29
  try {
@@ -61,9 +62,7 @@ export default new Action({
61
62
  }
62
63
  }
63
64
  catch (error) {
64
- return response.json({
65
- message: error instanceof Error ? error.message : 'Product details could not be read.',
66
- }, 503)
65
+ return dashboardOperationalError(error, 'Product details could not be read.', 'CommerceProductDetailAction')
67
66
  }
68
67
  },
69
68
  })
@@ -1,7 +1,7 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { config } from '@stacksjs/config'
3
3
  import { Category, Manufacturer, Product, ProductUnit, ProductVariant, Review } from '@stacksjs/orm'
4
- import { response } from '@stacksjs/router'
4
+ import { dashboardOperationalError } from '../dashboard-response'
5
5
  import {
6
6
  commerceRecordIdentifier,
7
7
  countProductRelations,
@@ -54,9 +54,7 @@ export default new Action({
54
54
  }
55
55
  }
56
56
  catch (error) {
57
- return response.json({
58
- message: error instanceof Error ? error.message : 'Product records could not be read.',
59
- }, 503)
57
+ return dashboardOperationalError(error, 'Product records could not be read.', 'CommerceProductsAction')
60
58
  }
61
59
  },
62
60
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { TaxRate } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import { normalizeTaxRateRecord, summarizeTaxRates } from './tax-rate-records'
5
5
 
6
6
  export default new Action({
@@ -19,9 +19,7 @@ export default new Action({
19
19
  }
20
20
  }
21
21
  catch (error) {
22
- return response.json({
23
- message: error instanceof Error ? error.message : 'Tax rate records could not be read.',
24
- }, 503)
22
+ return dashboardOperationalError(error, 'Tax rate records could not be read.', 'CommerceTaxesAction')
25
23
  }
26
24
  },
27
25
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { DeliveryRoute, Driver } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  indexDeliveryRouteDrivers,
6
6
  normalizeDeliveryRouteRecord,
@@ -21,9 +21,7 @@ export default new Action({
21
21
  return routes.map(route => normalizeDeliveryRouteRecord(route, driversById))
22
22
  }
23
23
  catch (error) {
24
- return response.json({
25
- message: error instanceof Error ? error.message : 'Delivery route records could not be read.',
26
- }, 503)
24
+ return dashboardOperationalError(error, 'Delivery route records could not be read.', 'DeliveryRouteIndexAction')
27
25
  }
28
26
  },
29
27
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { DigitalDelivery } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import { normalizeDigitalDeliveryRecord } from './digital-delivery-records'
5
5
 
6
6
  export default new Action({
@@ -15,9 +15,7 @@ export default new Action({
15
15
  return records.map(normalizeDigitalDeliveryRecord)
16
16
  }
17
17
  catch (error) {
18
- return response.json({
19
- message: error instanceof Error ? error.message : 'Digital delivery records could not be read.',
20
- }, 503)
18
+ return dashboardOperationalError(error, 'Digital delivery records could not be read.', 'DigitalDeliveryIndexAction')
21
19
  }
22
20
  },
23
21
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Driver, User } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import { indexDriverUsers, normalizeDriverRecord } from './driver-records'
5
5
 
6
6
  export default new Action({
@@ -18,9 +18,7 @@ export default new Action({
18
18
  return drivers.map(driver => normalizeDriverRecord(driver, usersById))
19
19
  }
20
20
  catch (error) {
21
- return response.json({
22
- message: error instanceof Error ? error.message : 'Driver records could not be read.',
23
- }, 503)
21
+ return dashboardOperationalError(error, 'Driver records could not be read.', 'DriverIndexAction')
24
22
  }
25
23
  },
26
24
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Customer, LicenseKey, Order, Product } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  indexLicenseKeyOptions,
6
6
  normalizeLicenseKeyCustomer,
@@ -31,9 +31,7 @@ export default new Action({
31
31
  return keys.map(key => normalizeLicenseKeyRecord(key, customerMap, productMap, orderMap))
32
32
  }
33
33
  catch (error) {
34
- return response.json({
35
- message: error instanceof Error ? error.message : 'License key records could not be read.',
36
- }, 503)
34
+ return dashboardOperationalError(error, 'License key records could not be read.', 'LicenseKeyIndexAction')
37
35
  }
38
36
  },
39
37
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Customer, Order, Product } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  normalizeLicenseKeyCustomer,
6
6
  normalizeLicenseKeyOrder,
@@ -26,9 +26,7 @@ export default new Action({
26
26
  }
27
27
  }
28
28
  catch (error) {
29
- return response.json({
30
- message: error instanceof Error ? error.message : 'License key options could not be read.',
31
- }, 503)
29
+ return dashboardOperationalError(error, 'License key options could not be read.', 'LicenseKeyOptionsAction')
32
30
  }
33
31
  },
34
32
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Manufacturer, Product } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  manufacturerIdentifiers,
6
6
  manufacturerProductCounts,
@@ -31,9 +31,7 @@ export default new Action({
31
31
  }
32
32
  }
33
33
  catch (error) {
34
- return response.json({
35
- message: error instanceof Error ? error.message : 'Manufacturer records could not be read.',
36
- }, 503)
34
+ return dashboardOperationalError(error, 'Manufacturer records could not be read.', 'ManufacturerIndexAction')
37
35
  }
38
36
  },
39
37
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Product, ProductUnit } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  normalizeProductUnitRecord,
6
6
  productUnitOptions,
@@ -30,9 +30,7 @@ export default new Action({
30
30
  }
31
31
  }
32
32
  catch (error) {
33
- return response.json({
34
- message: error instanceof Error ? error.message : 'Product unit records could not be read.',
35
- }, 503)
33
+ return dashboardOperationalError(error, 'Product unit records could not be read.', 'ProductUnitIndexAction')
36
34
  }
37
35
  },
38
36
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Product, ProductVariant } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  normalizeProductVariantRecord,
6
6
  productVariantOptions,
@@ -29,9 +29,7 @@ export default new Action({
29
29
  }
30
30
  }
31
31
  catch (error) {
32
- return response.json({
33
- message: error instanceof Error ? error.message : 'Product variant records could not be read.',
34
- }, 503)
32
+ return dashboardOperationalError(error, 'Product variant records could not be read.', 'ProductVariantIndexAction')
35
33
  }
36
34
  },
37
35
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Customer, Product, WaitlistProduct } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import { normalizeProductWaitlistCustomerOption, normalizeProductWaitlistOption, normalizeProductWaitlistRecord, summarizeProductWaitlist } from './product-waitlist-records'
5
5
 
6
6
  export default new Action({
@@ -33,9 +33,7 @@ export default new Action({
33
33
  }
34
34
  }
35
35
  catch (error) {
36
- return response.json({
37
- message: error instanceof Error ? error.message : 'Product waitlist records could not be read.',
38
- }, 503)
36
+ return dashboardOperationalError(error, 'Product waitlist records could not be read.', 'ProductWaitlistIndexAction')
39
37
  }
40
38
  },
41
39
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Customer, WaitlistRestaurant } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import { normalizeRestaurantWaitlistCustomerOption, normalizeRestaurantWaitlistRecord, summarizeRestaurantWaitlist } from './restaurant-waitlist-records'
5
5
 
6
6
  export default new Action({
@@ -28,9 +28,7 @@ export default new Action({
28
28
  }
29
29
  }
30
30
  catch (error) {
31
- return response.json({
32
- message: error instanceof Error ? error.message : 'Restaurant waitlist records could not be read.',
33
- }, 503)
31
+ return dashboardOperationalError(error, 'Restaurant waitlist records could not be read.', 'RestaurantWaitlistIndexAction')
34
32
  }
35
33
  },
36
34
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Customer, Product, Review } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  normalizeReviewCustomerContext,
6
6
  normalizeReviewProductOption,
@@ -42,9 +42,7 @@ export default new Action({
42
42
  }
43
43
  }
44
44
  catch (error) {
45
- return response.json({
46
- message: error instanceof Error ? error.message : 'Review records could not be read.',
47
- }, 503)
45
+ return dashboardOperationalError(error, 'Review records could not be read.', 'ReviewIndexAction')
48
46
  }
49
47
  },
50
48
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { ShippingMethod, ShippingZone } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  groupShippingMethodZones,
6
6
  normalizeShippingMethodRecord,
@@ -24,9 +24,7 @@ export default new Action({
24
24
  return methods.map(method => normalizeShippingMethodRecord(method, zonesByMethodId))
25
25
  }
26
26
  catch (error) {
27
- return response.json({
28
- message: error instanceof Error ? error.message : 'Shipping method records could not be read.',
29
- }, 503)
27
+ return dashboardOperationalError(error, 'Shipping method records could not be read.', 'ShippingMethodIndexAction')
30
28
  }
31
29
  },
32
30
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { ShippingMethod, ShippingRate, ShippingZone } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  indexShippingRateMethods,
6
6
  indexShippingRateZones,
@@ -27,9 +27,7 @@ export default new Action({
27
27
  return rates.map(rate => normalizeShippingRateRecord(rate, methodsById, zonesById))
28
28
  }
29
29
  catch (error) {
30
- return response.json({
31
- message: error instanceof Error ? error.message : 'Shipping rate records could not be read.',
32
- }, 503)
30
+ return dashboardOperationalError(error, 'Shipping rate records could not be read.', 'ShippingRateIndexAction')
33
31
  }
34
32
  },
35
33
  })
@@ -1,6 +1,6 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { ShippingMethod, ShippingZone } from '@stacksjs/orm'
3
- import { response } from '@stacksjs/router'
3
+ import { dashboardOperationalError } from '../dashboard-response'
4
4
  import {
5
5
  indexShippingZoneMethods,
6
6
  normalizeShippingZoneRecord,
@@ -23,9 +23,7 @@ export default new Action({
23
23
  return zones.map(zone => normalizeShippingZoneRecord(zone, methodsById))
24
24
  }
25
25
  catch (error) {
26
- return response.json({
27
- message: error instanceof Error ? error.message : 'Shipping zone records could not be read.',
28
- }, 503)
26
+ return dashboardOperationalError(error, 'Shipping zone records could not be read.', 'ShippingZoneIndexAction')
29
27
  }
30
28
  },
31
29
  })
@@ -1,6 +1,7 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Activity } from '@stacksjs/orm'
3
3
  import { safeGet } from '../../../resources/functions/dashboard/data'
4
+ import { dashboardOperationalError } from './dashboard-response'
4
5
  import { dateValue, numberValue, textValue } from './Data/data-records'
5
6
 
6
7
  export function activityStatus(type: string): 'success' | 'warning' {
@@ -35,11 +36,7 @@ export default new Action({
35
36
  return { activity, count: activity.length }
36
37
  }
37
38
  catch (error) {
38
- return {
39
- activity: [],
40
- count: 0,
41
- error: error instanceof Error ? error.message : 'Activity records could not be loaded.',
42
- }
39
+ return dashboardOperationalError(error, 'Activity records could not be loaded.', 'DashboardActivityAction')
43
40
  }
44
41
  },
45
42
  })
@@ -1,6 +1,7 @@
1
1
  import { Action } from '@stacksjs/actions'
2
2
  import { Activity } from '@stacksjs/orm'
3
3
  import { safeGet } from '../../../../resources/functions/dashboard/data'
4
+ import { dashboardOperationalError } from '../dashboard-response'
4
5
  import { dateValue, daysAgoIso, numberValue, textValue } from './data-records'
5
6
 
6
7
  export default new Action({
@@ -37,11 +38,7 @@ export default new Action({
37
38
  }
38
39
  }
39
40
  catch (error) {
40
- return {
41
- activities: [],
42
- stats: { total: 0, last24Hours: 0, last7Days: 0 },
43
- error: error instanceof Error ? error.message : 'Activity could not be loaded.',
44
- }
41
+ return dashboardOperationalError(error, 'Activity could not be loaded.', 'ActivityIndexAction')
45
42
  }
46
43
  },
47
44
  })