@stacksjs/defaults 0.70.206 → 0.70.208

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 (408) hide show
  1. package/TODO.md +21 -0
  2. package/ai/AGENTS.md +79 -0
  3. package/ai/README.md +45 -0
  4. package/ai/claude/launch.json +12 -0
  5. package/ai/skills/stacks-actions/SKILL.md +128 -0
  6. package/ai/skills/stacks-ai/SKILL.md +276 -0
  7. package/ai/skills/stacks-alias/SKILL.md +94 -0
  8. package/ai/skills/stacks-analytics/SKILL.md +91 -0
  9. package/ai/skills/stacks-api/SKILL.md +738 -0
  10. package/ai/skills/stacks-arrays/SKILL.md +277 -0
  11. package/ai/skills/stacks-auth/SKILL.md +422 -0
  12. package/ai/skills/stacks-auto-imports/SKILL.md +138 -0
  13. package/ai/skills/stacks-brandkit/SKILL.md +811 -0
  14. package/ai/skills/stacks-browse/SKILL.md +127 -0
  15. package/ai/skills/stacks-browse/scripts/browse.ts +492 -0
  16. package/ai/skills/stacks-browser/SKILL.md +145 -0
  17. package/ai/skills/stacks-buddy/SKILL.md +676 -0
  18. package/ai/skills/stacks-build/SKILL.md +163 -0
  19. package/ai/skills/stacks-cache/SKILL.md +125 -0
  20. package/ai/skills/stacks-calendar/SKILL.md +113 -0
  21. package/ai/skills/stacks-chat/SKILL.md +371 -0
  22. package/ai/skills/stacks-cli/SKILL.md +112 -0
  23. package/ai/skills/stacks-cloud/SKILL.md +192 -0
  24. package/ai/skills/stacks-cms/SKILL.md +217 -0
  25. package/ai/skills/stacks-collections/SKILL.md +82 -0
  26. package/ai/skills/stacks-commerce/SKILL.md +114 -0
  27. package/ai/skills/stacks-composables/SKILL.md +161 -0
  28. package/ai/skills/stacks-config/SKILL.md +144 -0
  29. package/ai/skills/stacks-configuration/SKILL.md +154 -0
  30. package/ai/skills/stacks-cron/SKILL.md +123 -0
  31. package/ai/skills/stacks-crosswind/SKILL.md +190 -0
  32. package/ai/skills/stacks-dashboard/SKILL.md +173 -0
  33. package/ai/skills/stacks-database/SKILL.md +286 -0
  34. package/ai/skills/stacks-datetime/SKILL.md +269 -0
  35. package/ai/skills/stacks-dependencies/SKILL.md +111 -0
  36. package/ai/skills/stacks-deploy/SKILL.md +102 -0
  37. package/ai/skills/stacks-design-brutalist/SKILL.md +110 -0
  38. package/ai/skills/stacks-design-minimalist/SKILL.md +115 -0
  39. package/ai/skills/stacks-design-output/SKILL.md +55 -0
  40. package/ai/skills/stacks-design-soft/SKILL.md +156 -0
  41. package/ai/skills/stacks-design-taste/SKILL.md +1012 -0
  42. package/ai/skills/stacks-design-taste-codex/SKILL.md +294 -0
  43. package/ai/skills/stacks-desktop/SKILL.md +78 -0
  44. package/ai/skills/stacks-development/SKILL.md +298 -0
  45. package/ai/skills/stacks-dns/SKILL.md +149 -0
  46. package/ai/skills/stacks-docs/SKILL.md +109 -0
  47. package/ai/skills/stacks-email/SKILL.md +236 -0
  48. package/ai/skills/stacks-enums/SKILL.md +100 -0
  49. package/ai/skills/stacks-env/SKILL.md +181 -0
  50. package/ai/skills/stacks-error-handling/SKILL.md +137 -0
  51. package/ai/skills/stacks-events/SKILL.md +228 -0
  52. package/ai/skills/stacks-faker/SKILL.md +158 -0
  53. package/ai/skills/stacks-git/SKILL.md +158 -0
  54. package/ai/skills/stacks-guard/SKILL.md +98 -0
  55. package/ai/skills/stacks-health/SKILL.md +75 -0
  56. package/ai/skills/stacks-http/SKILL.md +316 -0
  57. package/ai/skills/stacks-i18n/SKILL.md +198 -0
  58. package/ai/skills/stacks-image-to-code/SKILL.md +629 -0
  59. package/ai/skills/stacks-imagegen-mobile/SKILL.md +1474 -0
  60. package/ai/skills/stacks-imagegen-web/SKILL.md +998 -0
  61. package/ai/skills/stacks-investigate/SKILL.md +119 -0
  62. package/ai/skills/stacks-jobs/SKILL.md +136 -0
  63. package/ai/skills/stacks-lint/SKILL.md +184 -0
  64. package/ai/skills/stacks-listeners/SKILL.md +99 -0
  65. package/ai/skills/stacks-logging/SKILL.md +78 -0
  66. package/ai/skills/stacks-mail/SKILL.md +120 -0
  67. package/ai/skills/stacks-middleware/SKILL.md +249 -0
  68. package/ai/skills/stacks-migrations/SKILL.md +105 -0
  69. package/ai/skills/stacks-models/SKILL.md +267 -0
  70. package/ai/skills/stacks-new-feature/SKILL.md +206 -0
  71. package/ai/skills/stacks-notifications/SKILL.md +210 -0
  72. package/ai/skills/stacks-objects/SKILL.md +205 -0
  73. package/ai/skills/stacks-office-hours/SKILL.md +134 -0
  74. package/ai/skills/stacks-orm/SKILL.md +342 -0
  75. package/ai/skills/stacks-path/SKILL.md +118 -0
  76. package/ai/skills/stacks-payments/SKILL.md +373 -0
  77. package/ai/skills/stacks-plan-review/SKILL.md +152 -0
  78. package/ai/skills/stacks-plugins/SKILL.md +149 -0
  79. package/ai/skills/stacks-push/SKILL.md +376 -0
  80. package/ai/skills/stacks-query-builder/SKILL.md +128 -0
  81. package/ai/skills/stacks-queue/SKILL.md +559 -0
  82. package/ai/skills/stacks-realtime/SKILL.md +442 -0
  83. package/ai/skills/stacks-redesign/SKILL.md +182 -0
  84. package/ai/skills/stacks-registry/SKILL.md +58 -0
  85. package/ai/skills/stacks-repl/SKILL.md +80 -0
  86. package/ai/skills/stacks-retro/SKILL.md +122 -0
  87. package/ai/skills/stacks-review/SKILL.md +135 -0
  88. package/ai/skills/stacks-router/SKILL.md +231 -0
  89. package/ai/skills/stacks-routes/SKILL.md +105 -0
  90. package/ai/skills/stacks-scaffolding/SKILL.md +162 -0
  91. package/ai/skills/stacks-scheduler/SKILL.md +363 -0
  92. package/ai/skills/stacks-search-engine/SKILL.md +112 -0
  93. package/ai/skills/stacks-security/SKILL.md +129 -0
  94. package/ai/skills/stacks-security-audit/SKILL.md +128 -0
  95. package/ai/skills/stacks-server/SKILL.md +458 -0
  96. package/ai/skills/stacks-shell/SKILL.md +62 -0
  97. package/ai/skills/stacks-slug/SKILL.md +87 -0
  98. package/ai/skills/stacks-sms/SKILL.md +385 -0
  99. package/ai/skills/stacks-socials/SKILL.md +303 -0
  100. package/ai/skills/stacks-storage/SKILL.md +576 -0
  101. package/ai/skills/stacks-strings/SKILL.md +416 -0
  102. package/ai/skills/stacks-stx/SKILL.md +176 -0
  103. package/ai/skills/stacks-technical-diagrams/LICENSE +22 -0
  104. package/ai/skills/stacks-technical-diagrams/SKILL.md +290 -0
  105. package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +4 -0
  106. package/ai/skills/stacks-technical-diagrams/assets/template.html +1252 -0
  107. package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +289 -0
  108. package/ai/skills/stacks-technical-diagrams/bunfig.toml +1 -0
  109. package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +64 -0
  110. package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +88 -0
  111. package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +75 -0
  112. package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +70 -0
  113. package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +41 -0
  114. package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +62 -0
  115. package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +371 -0
  116. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +82 -0
  117. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +295 -0
  118. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +91 -0
  119. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +384 -0
  120. package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +84 -0
  121. package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +257 -0
  122. package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +42 -0
  123. package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +13 -0
  124. package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +230 -0
  125. package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +40 -0
  126. package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +88 -0
  127. package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +40 -0
  128. package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +103 -0
  129. package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +481 -0
  130. package/ai/skills/stacks-technical-diagrams/schemas/README.md +68 -0
  131. package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +121 -0
  132. package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +43 -0
  133. package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +221 -0
  134. package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +241 -0
  135. package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +186 -0
  136. package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +332 -0
  137. package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +297 -0
  138. package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +28 -0
  139. package/ai/skills/stacks-testing/SKILL.md +129 -0
  140. package/ai/skills/stacks-tunnel/SKILL.md +125 -0
  141. package/ai/skills/stacks-types/SKILL.md +178 -0
  142. package/ai/skills/stacks-ui/SKILL.md +246 -0
  143. package/ai/skills/stacks-utils/SKILL.md +444 -0
  144. package/ai/skills/stacks-validation/SKILL.md +371 -0
  145. package/ai/skills/stacks-whois/SKILL.md +315 -0
  146. package/assets/world-map-data.ts +121 -0
  147. package/bootstrap.ts +114 -0
  148. package/docs/api-examples.md +46 -0
  149. package/docs/index.md +24 -0
  150. package/docs/markdown-examples.md +87 -0
  151. package/functions/analytics.ts +97 -0
  152. package/functions/api.ts +143 -0
  153. package/functions/auth.ts +208 -0
  154. package/functions/billing/payments.ts +149 -0
  155. package/functions/blog.ts +120 -0
  156. package/functions/cms/categorizables.ts +107 -0
  157. package/functions/cms/pages.ts +108 -0
  158. package/functions/cms/posts.ts +100 -0
  159. package/functions/cms/taggables.ts +102 -0
  160. package/functions/commerce/coupons.ts +128 -0
  161. package/functions/commerce/customers.ts +128 -0
  162. package/functions/commerce/gift-cards.ts +119 -0
  163. package/functions/commerce/orders.ts +112 -0
  164. package/functions/commerce/payments.ts +119 -0
  165. package/functions/commerce/products/categories.ts +123 -0
  166. package/functions/commerce/products/manufacturers.ts +123 -0
  167. package/functions/commerce/products/products.ts +123 -0
  168. package/functions/commerce/products/reviews.ts +123 -0
  169. package/functions/commerce/products/units.ts +123 -0
  170. package/functions/commerce/products/variants.ts +123 -0
  171. package/functions/commerce/shippings/delivery-routes.ts +123 -0
  172. package/functions/commerce/shippings/digital-deliveries.ts +119 -0
  173. package/functions/commerce/shippings/drivers.ts +123 -0
  174. package/functions/commerce/shippings/license-keys.ts +123 -0
  175. package/functions/commerce/shippings/shipping-methods.ts +123 -0
  176. package/functions/commerce/shippings/shipping-rates.ts +119 -0
  177. package/functions/commerce/shippings/shipping-zones.ts +119 -0
  178. package/functions/commerce/taxes.ts +119 -0
  179. package/functions/commerce/waitlist/products.ts +123 -0
  180. package/functions/commerce/waitlist/restaurants.ts +123 -0
  181. package/functions/craft.ts +107 -0
  182. package/functions/dashboard.ts +153 -0
  183. package/functions/inbox.ts +95 -0
  184. package/functions/jobs.ts +86 -0
  185. package/functions/monitoring/errors.ts +295 -0
  186. package/functions/queue.ts +111 -0
  187. package/functions/realtime/websockets.ts +96 -0
  188. package/functions/realtime.ts +52 -0
  189. package/functions/releases.ts +49 -0
  190. package/functions/search.ts +126 -0
  191. package/functions/toasts.ts +95 -0
  192. package/functions/uploads.ts +216 -0
  193. package/ide/.gitignore +4 -0
  194. package/ide/cursor/rules/auto-imports.mdc +574 -0
  195. package/ide/cursor/rules/code-style.mdc +12 -0
  196. package/ide/cursor/rules/documentation.mdc +9 -0
  197. package/ide/cursor/rules/error-handling-validation.mdc +11 -0
  198. package/ide/cursor/rules/key-conventions.mdc +11 -0
  199. package/ide/cursor/rules/project-structure.mdc +169 -0
  200. package/ide/cursor/rules/readme.mdc +318 -0
  201. package/ide/cursor/rules/syntax-formatting.mdc +9 -0
  202. package/ide/cursor/rules/testing.mdc +10 -0
  203. package/ide/cursor/rules/typescript.mdc +9 -0
  204. package/ide/cursor/rules/ui-styling.mdc +0 -0
  205. package/ide/dictionary.txt +397 -0
  206. package/ide/jetbrains/.fleet/settings.json +4 -0
  207. package/ide/jetbrains/.idea/.gitignore +5 -0
  208. package/ide/jetbrains/.idea/.name +1 -0
  209. package/ide/jetbrains/.idea/inspectionProfiles/Project_Default.xml +6 -0
  210. package/ide/jetbrains/.idea/jsLinters/eslint.xml +7 -0
  211. package/ide/jetbrains/.idea/modules.xml +8 -0
  212. package/ide/jetbrains/.idea/stacks.iml +22 -0
  213. package/ide/jetbrains/.idea/vcs.xml +6 -0
  214. package/ide/jetbrains/.idea/webResources.xml +14 -0
  215. package/ide/jetbrains/IntelliJ IDEA Global Settings +0 -0
  216. package/ide/jetbrains/installed.txt +4 -0
  217. package/ide/jetbrains/options/github-copilot.xml +5 -0
  218. package/ide/jetbrains/options/nodejs.xml +7 -0
  219. package/ide/jetbrains/options/templates.xml +124 -0
  220. package/ide/jetbrains/templates/JavaScript.xml +6 -0
  221. package/ide/jetbrains/templates/Stacks.xml +8 -0
  222. package/ide/vscode/.vscode/README.md +23 -0
  223. package/ide/vscode/.vscode/extensions.json +5 -0
  224. package/ide/vscode/.vscode/settings.json +176 -0
  225. package/ide/vscode/.vscode/stacks.code-snippets +181 -0
  226. package/ide/vscode/LICENSE.md +21 -0
  227. package/ide/vscode/README.md +36 -0
  228. package/ide/vscode/logo.png +0 -0
  229. package/ide/vscode/package.json +79 -0
  230. package/ide/zed/.zed/settings.json +139 -0
  231. package/lang/README.md +28 -0
  232. package/lang/de.yml +14 -0
  233. package/lang/en.yml +15 -0
  234. package/package.json +19 -3
  235. package/project/bootstrap +161 -0
  236. package/project/buddy +175 -0
  237. package/project/storage/framework/tsconfig.app.json +50 -0
  238. package/project/storage/framework/tsconfig.base.json +58 -0
  239. package/routes/core.ts +78 -0
  240. package/routes/dashboard-api.ts +233 -0
  241. package/routes/dashboard.ts +739 -0
  242. package/routes/email.ts +129 -0
  243. package/stores/[name].stx +16 -0
  244. package/stores/git.ts +71 -0
  245. package/stores/payment.ts +474 -0
  246. package/stores/queue.ts +43 -0
  247. package/stores/user.ts +29 -0
  248. package/stx-components-plugin.ts +25 -0
  249. package/styles/design-tokens.css +597 -0
  250. package/types/dashboard.ts +70 -0
  251. package/types/defaults.ts +438 -0
  252. package/vcs/github/CODE_OF_CONDUCT.md +83 -0
  253. package/vcs/github/CONTRIBUTING.md +187 -0
  254. package/vcs/github/EXPLANATIONS.md +41 -0
  255. package/vcs/github/FUNDING.yml +1 -0
  256. package/vcs/github/ISSUE_TEMPLATE/bug_report.yml +49 -0
  257. package/vcs/github/ISSUE_TEMPLATE/config.yml +10 -0
  258. package/vcs/github/ISSUE_TEMPLATE/feature_request.yml +44 -0
  259. package/vcs/github/SECURITY.md +70 -0
  260. package/vcs/github/renovate.json +5 -0
  261. package/vcs/github/stale.yml +14 -0
  262. package/vcs/github/workflows/README.md +16 -0
  263. package/vcs/github/workflows/ci.yml +114 -0
  264. package/vcs/github/workflows/export-size.yml +25 -0
  265. package/vcs/github/workflows/labeler.yml +13 -0
  266. package/vcs/github/workflows/release.yml +219 -0
  267. package/views/[...all].stx +8 -0
  268. package/views/about.md +3 -0
  269. package/views/auth/login.stx +1 -0
  270. package/views/auth/signup.stx +85 -0
  271. package/views/dashboard/.discovered-models.json +542 -0
  272. package/views/dashboard/AUDIT.md +904 -0
  273. package/views/dashboard/[...all].stx +89 -0
  274. package/views/dashboard/access-tokens/index.stx +177 -0
  275. package/views/dashboard/actions/index.stx +129 -0
  276. package/views/dashboard/analytics/blog/index.stx +356 -0
  277. package/views/dashboard/analytics/browsers/index.stx +263 -0
  278. package/views/dashboard/analytics/commerce/sales/index.stx +329 -0
  279. package/views/dashboard/analytics/commerce/web/index.stx +379 -0
  280. package/views/dashboard/analytics/countries/index.stx +289 -0
  281. package/views/dashboard/analytics/devices/index.stx +305 -0
  282. package/views/dashboard/analytics/events/index.stx +536 -0
  283. package/views/dashboard/analytics/index.stx +88 -0
  284. package/views/dashboard/analytics/marketing/index.stx +315 -0
  285. package/views/dashboard/analytics/pages/index.stx +271 -0
  286. package/views/dashboard/analytics/referrers/index.stx +319 -0
  287. package/views/dashboard/analytics/web/index.stx +356 -0
  288. package/views/dashboard/buddy/index.stx +198 -0
  289. package/views/dashboard/ci/index.stx +462 -0
  290. package/views/dashboard/cloud/index.stx +452 -0
  291. package/views/dashboard/commands/index.stx +295 -0
  292. package/views/dashboard/commerce/categories/index.stx +406 -0
  293. package/views/dashboard/commerce/coupons/index.stx +485 -0
  294. package/views/dashboard/commerce/customers/index.stx +410 -0
  295. package/views/dashboard/commerce/dashboard/index.stx +287 -0
  296. package/views/dashboard/commerce/delivery/delivery-routes.stx +305 -0
  297. package/views/dashboard/commerce/delivery/digital-delivery.stx +332 -0
  298. package/views/dashboard/commerce/delivery/drivers.stx +397 -0
  299. package/views/dashboard/commerce/delivery/index.stx +18 -0
  300. package/views/dashboard/commerce/delivery/license-keys.stx +380 -0
  301. package/views/dashboard/commerce/delivery/shipping-methods.stx +346 -0
  302. package/views/dashboard/commerce/delivery/shipping-rates.stx +338 -0
  303. package/views/dashboard/commerce/delivery/shipping-zones.stx +302 -0
  304. package/views/dashboard/commerce/delivery/tabs.ts +25 -0
  305. package/views/dashboard/commerce/gift-cards/index.stx +561 -0
  306. package/views/dashboard/commerce/manufacturers/index.stx +308 -0
  307. package/views/dashboard/commerce/orders/index.stx +247 -0
  308. package/views/dashboard/commerce/payments/index.stx +535 -0
  309. package/views/dashboard/commerce/pos/index.stx +653 -0
  310. package/views/dashboard/commerce/printers/devices/index.stx +273 -0
  311. package/views/dashboard/commerce/printers/receipts/index.stx +308 -0
  312. package/views/dashboard/commerce/products/detail.stx +563 -0
  313. package/views/dashboard/commerce/products/index.stx +370 -0
  314. package/views/dashboard/commerce/reviews/index.stx +656 -0
  315. package/views/dashboard/commerce/reviews/index.ts +0 -0
  316. package/views/dashboard/commerce/taxes/index.stx +377 -0
  317. package/views/dashboard/commerce/units/index.stx +317 -0
  318. package/views/dashboard/commerce/variants/index.stx +319 -0
  319. package/views/dashboard/commerce/waitlist/products.stx +942 -0
  320. package/views/dashboard/commerce/waitlist/restaurant.stx +1024 -0
  321. package/views/dashboard/components/index.stx +330 -0
  322. package/views/dashboard/composables/index.ts +19 -0
  323. package/views/dashboard/composables/useChart.ts +77 -0
  324. package/views/dashboard/composables/useNavigation.ts +99 -0
  325. package/views/dashboard/composables/useRole.ts +58 -0
  326. package/views/dashboard/composables/useTheme.ts +74 -0
  327. package/views/dashboard/content/authors/index.stx +171 -0
  328. package/views/dashboard/content/blog/index.stx +493 -0
  329. package/views/dashboard/content/categories/index.stx +169 -0
  330. package/views/dashboard/content/comments/index.stx +189 -0
  331. package/views/dashboard/content/dashboard.stx +383 -0
  332. package/views/dashboard/content/files/index.stx +706 -0
  333. package/views/dashboard/content/pages/index.stx +174 -0
  334. package/views/dashboard/content/posts/index.stx +269 -0
  335. package/views/dashboard/content/seo/index.stx +240 -0
  336. package/views/dashboard/content/tags/index.stx +167 -0
  337. package/views/dashboard/data/activity/index.stx +261 -0
  338. package/views/dashboard/data/dashboard/index.stx +116 -0
  339. package/views/dashboard/data/subscribers.stx +270 -0
  340. package/views/dashboard/data/teams.stx +275 -0
  341. package/views/dashboard/data/users.stx +279 -0
  342. package/views/dashboard/dependencies/index.stx +178 -0
  343. package/views/dashboard/deployments/[id].stx +234 -0
  344. package/views/dashboard/deployments/index.stx +9 -0
  345. package/views/dashboard/dns/index.stx +163 -0
  346. package/views/dashboard/environment/index.stx +283 -0
  347. package/views/dashboard/errors/index.stx +274 -0
  348. package/views/dashboard/forgot-password.stx +57 -0
  349. package/views/dashboard/functions/index.stx +159 -0
  350. package/views/dashboard/health/index.stx +248 -0
  351. package/views/dashboard/inbox/activity.stx +350 -0
  352. package/views/dashboard/inbox/index.stx +452 -0
  353. package/views/dashboard/inbox/settings.stx +290 -0
  354. package/views/dashboard/index.stx +252 -0
  355. package/views/dashboard/insights/index.stx +529 -0
  356. package/views/dashboard/jobs/[id].stx +430 -0
  357. package/views/dashboard/jobs/history.stx +222 -0
  358. package/views/dashboard/jobs/index.stx +214 -0
  359. package/views/dashboard/kanban/[id].stx +899 -0
  360. package/views/dashboard/kanban/index.stx +260 -0
  361. package/views/dashboard/layouts/default.stx +565 -0
  362. package/views/dashboard/layouts/guest.stx +10 -0
  363. package/views/dashboard/login.stx +48 -0
  364. package/views/dashboard/logs/index.stx +540 -0
  365. package/views/dashboard/mailboxes/index.stx +149 -0
  366. package/views/dashboard/management/permissions/index.stx +490 -0
  367. package/views/dashboard/marketing/campaigns/index.stx +604 -0
  368. package/views/dashboard/marketing/lists/index.stx +514 -0
  369. package/views/dashboard/marketing/reviews/index.stx +475 -0
  370. package/views/dashboard/marketing/social-posts/index.stx +560 -0
  371. package/views/dashboard/models/[model].stx +195 -0
  372. package/views/dashboard/models/index.stx +159 -0
  373. package/views/dashboard/monitoring/errors/index.stx +415 -0
  374. package/views/dashboard/notifications/dashboard.stx +383 -0
  375. package/views/dashboard/notifications/email.stx +336 -0
  376. package/views/dashboard/notifications/history.stx +373 -0
  377. package/views/dashboard/notifications/sms.stx +332 -0
  378. package/views/dashboard/packages/index.stx +195 -0
  379. package/views/dashboard/queries/[id].stx +381 -0
  380. package/views/dashboard/queries/history.stx +227 -0
  381. package/views/dashboard/queries/index.stx +335 -0
  382. package/views/dashboard/queries/slow.stx +318 -0
  383. package/views/dashboard/queue/index.stx +427 -0
  384. package/views/dashboard/realtime/index.stx +429 -0
  385. package/views/dashboard/register.stx +46 -0
  386. package/views/dashboard/releases/index.stx +389 -0
  387. package/views/dashboard/requests/index.stx +462 -0
  388. package/views/dashboard/serverless/index.stx +475 -0
  389. package/views/dashboard/servers/[id].stx +299 -0
  390. package/views/dashboard/servers/index.stx +483 -0
  391. package/views/dashboard/settings/billing.stx +50 -0
  392. package/views/dashboard/settings/index.stx +256 -0
  393. package/views/dashboard/settings/mail.stx +252 -0
  394. package/views/dashboard/stores/auth.ts +123 -0
  395. package/views/dashboard/stores/ci.ts +342 -0
  396. package/views/dashboard/stores/index.ts +129 -0
  397. package/views/dashboard/stores/kanban.ts +723 -0
  398. package/views/dashboard/stores/rbac.ts +350 -0
  399. package/views/dashboard/stx.config.ts +34 -0
  400. package/views/dashboard/teams/[id].stx +170 -0
  401. package/views/forum/category.stx +92 -0
  402. package/views/forum/index.stx +209 -0
  403. package/views/forum/new-topic.stx +113 -0
  404. package/views/forum/profile.stx +1 -0
  405. package/views/forum/topic.stx +143 -0
  406. package/views/hello-world/[name].stx +47 -0
  407. package/views/index.stx +21 -0
  408. package/views/system-tray/index.stx +147 -0
