@stacksjs/defaults 0.75.484 → 0.75.487

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 (36) hide show
  1. package/ai/skills/stacks-actions/SKILL.md +1 -1
  2. package/ai/skills/stacks-auto-imports/SKILL.md +1 -1
  3. package/ai/skills/stacks-dashboard/SKILL.md +33 -2
  4. package/ai/skills/stacks-database/SKILL.md +1 -1
  5. package/ai/skills/stacks-error-handling/SKILL.md +8 -0
  6. package/ai/skills/stacks-migrations/SKILL.md +2 -2
  7. package/ai/skills/stacks-models/SKILL.md +2 -2
  8. package/ai/skills/stacks-native/CATALOG.md +3 -3
  9. package/ai/skills/stacks-orm/SKILL.md +2 -2
  10. package/app/Actions/Dashboard/Content/CategoryDestroyAction.ts +2 -2
  11. package/app/Actions/Dashboard/Content/CategoryIndexAction.ts +2 -13
  12. package/app/Actions/Dashboard/Content/CategoryStoreAction.ts +5 -11
  13. package/app/Actions/Dashboard/Content/ContentDashboardAction.ts +1 -1
  14. package/app/Actions/Dashboard/Content/PostIndexAction.ts +1 -1
  15. package/app/Actions/Dashboard/Content/post-input.ts +1 -1
  16. package/app/Actions/Dashboard/Jobs/JobDefinitionsAction.ts +26 -0
  17. package/app/Actions/Dashboard/Jobs/JobStatsAction.ts +2 -2
  18. package/app/Actions/Dashboard/Models/ModelShowAction.ts +1 -11
  19. package/app/Actions/Dashboard/Models/ModelsIndexAction.ts +9 -41
  20. package/app/Actions/Dashboard/Queue/QueueStatsAction.ts +5 -7
  21. package/app/Actions/Dashboard/Queue/QueueWorkersAction.ts +6 -6
  22. package/app/Actions/Dashboard/Queue/queue-stats.ts +5 -1
  23. package/app/Actions/Dashboard/Search/GlobalSearchAction.ts +47 -89
  24. package/app/Actions/Dashboard/Search/SearchEngineIndexAction.ts +59 -0
  25. package/app/Models/QueueWorker.ts +17 -0
  26. package/functions/jobs.ts +14 -0
  27. package/functions/search-engine.ts +13 -0
  28. package/ide/vscode/package.json +1 -1
  29. package/package.json +2 -2
  30. package/resources/components/Dashboard/Jobs/JobDashboard.stx +24 -5
  31. package/resources/components/Dashboard/Queue/QueueDashboard.stx +2 -3
  32. package/resources/components/Dashboard/Search/SearchEngineDashboard.stx +58 -0
  33. package/resources/functions/dashboard/model-columns.ts +12 -0
  34. package/resources/functions/dashboard/sidebar.ts +4 -2
  35. package/routes/dashboard-api.ts +178 -166
  36. package/views/dashboard/search-engine/index.stx +8 -0
@@ -16,6 +16,7 @@
16
16
  * unauthenticated.
17
17
  */
18
18
 
19
+ import { feature } from '@stacksjs/config'
19
20
  import { isLocalDeployment } from '@stacksjs/env'
20
21
  import { route } from '@stacksjs/router'
21
22
 
