@stacksjs/defaults 0.70.354 → 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 (214) hide show
  1. package/ai/skills/stacks-browse/SKILL.md +17 -2
  2. package/ai/skills/stacks-browse/scripts/browse.ts +207 -6
  3. package/ai/skills/stacks-email/SKILL.md +73 -16
  4. package/app/Actions/ContactAction.ts +2 -2
  5. package/app/Actions/Dashboard/Analytics/EventAnalyticsAction.ts +2 -3
  6. package/app/Actions/Dashboard/Analytics/MarketingAnalyticsAction.ts +2 -3
  7. package/app/Actions/Dashboard/Analytics/SalesAnalyticsAction.ts +2 -3
  8. package/app/Actions/Dashboard/Analytics/WebAnalyticsAction.ts +9 -3
  9. package/app/Actions/Dashboard/Auth/MeAction.ts +12 -14
  10. package/app/Actions/Dashboard/Buddy/BuddyChatAction.ts +2 -3
  11. package/app/Actions/Dashboard/Ci/RepoRunJobsAction.ts +10 -15
  12. package/app/Actions/Dashboard/Ci/RepoRunsAction.ts +12 -14
  13. package/app/Actions/Dashboard/Ci/RunnerHistoryAction.ts +11 -10
  14. package/app/Actions/Dashboard/Ci/StatusAction.ts +2 -11
  15. package/app/Actions/Dashboard/Cloud/CloudIndexAction.ts +8 -1
  16. package/app/Actions/Dashboard/Cloud/ServerlessIndexAction.ts +15 -8
  17. package/app/Actions/Dashboard/Commerce/CommerceCategoriesAction.ts +2 -4
  18. package/app/Actions/Dashboard/Commerce/CommerceCouponsAction.ts +2 -4
  19. package/app/Actions/Dashboard/Commerce/CommerceCustomersAction.ts +2 -4
  20. package/app/Actions/Dashboard/Commerce/CommerceDashboardAction.ts +2 -4
  21. package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +2 -4
  22. package/app/Actions/Dashboard/Commerce/CommerceGiftCardsAction.ts +2 -4
  23. package/app/Actions/Dashboard/Commerce/CommerceOrdersAction.ts +2 -4
  24. package/app/Actions/Dashboard/Commerce/CommercePaymentsAction.ts +2 -4
  25. package/app/Actions/Dashboard/Commerce/CommercePosAction.ts +2 -4
  26. package/app/Actions/Dashboard/Commerce/CommercePosCheckoutAction.ts +76 -61
  27. package/app/Actions/Dashboard/Commerce/CommercePrintDevicesAction.ts +2 -4
  28. package/app/Actions/Dashboard/Commerce/CommercePrintLogsAction.ts +4 -7
  29. package/app/Actions/Dashboard/Commerce/CommerceProductDetailAction.ts +4 -4
  30. package/app/Actions/Dashboard/Commerce/CommerceProductsAction.ts +2 -4
  31. package/app/Actions/Dashboard/Commerce/CommerceTaxesAction.ts +2 -4
  32. package/app/Actions/Dashboard/Commerce/DeliveryRouteIndexAction.ts +2 -4
  33. package/app/Actions/Dashboard/Commerce/DigitalDeliveryIndexAction.ts +2 -4
  34. package/app/Actions/Dashboard/Commerce/DriverIndexAction.ts +2 -4
  35. package/app/Actions/Dashboard/Commerce/LicenseKeyIndexAction.ts +2 -4
  36. package/app/Actions/Dashboard/Commerce/LicenseKeyOptionsAction.ts +2 -4
  37. package/app/Actions/Dashboard/Commerce/ManufacturerIndexAction.ts +2 -4
  38. package/app/Actions/Dashboard/Commerce/PaymentRefundAction.ts +1 -0
  39. package/app/Actions/Dashboard/Commerce/ProductUnitDefaultAction.ts +1 -0
  40. package/app/Actions/Dashboard/Commerce/ProductUnitIndexAction.ts +2 -4
  41. package/app/Actions/Dashboard/Commerce/ProductVariantIndexAction.ts +2 -4
  42. package/app/Actions/Dashboard/Commerce/ProductWaitlistIndexAction.ts +2 -4
  43. package/app/Actions/Dashboard/Commerce/RestaurantWaitlistIndexAction.ts +2 -4
  44. package/app/Actions/Dashboard/Commerce/ReviewIndexAction.ts +2 -4
  45. package/app/Actions/Dashboard/Commerce/ShippingMethodIndexAction.ts +2 -4
  46. package/app/Actions/Dashboard/Commerce/ShippingRateIndexAction.ts +2 -4
  47. package/app/Actions/Dashboard/Commerce/ShippingZoneIndexAction.ts +2 -4
  48. package/app/Actions/Dashboard/Commerce/TaxRateDefaultAction.ts +1 -0
  49. package/app/Actions/Dashboard/DashboardActivityAction.ts +2 -5
  50. package/app/Actions/Dashboard/Data/ActivityIndexAction.ts +2 -5
  51. package/app/Actions/Dashboard/Data/SubscriberIndexAction.ts +2 -5
  52. package/app/Actions/Dashboard/Data/TeamIndexAction.ts +2 -5
  53. package/app/Actions/Dashboard/Data/UserIndexAction.ts +2 -5
  54. package/app/Actions/Dashboard/Deployments/CreateDeployment.ts +26 -21
  55. package/app/Actions/Dashboard/Deployments/GetAverageDeploymentTime.ts +8 -2
  56. package/app/Actions/Dashboard/Deployments/GetDeployScript.ts +3 -6
  57. package/app/Actions/Dashboard/Deployments/GetDeployment.ts +5 -5
  58. package/app/Actions/Dashboard/Deployments/GetDeploymentCount.ts +7 -1
  59. package/app/Actions/Dashboard/Deployments/GetDeploymentLiveTerminalOutput.ts +10 -9
  60. package/app/Actions/Dashboard/Deployments/GetDeployments.ts +2 -4
  61. package/app/Actions/Dashboard/Deployments/GetRecentDeployments.ts +8 -2
  62. package/app/Actions/Dashboard/Deployments/UpdateDeployScript.ts +21 -7
  63. package/app/Actions/Dashboard/Email/CapturedMailIndexAction.ts +2 -4
  64. package/app/Actions/Dashboard/Email/CapturedMailShowAction.ts +3 -4
  65. package/app/Actions/Dashboard/Email/InboxActivityAction.ts +28 -16
  66. package/app/Actions/Dashboard/Email/InboxAttachmentDownloadAction.ts +45 -0
  67. package/app/Actions/Dashboard/Email/InboxDeleteAction.ts +11 -6
  68. package/app/Actions/Dashboard/Email/InboxIndexAction.ts +5 -7
  69. package/app/Actions/Dashboard/Email/InboxMarkReadAction.ts +11 -6
  70. package/app/Actions/Dashboard/Email/InboxMarkUnreadAction.ts +11 -6
  71. package/app/Actions/Dashboard/Email/InboxPreferenceShowAction.ts +10 -4
  72. package/app/Actions/Dashboard/Email/InboxPreferenceUpdateAction.ts +8 -9
  73. package/app/Actions/Dashboard/Email/InboxShowAction.ts +7 -7
  74. package/app/Actions/Dashboard/Email/InboxStatsAction.ts +5 -7
  75. package/app/Actions/Dashboard/Email/inbox-request.ts +33 -0
  76. package/app/Actions/Dashboard/Infrastructure/InsightsAction.ts +15 -14
  77. package/app/Actions/Dashboard/Infrastructure/LogIndexAction.ts +4 -11
  78. package/app/Actions/Dashboard/Infrastructure/ServerShowAction.ts +3 -6
  79. package/app/Actions/Dashboard/Jobs/JobIndexAction.ts +9 -18
  80. package/app/Actions/Dashboard/Jobs/JobRetryAction.ts +4 -3
  81. package/app/Actions/Dashboard/Jobs/JobShowAction.ts +16 -11
  82. package/app/Actions/Dashboard/Jobs/JobStatsAction.ts +2 -4
  83. package/app/Actions/Dashboard/Kanban/BoardDestroyAction.ts +7 -8
  84. package/app/Actions/Dashboard/Kanban/BoardShowAction.ts +11 -19
  85. package/app/Actions/Dashboard/Kanban/BoardStoreAction.ts +6 -6
  86. package/app/Actions/Dashboard/Kanban/BoardUpdateAction.ts +7 -8
  87. package/app/Actions/Dashboard/Kanban/BoardsIndexAction.ts +3 -5
  88. package/app/Actions/Dashboard/Kanban/BoardsReorderAction.ts +6 -6
  89. package/app/Actions/Dashboard/Kanban/CardAssigneesSyncAction.ts +13 -12
  90. package/app/Actions/Dashboard/Kanban/CardCommentDestroyAction.ts +12 -15
  91. package/app/Actions/Dashboard/Kanban/CardCommentStoreAction.ts +21 -46
  92. package/app/Actions/Dashboard/Kanban/CardCommentUpdateAction.ts +43 -0
  93. package/app/Actions/Dashboard/Kanban/CardDestroyAction.ts +7 -8
  94. package/app/Actions/Dashboard/Kanban/CardLabelsSyncAction.ts +8 -9
  95. package/app/Actions/Dashboard/Kanban/CardShowAction.ts +6 -7
  96. package/app/Actions/Dashboard/Kanban/CardStoreAction.ts +9 -9
  97. package/app/Actions/Dashboard/Kanban/CardUpdateAction.ts +7 -8
  98. package/app/Actions/Dashboard/Kanban/CardsReorderAction.ts +6 -6
  99. package/app/Actions/Dashboard/Kanban/ColumnDestroyAction.ts +7 -8
  100. package/app/Actions/Dashboard/Kanban/ColumnStoreAction.ts +6 -6
  101. package/app/Actions/Dashboard/Kanban/ColumnUpdateAction.ts +7 -8
  102. package/app/Actions/Dashboard/Kanban/ColumnsReorderAction.ts +6 -6
  103. package/app/Actions/Dashboard/Kanban/LabelDestroyAction.ts +6 -7
  104. package/app/Actions/Dashboard/Kanban/LabelStoreAction.ts +6 -6
  105. package/app/Actions/Dashboard/Kanban/LabelUpdateAction.ts +7 -8
  106. package/app/Actions/Dashboard/Kanban/UsersListAction.ts +3 -4
  107. package/app/Actions/Dashboard/Kanban/kanban-comment.ts +14 -0
  108. package/app/Actions/Dashboard/Kanban/kanban-model.test.ts +36 -0
  109. package/app/Actions/Dashboard/Kanban/kanban-model.ts +14 -7
  110. package/app/Actions/Dashboard/Kanban/kanban-response.ts +5 -0
  111. package/app/Actions/Dashboard/Library/CreateComponent.ts +15 -6
  112. package/app/Actions/Dashboard/Library/CreateFunction.ts +15 -6
  113. package/app/Actions/Dashboard/Library/DependencyIndexAction.ts +88 -77
  114. package/app/Actions/Dashboard/Library/GetAverageReleaseTime.ts +21 -15
  115. package/app/Actions/Dashboard/Library/GetComponents.ts +14 -7
  116. package/app/Actions/Dashboard/Library/GetDownloadCount.ts +14 -5
  117. package/app/Actions/Dashboard/Library/GetFunctions.ts +12 -5
  118. package/app/Actions/Dashboard/Library/GetReleaseCount.ts +14 -5
  119. package/app/Actions/Dashboard/Library/GetReleases.ts +17 -10
  120. package/app/Actions/Dashboard/Library/PackageIndexAction.ts +14 -7
  121. package/app/Actions/Dashboard/Models/ModelDestroyAction.ts +11 -8
  122. package/app/Actions/Dashboard/Models/ModelShowAction.ts +97 -192
  123. package/app/Actions/Dashboard/Models/ModelStoreAction.ts +14 -12
  124. package/app/Actions/Dashboard/Models/ModelUpdateAction.ts +18 -16
  125. package/app/Actions/Dashboard/Models/ModelsIndexAction.ts +50 -19
  126. package/app/Actions/Dashboard/Models/model-api.ts +27 -0
  127. package/app/Actions/Dashboard/Models/model-write.ts +22 -15
  128. package/app/Actions/Dashboard/Notifications/NotificationDeliveryHistoryAction.ts +49 -40
  129. package/app/Actions/Dashboard/Notifications/NotificationDeliveryIndexAction.ts +20 -10
  130. package/app/Actions/Dashboard/Notifications/NotificationDeliveryOverviewAction.ts +96 -84
  131. package/app/Actions/Dashboard/Notifications/NotificationDeliveryRetryAction.ts +34 -21
  132. package/app/Actions/Dashboard/Queries/QueryDashboardAction.ts +2 -4
  133. package/app/Actions/Dashboard/Queries/QueryShowAction.ts +3 -3
  134. package/app/Actions/Dashboard/Queue/QueueStatsAction.ts +2 -4
  135. package/app/Actions/Dashboard/Queue/QueueWorkersAction.ts +2 -4
  136. package/app/Actions/Dashboard/Rbac/PermissionDestroyAction.ts +6 -6
  137. package/app/Actions/Dashboard/Rbac/PermissionStoreAction.ts +5 -4
  138. package/app/Actions/Dashboard/Rbac/PermissionsIndexAction.ts +2 -3
  139. package/app/Actions/Dashboard/Rbac/RoleDestroyAction.ts +6 -6
  140. package/app/Actions/Dashboard/Rbac/RolePermissionsShowAction.ts +6 -6
  141. package/app/Actions/Dashboard/Rbac/RolePermissionsSyncAction.ts +6 -9
  142. package/app/Actions/Dashboard/Rbac/RoleStoreAction.ts +5 -4
  143. package/app/Actions/Dashboard/Rbac/RolesIndexAction.ts +4 -6
  144. package/app/Actions/Dashboard/Rbac/UserRolesShowAction.ts +6 -7
  145. package/app/Actions/Dashboard/Rbac/UserRolesSyncAction.ts +6 -13
  146. package/app/Actions/Dashboard/Rbac/UsersListAction.ts +2 -3
  147. package/app/Actions/Dashboard/Rbac/rbac-response.ts +10 -0
  148. package/app/Actions/Dashboard/Realtime/RealtimeStatsAction.ts +2 -4
  149. package/app/Actions/Dashboard/Search/GlobalSearchAction.ts +69 -55
  150. package/app/Actions/Dashboard/Teams/TeamInvitationDestroyAction.ts +34 -16
  151. package/app/Actions/Dashboard/Teams/TeamInvitationResendAction.ts +52 -29
  152. package/app/Actions/Dashboard/Teams/TeamInviteAction.ts +104 -73
  153. package/app/Actions/Dashboard/Teams/TeamMemberDestroyAction.ts +36 -17
  154. package/app/Actions/Dashboard/Teams/TeamMemberUpdateAction.ts +41 -28
  155. package/app/Actions/Dashboard/Teams/TeamPeopleIndexAction.ts +71 -58
  156. package/app/Actions/Dashboard/Teams/team-invitation-delivery.ts +29 -7
  157. package/app/Actions/Dashboard/Teams/team-member-count.ts +4 -2
  158. package/app/Actions/Dashboard/Teams/team-records.test.ts +2 -0
  159. package/app/Actions/Dashboard/Teams/team-records.ts +2 -0
  160. package/app/Actions/Dashboard/dashboard-request.ts +13 -0
  161. package/app/Actions/Dashboard/dashboard-response.ts +16 -0
  162. package/app/Actions/SendWelcomeEmail.ts +1 -1
  163. package/app/Actions/Teams/AcceptInvitationAction.ts +74 -51
  164. package/app/Actions/Teams/ShowInvitationAction.ts +21 -14
  165. package/app/Actions/Teams/team-response.ts +23 -0
  166. package/app/Mail/OrderConfirmation.ts +1 -1
  167. package/app/Mail/SubscriptionConfirmation.ts +1 -1
  168. package/app/Mail/TeamInvitation.ts +1 -1
  169. package/app/Models/CardComment.ts +3 -4
  170. package/app/Models/EmailIdempotency.ts +64 -0
  171. package/app/Models/EmailSuppression.ts +52 -0
  172. package/app/Models/EmailWebhookEvent.ts +51 -0
  173. package/app/Models/TeamInvitation.ts +13 -0
  174. package/functions/dashboard-api.ts +51 -10
  175. package/functions/data.ts +0 -1
  176. package/functions/inbox.test.ts +2 -0
  177. package/functions/inbox.ts +27 -2
  178. package/functions/jobs.ts +0 -1
  179. package/functions/public-application-url.test.ts +13 -0
  180. package/functions/public-application-url.ts +27 -0
  181. package/ide/vscode/package.json +1 -1
  182. package/package.json +1 -1
  183. package/resources/components/Dashboard/Auth/AccessTokens.stx +15 -0
  184. package/resources/components/Dashboard/Ci/CiDashboard.stx +24 -6
  185. package/resources/components/Dashboard/Commerce/CommerceTaxDialog.stx +1 -1
  186. package/resources/components/Dashboard/Commerce/ProductWaitlistDashboard.stx +8 -7
  187. package/resources/components/Dashboard/Commerce/RestaurantWaitlistDashboard.stx +8 -7
  188. package/resources/components/Dashboard/Content/BlogDashboard.stx +14 -2
  189. package/resources/components/Dashboard/Content/PostsDashboard.stx +7 -1
  190. package/resources/components/Dashboard/Data/DataRecords.stx +0 -4
  191. package/resources/components/Dashboard/Deployments/DeploymentDetail.stx +16 -2
  192. package/resources/components/Dashboard/Email/EmailNavigation.stx +5 -5
  193. package/resources/components/Dashboard/Email/EmailSidebar.stx +1 -1
  194. package/resources/components/Dashboard/Email/InboxAttachmentList.stx +53 -0
  195. package/resources/components/Dashboard/Email/InboxDashboard.stx +5 -4
  196. package/resources/components/Dashboard/Email/InboxMessageDetail.stx +6 -4
  197. package/resources/components/Dashboard/Jobs/JobDetail.stx +3 -2
  198. package/resources/components/Dashboard/Kanban/KanbanBoardDashboard.stx +63 -6
  199. package/resources/components/Dashboard/Kanban/KanbanBoardsDashboard.stx +3 -6
  200. package/resources/components/Dashboard/Management/PermissionsDashboard.stx +4 -4
  201. package/resources/components/Dashboard/Models/ModelRecordsDashboard.stx +7 -13
  202. package/resources/components/Dashboard/Models/ModelsOverview.stx +1 -1
  203. package/resources/components/Dashboard/NotFoundDashboard.stx +2 -5
  204. package/resources/components/Dashboard/Queries/QueryDashboard.stx +6 -2
  205. package/resources/components/Dashboard/Settings/AppearanceSettingsDashboard.stx +4 -4
  206. package/resources/components/Dashboard/UI/EmptyState.stx +2 -2
  207. package/resources/components/Dashboard/UI/PageLayout.stx +3 -3
  208. package/resources/functions/dashboard/sidebar.ts +4 -4
  209. package/routes/dashboard-api.ts +8 -20
  210. package/views/dashboard/.discovered-models.json +54 -0
  211. package/views/dashboard/layouts/default.stx +19 -16
  212. package/views/dashboard/stores/auth.ts +15 -14
  213. package/views/dashboard/stores/ci.ts +13 -7
  214. package/views/dashboard/stores/kanban.ts +48 -11