@@ -0,0 +1,739 @@
1
+ /**
2
+ * Framework Default Routes
3
+ *
4
+ * These routes power the Stacks dashboard and framework features.
5
+ * They are loaded automatically AFTER user-defined routes.
6
+ *
7
+ * Users should NOT edit this file. To override any framework route,
8
+ * simply define the same method + path in your routes/api.ts file.
9
+ * bun-router uses first-registration-wins, and user routes load first,
10
+ * so your custom handler will always take priority.
11
+ *
12
+ * @example Override the login route in routes/api.ts:
13
+ * ```ts
14
+ * route.post('/login', 'Actions/MyCustomLoginAction')
15
+ * ```
16
+ */
17
+
18
+ import process from 'node:process'
19
+ import { response, route } from '@stacksjs/router'
20
+
21
+ // ============================================================================
22
+ // Auth Routes
23
+ // ============================================================================
24
+
25
+ // Rate limits on token-issuance + password-reset endpoints
26
+ // (stacksjs/stacks#1921). `Auth.attempt()` already has a per-email
27
+ // lockout but it doesn't stop credential-stuffing across many emails
28
+ // from one IP, and the token endpoints have no upstream brake at all
29
+ // — a leaked refresh token could be hammered for unlimited access
30
+ // tokens until the row TTL. Userland that overrides any of these in
31
+ // `routes/api.ts` (user routes win) gets to pick its own limits.
32
+ route.post('/login', 'Actions/Auth/LoginAction').rateLimit(5, 'minute')
33
+ route.post('/register', 'Actions/Auth/RegisterAction').rateLimit(3, 'minute')
34
+ // Passkey ENROLLMENT (attaching a new credential to an account) must be
35
+ // auth-gated — it's not a login flow, it's a logged-in user adding a
36
+ // second factor to their own account. Previously unauthenticated and
37
+ // keyed off a client-supplied `email` field: anyone who knew a victim's
38
+ // email could register a passkey against that account and log in as
39
+ // them, no password required. GenerateRegistrationAction/
40
+ // VerifyRegistrationAction now derive identity from request.user().
41
+ route.get('/generate-registration-options', 'Actions/Auth/GenerateRegistrationAction').middleware('auth').rateLimit(10, 'minute')
42
+ route.post('/verify-registration', 'Actions/Auth/VerifyRegistrationAction').middleware('auth').rateLimit(5, 'minute')
43
+ // Passkey AUTHENTICATION (logging in) is correctly unauthenticated —
44
+ // the caller doesn't have a session yet, that's the point.
45
+ route.get('/generate-authentication-options', 'Actions/Auth/GenerateAuthenticationAction').rateLimit(10, 'minute')
46
+ route.get('/verify-authentication', 'Actions/Auth/VerifyAuthenticationAction').rateLimit(10, 'minute')
47
+
48
+ // TOTP 2FA. Setup/enable/disable act on the caller's own authenticated
49
+ // account (auth-gated, same identity rule as passkey enrollment above).
50
+ // verify-two-factor-login is the second step of LoginAction's flow and
51
+ // is correctly unauthenticated — the caller only has a short-lived
52
+ // challenge token at that point, not a session yet.
53
+ route.post('/generate-two-factor-secret', 'Actions/Auth/GenerateTwoFactorSecretAction').middleware('auth').rateLimit(10, 'minute')
54
+ route.post('/enable-two-factor', 'Actions/Auth/EnableTwoFactorAction').middleware('auth').rateLimit(10, 'minute')
55
+ route.post('/disable-two-factor', 'Actions/Auth/DisableTwoFactorAction').middleware('auth').rateLimit(10, 'minute')
56
+ route.post('/verify-two-factor-login', 'Actions/Auth/VerifyTwoFactorLoginAction').rateLimit(10, 'minute')
57
+
58
+ route.group({ prefix: '/auth' }, () => {
59
+ route.post('/refresh', 'Actions/Auth/RefreshTokenAction').rateLimit(10, 'minute')
60
+ route.get('/tokens', 'Actions/Auth/ListTokensAction').middleware('auth')
61
+ route.post('/token', 'Actions/Auth/CreateTokenAction').middleware('auth').rateLimit(10, 'minute')
62
+ route.delete('/tokens/{id}', 'Actions/Auth/RevokeTokenAction').middleware('auth')
63
+ route.get('/abilities', 'Actions/Auth/TestAbilitiesAction').middleware('auth')
64
+ })
65
+
66
+ route.group({ middleware: 'auth' }, () => {
67
+ route.get('/me', 'Actions/Auth/AuthUserAction')
68
+ route.post('/logout', 'Actions/Auth/LogoutAction')
69
+ // Sign out everywhere: revoke every access/refresh token AND destroy
70
+ // every session for the authenticated user (stacksjs/stacks#1957).
71
+ route.post('/logout-all', 'Actions/Auth/LogoutAllAction')
72
+ })
73
+
74
+ // Password Reset. `/forgot` triggers a mailer hop so it's the most
75
+ // abuse-prone — keep that tighter than the verification endpoints.
76
+ route.group({ prefix: '/password' }, () => {
77
+ route.post('/forgot', 'Actions/Password/SendPasswordResetEmailAction').rateLimit(3, 'minute')
78
+ route.post('/reset', 'Actions/Password/PasswordResetAction').rateLimit(5, 'minute')
79
+ route.post('/verify-token', 'Actions/Password/VerifyResetTokenAction').rateLimit(10, 'minute')
80
+ })
81
+
82
+ // ============================================================================
83
+ // Email
84
+ // ============================================================================
85
+
86
+ // CSRF is skipped for the same reason the storefront cart routes skip
87
+ // it: the storefront's email-subscribe form is rendered in static HTML
88
+ // without a CSRF token round-trip, and the abuse case (bots inflating
89
+ // the subscriber list) is better handled with the rate limiter — at
90
+ // the action layer — than with a token check the form can't satisfy.
91
+ route.post('/api/email/subscribe', 'Actions/SubscriberEmailAction').name('email.subscribe').skipCsrf()
92
+ route.get('/api/email/unsubscribe', 'Actions/UnsubscribeAction').name('email.unsubscribe')
93
+ // RFC 8058 one-click endpoint. Mailbox providers (Gmail, Yahoo, Outlook)
94
+ // POST here with body `List-Unsubscribe=One-Click` when the user clicks
95
+ // the inbox-native unsubscribe affordance — the request never carries a
96
+ // CSRF token because the mailbox provider isn't in our session, so skip.
97
+ route.post('/api/email/unsubscribe', 'Actions/UnsubscribeAction').name('email.unsubscribe.oneclick').skipCsrf()
98
+
99
+ // Public contact form. CSRF skipped for the same reason as the
100
+ // subscribe endpoint — the form renders without JS — and the outbound
101
+ // mailer hop makes rate-limiting essential. Quota is enforced inside
102
+ // the action itself.
103
+ route.post('/api/contact', 'Actions/ContactAction').name('contact.send').skipCsrf()
104
+
105
+ // ============================================================================
106
+ // Storefront (anonymous cart + multi-step checkout)
107
+ //
108
+ // CSRF is skipped because the storefront uses progressive-enhancement
109
+ // HTML forms — there's no JS to mint a token — and each cart is
110
+ // already gated by an opaque, HttpOnly session cookie that can't be
111
+ // guessed. Apps that want classic CSRF on top can re-register the
112
+ // same routes in their `routes/api.ts` without `.skipCsrf()`.
113
+ // ============================================================================
114
+
115
+ route.get('/api/cart', 'Actions/Storefront/GetCartAction').skipCsrf()
116
+ route.post('/api/cart/add', 'Actions/Storefront/AddToCartAction').skipCsrf()
117
+ route.post('/api/cart/update', 'Actions/Storefront/UpdateCartItemAction').skipCsrf()
118
+ route.post('/api/checkout/contact', 'Actions/Storefront/CheckoutContactAction').skipCsrf()
119
+ route.post('/api/checkout/shipping', 'Actions/Storefront/CheckoutShippingAction').skipCsrf()
120
+ route.post('/api/checkout/place', 'Actions/Storefront/PlaceOrderAction').skipCsrf()
121
+
122
+ // Buyer-submitted product review. Tied to a shipped order via
123
+ // order_id + email match (the SubmitReviewAction verifies ownership
124
+ // and stamps is_verified_purchase=1). Stored as is_approved=0 for
125
+ // admin moderation through `/dashboard/commerce/reviews`.
126
+ route.post('/api/reviews/submit', 'Actions/Storefront/SubmitReviewAction').skipCsrf()
127
+
128
+ // ============================================================================
129
+ // Health & System
130
+ // ============================================================================
131
+
132
+ route.health()
133
+
134
+ // Dev-only diagnostics (stacksjs/stacks#1955). `/install` returns the
135
+ // framework's shell bootstrap script (free stack fingerprinting) and
136
+ // `/test-error` is an on-demand exception generator — `?type=` picks a
137
+ // 401/404/422/500 scenario — so neither belongs on a production app's
138
+ // public API. Same env detection as defaults/routes/dashboard-api.ts:
139
+ // APP_ENV wins over NODE_ENV, and an unset env counts as local so
140
+ // `buddy dev` and test suites keep both endpoints out of the box.
141
+ // Apps that intentionally want either route in production can
142
+ // re-register the path in `routes/api.ts` — user routes load first,
143
+ // so their copy wins.
144
+ const APP_ENV = (process.env.APP_ENV ?? process.env.NODE_ENV ?? '').toLowerCase()
145
+ const IS_LOCAL_ENV = APP_ENV === '' || APP_ENV === 'local' || APP_ENV === 'development' || APP_ENV === 'dev' || APP_ENV === 'test' || APP_ENV === 'testing'
146
+
147
+ if (IS_LOCAL_ENV) {
148
+ route.get('/install', 'Actions/InstallAction')
149
+ route.get('/test-error', 'Actions/TestErrorAction')
150
+ }
151
+
152
+ // ============================================================================
153
+ // SEO — sitemap.xml + robots.txt
154
+ //
155
+ // Both are framework defaults so every Stacks app ships discoverable
156
+ // out of the box. SitemapAction walks resources/views (skipping
157
+ // dynamic [slug] / [...all] pages and private routes like /cart) and
158
+ // fans the products table for product detail URLs. RobotsAction emits
159
+ // safe defaults — Allow: / plus Disallow on cart/checkout/auth/dashboard.
160
+ //
161
+ // Apps with stricter rules can re-register either route in routes/api.ts
162
+ // against their own action; user routes load before framework defaults
163
+ // so the override wins.
164
+ // ============================================================================
165
+
166
+ route.get('/sitemap.xml', 'Actions/SitemapAction')
167
+ route.get('/robots.txt', 'Actions/RobotsAction')
168
+
169
+ // ============================================================================
170
+ // AI
171
+ // ============================================================================
172
+
173
+ // `/ai/*` hits the user's configured LLM provider on the server side. Left
174
+ // unauthenticated, an attacker can rack up token bills and exfiltrate
175
+ // completions. Auth-gate by default; if a userland app intentionally wants
176
+ // a public AI endpoint (e.g. a homepage chat widget), it can register the
177
+ // route in `routes/api.ts` without the middleware — user routes load before
178
+ // framework routes, so the unauthenticated copy wins.
179
+ route.group({ middleware: 'auth' }, () => {
180
+ route.post('/ai/ask', 'Actions/AI/AskAction')
181
+ route.post('/ai/summary', 'Actions/AI/SummaryAction')
182
+ })
183
+
184
+ // ============================================================================
185
+ // Voide — Voice AI Code Assistant
186
+ //
187
+ // These endpoints drive the buddy/voice agent: open repos, run AI commits,
188
+ // push branches, manage GitHub credentials. Unauthenticated, an attacker
189
+ // could open arbitrary local repos and push to the user's GitHub account.
190
+ // Always auth-gated.
191
+ // ============================================================================
192
+
193
+ route.group({ prefix: '/voide', middleware: 'auth' }, () => {
194
+ route.get('/state', 'Actions/Buddy/BuddyStateAction')
195
+ route.post('/repo', 'Actions/Buddy/BuddyRepoOpenAction')
196
+ route.post('/repo/validate', 'Actions/Buddy/BuddyRepoValidateAction')
197
+ route.post('/process', 'Actions/Buddy/BuddyProcessAction')
198
+ route.post('/process/stream', 'Actions/Buddy/BuddyProcessStreamAction')
199
+ route.post('/commit', 'Actions/Buddy/BuddyCommitAction')
200
+ route.post('/push', 'Actions/Buddy/BuddyPushAction')
201
+ route.post('/cancel', 'Actions/Buddy/BuddyCancelAction')
202
+ route.post('/browse', 'Actions/Buddy/BuddyBrowseAction')
203
+ route.post('/title', 'Actions/Buddy/BuddyTitleAction')
204
+ route.get('/settings', 'Actions/Buddy/BuddySettingsAction')
205
+ route.post('/settings', 'Actions/Buddy/BuddySettingsUpdateAction')
206
+ route.post('/github/connect', 'Actions/Buddy/BuddyGitHubConnectAction')
207
+ route.post('/github/disconnect', 'Actions/Buddy/BuddyGitHubDisconnectAction')
208
+ })
209
+
210
+ // ============================================================================
211
+ // Dashboard
212
+ //
213
+ // Every dashboard-internal endpoint below is auth-gated. These routes back
214
+ // the admin UI and dump operational data (jobs, queues, mailboxes, captured
215
+ // transactional emails, error tracking, deployments). Anonymous access here
216
+ // would leak password-reset tokens, billing receipts, and PII via the
217
+ // inbox / notifications endpoints. The public CMS mirror lives at /blog,
218
+ // the newsletter signup lives at /api/email/subscribe — those stay open.
219
+ // ============================================================================
220
+
221
+ route.group({ prefix: '/dashboard', middleware: 'auth' }, () => {
222
+ route.get('/home', 'Actions/Dashboard/DashboardHomeAction')
223
+ route.get('/stats', 'Actions/Dashboard/DashboardStatsAction')
224
+ route.get('/activity', 'Actions/Dashboard/DashboardActivityAction')
225
+ route.get('/health', 'Actions/Dashboard/DashboardHealthAction')
226
+ route.get('/services', 'Actions/Dashboard/ServiceHealthAction')
227
+ route.get('/buddy', 'Actions/Dashboard/BuddyDashboardAction')
228
+ route.get('/actions/list', 'Actions/Dashboard/Actions/GetActions')
229
+ route.get('/settings', 'Actions/Dashboard/Settings/SettingsIndexAction')
230
+ // Dashboard's omnisearch endpoint. Lived at root `/search` until users
231
+ // building a public site discovered it shadowed `resources/views/search.stx`
232
+ // (a registered route always wins over a same-path stx file). Now scoped
233
+ // under /dashboard so userland keeps `/search` for their own pages.
234
+ route.get('/search', 'Actions/Dashboard/Search/GlobalSearchAction')
235
+ })
236
+
237
+ // ============================================================================
238
+ // Payments
239
+ // ============================================================================
240
+
241
+ // Auth-gated: every handler reads a `{id}` path param and resolves that user's
242
+ // Stripe customer/payment data. Without `auth` the whole group was an
243
+ // unauthenticated IDOR — anyone could enumerate billing/PII or mutate payment
244
+ // methods by incrementing the id. `auth` closes the unauthenticated hole; each
245
+ // action must STILL scope to the authenticated user (derive the customer from
246
+ // `await request.user()`, never trust the `{id}` path param) to prevent an
247
+ // authenticated user from reaching another user's billing.
248
+ route.group({ prefix: '/payments', middleware: 'auth' }, () => {
249
+ route.get('/fetch-customer/{id}', 'Actions/Payment/FetchPaymentCustomerAction')
250
+ route.get('/fetch-transaction-history/{id}', 'Actions/Payment/FetchTransactionHistoryAction')
251
+ route.get('/fetch-user-subscriptions/{id}', 'Actions/Payment/FetchUserSubscriptionsAction')
252
+ route.get('/fetch-active-subscription/{id}', 'Actions/Payment/FetchActiveSubscriptionAction')
253
+ route.get('/default-payment-method/{id}', 'Actions/Payment/FetchDefaultPaymentMethodAction')
254
+ route.get('/payment-methods/{id}', 'Actions/Payment/FetchPaymentMethodsAction')
255
+ route.get('/create-setup-intent/{id}', 'Actions/Payment/CreateSetupIntentAction')
256
+ route.delete('/delete-payment-method/{id}', 'Actions/Payment/DeleteDefaultPaymentAction')
257
+ route.put('/update-default-payment-method/{id}', 'Actions/Payment/UpdateDefaultPaymentMethodAction')
258
+ route.post('/set-default-payment-method/{id}', 'Actions/Payment/SetDefaultPaymentAction')
259
+ route.post('/user-default-payment-method/{id}', 'Actions/Payment/SetUserDefaultPaymentAction')
260
+ route.post('/payment-method/{id}', 'Actions/Payment/StorePaymentMethodAction')
261
+ route.post('/create-payment-intent/{id}', 'Actions/Payment/CreatePaymentIntentAction')
262
+ route.post('/create-subscription/{id}', 'Actions/Payment/CreateSubscriptionAction')
263
+ route.post('/update-subscription/{id}', 'Actions/Payment/UpdateSubscriptionAction')
264
+ route.post('/cancel-subscription/{id}', 'Actions/Payment/CancelSubscriptionAction')
265
+ route.post('/create-invoice-subscription/{id}', 'Actions/Payment/CreateInvoiceSubscription')
266
+ route.patch('/update-customer/{id}', 'Actions/Payment/UpdateCustomerAction')
267
+ route.post('/checkout/{id}', 'Actions/Payment/CreateCheckoutAction')
268
+ route.get('/fetch-product/{id}', 'Actions/Payment/FetchProductAction')
269
+ route.post('/store-transaction/{id}', 'Actions/Payment/StoreTransactionAction')
270
+ })
271
+
272
+ // ============================================================================
273
+ // Queues & Realtime (legacy endpoints)
274
+ // ============================================================================
275
+
276
+ // Auth-gated to match every other operational dashboard group — these expose
277
+ // internal job/queue and websocket state and were the only siblings missing
278
+ // `auth`, leaking infra telemetry to anonymous callers.
279
+ route.group({ prefix: '/queues', middleware: 'auth' }, () => {
280
+ route.get('/', 'Actions/Queue/FetchQueuesAction')
281
+ })
282
+
283
+ route.group({ prefix: '/realtime', middleware: 'auth' }, () => {
284
+ route.get('/websockets', 'Actions/Realtime/FetchWebsocketsAction')
285
+ route.get('/stats', 'Actions/Dashboard/Realtime/RealtimeStatsAction')
286
+ })
287
+
288
+ // ============================================================================
289
+ // Query Dashboard
290
+ // ============================================================================
291
+
292
+ route.group({ prefix: '/api/queries', middleware: 'auth' }, () => {
293
+ route.get('/dashboard', 'Actions/Dashboard/Queries/QueryIndexAction')
294
+ route.get('/stats', 'Controllers/QueryController@getStats')
295
+ route.get('/recent', 'Controllers/QueryController@getRecentQueries')
296
+ route.get('/slow', 'Controllers/QueryController@getSlowQueries')
297
+ route.get('/:id', 'Controllers/QueryController@getQuery')
298
+ route.get('/timeline', 'Controllers/QueryController@getQueryTimeline')
299
+ route.get('/frequent', 'Controllers/QueryController@getFrequentQueries')
300
+ route.post('/prune', 'Controllers/QueryController@pruneQueryLogs')
301
+ })
302
+
303
+ // ============================================================================
304
+ // Monitoring / Error Tracking
305
+ // ============================================================================
306
+
307
+ route.group({ prefix: '/api/monitoring', middleware: 'auth' }, () => {
308
+ route.get('/errors', 'Actions/Monitoring/ErrorIndexAction')
309
+ route.get('/errors/stats', 'Actions/Monitoring/ErrorStatsAction')
310
+ route.get('/errors/timeline', 'Actions/Monitoring/ErrorTimelineAction')
311
+ route.get('/errors/group', 'Actions/Monitoring/ErrorGroupAction')
312
+ route.get('/errors/{id}', 'Actions/Monitoring/ErrorShowAction')
313
+ route.patch('/errors/resolve', 'Actions/Monitoring/ErrorResolveAction')
314
+ route.patch('/errors/ignore', 'Actions/Monitoring/ErrorIgnoreAction')
315
+ route.patch('/errors/unresolve', 'Actions/Monitoring/ErrorUnresolveAction')
316
+ route.delete('/errors', 'Actions/Monitoring/ErrorDestroyAction')
317
+ })
318
+
319
+ // ============================================================================
320
+ // CMS (admin surface, auth-gated)
321
+ //
322
+ // The PUBLIC blog at /blog is served separately by BunPress from markdown in
323
+ // content/blog/ (dev: actions onRequest; prod: a static BunPress build) — it
324
+ // is no longer a DB/CMS mirror. /cms below remains the authoring API.
325
+ // ============================================================================
326
+
327
+ route.group({ prefix: '/cms', middleware: 'auth' }, () => {
328
+ route.get('/dashboard', 'Actions/Dashboard/Content/ContentDashboardAction')
329
+ route.get('/posts', 'Actions/Cms/PostIndexAction')
330
+ route.get('/posts/{id}', 'Actions/Cms/PostShowAction')
331
+ route.post('/posts', 'Actions/Cms/PostStoreAction')
332
+ route.patch('/posts/{id}', 'Actions/Cms/PostUpdateAction')
333
+ route.delete('/posts/{id}', 'Actions/Cms/PostDestroyAction')
334
+ route.patch('/posts/{id}/views', 'Actions/Cms/PostViewsUpdateAction')
335
+
336
+ route.get('/authors', 'Actions/Cms/AuthorIndexAction')
337
+ route.get('/authors/{id}', 'Actions/Cms/AuthorShowAction')
338
+ route.post('/authors', 'Actions/Cms/AuthorStoreAction')
339
+ route.patch('/authors/{id}', 'Actions/Cms/AuthorUpdateAction')
340
+ route.delete('/authors/{id}', 'Actions/Cms/AuthorDestroyAction')
341
+
342
+ route.get('/categories', 'Actions/Cms/CategorizableIndexAction')
343
+ route.get('/categories/{id}', 'Actions/Cms/CategorizableShowAction')
344
+ route.post('/categories', 'Actions/Cms/CategorizableStoreAction')
345
+ route.patch('/categories/{id}', 'Actions/Cms/CategorizableUpdateAction')
346
+ route.delete('/categories/{id}', 'Actions/Cms/CategorizableDestroyAction')
347
+
348
+ route.get('/tags', 'Actions/Cms/TaggableIndexAction')
349
+ route.get('/tags/{id}', 'Actions/Cms/TaggableShowAction')
350
+ route.post('/tags', 'Actions/Cms/TaggableStoreAction')
351
+ route.patch('/tags/{id}', 'Actions/Cms/TaggableUpdateAction')
352
+ route.delete('/tags/{id}', 'Actions/Cms/TaggableDestroyAction')
353
+
354
+ route.get('/comments', 'Actions/Cms/CommentIndexAction')
355
+ route.get('/comments/{id}', 'Actions/Cms/CommentShowAction')
356
+ route.post('/comments', 'Actions/Cms/CommentStoreAction')
357
+ route.patch('/comments/{id}', 'Actions/Cms/CommentUpdateAction')
358
+ route.delete('/comments/{id}', 'Actions/Cms/CommentDestroyAction')
359
+
360
+ route.get('/pages', 'Actions/Cms/PageIndexAction')
361
+ route.post('/pages', 'Actions/Cms/PageStoreAction')
362
+ route.patch('/pages/{id}', 'Actions/Cms/PageUpdateAction')
363
+ route.delete('/pages/{id}', 'Actions/Cms/PageDestroyAction')
364
+
365
+ route.get('/seo', 'Actions/Dashboard/Content/SeoIndexAction')
366
+ route.get('/files', 'Actions/Dashboard/Content/FileIndexAction')
367
+ })
368
+
369
+ // (The public /blog mirror — posts/categories/tags/feed/sitemap from the DB —
370
+ // was retired. The blog is now BunPress + markdown; its feed.xml and
371
+ // sitemap.xml are generated by BunPress from content/blog/.)
372
+
373
+ // ============================================================================
374
+ // Commerce
375
+ //
376
+ // Admin commerce surface — products, orders, customers, etc. Storefront
377
+ // flows that need anonymous access (checkout, public product browsing,
378
+ // guest carts) should be defined in `routes/api.ts` against the same
379
+ // underlying actions, since user routes load before framework routes.
380
+ // ============================================================================
381
+
382
+ route.group({ prefix: '/api/commerce', middleware: 'auth' }, () => {
383
+ route.get('/dashboard', 'Actions/Dashboard/Commerce/CommerceDashboardAction')
384
+ route.get('/pos', 'Actions/Dashboard/Commerce/PosIndexAction')
385
+ route.get('/products', 'Actions/Commerce/Product/ProductIndexAction')
386
+ route.get('/products/{id}', 'Actions/Commerce/Product/ProductShowAction')
387
+ route.post('/products', 'Actions/Commerce/Product/ProductStoreAction')
388
+ route.patch('/products/{id}', 'Actions/Commerce/Product/ProductUpdateAction')
389
+ route.delete('/products/{id}', 'Actions/Commerce/Product/ProductDestroyAction')
390
+
391
+ // Product subresources nested under /products/* to match the
392
+ // frontend composables (defaults/functions/commerce/products/*.ts).
393
+ route.get('/products/{productId}/variants', 'Actions/Commerce/Product/ProductVariantIndexAction')
394
+ route.get('/products/variants', 'Actions/Commerce/Product/ProductVariantIndexAction')
395
+ route.get('/products/variants/{id}', 'Actions/Commerce/Product/ProductVariantShowAction')
396
+ route.post('/products/variants', 'Actions/Commerce/Product/ProductVariantStoreAction')
397
+ route.patch('/products/variants/{id}', 'Actions/Commerce/Product/ProductVariantUpdateAction')
398
+ route.delete('/products/variants/{id}', 'Actions/Commerce/Product/ProductVariantDestroyAction')
399
+
400
+ route.get('/products/units', 'Actions/Commerce/Product/ProductUnitIndexAction')
401
+ route.get('/products/units/{id}', 'Actions/Commerce/Product/ProductUnitShowAction')
402
+ route.post('/products/units', 'Actions/Commerce/Product/ProductUnitStoreAction')
403
+ route.delete('/products/units/{id}', 'Actions/Commerce/Product/ProductUnitDestroyAction')
404
+
405
+ route.get('/product-categories', 'Actions/Commerce/Product/ProductCategoryIndexAction')
406
+ route.post('/product-categories', 'Actions/Commerce/Product/ProductCategoryStoreAction')
407
+
408
+ // Manufacturers — frontend composable hits `/commerce/product-manufacturers`,
409
+ // so the resource name is namespaced to disambiguate from any future
410
+ // standalone manufacturers concept.
411
+ route.get('/product-manufacturers', 'Actions/Commerce/Product/ManufacturerIndexAction')
412
+ route.get('/product-manufacturers/{id}', 'Actions/Commerce/Product/ManufacturerShowAction')
413
+ route.post('/product-manufacturers', 'Actions/Commerce/Product/ManufacturerStoreAction')
414
+ route.patch('/product-manufacturers/{id}', 'Actions/Commerce/Product/ProductManufacturerUpdateAction')
415
+ route.delete('/product-manufacturers/{id}', 'Actions/Commerce/Product/ManufacturerDestroyAction')
416
+
417
+ route.get('/orders', 'Actions/Commerce/OrderIndexAction')
418
+ route.get('/orders/{id}', 'Actions/Commerce/OrderShowAction')
419
+ route.post('/orders', 'Actions/Commerce/OrderStoreAction')
420
+ route.patch('/orders/{id}', 'Actions/Commerce/OrderUpdateAction')
421
+ route.delete('/orders/{id}', 'Actions/Commerce/OrderDestroyAction')
422
+ route.get('/orders/export', 'Actions/Commerce/OrderExportAction')
423
+
424
+ route.get('/customers', 'Actions/Commerce/CustomerIndexAction')
425
+ route.get('/customers/{id}', 'Actions/Commerce/CustomerShowAction')
426
+ route.post('/customers', 'Actions/Commerce/CustomerStoreAction')
427
+ route.patch('/customers/{id}', 'Actions/Commerce/CustomerUpdateAction')
428
+ route.delete('/customers/{id}', 'Actions/Commerce/CustomerDestroyAction')
429
+
430
+ route.get('/coupons', 'Actions/Commerce/CouponIndexAction')
431
+ route.get('/coupons/{id}', 'Actions/Commerce/CouponShowAction')
432
+ route.post('/coupons', 'Actions/Commerce/CouponStoreAction')
433
+ route.patch('/coupons/{id}', 'Actions/Commerce/CouponUpdateAction')
434
+ route.delete('/coupons/{id}', 'Actions/Commerce/CouponDestroyAction')
435
+
436
+ route.get('/gift-cards', 'Actions/Commerce/GiftCardIndexAction')
437
+ route.get('/gift-cards/stats', 'Actions/Commerce/GiftCardStatsAction')
438
+ route.get('/gift-cards/{id}', 'Actions/Commerce/GiftCardShowAction')
439
+ route.post('/gift-cards', 'Actions/Commerce/GiftCardStoreAction')
440
+ route.patch('/gift-cards/{id}', 'Actions/Commerce/GiftCardUpdateAction')
441
+ route.patch('/gift-cards/{id}/balance', 'Actions/Commerce/GiftCardUpdateBalanceAction')
442
+ route.delete('/gift-cards/{id}', 'Actions/Commerce/GiftCardDestroyAction')
443
+
444
+ route.get('/tax-rates', 'Actions/Commerce/TaxRateIndexAction')
445
+ route.get('/tax-rates/{id}', 'Actions/Commerce/TaxRateShowAction')
446
+ route.post('/tax-rates', 'Actions/Commerce/TaxRateStoreAction')
447
+ route.patch('/tax-rates/{id}', 'Actions/Commerce/TaxRateUpdateAction')
448
+ route.delete('/tax-rates/{id}', 'Actions/Commerce/TaxRateDestroyAction')
449
+
450
+ // Reviews are scoped to products — frontend composable hits
451
+ // `/commerce/products/reviews`, not `/commerce/reviews`.
452
+ route.get('/products/reviews', 'Actions/Commerce/ReviewIndexAction')
453
+ route.get('/products/reviews/{id}', 'Actions/Commerce/ReviewShowAction')
454
+ route.post('/products/reviews', 'Actions/Commerce/ReviewStoreAction')
455
+ route.patch('/products/reviews/{id}', 'Actions/Commerce/ReviewUpdateAction')
456
+
457
+ route.get('/receipts', 'Actions/Commerce/ReceiptIndexAction')
458
+ route.get('/receipts/{id}', 'Actions/Commerce/ReceiptShowAction')
459
+ route.post('/receipts', 'Actions/Commerce/ReceiptStoreAction')
460
+ route.patch('/receipts/{id}', 'Actions/Commerce/ReceiptUpdateAction')
461
+ route.delete('/receipts/{id}', 'Actions/Commerce/ReceiptDestroyAction')
462
+
463
+ route.get('/print-devices', 'Actions/Commerce/PrintDeviceIndexAction')
464
+ route.get('/print-devices/{id}', 'Actions/Commerce/PrintDeviceShowAction')
465
+ route.post('/print-devices', 'Actions/Commerce/PrintDeviceStoreAction')
466
+ route.patch('/print-devices/{id}', 'Actions/Commerce/PrintDeviceUpdateAction')
467
+ route.delete('/print-devices/{id}', 'Actions/Commerce/PrintDeviceDestroyAction')
468
+
469
+ route.get('/payment-stats', 'Actions/Commerce/PaymentFetchStatsAction')
470
+ route.get('/payment-trends', 'Actions/Commerce/PaymentMonthlyTrendsAction')
471
+ // Renamed from `/commerce-payments` — that path was double-prefixed
472
+ // because this group already mounts under `/commerce`, so callers
473
+ // hitting `/api/commerce/payments` (which the frontend composable
474
+ // does — see defaults/functions/commerce/payments.ts) were 404ing.
475
+ route.get('/payments', 'Actions/Commerce/PaymentIndexAction')
476
+ route.get('/payments/{id}', 'Actions/Commerce/PaymentShowAction')
477
+ route.post('/payments', 'Actions/Commerce/PaymentStoreAction')
478
+ route.patch('/payments/{id}', 'Actions/Commerce/PaymentUpdateAction')
479
+ route.delete('/payments/{id}', 'Actions/Commerce/PaymentDestroyAction')
480
+
481
+ route.get('/waitlist/products', 'Actions/Commerce/WaitlistProductIndexAction')
482
+ route.get('/waitlist/products/analytics', 'Actions/Commerce/WaitlistProductAnalyticsAction')
483
+ route.get('/waitlist/products/status', 'Actions/Commerce/WaitlistProductStatusAction')
484
+ route.get('/waitlist/products/time-series', 'Actions/Commerce/WaitlistProductTimeSeriesAction')
485
+ route.get('/waitlist/products/quantity-distribution', 'Actions/Commerce/WaitlistProductQuantityDistributionAction')
486
+ route.get('/waitlist/products/{id}', 'Actions/Commerce/WaitlistProductShowAction')
487
+ route.post('/waitlist/products', 'Actions/Commerce/WaitlistProductStoreAction')
488
+ route.patch('/waitlist/products/{id}', 'Actions/Commerce/WaitlistProductUpdateAction')
489
+ route.delete('/waitlist/products/{id}', 'Actions/Commerce/WaitlistProductDestroyAction')
490
+
491
+ route.get('/waitlist/restaurants', 'Actions/Commerce/WaitlistRestaurantIndexAction')
492
+ route.get('/waitlist/restaurants/dashboard', 'Actions/Commerce/WaitlistRestaurantDashboardAction')
493
+ route.get('/waitlist/restaurants/{id}', 'Actions/Commerce/WaitlistRestaurantShowAction')
494
+ route.post('/waitlist/restaurants', 'Actions/Commerce/WaitlistRestaurantStoreAction')
495
+ route.patch('/waitlist/restaurants/{id}', 'Actions/Commerce/WaitlistRestaurantUpdateAction')
496
+ route.delete('/waitlist/restaurants/{id}', 'Actions/Commerce/WaitlistRestaurantDestroyAction')
497
+
498
+ // ----------------------------------------------------------------
499
+ // Shipping (moved from a top-level /shipping group on 2026-05-08).
500
+ // The frontend composables (defaults/functions/commerce/shippings/*.ts)
501
+ // all expect these resources under /commerce/*, so the prior /shipping
502
+ // group was orphaned — every shipping/driver/license/digital call
503
+ // from the dashboard was 404ing. Resource names match the composable
504
+ // file names: shipping-methods/rates/zones, delivery-routes, drivers,
505
+ // digital-deliveries, license-keys.
506
+ // ----------------------------------------------------------------
507
+ route.get('/shipping-methods', 'Actions/Commerce/Shipping/ShippingMethodIndexAction')
508
+ route.get('/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodShowAction')
509
+ route.post('/shipping-methods', 'Actions/Commerce/Shipping/ShippingMethodStoreAction')
510
+ route.patch('/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodUpdateAction')
511
+ route.delete('/shipping-methods/{id}', 'Actions/Commerce/Shipping/ShippingMethodDestroyAction')
512
+
513
+ route.get('/shipping-rates', 'Actions/Commerce/Shipping/ShippingRateIndexAction')
514
+ route.get('/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateShowAction')
515
+ route.post('/shipping-rates', 'Actions/Commerce/Shipping/ShippingRateStoreAction')
516
+ route.patch('/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateUpdateAction')
517
+ route.delete('/shipping-rates/{id}', 'Actions/Commerce/Shipping/ShippingRateDestroyAction')
518
+
519
+ route.get('/shipping-zones', 'Actions/Commerce/Shipping/ShippingZoneIndexAction')
520
+ route.get('/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneShowAction')
521
+ route.post('/shipping-zones', 'Actions/Commerce/Shipping/ShippingZoneStoreAction')
522
+ route.patch('/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneUpdateAction')
523
+ route.delete('/shipping-zones/{id}', 'Actions/Commerce/Shipping/ShippingZoneDestroyAction')
524
+
525
+ route.get('/delivery-routes', 'Actions/Commerce/Shipping/DeliveryRouteIndexAction')
526
+ route.get('/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteShowAction')
527
+ route.post('/delivery-routes', 'Actions/Commerce/Shipping/DeliveryRouteStoreAction')
528
+ route.patch('/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteUpdateAction')
529
+ route.delete('/delivery-routes/{id}', 'Actions/Commerce/Shipping/DeliveryRouteDestroyAction')
530
+
531
+ route.get('/drivers', 'Actions/Commerce/Shipping/DriverIndexAction')
532
+ route.get('/drivers/{id}', 'Actions/Commerce/Shipping/DriverShowAction')
533
+ route.post('/drivers', 'Actions/Commerce/Shipping/DriverStoreAction')
534
+ route.patch('/drivers/{id}', 'Actions/Commerce/Shipping/DriverUpdateAction')
535
+
536
+ // Renamed from `/digital` — frontend composable expects `/digital-deliveries`.
537
+ route.get('/digital-deliveries', 'Actions/Commerce/Shipping/DigitalDeliveryIndexAction')
538
+ route.get('/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryShowAction')
539
+ route.post('/digital-deliveries', 'Actions/Commerce/Shipping/DigitalDeliveryStoreAction')
540
+ route.patch('/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryUpdateAction')
541
+ route.delete('/digital-deliveries/{id}', 'Actions/Commerce/Shipping/DigitalDeliveryDestroyAction')
542
+
543
+ route.get('/license-keys', 'Actions/Commerce/Shipping/LicenseKeyIndexAction')
544
+ route.get('/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyShowAction')
545
+ route.post('/license-keys', 'Actions/Commerce/Shipping/LicenseKeyStoreAction')
546
+ route.patch('/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyUpdateAction')
547
+ route.delete('/license-keys/{id}', 'Actions/Commerce/Shipping/LicenseKeyDestroyAction')
548
+ })
549
+
550
+ // ============================================================================
551
+ // Analytics
552
+ // ============================================================================
553
+
554
+ route.group({ prefix: '/api/analytics', middleware: 'auth' }, () => {
555
+ route.get('/sales', 'Actions/Dashboard/Analytics/SalesAnalyticsAction')
556
+ route.get('/web', 'Actions/Dashboard/Analytics/WebAnalyticsAction')
557
+ route.get('/blog', 'Actions/Dashboard/Analytics/BlogAnalyticsAction')
558
+ route.get('/browsers', 'Actions/Dashboard/Analytics/BrowserAnalyticsAction')
559
+ route.get('/countries', 'Actions/Dashboard/Analytics/CountryAnalyticsAction')
560
+ route.get('/devices', 'Actions/Dashboard/Analytics/DeviceAnalyticsAction')
561
+ route.get('/events', 'Actions/Dashboard/Analytics/EventAnalyticsAction')
562
+ route.get('/marketing', 'Actions/Dashboard/Analytics/MarketingAnalyticsAction')
563
+ route.get('/pages', 'Actions/Dashboard/Analytics/PageAnalyticsAction')
564
+ route.get('/referrers', 'Actions/Dashboard/Analytics/ReferrerAnalyticsAction')
565
+ route.get('/commerce', 'Actions/Dashboard/Analytics/CommerceAnalyticsAction')
566
+ })
567
+
568
+ // ============================================================================
569
+ // Jobs & Queue
570
+ // ============================================================================
571
+
572
+ route.group({ prefix: '/jobs', middleware: 'auth' }, () => {
573
+ route.get('/', 'Actions/Dashboard/Jobs/JobIndexAction')
574
+ route.get('/stats', 'Actions/Dashboard/Jobs/JobStatsAction')
575
+ route.post('/{id}/retry', 'Actions/Dashboard/Jobs/JobRetryAction')
576
+ })
577
+
578
+ route.group({ prefix: '/queue', middleware: 'auth' }, () => {
579
+ route.get('/stats', 'Actions/Dashboard/Queue/QueueStatsAction')
580
+ route.get('/workers', 'Actions/Dashboard/Queue/QueueWorkersAction')
581
+ route.post('/retry-failed', 'Actions/Dashboard/Queue/QueueRetryFailedAction')
582
+ })
583
+
584
+ // ============================================================================
585
+ // Inbox — captured transactional emails (log driver)
586
+ //
587
+ // Auth-gated: the rendered email body can include reset links, billing
588
+ // receipts, and PII. Treat as sensitive even though the log driver is
589
+ // "dev-only" — staging environments are still real.
590
+ // ============================================================================
591
+
592
+ route.group({ prefix: '/inbox', middleware: 'auth' }, () => {
593
+ route.get('/', 'Actions/Dashboard/Inbox/InboxIndexAction')
594
+ route.get('/{id}', 'Actions/Dashboard/Inbox/InboxShowAction')
595
+ })
596
+
597
+ // ============================================================================
598
+ // Releases
599
+ // ============================================================================
600
+
601
+ route.group({ prefix: '/releases', middleware: 'auth' }, () => {
602
+ route.get('/', 'Actions/Dashboard/Releases/ReleaseIndexAction')
603
+ route.get('/stats', 'Actions/Dashboard/Releases/ReleaseIndexAction')
604
+ })
605
+
606
+ // ============================================================================
607
+ // Settings
608
+ // ============================================================================
609
+
610
+ route.group({ prefix: '/api/settings', middleware: 'auth' }, () => {
611
+ route.get('/mail', 'Actions/Dashboard/Settings/MailSettingsGetAction')
612
+ route.put('/mail', 'Actions/Dashboard/Settings/MailSettingsUpdateAction')
613
+ })
614
+
615
+ // ============================================================================
616
+ // Data Management
617
+ // ============================================================================
618
+
619
+ route.group({ prefix: '/api/data', middleware: 'auth' }, () => {
620
+ route.get('/dashboard', 'Actions/Dashboard/Data/DataDashboardAction')
621
+ route.get('/access-tokens', 'Actions/Dashboard/Data/AccessTokenIndexAction')
622
+ route.get('/subscribers', 'Actions/Dashboard/Data/SubscriberIndexAction')
623
+ route.get('/teams', 'Actions/Dashboard/Data/TeamIndexAction')
624
+ route.get('/users', 'Actions/Dashboard/Data/UserIndexAction')
625
+ route.get('/activity', 'Actions/Dashboard/Data/ActivityIndexAction')
626
+ })
627
+
628
+ // ============================================================================
629
+ // Infrastructure
630
+ // ============================================================================
631
+
632
+ route.group({ prefix: '/infrastructure', middleware: 'auth' }, () => {
633
+ route.get('/commands', 'Actions/Dashboard/Infrastructure/CommandIndexAction')
634
+ route.get('/requests', 'Actions/Dashboard/Infrastructure/RequestIndexAction')
635
+ route.get('/servers', 'Actions/Dashboard/Infrastructure/ServerIndexAction')
636
+ route.get('/dns', 'Actions/Dashboard/Infrastructure/DnsIndexAction')
637
+ route.get('/environment', 'Actions/Dashboard/Infrastructure/EnvironmentIndexAction')
638
+ route.get('/logs', 'Actions/Dashboard/Infrastructure/LogIndexAction')
639
+ route.get('/mailboxes', 'Actions/Dashboard/Infrastructure/MailboxIndexAction')
640
+ route.get('/permissions', 'Actions/Dashboard/Infrastructure/PermissionIndexAction')
641
+ route.get('/insights', 'Actions/Dashboard/Infrastructure/InsightsAction')
642
+ route.get('/cloud', 'Actions/Dashboard/Cloud/CloudIndexAction')
643
+ })
644
+
645
+ route.get('/api/serverless', 'Actions/Dashboard/Cloud/CloudIndexAction').middleware('auth')
646
+
647
+ // ============================================================================
648
+ // Dashboard Views — Commerce
649
+ // ============================================================================
650
+
651
+ route.group({ prefix: '/dashboard/commerce', middleware: 'auth' }, () => {
652
+ route.get('/customers', 'Actions/Dashboard/Commerce/CommerceCustomersAction')
653
+ route.get('/orders', 'Actions/Dashboard/Commerce/CommerceOrdersAction')
654
+ route.get('/products', 'Actions/Dashboard/Commerce/CommerceProductsAction')
655
+ route.get('/coupons', 'Actions/Dashboard/Commerce/CommerceCouponsAction')
656
+ route.get('/gift-cards', 'Actions/Dashboard/Commerce/CommerceGiftCardsAction')
657
+ route.get('/payments', 'Actions/Dashboard/Commerce/CommercePaymentsAction')
658
+ route.get('/delivery', 'Actions/Dashboard/Commerce/CommerceDeliveryAction')
659
+ route.get('/taxes', 'Actions/Dashboard/Commerce/CommerceTaxesAction')
660
+ route.get('/reviews', 'Actions/Dashboard/Commerce/ReviewIndexAction')
661
+ })
662
+
663
+ // ============================================================================
664
+ // Dashboard Views — CMS Content
665
+ // ============================================================================
666
+
667
+ route.group({ prefix: '/dashboard/cms', middleware: 'auth' }, () => {
668
+ route.get('/posts', 'Actions/Dashboard/Content/PostIndexAction')
669
+ route.get('/pages', 'Actions/Dashboard/Content/PageIndexAction')
670
+ route.get('/categories', 'Actions/Dashboard/Content/CategoryIndexAction')
671
+ route.get('/tags', 'Actions/Dashboard/Content/TagIndexAction')
672
+ route.get('/comments', 'Actions/Dashboard/Content/CommentIndexAction')
673
+ route.get('/authors', 'Actions/Dashboard/Content/AuthorIndexAction')
674
+ })
675
+
676
+ // ============================================================================
677
+ // Marketing
678
+ // ============================================================================
679
+
680
+ route.group({ prefix: '/api/marketing', middleware: 'auth' }, () => {
681
+ route.get('/campaigns', 'Actions/Dashboard/Marketing/CampaignIndexAction')
682
+ route.get('/lists', 'Actions/Dashboard/Marketing/ListIndexAction')
683
+ route.get('/social-posts', 'Actions/Dashboard/Marketing/SocialPostIndexAction')
684
+ })
685
+
686
+ // ============================================================================
687
+ // Notifications
688
+ // ============================================================================
689
+
690
+ route.group({ prefix: '/api/notifications', middleware: 'auth' }, () => {
691
+ route.get('/dashboard', 'Actions/Dashboard/Notifications/NotificationDashboardAction')
692
+ route.get('/email', 'Actions/Dashboard/Notifications/NotificationDashboardAction')
693
+ route.get('/sms', 'Actions/Dashboard/Notifications/NotificationDashboardAction')
694
+ route.get('/history', 'Actions/Dashboard/Notifications/NotificationDashboardAction')
695
+ })
696
+
697
+ // ============================================================================
698
+ // Library & Packages
699
+ // ============================================================================
700
+
701
+ route.group({ prefix: '/library', middleware: 'auth' }, () => {
702
+ route.get('/dependencies', 'Actions/Dashboard/Library/DependencyIndexAction')
703
+ route.get('/packages', 'Actions/Dashboard/Library/PackageIndexAction')
704
+ route.get('/functions', 'Actions/Dashboard/Library/GetFunctions')
705
+ route.get('/functions/downloads', 'Actions/Dashboard/Library/GetFunctionsDownloadCount')
706
+ route.post('/functions', 'Actions/Dashboard/Library/CreateFunction')
707
+ route.get('/components', 'Actions/Dashboard/Library/GetComponents')
708
+ route.get('/components/downloads', 'Actions/Dashboard/Library/GetComponentsDownloadCount')
709
+ route.post('/components', 'Actions/Dashboard/Library/CreateComponent')
710
+ route.get('/releases', 'Actions/Dashboard/Library/GetReleases')
711
+ route.get('/releases/count', 'Actions/Dashboard/Library/GetReleaseCount')
712
+ route.get('/releases/avg-time', 'Actions/Dashboard/Library/GetAverageReleaseTime')
713
+ route.get('/downloads', 'Actions/Dashboard/Library/GetDownloadCount')
714
+ })
715
+
716
+ // ============================================================================
717
+ // Deployments
718
+ // ============================================================================
719
+
720
+ route.group({ prefix: '/deployments', middleware: 'auth' }, () => {
721
+ route.get('/', 'Actions/Dashboard/Deployments/GetDeployments')
722
+ route.get('/count', 'Actions/Dashboard/Deployments/GetDeploymentCount')
723
+ route.get('/recent', 'Actions/Dashboard/Deployments/GetRecentDeployments')
724
+ route.get('/avg-time', 'Actions/Dashboard/Deployments/GetAverageDeploymentTime')
725
+ route.post('/', 'Actions/Dashboard/Deployments/CreateDeployment')
726
+ route.get('/script', 'Actions/Dashboard/Deployments/GetDeployScript')
727
+ route.put('/script', 'Actions/Dashboard/Deployments/UpdateDeployScript')
728
+ route.get('/terminal', 'Actions/Dashboard/Deployments/GetDeploymentLiveTerminalOutput')
729
+ })
730
+
731
+ // ============================================================================
732
+ // Models
733
+ // ============================================================================
734
+
735
+ route.group({ prefix: '/models', middleware: 'auth' }, () => {
736
+ route.get('/', 'Actions/Dashboard/Models/GetModels')
737
+ route.get('/user-count', 'Actions/Dashboard/Models/GetUserCount')
738
+ route.get('/subscriber-count', 'Actions/Dashboard/Models/GetSubscriberCount')
739
+ })