@@ -57,6 +58,8 @@ route.group({ prefix: '/api/dashboard', apiResponse: true }, () => {
57
58
  guard(route.get('/home', 'Actions/Dashboard/DashboardHomeAction'))
58
59
  guard(route.get('/stats', 'Actions/Dashboard/DashboardStatsAction'))
59
60
  guard(route.get('/activity', 'Actions/Dashboard/DashboardActivityAction'))
61
+ guard(route.get('/search-engine', 'Actions/Dashboard/Search/SearchEngineIndexAction'))
62
+ guard(route.get('/jobs/definitions', 'Actions/Dashboard/Jobs/JobDefinitionsAction'))
60
63
  guard(route.get('/search', 'Actions/Dashboard/Search/GlobalSearchAction'))
61
64
  guard(route.get('/requests', 'Actions/Dashboard/Infrastructure/RequestIndexAction'))
62
65
  guard(route.get('/cloud', 'Actions/Dashboard/Cloud/CloudIndexAction'))
@@ -103,70 +106,72 @@ route.group({ prefix: '/api/dashboard', apiResponse: true }, () => {
103
106
  guard(route.post('/library/functions', 'Actions/Dashboard/Library/CreateFunction'))
104
107
  guard(route.get('/library/components', 'Actions/Dashboard/Library/GetComponents'))
105
108
  guard(route.post('/library/components', 'Actions/Dashboard/Library/CreateComponent'))
106
- guard(route.get('/commerce/waitlist-products', 'Actions/Dashboard/Commerce/ProductWaitlistIndexAction'))
107
- guard(route.post('/commerce/waitlist-products', 'Actions/Commerce/WaitlistProductStoreAction'))
108
- guard(route.patch('/commerce/waitlist-products/{id}', 'Actions/Commerce/WaitlistProductUpdateAction'))
109
- guard(route.delete('/commerce/waitlist-products/{id}', 'Actions/Commerce/WaitlistProductDestroyAction'))
110
- guard(route.get('/commerce/waitlist-restaurants', 'Actions/Dashboard/Commerce/RestaurantWaitlistIndexAction'))
111
- guard(route.post('/commerce/waitlist-restaurants', 'Actions/Commerce/WaitlistRestaurantStoreAction'))
112
- guard(route.patch('/commerce/waitlist-restaurants/{id}', 'Actions/Commerce/WaitlistRestaurantUpdateAction'))
113
- guard(route.delete('/commerce/waitlist-restaurants/{id}', 'Actions/Commerce/WaitlistRestaurantDestroyAction'))
114
- guard(route.get('/commerce/reviews', 'Actions/Dashboard/Commerce/ReviewIndexAction'))
115
- guard(route.patch('/commerce/reviews/{id}', 'Actions/Commerce/ReviewUpdateAction'))
116
- guard(route.delete('/commerce/reviews/{id}', 'Actions/Commerce/ReviewDestroyAction'))
117
- guard(route.get('/commerce/coupons', 'Actions/Dashboard/Commerce/CommerceCouponsAction'))
118
- guard(route.post('/commerce/coupons', 'Actions/Commerce/CouponStoreAction'))
119
- guard(route.patch('/commerce/coupons/{id}', 'Actions/Commerce/CouponUpdateAction'))
120
- guard(route.delete('/commerce/coupons/{id}', 'Actions/Commerce/CouponDestroyAction'))
121
- guard(route.get('/commerce/gift-cards', 'Actions/Dashboard/Commerce/CommerceGiftCardsAction'))
122
- guard(route.post('/commerce/gift-cards', 'Actions/Commerce/GiftCardStoreAction'))
123
- guard(route.patch('/commerce/gift-cards/{id}', 'Actions/Commerce/GiftCardUpdateAction'))
124
- guard(route.delete('/commerce/gift-cards/{id}', 'Actions/Commerce/GiftCardDestroyAction'))
125
- guard(route.get('/commerce/categories', 'Actions/Dashboard/Commerce/CommerceCategoriesAction'))
126
- guard(route.post('/commerce/categories', 'Actions/Commerce/Product/ProductCategoryStoreAction'))
127
- guard(route.patch('/commerce/categories/{id}', 'Actions/Commerce/Product/ProductCategoryUpdateAction'))
128
- guard(route.delete('/commerce/categories/{id}', 'Actions/Commerce/Product/ProductCategoryDestroyAction'))
129
- guard(route.get('/commerce/customers', 'Actions/Dashboard/Commerce/CommerceCustomersAction'))
130
- guard(route.post('/commerce/customers', 'Actions/Commerce/CustomerStoreAction'))
131
- guard(route.patch('/commerce/customers/{id}', 'Actions/Commerce/CustomerUpdateAction'))
132
- guard(route.delete('/commerce/customers/{id}', 'Actions/Commerce/CustomerDestroyAction'))
133
- guard(route.get('/commerce/orders', 'Actions/Dashboard/Commerce/CommerceOrdersAction'))
134
- guard(route.post('/commerce/orders', 'Actions/Commerce/OrderStoreAction'))
135
- guard(route.patch('/commerce/orders/{id}', 'Actions/Commerce/OrderUpdateAction'))
136
- guard(route.delete('/commerce/orders/{id}', 'Actions/Commerce/OrderDestroyAction'))
137
- guard(route.get('/commerce/pos', 'Actions/Dashboard/Commerce/CommercePosAction'))
138
- guard(route.post('/commerce/pos/checkout', 'Actions/Dashboard/Commerce/CommercePosCheckoutAction'))
139
- guard(route.get('/commerce/products', 'Actions/Dashboard/Commerce/CommerceProductsAction'))
140
- guard(route.get('/commerce/products/{id}', 'Actions/Dashboard/Commerce/CommerceProductDetailAction'))
141
- guard(route.post('/commerce/products', 'Actions/Commerce/Product/ProductStoreAction'))
142
- guard(route.patch('/commerce/products/{id}', 'Actions/Commerce/Product/ProductUpdateAction'))
143
- guard(route.delete('/commerce/products/{id}', 'Actions/Commerce/Product/ProductDestroyAction'))
144
- guard(route.get('/commerce/manufacturers', 'Actions/Dashboard/Commerce/ManufacturerIndexAction'))
145
- guard(route.post('/commerce/manufacturers', 'Actions/Commerce/Product/ManufacturerStoreAction'))
146
- guard(route.patch('/commerce/manufacturers/{id}', 'Actions/Commerce/Product/ManufacturerUpdateAction'))
147
- guard(route.delete('/commerce/manufacturers/{id}', 'Actions/Commerce/Product/ManufacturerDestroyAction'))
148
- guard(route.get('/commerce/units', 'Actions/Dashboard/Commerce/ProductUnitIndexAction'))
149
- guard(route.post('/commerce/units', 'Actions/Commerce/Product/ProductUnitStoreAction'))
150
- guard(route.patch('/commerce/units/{id}', 'Actions/Commerce/Product/ProductUnitUpdateAction'))
151
- guard(route.delete('/commerce/units/{id}', 'Actions/Commerce/Product/ProductUnitDestroyAction'))
152
- guard(route.patch('/commerce/units/{id}/default', 'Actions/Dashboard/Commerce/ProductUnitDefaultAction'))
153
- guard(route.get('/commerce/taxes', 'Actions/Dashboard/Commerce/CommerceTaxesAction'))
154
- guard(route.post('/commerce/taxes', 'Actions/Commerce/TaxRateStoreAction'))
155
- guard(route.patch('/commerce/taxes/{id}', 'Actions/Commerce/TaxRateUpdateAction'))
156
- guard(route.delete('/commerce/taxes/{id}', 'Actions/Commerce/TaxRateDestroyAction'))
157
- guard(route.patch('/commerce/taxes/{id}/default', 'Actions/Dashboard/Commerce/TaxRateDefaultAction'))
158
- guard(route.get('/commerce/variants', 'Actions/Dashboard/Commerce/ProductVariantIndexAction'))
159
- guard(route.post('/commerce/variants', 'Actions/Commerce/Product/ProductVariantStoreAction'))
160
- guard(route.patch('/commerce/variants/{id}', 'Actions/Commerce/Product/ProductVariantUpdateAction'))
161
- guard(route.delete('/commerce/variants/{id}', 'Actions/Commerce/Product/ProductVariantDestroyAction'))
162
- guard(route.get('/commerce/payments', 'Actions/Dashboard/Commerce/CommercePaymentsAction'))
163
- guard(route.post('/commerce/payments/{id}/refund', 'Actions/Dashboard/Commerce/PaymentRefundAction'))
164
- guard(route.get('/commerce/print-devices', 'Actions/Dashboard/Commerce/CommercePrintDevicesAction'))
165
- guard(route.post('/commerce/print-devices', 'Actions/Commerce/PrintDeviceStoreAction'))
166
- guard(route.patch('/commerce/print-devices/{id}', 'Actions/Commerce/PrintDeviceUpdateAction'))
167
- guard(route.delete('/commerce/print-devices/{id}', 'Actions/Commerce/PrintDeviceDestroyAction'))
168
- guard(route.get('/commerce/print-logs', 'Actions/Dashboard/Commerce/CommercePrintLogsAction'))
169
- guard(route.delete('/commerce/print-logs/{id}', 'Actions/Commerce/ReceiptDestroyAction'))
109
+ if (feature('commerce')) {
110
+ guard(route.get('/commerce/waitlist-products', 'Actions/Dashboard/Commerce/ProductWaitlistIndexAction'))
111
+ guard(route.post('/commerce/waitlist-products', 'Actions/Commerce/WaitlistProductStoreAction'))
112
+ guard(route.patch('/commerce/waitlist-products/{id}', 'Actions/Commerce/WaitlistProductUpdateAction'))
113
+ guard(route.delete('/commerce/waitlist-products/{id}', 'Actions/Commerce/WaitlistProductDestroyAction'))
114
+ guard(route.get('/commerce/waitlist-restaurants', 'Actions/Dashboard/Commerce/RestaurantWaitlistIndexAction'))
115
+ guard(route.post('/commerce/waitlist-restaurants', 'Actions/Commerce/WaitlistRestaurantStoreAction'))
116
+ guard(route.patch('/commerce/waitlist-restaurants/{id}', 'Actions/Commerce/WaitlistRestaurantUpdateAction'))
117
+ guard(route.delete('/commerce/waitlist-restaurants/{id}', 'Actions/Commerce/WaitlistRestaurantDestroyAction'))
118
+ guard(route.get('/commerce/reviews', 'Actions/Dashboard/Commerce/ReviewIndexAction'))
119
+ guard(route.patch('/commerce/reviews/{id}', 'Actions/Commerce/ReviewUpdateAction'))
120
+ guard(route.delete('/commerce/reviews/{id}', 'Actions/Commerce/ReviewDestroyAction'))
121
+ guard(route.get('/commerce/coupons', 'Actions/Dashboard/Commerce/CommerceCouponsAction'))
122
+ guard(route.post('/commerce/coupons', 'Actions/Commerce/CouponStoreAction'))
123
+ guard(route.patch('/commerce/coupons/{id}', 'Actions/Commerce/CouponUpdateAction'))
124
+ guard(route.delete('/commerce/coupons/{id}', 'Actions/Commerce/CouponDestroyAction'))
125
+ guard(route.get('/commerce/gift-cards', 'Actions/Dashboard/Commerce/CommerceGiftCardsAction'))
126
+ guard(route.post('/commerce/gift-cards', 'Actions/Commerce/GiftCardStoreAction'))
127
+ guard(route.patch('/commerce/gift-cards/{id}', 'Actions/Commerce/GiftCardUpdateAction'))
128
+ guard(route.delete('/commerce/gift-cards/{id}', 'Actions/Commerce/GiftCardDestroyAction'))
129
+ guard(route.get('/commerce/categories', 'Actions/Dashboard/Commerce/CommerceCategoriesAction'))
130
+ guard(route.post('/commerce/categories', 'Actions/Commerce/Product/ProductCategoryStoreAction'))
131
+ guard(route.patch('/commerce/categories/{id}', 'Actions/Commerce/Product/ProductCategoryUpdateAction'))
132
+ guard(route.delete('/commerce/categories/{id}', 'Actions/Commerce/Product/ProductCategoryDestroyAction'))
133
+ guard(route.get('/commerce/customers', 'Actions/Dashboard/Commerce/CommerceCustomersAction'))
134
+ guard(route.post('/commerce/customers', 'Actions/Commerce/CustomerStoreAction'))
135
+ guard(route.patch('/commerce/customers/{id}', 'Actions/Commerce/CustomerUpdateAction'))
136
+ guard(route.delete('/commerce/customers/{id}', 'Actions/Commerce/CustomerDestroyAction'))
137
+ guard(route.get('/commerce/orders', 'Actions/Dashboard/Commerce/CommerceOrdersAction'))
138
+ guard(route.post('/commerce/orders', 'Actions/Commerce/OrderStoreAction'))
139
+ guard(route.patch('/commerce/orders/{id}', 'Actions/Commerce/OrderUpdateAction'))
140
+ guard(route.delete('/commerce/orders/{id}', 'Actions/Commerce/OrderDestroyAction'))
141
+ guard(route.get('/commerce/pos', 'Actions/Dashboard/Commerce/CommercePosAction'))
142
+ guard(route.post('/commerce/pos/checkout', 'Actions/Dashboard/Commerce/CommercePosCheckoutAction'))
143
+ guard(route.get('/commerce/products', 'Actions/Dashboard/Commerce/CommerceProductsAction'))
144
+ guard(route.get('/commerce/products/{id}', 'Actions/Dashboard/Commerce/CommerceProductDetailAction'))
145
+ guard(route.post('/commerce/products', 'Actions/Commerce/Product/ProductStoreAction'))
146
+ guard(route.patch('/commerce/products/{id}', 'Actions/Commerce/Product/ProductUpdateAction'))
147
+ guard(route.delete('/commerce/products/{id}', 'Actions/Commerce/Product/ProductDestroyAction'))
148
+ guard(route.get('/commerce/manufacturers', 'Actions/Dashboard/Commerce/ManufacturerIndexAction'))
149
+ guard(route.post('/commerce/manufacturers', 'Actions/Commerce/Product/ManufacturerStoreAction'))
150
+ guard(route.patch('/commerce/manufacturers/{id}', 'Actions/Commerce/Product/ManufacturerUpdateAction'))
151
+ guard(route.delete('/commerce/manufacturers/{id}', 'Actions/Commerce/Product/ManufacturerDestroyAction'))
152
+ guard(route.get('/commerce/units', 'Actions/Dashboard/Commerce/ProductUnitIndexAction'))
153
+ guard(route.post('/commerce/units', 'Actions/Commerce/Product/ProductUnitStoreAction'))
154
+ guard(route.patch('/commerce/units/{id}', 'Actions/Commerce/Product/ProductUnitUpdateAction'))
155
+ guard(route.delete('/commerce/units/{id}', 'Actions/Commerce/Product/ProductUnitDestroyAction'))
156
+ guard(route.patch('/commerce/units/{id}/default', 'Actions/Dashboard/Commerce/ProductUnitDefaultAction'))
157
+ guard(route.get('/commerce/taxes', 'Actions/Dashboard/Commerce/CommerceTaxesAction'))
158
+ guard(route.post('/commerce/taxes', 'Actions/Commerce/TaxRateStoreAction'))
159
+ guard(route.patch('/commerce/taxes/{id}', 'Actions/Commerce/TaxRateUpdateAction'))
160
+ guard(route.delete('/commerce/taxes/{id}', 'Actions/Commerce/TaxRateDestroyAction'))
161
+ guard(route.patch('/commerce/taxes/{id}/default', 'Actions/Dashboard/Commerce/TaxRateDefaultAction'))
162
+ guard(route.get('/commerce/variants', 'Actions/Dashboard/Commerce/ProductVariantIndexAction'))
163
+ guard(route.post('/commerce/variants', 'Actions/Commerce/Product/ProductVariantStoreAction'))
164
+ guard(route.patch('/commerce/variants/{id}', 'Actions/Commerce/Product/ProductVariantUpdateAction'))
165
+ guard(route.delete('/commerce/variants/{id}', 'Actions/Commerce/Product/ProductVariantDestroyAction'))
166
+ guard(route.get('/commerce/payments', 'Actions/Dashboard/Commerce/CommercePaymentsAction'))
167
+ guard(route.post('/commerce/payments/{id}/refund', 'Actions/Dashboard/Commerce/PaymentRefundAction'))
168
+ guard(route.get('/commerce/print-devices', 'Actions/Dashboard/Commerce/CommercePrintDevicesAction'))
169
+ guard(route.post('/commerce/print-devices', 'Actions/Commerce/PrintDeviceStoreAction'))
170
+ guard(route.patch('/commerce/print-devices/{id}', 'Actions/Commerce/PrintDeviceUpdateAction'))
171
+ guard(route.delete('/commerce/print-devices/{id}', 'Actions/Commerce/PrintDeviceDestroyAction'))
172
+ guard(route.get('/commerce/print-logs', 'Actions/Dashboard/Commerce/CommercePrintLogsAction'))
173
+ guard(route.delete('/commerce/print-logs/{id}', 'Actions/Commerce/ReceiptDestroyAction'))
174
+ }
170
175
  guard(route.get('/deployments', 'Actions/Dashboard/Deployments/GetDeployments'))
171
176
  guard(route.post('/deployments', 'Actions/Dashboard/Deployments/CreateDeployment'))
172
177
  guard(route.post('/deployments/preview', 'Actions/Dashboard/Deployments/PreviewDeployment'))
@@ -221,35 +226,37 @@ route.group({ prefix: '/api/dashboard', apiResponse: true }, () => {
221
226
  //
222
227
  // Guarded for the same reason as the blog routes below: the writes mutate the
223
228
  // database and the reads expose unpublished drafts and unmoderated comments.
224
- guard(route.get('/content/overview', 'Actions/Dashboard/Content/ContentDashboardAction'))
225
- guard(route.get('/posts', 'Actions/Dashboard/Content/PostIndexAction'))
226
- guard(route.post('/posts', 'Actions/Dashboard/Content/PostStoreAction'))
227
- guard(route.get('/posts/{id}', 'Actions/Dashboard/Content/PostShowAction'))
228
- guard(route.patch('/posts/{id}', 'Actions/Dashboard/Content/PostUpdateAction'))
229
- guard(route.delete('/posts/{id}', 'Actions/Dashboard/Content/PostDestroyAction'))
230
-
231
- guard(route.get('/authors', 'Actions/Dashboard/Content/AuthorIndexAction'))
232
- guard(route.post('/authors', 'Actions/Dashboard/Content/AuthorStoreAction'))
233
- guard(route.patch('/authors/{id}', 'Actions/Dashboard/Content/AuthorUpdateAction'))
234
- guard(route.delete('/authors/{id}', 'Actions/Dashboard/Content/AuthorDestroyAction'))
235
-
236
- guard(route.get('/categories', 'Actions/Dashboard/Content/CategoryIndexAction'))
237
- guard(route.post('/categories', 'Actions/Dashboard/Content/CategoryStoreAction'))
238
- guard(route.delete('/categories/{id}', 'Actions/Dashboard/Content/CategoryDestroyAction'))
239
-
240
- guard(route.get('/tags', 'Actions/Dashboard/Content/TagIndexAction'))
241
- guard(route.post('/tags', 'Actions/Dashboard/Content/TagStoreAction'))
242
- guard(route.delete('/tags/{id}', 'Actions/Dashboard/Content/TagDestroyAction'))
243
-
244
- guard(route.get('/pages', 'Actions/Dashboard/Content/PageIndexAction'))
245
- guard(route.post('/pages', 'Actions/Dashboard/Content/PageStoreAction'))
246
- guard(route.patch('/pages/{id}', 'Actions/Dashboard/Content/PageUpdateAction'))
247
- guard(route.delete('/pages/{id}', 'Actions/Dashboard/Content/PageDestroyAction'))
248
-
249
- // No store route: comments arrive from readers, the dashboard only moderates.
250
- guard(route.get('/comments', 'Actions/Dashboard/Content/CommentIndexAction'))
251
- guard(route.patch('/comments/{id}', 'Actions/Dashboard/Content/CommentUpdateAction'))
252
- guard(route.delete('/comments/{id}', 'Actions/Dashboard/Content/CommentDestroyAction'))
229
+ if (feature('cms')) {
230
+ guard(route.get('/content/overview', 'Actions/Dashboard/Content/ContentDashboardAction'))
231
+ guard(route.get('/posts', 'Actions/Dashboard/Content/PostIndexAction'))
232
+ guard(route.post('/posts', 'Actions/Dashboard/Content/PostStoreAction'))
233
+ guard(route.get('/posts/{id}', 'Actions/Dashboard/Content/PostShowAction'))
234
+ guard(route.patch('/posts/{id}', 'Actions/Dashboard/Content/PostUpdateAction'))
235
+ guard(route.delete('/posts/{id}', 'Actions/Dashboard/Content/PostDestroyAction'))
236
+
237
+ guard(route.get('/authors', 'Actions/Dashboard/Content/AuthorIndexAction'))
238
+ guard(route.post('/authors', 'Actions/Dashboard/Content/AuthorStoreAction'))
239
+ guard(route.patch('/authors/{id}', 'Actions/Dashboard/Content/AuthorUpdateAction'))
240
+ guard(route.delete('/authors/{id}', 'Actions/Dashboard/Content/AuthorDestroyAction'))
241
+
242
+ guard(route.get('/categories', 'Actions/Dashboard/Content/CategoryIndexAction'))
243
+ guard(route.post('/categories', 'Actions/Dashboard/Content/CategoryStoreAction'))
244
+ guard(route.delete('/categories/{id}', 'Actions/Dashboard/Content/CategoryDestroyAction'))
245
+
246
+ guard(route.get('/tags', 'Actions/Dashboard/Content/TagIndexAction'))
247
+ guard(route.post('/tags', 'Actions/Dashboard/Content/TagStoreAction'))
248
+ guard(route.delete('/tags/{id}', 'Actions/Dashboard/Content/TagDestroyAction'))
249
+
250
+ guard(route.get('/pages', 'Actions/Dashboard/Content/PageIndexAction'))
251
+ guard(route.post('/pages', 'Actions/Dashboard/Content/PageStoreAction'))
252
+ guard(route.patch('/pages/{id}', 'Actions/Dashboard/Content/PageUpdateAction'))
253
+ guard(route.delete('/pages/{id}', 'Actions/Dashboard/Content/PageDestroyAction'))
254
+
255
+ // No store route: comments arrive from readers, the dashboard only moderates.
256
+ guard(route.get('/comments', 'Actions/Dashboard/Content/CommentIndexAction'))
257
+ guard(route.patch('/comments/{id}', 'Actions/Dashboard/Content/CommentUpdateAction'))
258
+ guard(route.delete('/comments/{id}', 'Actions/Dashboard/Content/CommentDestroyAction'))
259
+ }
253
260
 
254
261
  guard(route.get('/files', 'Actions/Dashboard/Content/FileIndexAction'))
255
262
  guard(route.post('/files/directories', 'Actions/Dashboard/Content/FileDirectoryStoreAction'))
@@ -393,79 +400,84 @@ route.group({ prefix: '/api/dashboard', apiResponse: true }, () => {
393
400
  // Commerce dashboard stats. Same Action that backs the auth'd
394
401
  // `/api/commerce/dashboard`, projected through the local-friendly dashboard
395
402
  // guard so production totals are never protected by client-side role checks.
396
- guard(route.get('/commerce/stats', 'Actions/Dashboard/Commerce/CommerceDashboardAction'))
397
-
398
- // Delivery operations overview. Guarded because route and courier data is
399
- // operational information even though the underlying models expose their
400
- // own generated useApi endpoints.
401
- guard(route.get('/commerce/delivery', 'Actions/Dashboard/Commerce/CommerceDeliveryAction'))
402
-
403
- // Dashboard-local aliases for the model-backed delivery resources. These
404
- // reuse the same commerce Actions as the authenticated public API while the
405
- // local guard keeps `buddy dev --dashboard` usable without a login session.
406
- guard(route.get('/commerce/shipping-methods', 'Actions/Dashboard/Commerce/ShippingMethodIndexAction'))
407
- guard(route.get('/commerce/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodShowAction'))
408
- guard(route.post('/commerce/shipping-methods', 'Actions/Commerce/Shipping/ShippingMethodStoreAction'))
409
- guard(route.patch('/commerce/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodUpdateAction'))
410
- guard(route.delete('/commerce/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodDestroyAction'))
411
-
412
- guard(route.get('/commerce/shipping-rates', 'Actions/Dashboard/Commerce/ShippingRateIndexAction'))
413
- guard(route.get('/commerce/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateShowAction'))
414
- guard(route.post('/commerce/shipping-rates', 'Actions/Commerce/Shipping/ShippingRateStoreAction'))
415
- guard(route.patch('/commerce/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateUpdateAction'))
416
- guard(route.delete('/commerce/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateDestroyAction'))
417
-
418
- guard(route.get('/commerce/shipping-zones', 'Actions/Dashboard/Commerce/ShippingZoneIndexAction'))
419
- guard(route.get('/commerce/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneShowAction'))
420
- guard(route.post('/commerce/shipping-zones', 'Actions/Commerce/Shipping/ShippingZoneStoreAction'))
421
- guard(route.patch('/commerce/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneUpdateAction'))
422
- guard(route.delete('/commerce/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneDestroyAction'))
423
-
424
- guard(route.get('/commerce/delivery-routes', 'Actions/Dashboard/Commerce/DeliveryRouteIndexAction'))
425
- guard(route.get('/commerce/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteShowAction'))
426
- guard(route.post('/commerce/delivery-routes', 'Actions/Commerce/Shipping/DeliveryRouteStoreAction'))
427
- guard(route.patch('/commerce/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteUpdateAction'))
428
- guard(route.delete('/commerce/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteDestroyAction'))
429
-
430
- guard(route.get('/commerce/couriers', 'Actions/Dashboard/Commerce/CourierIndexAction'))
431
- guard(route.get('/commerce/couriers/{id}', 'Actions/Commerce/Shipping/CourierShowAction'))
432
- guard(route.post('/commerce/couriers', 'Actions/Commerce/Shipping/CourierStoreAction'))
433
- guard(route.patch('/commerce/couriers/{id}', 'Actions/Commerce/Shipping/CourierUpdateAction'))
434
- guard(route.delete('/commerce/couriers/{id}', 'Actions/Commerce/Shipping/CourierDestroyAction'))
435
-
436
- guard(route.get('/commerce/digital-deliveries', 'Actions/Dashboard/Commerce/DigitalDeliveryIndexAction'))
437
- guard(route.get('/commerce/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryShowAction'))
438
- guard(route.post('/commerce/digital-deliveries', 'Actions/Commerce/Shipping/DigitalDeliveryStoreAction'))
439
- guard(route.patch('/commerce/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryUpdateAction'))
440
- guard(route.delete('/commerce/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryDestroyAction'))
441
-
442
- guard(route.get('/commerce/license-keys', 'Actions/Dashboard/Commerce/LicenseKeyIndexAction'))
443
- guard(route.get('/commerce/license-key-options', 'Actions/Dashboard/Commerce/LicenseKeyOptionsAction'))
444
- guard(route.get('/commerce/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyShowAction'))
445
- guard(route.post('/commerce/license-keys', 'Actions/Commerce/Shipping/LicenseKeyStoreAction'))
446
- guard(route.patch('/commerce/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyUpdateAction'))
447
- guard(route.delete('/commerce/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyDestroyAction'))
448
-
449
- guard(route.get('/marketing/lists', 'Actions/Dashboard/Marketing/ListIndexAction'))
450
- guard(route.post('/marketing/lists', 'Actions/Dashboard/Marketing/ListStoreAction'))
451
- guard(route.patch('/marketing/lists/{id}', 'Actions/Dashboard/Marketing/ListUpdateAction'))
452
- guard(route.delete('/marketing/lists/{id}', 'Actions/Dashboard/Marketing/ListDestroyAction'))
453
- guard(route.get('/marketing/campaigns', 'Actions/Dashboard/Marketing/CampaignIndexAction'))
454
- guard(route.post('/marketing/campaigns', 'Actions/Dashboard/Marketing/CampaignStoreAction'))
455
- guard(route.patch('/marketing/campaigns/{id}', 'Actions/Dashboard/Marketing/CampaignUpdateAction'))
456
- guard(route.delete('/marketing/campaigns/{id}', 'Actions/Dashboard/Marketing/CampaignDestroyAction'))
457
- guard(route.post('/marketing/campaigns/{id}/send', 'Actions/Dashboard/Marketing/CampaignSendAction'))
458
- guard(route.post('/marketing/campaigns/{id}/schedule', 'Actions/Dashboard/Marketing/CampaignScheduleAction'))
459
- guard(route.post('/marketing/campaigns/{id}/cancel', 'Actions/Dashboard/Marketing/CampaignCancelAction'))
460
- // Abandoned carts: the audience a shop already has, and the campaign that
461
- // goes after it. The campaign it writes is an ordinary Campaign row, so it
462
- // shows up on /marketing/campaigns and sends through the same pipeline.
463
- guard(route.get('/marketing/abandoned-carts', 'Actions/Dashboard/Marketing/AbandonedCartIndexAction'))
464
- guard(route.post('/marketing/abandoned-carts/campaign', 'Actions/Dashboard/Marketing/AbandonedCartCampaignAction'))
465
- guard(route.get('/marketing/social-posts', 'Actions/Dashboard/Marketing/SocialPostIndexAction'))
466
- guard(route.post('/marketing/social-posts', 'Actions/Dashboard/Marketing/SocialPostStoreAction'))
467
- guard(route.patch('/marketing/social-posts/{id}', 'Actions/Dashboard/Marketing/SocialPostUpdateAction'))
468
- guard(route.delete('/marketing/social-posts/{id}', 'Actions/Dashboard/Marketing/SocialPostDestroyAction'))
403
+ if (feature('commerce')) {
404
+ guard(route.get('/commerce/stats', 'Actions/Dashboard/Commerce/CommerceDashboardAction'))
405
+
406
+ // Delivery operations overview. Guarded because route and courier data is
407
+ // operational information even though the underlying models expose their
408
+ // own generated useApi endpoints.
409
+ guard(route.get('/commerce/delivery', 'Actions/Dashboard/Commerce/CommerceDeliveryAction'))
410
+
411
+ // Dashboard-local aliases for the model-backed delivery resources. These
412
+ // reuse the same commerce Actions as the authenticated public API while the
413
+ // local guard keeps `buddy dev --dashboard` usable without a login session.
414
+ guard(route.get('/commerce/shipping-methods', 'Actions/Dashboard/Commerce/ShippingMethodIndexAction'))
415
+ guard(route.get('/commerce/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodShowAction'))
416
+ guard(route.post('/commerce/shipping-methods', 'Actions/Commerce/Shipping/ShippingMethodStoreAction'))
417
+ guard(route.patch('/commerce/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodUpdateAction'))
418
+ guard(route.delete('/commerce/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodDestroyAction'))
419
+
420
+ guard(route.get('/commerce/shipping-rates', 'Actions/Dashboard/Commerce/ShippingRateIndexAction'))
421
+ guard(route.get('/commerce/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateShowAction'))
422
+ guard(route.post('/commerce/shipping-rates', 'Actions/Commerce/Shipping/ShippingRateStoreAction'))
423
+ guard(route.patch('/commerce/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateUpdateAction'))
424
+ guard(route.delete('/commerce/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateDestroyAction'))
425
+
426
+ guard(route.get('/commerce/shipping-zones', 'Actions/Dashboard/Commerce/ShippingZoneIndexAction'))
427
+ guard(route.get('/commerce/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneShowAction'))
428
+ guard(route.post('/commerce/shipping-zones', 'Actions/Commerce/Shipping/ShippingZoneStoreAction'))
429
+ guard(route.patch('/commerce/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneUpdateAction'))
430
+ guard(route.delete('/commerce/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneDestroyAction'))
431
+
432
+ guard(route.get('/commerce/delivery-routes', 'Actions/Dashboard/Commerce/DeliveryRouteIndexAction'))
433
+ guard(route.get('/commerce/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteShowAction'))
434
+ guard(route.post('/commerce/delivery-routes', 'Actions/Commerce/Shipping/DeliveryRouteStoreAction'))
435
+ guard(route.patch('/commerce/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteUpdateAction'))
436
+ guard(route.delete('/commerce/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteDestroyAction'))
437
+
438
+ guard(route.get('/commerce/couriers', 'Actions/Dashboard/Commerce/CourierIndexAction'))
439
+ guard(route.get('/commerce/couriers/{id}', 'Actions/Commerce/Shipping/CourierShowAction'))
440
+ guard(route.post('/commerce/couriers', 'Actions/Commerce/Shipping/CourierStoreAction'))
441
+ guard(route.patch('/commerce/couriers/{id}', 'Actions/Commerce/Shipping/CourierUpdateAction'))
442
+ guard(route.delete('/commerce/couriers/{id}', 'Actions/Commerce/Shipping/CourierDestroyAction'))
443
+
444
+ guard(route.get('/commerce/digital-deliveries', 'Actions/Dashboard/Commerce/DigitalDeliveryIndexAction'))
445
+ guard(route.get('/commerce/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryShowAction'))
446
+ guard(route.post('/commerce/digital-deliveries', 'Actions/Commerce/Shipping/DigitalDeliveryStoreAction'))
447
+ guard(route.patch('/commerce/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryUpdateAction'))
448
+ guard(route.delete('/commerce/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryDestroyAction'))
449
+
450
+ guard(route.get('/commerce/license-keys', 'Actions/Dashboard/Commerce/LicenseKeyIndexAction'))
451
+ guard(route.get('/commerce/license-key-options', 'Actions/Dashboard/Commerce/LicenseKeyOptionsAction'))
452
+ guard(route.get('/commerce/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyShowAction'))
453
+ guard(route.post('/commerce/license-keys', 'Actions/Commerce/Shipping/LicenseKeyStoreAction'))
454
+ guard(route.patch('/commerce/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyUpdateAction'))
455
+ guard(route.delete('/commerce/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyDestroyAction'))
456
+ }
457
+
458
+ if (feature('marketing')) {
459
+ guard(route.get('/marketing/lists', 'Actions/Dashboard/Marketing/ListIndexAction'))
460
+ guard(route.post('/marketing/lists', 'Actions/Dashboard/Marketing/ListStoreAction'))
461
+ guard(route.patch('/marketing/lists/{id}', 'Actions/Dashboard/Marketing/ListUpdateAction'))
462
+ guard(route.delete('/marketing/lists/{id}', 'Actions/Dashboard/Marketing/ListDestroyAction'))
463
+ guard(route.get('/marketing/campaigns', 'Actions/Dashboard/Marketing/CampaignIndexAction'))
464
+ guard(route.post('/marketing/campaigns', 'Actions/Dashboard/Marketing/CampaignStoreAction'))
465
+ guard(route.patch('/marketing/campaigns/{id}', 'Actions/Dashboard/Marketing/CampaignUpdateAction'))
466
+ guard(route.delete('/marketing/campaigns/{id}', 'Actions/Dashboard/Marketing/CampaignDestroyAction'))
467
+ guard(route.post('/marketing/campaigns/{id}/send', 'Actions/Dashboard/Marketing/CampaignSendAction'))
468
+ guard(route.post('/marketing/campaigns/{id}/schedule', 'Actions/Dashboard/Marketing/CampaignScheduleAction'))
469
+ guard(route.post('/marketing/campaigns/{id}/cancel', 'Actions/Dashboard/Marketing/CampaignCancelAction'))
470
+ // Abandoned carts: the audience a shop already has, and the campaign that
471
+ // goes after it. The campaign it writes is an ordinary Campaign row, so it
472
+ // shows up on /marketing/campaigns and sends through the same pipeline.
473
+ if (feature('commerce'))
474
+ guard(route.get('/marketing/abandoned-carts', 'Actions/Dashboard/Marketing/AbandonedCartIndexAction'))
475
+ guard(route.post('/marketing/abandoned-carts/campaign', 'Actions/Dashboard/Marketing/AbandonedCartCampaignAction'))
476
+ guard(route.get('/marketing/social-posts', 'Actions/Dashboard/Marketing/SocialPostIndexAction'))
477
+ guard(route.post('/marketing/social-posts', 'Actions/Dashboard/Marketing/SocialPostStoreAction'))
478
+ guard(route.patch('/marketing/social-posts/{id}', 'Actions/Dashboard/Marketing/SocialPostUpdateAction'))
479
+ guard(route.delete('/marketing/social-posts/{id}', 'Actions/Dashboard/Marketing/SocialPostDestroyAction'))
480
+ }
469
481
 
470
482
  guard(route.get('/notification-deliveries', 'Actions/Dashboard/Notifications/NotificationDeliveryIndexAction'))
471
483
  guard(route.get('/notification-deliveries/overview', 'Actions/Dashboard/Notifications/NotificationDeliveryOverviewAction'))
@@ -0,0 +1,8 @@
1
+ @extends('layouts/default')
2
+
3
+ @section('content')
4
+ @title('Dashboard - Search Engine')
5
+ <PageLayout>
6
+ <SearchEngineDashboard />
7
+ </PageLayout>
8
+ @endsection