@@ -1,3 +1,4 @@
1
+ import type { RequestInstance } from '@stacksjs/types'
1
2
  import { randomUUIDv7 } from 'bun'
2
3
  import { Action } from '@stacksjs/actions'
3
4
  import { orders } from '@stacksjs/commerce'
@@ -5,6 +6,7 @@ import { config } from '@stacksjs/config'
5
6
  import { log } from '@stacksjs/logging'
6
7
  import { Category, Customer, Manufacturer, OrderItem, Payment, Product, TaxRate } from '@stacksjs/orm'
7
8
  import { response } from '@stacksjs/router'
9
+ import { dashboardOperationalError } from '../dashboard-response'
8
10
  import {
9
11
  calculateCommercePosSale,
10
12
  CommercePosAvailabilityError,
@@ -164,7 +166,13 @@ export default new Action({
164
166
  if (idempotencyKey.length < 8 || idempotencyKey.length > 255)
165
167
  return response.json({ message: 'A valid checkout idempotency key is required.' }, 422)
166
168
 
167
- 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
+ }
168
176
  if (existing) {
169
177
  try {
170
178
  return {
@@ -174,9 +182,7 @@ export default new Action({
174
182
  }
175
183
  }
176
184
  catch (error) {
177
- return response.json({
178
- message: error instanceof Error ? error.message : 'Existing receipt records could not be read.',
179
- }, 503)
185
+ return dashboardOperationalError(error, 'Existing receipt records could not be read.', 'CommercePosCheckoutAction')
180
186
  }
181
187
  }
182
188
 
@@ -210,7 +216,13 @@ export default new Action({
210
216
  : Number.NaN
211
217
  if (customerId && (!Number.isInteger(customerId) || customerId <= 0))
212
218
  return response.json({ message: 'Select a valid customer.' }, 422)
213
- 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
+ }
214
226
  if (customerId && !customer)
215
227
  return response.json({ message: 'The selected customer no longer exists.' }, 422)
216
228
 
@@ -226,17 +238,18 @@ export default new Action({
226
238
  return response.json({ message: 'Order instructions must be 1,000 characters or fewer.' }, 422)
227
239
 
228
240
  const productIds = parsed.lines.map(line => line.productId)
229
- const [productRows, categories, manufacturers, taxRates] = await Promise.all([
230
- Product.where('id', 'in', productIds).get(),
231
- Category.orderBy('name', 'asc').limit(500).get(),
232
- Manufacturer.orderBy('manufacturer', 'asc').limit(500).get(),
233
- TaxRate.orderBy('id', 'asc').limit(500).get(),
234
- ])
235
- const categoryMap = new Map(categories.map(normalizeProductOption).map(option => [option.id, option.label]))
236
- const manufacturerMap = new Map(manufacturers.map(normalizeManufacturerOption).map(option => [option.id, option.label]))
237
- const emptyCounts = new Map<string, number>()
238
241
  let products
242
+ let taxRates
239
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>()
240
253
  products = productRows.map(product => normalizeCommercePosProduct(normalizeCommerceProductRecord(
241
254
  product,
242
255
  categoryMap,
@@ -245,11 +258,10 @@ export default new Action({
245
258
  emptyCounts,
246
259
  emptyCounts,
247
260
  )))
261
+ taxRates = persistedTaxRates
248
262
  }
249
263
  catch (error) {
250
- return response.json({
251
- message: error instanceof Error ? error.message : 'Product records could not be read.',
252
- }, 503)
264
+ return dashboardOperationalError(error, 'Product records could not be read.', 'CommercePosCheckoutAction')
253
265
  }
254
266
  if (products.length !== productIds.length)
255
267
  return response.json({ message: 'One or more products no longer exist.' }, 422)
@@ -259,9 +271,7 @@ export default new Action({
259
271
  taxRate = selectCommercePosTaxRate(taxRates)
260
272
  }
261
273
  catch (error) {
262
- return response.json({
263
- message: error instanceof Error ? error.message : 'Tax rate records could not be read.',
264
- }, 503)
274
+ return dashboardOperationalError(error, 'Tax rate records could not be read.', 'CommercePosCheckoutAction')
265
275
  }
266
276
 
267
277
  let sale
@@ -269,48 +279,54 @@ export default new Action({
269
279
  sale = calculateCommercePosSale(products, parsed.lines, taxRate)
270
280
  }
271
281
  catch (error) {
272
- return response.json(
273
- { message: error instanceof Error ? error.message : String(error) },
274
- error instanceof CommercePosAvailabilityError ? 409 : 422,
275
- )
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')
276
286
  }
277
287
 
278
288
  const currency = normalizeCommerceCurrency((config as any).commerce?.currency)
279
289
  const transactionId = randomUUIDv7()
280
290
  const referenceNumber = `POS-${transactionId.slice(0, 12).toUpperCase()}`
281
- const result = await orders.placeOrder({
282
- idempotencyKey,
283
- order: {
284
- customer_id: customerId || null,
285
- status: 'DELIVERED',
286
- total_amount: sale.totalAmount,
287
- currency,
288
- tax_amount: sale.taxAmount,
289
- discount_amount: 0,
290
- delivery_fee: 0,
291
- tip_amount: 0,
292
- order_type: orderType,
293
- special_instructions: specialInstructions || null,
294
- } as any,
295
- items: sale.lines.map(line => ({
296
- productId: line.productId,
297
- quantity: line.quantity,
298
- price: line.unitPrice,
299
- specialInstructions: line.specialInstructions,
300
- })),
301
- payment: {
302
- customer_id: customerId || null,
303
- amount: sale.totalAmount,
304
- method: 'cash',
305
- status: 'completed',
306
- currency,
307
- reference_number: referenceNumber,
308
- transaction_id: transactionId,
309
- payment_provider: 'pos',
310
- notes: specialInstructions || null,
311
- } as any,
312
- inventory: sale.lines.map(line => ({ id: line.productId, delta: -line.quantity })),
313
- })
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
+ }
314
330
 
315
331
  if (!result.ok) {
316
332
  if (result.reason === 'unknown') {
@@ -324,7 +340,8 @@ export default new Action({
324
340
  : result.reason === 'duplicate-idempotency-key'
325
341
  ? 'This checkout is already being processed. Retry once.'
326
342
  : 'The sale could not be completed atomically.'
327
- 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)
328
345
  }
329
346
 
330
347
  const order = result.order as any
@@ -339,9 +356,7 @@ export default new Action({
339
356
  )
340
357
  }
341
358
  catch (error) {
342
- return response.json({
343
- message: error instanceof Error ? error.message : 'Created order record could not be read.',
344
- }, 503)
359
+ return dashboardOperationalError(error, 'Created order record could not be read.', 'CommercePosCheckoutAction', 500)
345
360
  }
346
361
  return {
347
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,8 @@ 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 { request as routerRequest, response } from '@stacksjs/router'
5
+ import { dashboardOperationalError } from '../dashboard-response'
6
+ import { dashboardRequestValue } from '../dashboard-request'
6
7
  import {
7
8
  commerceEnum,
8
9
  commerceIdentifier,
@@ -24,9 +25,7 @@ const SORTS = {
24
25
  type PrintLogSort = keyof typeof SORTS
25
26
 
26
27
  function queryValue(request: RequestInstance, key: string): string {
27
- const query = ((routerRequest as any).query || {}) as Record<string, string | string[] | undefined>
28
- const value = query[key]
29
- return String((Array.isArray(value) ? value[0] : value) || request.get(key) || '').trim()
28
+ return dashboardRequestValue(request, key)
30
29
  }
31
30
 
32
31
  function selectedSort(value: string): PrintLogSort {
@@ -116,9 +115,7 @@ export default new Action({
116
115
  }
117
116
  }
118
117
  catch (error) {
119
- return response.json({
120
- message: error instanceof Error ? error.message : 'Print log records could not be read.',
121
- }, 503)
118
+ return dashboardOperationalError(error, 'Print log records could not be read.', 'CommercePrintLogsAction')
122
119
  }
123
120
  },
124
121
  })
@@ -1,7 +1,9 @@
1
+ import type { RequestInstance } from '@stacksjs/types'
1
2
  import { Action } from '@stacksjs/actions'
2
3
  import { config } from '@stacksjs/config'
3
4
  import { Category, Manufacturer, Product, ProductUnit, ProductVariant, Review } from '@stacksjs/orm'
4
5
  import { response } from '@stacksjs/router'
6
+ import { dashboardOperationalError } from '../dashboard-response'
5
7
  import {
6
8
  countProductRelations,
7
9
  normalizeCommerceCurrency,
@@ -21,7 +23,7 @@ export default new Action({
21
23
 
22
24
  async handle(request: RequestInstance) {
23
25
  const id = Number(request.getParam('id'))
24
- if (!Number.isFinite(id) || id <= 0)
26
+ if (!Number.isSafeInteger(id) || id <= 0)
25
27
  return response.notFound({ error: 'Product not found' })
26
28
 
27
29
  try {
@@ -60,9 +62,7 @@ export default new Action({
60
62
  }
61
63
  }
62
64
  catch (error) {
63
- return response.json({
64
- message: error instanceof Error ? error.message : 'Product details could not be read.',
65
- }, 503)
65
+ return dashboardOperationalError(error, 'Product details could not be read.', 'CommerceProductDetailAction')
66
66
  }
67
67
  },
68
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,3 +1,4 @@
1
+ import type { RequestInstance } from '@stacksjs/types'
1
2
  import { Action } from '@stacksjs/actions'
2
3
  import { payments } from '@stacksjs/commerce'
3
4
  import { log } from '@stacksjs/logging'
@@ -1,3 +1,4 @@
1
+ import type { RequestInstance } from '@stacksjs/types'
1
2
  import { Action } from '@stacksjs/actions'
2
3
  import { products } from '@stacksjs/commerce'
3
4
  import { response } from '@stacksjs/router'
@@ -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,3 +1,4 @@
1
+ import type { RequestInstance } from '@stacksjs/types'
1
2
  import { Action } from '@stacksjs/actions'
2
3
  import { tax } from '@stacksjs/commerce'
3
4
  import { response } from '@stacksjs/router'
@@ -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
  })