@stacksjs/defaults 0.70.58 → 0.70.59

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 (575) hide show
  1. package/app/Actions/AI/AskAction.ts +40 -0
  2. package/app/Actions/AI/SummaryAction.ts +40 -0
  3. package/app/Actions/Auth/AuthUserAction.ts +13 -0
  4. package/app/Actions/Auth/CreateTokenAction.ts +64 -0
  5. package/app/Actions/Auth/DisableTwoFactorAction.ts +37 -0
  6. package/app/Actions/Auth/EnableTwoFactorAction.ts +37 -0
  7. package/app/Actions/Auth/GenerateAuthenticationAction.ts +51 -0
  8. package/app/Actions/Auth/GenerateRegistrationAction.ts +53 -0
  9. package/app/Actions/Auth/GenerateTwoFactorSecretAction.ts +26 -0
  10. package/app/Actions/Auth/ListTokensAction.ts +30 -0
  11. package/app/Actions/Auth/LoginAction.ts +73 -0
  12. package/app/Actions/Auth/LogoutAction.ts +16 -0
  13. package/app/Actions/Auth/LogoutAllAction.ts +28 -0
  14. package/app/Actions/Auth/RefreshTokenAction.ts +39 -0
  15. package/app/Actions/Auth/RegisterAction.ts +57 -0
  16. package/app/Actions/Auth/ResendVerificationAction.ts +24 -0
  17. package/app/Actions/Auth/RevokeTokenAction.ts +43 -0
  18. package/app/Actions/Auth/TestAbilitiesAction.ts +61 -0
  19. package/app/Actions/Auth/VerifyAuthenticationAction.ts +94 -0
  20. package/app/Actions/Auth/VerifyEmailAction.ts +25 -0
  21. package/app/Actions/Auth/VerifyRegistrationAction.ts +59 -0
  22. package/app/Actions/Auth/VerifyTwoFactorLoginAction.ts +57 -0
  23. package/app/Actions/Billable/CheckoutAction.ts +25 -0
  24. package/app/Actions/Buddy/BuddyBrowseAction.ts +34 -0
  25. package/app/Actions/Buddy/BuddyCancelAction.ts +32 -0
  26. package/app/Actions/Buddy/BuddyCommitAction.ts +25 -0
  27. package/app/Actions/Buddy/BuddyGitHubConnectAction.ts +40 -0
  28. package/app/Actions/Buddy/BuddyGitHubDisconnectAction.ts +19 -0
  29. package/app/Actions/Buddy/BuddyProcessAction.ts +65 -0
  30. package/app/Actions/Buddy/BuddyProcessStreamAction.ts +128 -0
  31. package/app/Actions/Buddy/BuddyPushAction.ts +21 -0
  32. package/app/Actions/Buddy/BuddyRepoOpenAction.ts +44 -0
  33. package/app/Actions/Buddy/BuddyRepoValidateAction.ts +35 -0
  34. package/app/Actions/Buddy/BuddySettingsAction.ts +21 -0
  35. package/app/Actions/Buddy/BuddySettingsUpdateAction.ts +46 -0
  36. package/app/Actions/Buddy/BuddyStateAction.ts +28 -0
  37. package/app/Actions/Buddy/BuddyTitleAction.ts +49 -0
  38. package/app/Actions/Buddy/CommandsAction.ts +802 -0
  39. package/app/Actions/Buddy/JobCancelAction.ts +32 -0
  40. package/app/Actions/Buddy/JobRetryAction.ts +49 -0
  41. package/app/Actions/Buddy/JobsListAction.ts +141 -0
  42. package/app/Actions/Buddy/ScheduleListAction.ts +52 -0
  43. package/app/Actions/Buddy/VersionsAction.ts +12 -0
  44. package/app/Actions/Cms/AuthorDestroyAction.ts +21 -0
  45. package/app/Actions/Cms/AuthorIndexAction.ts +14 -0
  46. package/app/Actions/Cms/AuthorShowAction.ts +19 -0
  47. package/app/Actions/Cms/AuthorStoreAction.ts +20 -0
  48. package/app/Actions/Cms/AuthorUpdateAction.ts +24 -0
  49. package/app/Actions/Cms/CategorizableDestroyAction.ts +16 -0
  50. package/app/Actions/Cms/CategorizableIndexAction.ts +14 -0
  51. package/app/Actions/Cms/CategorizableShowAction.ts +16 -0
  52. package/app/Actions/Cms/CategorizableStoreAction.ts +42 -0
  53. package/app/Actions/Cms/CategorizableUpdateAction.ts +38 -0
  54. package/app/Actions/Cms/CommentDestroyAction.ts +16 -0
  55. package/app/Actions/Cms/CommentIndexAction.ts +17 -0
  56. package/app/Actions/Cms/CommentShowAction.ts +16 -0
  57. package/app/Actions/Cms/CommentStoreAction.ts +39 -0
  58. package/app/Actions/Cms/CommentUpdateAction.ts +37 -0
  59. package/app/Actions/Cms/PageDestroyAction.ts +16 -0
  60. package/app/Actions/Cms/PageIndexAction.ts +14 -0
  61. package/app/Actions/Cms/PageStoreAction.ts +31 -0
  62. package/app/Actions/Cms/PageUpdateAction.ts +27 -0
  63. package/app/Actions/Cms/PostDestroyAction.ts +17 -0
  64. package/app/Actions/Cms/PostIndexAction.ts +14 -0
  65. package/app/Actions/Cms/PostShowAction.ts +16 -0
  66. package/app/Actions/Cms/PostStoreAction.ts +37 -0
  67. package/app/Actions/Cms/PostUpdateAction.ts +32 -0
  68. package/app/Actions/Cms/PostViewsUpdateAction.ts +34 -0
  69. package/app/Actions/Cms/RssFeedAction.ts +59 -0
  70. package/app/Actions/Cms/SitemapAction.ts +60 -0
  71. package/app/Actions/Cms/TaggableDestroyAction.ts +16 -0
  72. package/app/Actions/Cms/TaggableIndexAction.ts +14 -0
  73. package/app/Actions/Cms/TaggableShowAction.ts +16 -0
  74. package/app/Actions/Cms/TaggableStoreAction.ts +36 -0
  75. package/app/Actions/Cms/TaggableUpdateAction.ts +37 -0
  76. package/app/Actions/Commerce/CouponDestroyAction.ts +18 -0
  77. package/app/Actions/Commerce/CouponIndexAction.ts +16 -0
  78. package/app/Actions/Commerce/CouponShowAction.ts +18 -0
  79. package/app/Actions/Commerce/CouponStoreAction.ts +21 -0
  80. package/app/Actions/Commerce/CouponUpdateAction.ts +31 -0
  81. package/app/Actions/Commerce/CustomerDestroyAction.ts +16 -0
  82. package/app/Actions/Commerce/CustomerIndexAction.ts +15 -0
  83. package/app/Actions/Commerce/CustomerShowAction.ts +18 -0
  84. package/app/Actions/Commerce/CustomerStoreAction.ts +29 -0
  85. package/app/Actions/Commerce/CustomerUpdateAction.ts +27 -0
  86. package/app/Actions/Commerce/DriverDestroyAction.ts +18 -0
  87. package/app/Actions/Commerce/GiftCardDestroyAction.ts +18 -0
  88. package/app/Actions/Commerce/GiftCardIndexAction.ts +16 -0
  89. package/app/Actions/Commerce/GiftCardShowAction.ts +18 -0
  90. package/app/Actions/Commerce/GiftCardStatsAction.ts +30 -0
  91. package/app/Actions/Commerce/GiftCardStoreAction.ts +35 -0
  92. package/app/Actions/Commerce/GiftCardUpdateAction.ts +26 -0
  93. package/app/Actions/Commerce/GiftCardUpdateBalanceAction.ts +36 -0
  94. package/app/Actions/Commerce/OrderDestroyAction.ts +18 -0
  95. package/app/Actions/Commerce/OrderExportAction.ts +15 -0
  96. package/app/Actions/Commerce/OrderIndexAction.ts +15 -0
  97. package/app/Actions/Commerce/OrderShowAction.ts +18 -0
  98. package/app/Actions/Commerce/OrderStoreAction.ts +32 -0
  99. package/app/Actions/Commerce/OrderUpdateAction.ts +34 -0
  100. package/app/Actions/Commerce/PaymentDestroyAction.ts +16 -0
  101. package/app/Actions/Commerce/PaymentFetchStatsAction.ts +31 -0
  102. package/app/Actions/Commerce/PaymentIndexAction.ts +15 -0
  103. package/app/Actions/Commerce/PaymentMonthlyTrendsAction.ts +21 -0
  104. package/app/Actions/Commerce/PaymentShowAction.ts +17 -0
  105. package/app/Actions/Commerce/PaymentStoreAction.ts +24 -0
  106. package/app/Actions/Commerce/PaymentUpdateAction.ts +35 -0
  107. package/app/Actions/Commerce/PrintDeviceDestroyAction.ts +18 -0
  108. package/app/Actions/Commerce/PrintDeviceIndexAction.ts +14 -0
  109. package/app/Actions/Commerce/PrintDeviceShowAction.ts +17 -0
  110. package/app/Actions/Commerce/PrintDeviceStoreAction.ts +27 -0
  111. package/app/Actions/Commerce/PrintDeviceUpdateAction.ts +27 -0
  112. package/app/Actions/Commerce/Product/ManufacturerDestroyAction.ts +20 -0
  113. package/app/Actions/Commerce/Product/ManufacturerIndexAction.ts +16 -0
  114. package/app/Actions/Commerce/Product/ManufacturerShowAction.ts +18 -0
  115. package/app/Actions/Commerce/Product/ManufacturerStoreAction.ts +14 -0
  116. package/app/Actions/Commerce/Product/ProductCategoryIndexAction.ts +16 -0
  117. package/app/Actions/Commerce/Product/ProductCategoryStoreAction.ts +16 -0
  118. package/app/Actions/Commerce/Product/ProductDestroyAction.ts +16 -0
  119. package/app/Actions/Commerce/Product/ProductIndexAction.ts +14 -0
  120. package/app/Actions/Commerce/Product/ProductManufacturerDestroyAction.ts +18 -0
  121. package/app/Actions/Commerce/Product/ProductManufacturerIndexAction.ts +14 -0
  122. package/app/Actions/Commerce/Product/ProductManufacturerShowAction.ts +16 -0
  123. package/app/Actions/Commerce/Product/ProductManufacturerStoreAction.ts +14 -0
  124. package/app/Actions/Commerce/Product/ProductManufacturerUpdateAction.ts +18 -0
  125. package/app/Actions/Commerce/Product/ProductShowAction.ts +18 -0
  126. package/app/Actions/Commerce/Product/ProductStoreAction.ts +17 -0
  127. package/app/Actions/Commerce/Product/ProductUnitDestroyAction.ts +18 -0
  128. package/app/Actions/Commerce/Product/ProductUnitIndexAction.ts +14 -0
  129. package/app/Actions/Commerce/Product/ProductUnitShowAction.ts +18 -0
  130. package/app/Actions/Commerce/Product/ProductUnitStoreAction.ts +15 -0
  131. package/app/Actions/Commerce/Product/ProductUpdateAction.ts +17 -0
  132. package/app/Actions/Commerce/Product/ProductVariantDestroyAction.ts +18 -0
  133. package/app/Actions/Commerce/Product/ProductVariantIndexAction.ts +14 -0
  134. package/app/Actions/Commerce/Product/ProductVariantShowAction.ts +17 -0
  135. package/app/Actions/Commerce/Product/ProductVariantStoreAction.ts +14 -0
  136. package/app/Actions/Commerce/Product/ProductVariantUpdateAction.ts +16 -0
  137. package/app/Actions/Commerce/ReceiptDestroyAction.ts +18 -0
  138. package/app/Actions/Commerce/ReceiptIndexAction.ts +14 -0
  139. package/app/Actions/Commerce/ReceiptShowAction.ts +18 -0
  140. package/app/Actions/Commerce/ReceiptStoreAction.ts +28 -0
  141. package/app/Actions/Commerce/ReceiptUpdateAction.ts +30 -0
  142. package/app/Actions/Commerce/ReviewIndexAction.ts +14 -0
  143. package/app/Actions/Commerce/ReviewShowAction.ts +16 -0
  144. package/app/Actions/Commerce/ReviewStoreAction.ts +26 -0
  145. package/app/Actions/Commerce/ReviewUpdateAction.ts +28 -0
  146. package/app/Actions/Commerce/Shipping/DeliveryRouteDestroyAction.ts +18 -0
  147. package/app/Actions/Commerce/Shipping/DeliveryRouteIndexAction.ts +16 -0
  148. package/app/Actions/Commerce/Shipping/DeliveryRouteShowAction.ts +18 -0
  149. package/app/Actions/Commerce/Shipping/DeliveryRouteStoreAction.ts +16 -0
  150. package/app/Actions/Commerce/Shipping/DeliveryRouteUpdateAction.ts +18 -0
  151. package/app/Actions/Commerce/Shipping/DigitalDeliveryDestroyAction.ts +18 -0
  152. package/app/Actions/Commerce/Shipping/DigitalDeliveryIndexAction.ts +16 -0
  153. package/app/Actions/Commerce/Shipping/DigitalDeliveryShowAction.ts +18 -0
  154. package/app/Actions/Commerce/Shipping/DigitalDeliveryStoreAction.ts +18 -0
  155. package/app/Actions/Commerce/Shipping/DigitalDeliveryUpdateAction.ts +18 -0
  156. package/app/Actions/Commerce/Shipping/DriverIndexAction.ts +16 -0
  157. package/app/Actions/Commerce/Shipping/DriverShowAction.ts +18 -0
  158. package/app/Actions/Commerce/Shipping/DriverStoreAction.ts +16 -0
  159. package/app/Actions/Commerce/Shipping/DriverUpdateAction.ts +18 -0
  160. package/app/Actions/Commerce/Shipping/LicenseKeyDestroyAction.ts +20 -0
  161. package/app/Actions/Commerce/Shipping/LicenseKeyIndexAction.ts +16 -0
  162. package/app/Actions/Commerce/Shipping/LicenseKeyShowAction.ts +18 -0
  163. package/app/Actions/Commerce/Shipping/LicenseKeyStoreAction.ts +18 -0
  164. package/app/Actions/Commerce/Shipping/LicenseKeyUpdateAction.ts +18 -0
  165. package/app/Actions/Commerce/Shipping/ShippingMethodDestroyAction.ts +16 -0
  166. package/app/Actions/Commerce/Shipping/ShippingMethodIndexAction.ts +14 -0
  167. package/app/Actions/Commerce/Shipping/ShippingMethodShowAction.ts +16 -0
  168. package/app/Actions/Commerce/Shipping/ShippingMethodStoreAction.ts +16 -0
  169. package/app/Actions/Commerce/Shipping/ShippingMethodUpdateAction.ts +15 -0
  170. package/app/Actions/Commerce/Shipping/ShippingRateDestroyAction.ts +16 -0
  171. package/app/Actions/Commerce/Shipping/ShippingRateIndexAction.ts +14 -0
  172. package/app/Actions/Commerce/Shipping/ShippingRateShowAction.ts +16 -0
  173. package/app/Actions/Commerce/Shipping/ShippingRateStoreAction.ts +16 -0
  174. package/app/Actions/Commerce/Shipping/ShippingRateUpdateAction.ts +17 -0
  175. package/app/Actions/Commerce/Shipping/ShippingZoneDestroyAction.ts +16 -0
  176. package/app/Actions/Commerce/Shipping/ShippingZoneIndexAction.ts +14 -0
  177. package/app/Actions/Commerce/Shipping/ShippingZoneShowAction.ts +16 -0
  178. package/app/Actions/Commerce/Shipping/ShippingZoneStoreAction.ts +16 -0
  179. package/app/Actions/Commerce/Shipping/ShippingZoneUpdateAction.ts +15 -0
  180. package/app/Actions/Commerce/TaxRateDestroyAction.ts +16 -0
  181. package/app/Actions/Commerce/TaxRateIndexAction.ts +14 -0
  182. package/app/Actions/Commerce/TaxRateShowAction.ts +17 -0
  183. package/app/Actions/Commerce/TaxRateStoreAction.ts +24 -0
  184. package/app/Actions/Commerce/TaxRateUpdateAction.ts +24 -0
  185. package/app/Actions/Commerce/WaitlistProductAnalyticsAction.ts +29 -0
  186. package/app/Actions/Commerce/WaitlistProductDestroyAction.ts +16 -0
  187. package/app/Actions/Commerce/WaitlistProductIndexAction.ts +14 -0
  188. package/app/Actions/Commerce/WaitlistProductQuantityDistributionAction.ts +32 -0
  189. package/app/Actions/Commerce/WaitlistProductShowAction.ts +16 -0
  190. package/app/Actions/Commerce/WaitlistProductStatusAction.ts +37 -0
  191. package/app/Actions/Commerce/WaitlistProductStoreAction.ts +27 -0
  192. package/app/Actions/Commerce/WaitlistProductTimeSeriesAction.ts +25 -0
  193. package/app/Actions/Commerce/WaitlistProductUpdateAction.ts +29 -0
  194. package/app/Actions/Commerce/WaitlistRestaurantDashboardAction.ts +29 -0
  195. package/app/Actions/Commerce/WaitlistRestaurantDestroyAction.ts +16 -0
  196. package/app/Actions/Commerce/WaitlistRestaurantIndexAction.ts +14 -0
  197. package/app/Actions/Commerce/WaitlistRestaurantShowAction.ts +16 -0
  198. package/app/Actions/Commerce/WaitlistRestaurantStoreAction.ts +31 -0
  199. package/app/Actions/Commerce/WaitlistRestaurantUpdateAction.ts +33 -0
  200. package/app/Actions/ContactAction.ts +72 -0
  201. package/app/Actions/Dashboard/Actions/CreateAction.ts +11 -0
  202. package/app/Actions/Dashboard/Actions/GetActionCount.ts +12 -0
  203. package/app/Actions/Dashboard/Actions/GetActions.ts +19 -0
  204. package/app/Actions/Dashboard/Analytics/BlogAnalyticsAction.ts +58 -0
  205. package/app/Actions/Dashboard/Analytics/BrowserAnalyticsAction.ts +42 -0
  206. package/app/Actions/Dashboard/Analytics/CommerceAnalyticsAction.ts +64 -0
  207. package/app/Actions/Dashboard/Analytics/CountryAnalyticsAction.ts +41 -0
  208. package/app/Actions/Dashboard/Analytics/DeviceAnalyticsAction.ts +58 -0
  209. package/app/Actions/Dashboard/Analytics/EventAnalyticsAction.ts +90 -0
  210. package/app/Actions/Dashboard/Analytics/MarketingAnalyticsAction.ts +76 -0
  211. package/app/Actions/Dashboard/Analytics/PageAnalyticsAction.ts +45 -0
  212. package/app/Actions/Dashboard/Analytics/ReferrerAnalyticsAction.ts +72 -0
  213. package/app/Actions/Dashboard/Analytics/SalesAnalyticsAction.ts +73 -0
  214. package/app/Actions/Dashboard/Analytics/WebAnalyticsAction.ts +114 -0
  215. package/app/Actions/Dashboard/Auth/MeAction.ts +84 -0
  216. package/app/Actions/Dashboard/BuddyDashboardAction.ts +34 -0
  217. package/app/Actions/Dashboard/Ci/RepoRunJobsAction.ts +60 -0
  218. package/app/Actions/Dashboard/Ci/RepoRunsAction.ts +67 -0
  219. package/app/Actions/Dashboard/Ci/RunnerHistoryAction.ts +58 -0
  220. package/app/Actions/Dashboard/Ci/StatusAction.ts +73 -0
  221. package/app/Actions/Dashboard/Ci/failure-notifier.ts +214 -0
  222. package/app/Actions/Dashboard/Ci/runner-pressure-monitor.ts +259 -0
  223. package/app/Actions/Dashboard/Cloud/CloudIndexAction.ts +61 -0
  224. package/app/Actions/Dashboard/Commands/CreateCommand.ts +11 -0
  225. package/app/Actions/Dashboard/Commands/GetAverageCommandTime.ts +12 -0
  226. package/app/Actions/Dashboard/Commands/GetCommandCount.ts +12 -0
  227. package/app/Actions/Dashboard/Commands/GetCommandSuccessRate.ts +12 -0
  228. package/app/Actions/Dashboard/Commands/GetCommands.ts +12 -0
  229. package/app/Actions/Dashboard/Commerce/CommerceCouponsAction.ts +48 -0
  230. package/app/Actions/Dashboard/Commerce/CommerceCustomersAction.ts +48 -0
  231. package/app/Actions/Dashboard/Commerce/CommerceDashboardAction.ts +98 -0
  232. package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +65 -0
  233. package/app/Actions/Dashboard/Commerce/CommerceGiftCardsAction.ts +48 -0
  234. package/app/Actions/Dashboard/Commerce/CommerceOrdersAction.ts +51 -0
  235. package/app/Actions/Dashboard/Commerce/CommercePaymentsAction.ts +59 -0
  236. package/app/Actions/Dashboard/Commerce/CommerceProductsAction.ts +50 -0
  237. package/app/Actions/Dashboard/Commerce/CommerceTaxesAction.ts +46 -0
  238. package/app/Actions/Dashboard/Commerce/PosIndexAction.ts +57 -0
  239. package/app/Actions/Dashboard/Commerce/ReviewIndexAction.ts +51 -0
  240. package/app/Actions/Dashboard/Content/AuthorIndexAction.ts +51 -0
  241. package/app/Actions/Dashboard/Content/CategoryIndexAction.ts +27 -0
  242. package/app/Actions/Dashboard/Content/CommentIndexAction.ts +41 -0
  243. package/app/Actions/Dashboard/Content/ContentDashboardAction.ts +54 -0
  244. package/app/Actions/Dashboard/Content/FileIndexAction.ts +24 -0
  245. package/app/Actions/Dashboard/Content/PageIndexAction.ts +25 -0
  246. package/app/Actions/Dashboard/Content/PostIndexAction.ts +102 -0
  247. package/app/Actions/Dashboard/Content/SeoIndexAction.ts +17 -0
  248. package/app/Actions/Dashboard/Content/TagIndexAction.ts +23 -0
  249. package/app/Actions/Dashboard/CreateDnsRecords.ts +11 -0
  250. package/app/Actions/Dashboard/CreateMailbox.ts +11 -0
  251. package/app/Actions/Dashboard/DashboardActivityAction.ts +58 -0
  252. package/app/Actions/Dashboard/DashboardHealthAction.ts +52 -0
  253. package/app/Actions/Dashboard/DashboardHomeAction.ts +83 -0
  254. package/app/Actions/Dashboard/DashboardStatsAction.ts +48 -0
  255. package/app/Actions/Dashboard/Data/AccessTokenIndexAction.ts +65 -0
  256. package/app/Actions/Dashboard/Data/ActivityIndexAction.ts +28 -0
  257. package/app/Actions/Dashboard/Data/DataDashboardAction.ts +67 -0
  258. package/app/Actions/Dashboard/Data/SubscriberIndexAction.ts +48 -0
  259. package/app/Actions/Dashboard/Data/TeamIndexAction.ts +43 -0
  260. package/app/Actions/Dashboard/Data/UserIndexAction.ts +48 -0
  261. package/app/Actions/Dashboard/Deployments/CreateDeployment.ts +11 -0
  262. package/app/Actions/Dashboard/Deployments/GetAverageDeploymentTime.ts +15 -0
  263. package/app/Actions/Dashboard/Deployments/GetDeployScript.ts +12 -0
  264. package/app/Actions/Dashboard/Deployments/GetDeploymentCount.ts +12 -0
  265. package/app/Actions/Dashboard/Deployments/GetDeploymentLiveTerminalOutput.ts +12 -0
  266. package/app/Actions/Dashboard/Deployments/GetDeployments.ts +20 -0
  267. package/app/Actions/Dashboard/Deployments/GetRecentDeployments.ts +12 -0
  268. package/app/Actions/Dashboard/Deployments/UpdateDeployScript.ts +11 -0
  269. package/app/Actions/Dashboard/GetDnsRecords.ts +12 -0
  270. package/app/Actions/Dashboard/GetEmailInboxes.ts +12 -0
  271. package/app/Actions/Dashboard/GetProjects.ts +13 -0
  272. package/app/Actions/Dashboard/GetRecentCommits.ts +13 -0
  273. package/app/Actions/Dashboard/Inbox/InboxIndexAction.ts +144 -0
  274. package/app/Actions/Dashboard/Inbox/InboxShowAction.ts +89 -0
  275. package/app/Actions/Dashboard/Infrastructure/CommandIndexAction.ts +18 -0
  276. package/app/Actions/Dashboard/Infrastructure/DnsIndexAction.ts +101 -0
  277. package/app/Actions/Dashboard/Infrastructure/EnvironmentIndexAction.ts +67 -0
  278. package/app/Actions/Dashboard/Infrastructure/InsightsAction.ts +29 -0
  279. package/app/Actions/Dashboard/Infrastructure/LogIndexAction.ts +50 -0
  280. package/app/Actions/Dashboard/Infrastructure/MailboxIndexAction.ts +85 -0
  281. package/app/Actions/Dashboard/Infrastructure/PermissionIndexAction.ts +54 -0
  282. package/app/Actions/Dashboard/Infrastructure/RequestIndexAction.ts +44 -0
  283. package/app/Actions/Dashboard/Infrastructure/ServerIndexAction.ts +101 -0
  284. package/app/Actions/Dashboard/Jobs/CreateJob.ts +11 -0
  285. package/app/Actions/Dashboard/Jobs/GetAverageJobTime.ts +12 -0
  286. package/app/Actions/Dashboard/Jobs/GetJobHistory.ts +12 -0
  287. package/app/Actions/Dashboard/Jobs/GetJobs.ts +11 -0
  288. package/app/Actions/Dashboard/Jobs/GetJobsPerMinute.ts +12 -0
  289. package/app/Actions/Dashboard/Jobs/JobIndexAction.ts +136 -0
  290. package/app/Actions/Dashboard/Jobs/JobRetryAction.ts +23 -0
  291. package/app/Actions/Dashboard/Jobs/JobStatsAction.ts +49 -0
  292. package/app/Actions/Dashboard/Kanban/BoardDestroyAction.ts +84 -0
  293. package/app/Actions/Dashboard/Kanban/BoardShowAction.ts +215 -0
  294. package/app/Actions/Dashboard/Kanban/BoardStoreAction.ts +98 -0
  295. package/app/Actions/Dashboard/Kanban/BoardUpdateAction.ts +96 -0
  296. package/app/Actions/Dashboard/Kanban/BoardsIndexAction.ts +81 -0
  297. package/app/Actions/Dashboard/Kanban/BoardsReorderAction.ts +80 -0
  298. package/app/Actions/Dashboard/Kanban/CardAssigneesSyncAction.ts +103 -0
  299. package/app/Actions/Dashboard/Kanban/CardCommentDestroyAction.ts +33 -0
  300. package/app/Actions/Dashboard/Kanban/CardCommentStoreAction.ts +82 -0
  301. package/app/Actions/Dashboard/Kanban/CardDestroyAction.ts +48 -0
  302. package/app/Actions/Dashboard/Kanban/CardLabelsSyncAction.ts +103 -0
  303. package/app/Actions/Dashboard/Kanban/CardShowAction.ts +122 -0
  304. package/app/Actions/Dashboard/Kanban/CardStoreAction.ts +112 -0
  305. package/app/Actions/Dashboard/Kanban/CardUpdateAction.ts +91 -0
  306. package/app/Actions/Dashboard/Kanban/CardsReorderAction.ts +148 -0
  307. package/app/Actions/Dashboard/Kanban/ColumnDestroyAction.ts +59 -0
  308. package/app/Actions/Dashboard/Kanban/ColumnStoreAction.ts +94 -0
  309. package/app/Actions/Dashboard/Kanban/ColumnUpdateAction.ts +89 -0
  310. package/app/Actions/Dashboard/Kanban/ColumnsReorderAction.ts +85 -0
  311. package/app/Actions/Dashboard/Kanban/LabelDestroyAction.ts +41 -0
  312. package/app/Actions/Dashboard/Kanban/LabelStoreAction.ts +70 -0
  313. package/app/Actions/Dashboard/Kanban/LabelUpdateAction.ts +83 -0
  314. package/app/Actions/Dashboard/Kanban/UsersListAction.ts +36 -0
  315. package/app/Actions/Dashboard/Library/CreateComponent.ts +11 -0
  316. package/app/Actions/Dashboard/Library/CreateFunction.ts +11 -0
  317. package/app/Actions/Dashboard/Library/DependencyIndexAction.ts +92 -0
  318. package/app/Actions/Dashboard/Library/GetAverageReleaseTime.ts +12 -0
  319. package/app/Actions/Dashboard/Library/GetComponents.ts +24 -0
  320. package/app/Actions/Dashboard/Library/GetComponentsDownloadCount.ts +12 -0
  321. package/app/Actions/Dashboard/Library/GetDownloadCount.ts +12 -0
  322. package/app/Actions/Dashboard/Library/GetFunctions.ts +22 -0
  323. package/app/Actions/Dashboard/Library/GetFunctionsDownloadCount.ts +12 -0
  324. package/app/Actions/Dashboard/Library/GetReleaseCount.ts +12 -0
  325. package/app/Actions/Dashboard/Library/GetReleases.ts +28 -0
  326. package/app/Actions/Dashboard/Library/PackageIndexAction.ts +26 -0
  327. package/app/Actions/Dashboard/Marketing/CampaignIndexAction.ts +45 -0
  328. package/app/Actions/Dashboard/Marketing/ListIndexAction.ts +43 -0
  329. package/app/Actions/Dashboard/Marketing/SocialPostIndexAction.ts +47 -0
  330. package/app/Actions/Dashboard/Models/GetModels.ts +39 -0
  331. package/app/Actions/Dashboard/Models/GetSubscriberCount.ts +12 -0
  332. package/app/Actions/Dashboard/Models/GetUserCount.ts +12 -0
  333. package/app/Actions/Dashboard/Models/ModelShowAction.ts +131 -0
  334. package/app/Actions/Dashboard/Models/ModelsIndexAction.ts +169 -0
  335. package/app/Actions/Dashboard/Notifications/CreateNotification.ts +11 -0
  336. package/app/Actions/Dashboard/Notifications/GetAverageNotificationTime.ts +12 -0
  337. package/app/Actions/Dashboard/Notifications/GetNotificationCount.ts +12 -0
  338. package/app/Actions/Dashboard/Notifications/GetNotificationDeliveryRate.ts +12 -0
  339. package/app/Actions/Dashboard/Notifications/GetNotificationHistory.ts +12 -0
  340. package/app/Actions/Dashboard/Notifications/GetNotifications.ts +12 -0
  341. package/app/Actions/Dashboard/Notifications/NotificationDashboardAction.ts +43 -0
  342. package/app/Actions/Dashboard/Queries/QueryIndexAction.ts +22 -0
  343. package/app/Actions/Dashboard/Queue/QueueRetryFailedAction.ts +22 -0
  344. package/app/Actions/Dashboard/Queue/QueueStatsAction.ts +98 -0
  345. package/app/Actions/Dashboard/Queue/QueueWorkersAction.ts +46 -0
  346. package/app/Actions/Dashboard/Rbac/PermissionDestroyAction.ts +33 -0
  347. package/app/Actions/Dashboard/Rbac/PermissionStoreAction.ts +53 -0
  348. package/app/Actions/Dashboard/Rbac/PermissionsIndexAction.ts +34 -0
  349. package/app/Actions/Dashboard/Rbac/RoleDestroyAction.ts +35 -0
  350. package/app/Actions/Dashboard/Rbac/RolePermissionsShowAction.ts +45 -0
  351. package/app/Actions/Dashboard/Rbac/RolePermissionsSyncAction.ts +63 -0
  352. package/app/Actions/Dashboard/Rbac/RoleStoreAction.ts +58 -0
  353. package/app/Actions/Dashboard/Rbac/RolesIndexAction.ts +36 -0
  354. package/app/Actions/Dashboard/Rbac/UserRolesShowAction.ts +40 -0
  355. package/app/Actions/Dashboard/Rbac/UserRolesSyncAction.ts +65 -0
  356. package/app/Actions/Dashboard/Rbac/UsersListAction.ts +39 -0
  357. package/app/Actions/Dashboard/Realtime/RealtimeStatsAction.ts +50 -0
  358. package/app/Actions/Dashboard/Releases/ReleaseIndexAction.ts +21 -0
  359. package/app/Actions/Dashboard/Requests/GetAverageRequestTime.ts +12 -0
  360. package/app/Actions/Dashboard/Requests/GetRequestCount.ts +12 -0
  361. package/app/Actions/Dashboard/Requests/GetRequestSuccessRate.ts +12 -0
  362. package/app/Actions/Dashboard/Requests/GetRequests.ts +12 -0
  363. package/app/Actions/Dashboard/Search/GlobalSearchAction.ts +26 -0
  364. package/app/Actions/Dashboard/ServiceHealthAction.ts +243 -0
  365. package/app/Actions/Dashboard/Settings/MailSettingsGetAction.ts +20 -0
  366. package/app/Actions/Dashboard/Settings/MailSettingsUpdateAction.ts +10 -0
  367. package/app/Actions/Dashboard/Settings/SettingsIndexAction.ts +40 -0
  368. package/app/Actions/Dashboard/Settings/UpdateAiConfig.ts +27 -0
  369. package/app/Actions/Dashboard/Settings/UpdateAnalyticsConfig.ts +38 -0
  370. package/app/Actions/Dashboard/Settings/UpdateAppConfig.ts +38 -0
  371. package/app/Actions/Dashboard/Settings/UpdateCacheConfig.ts +11 -0
  372. package/app/Actions/Dashboard/Settings/UpdateCliConfig.ts +11 -0
  373. package/app/Actions/Dashboard/Settings/UpdateCloudConfig.ts +38 -0
  374. package/app/Actions/Dashboard/Settings/UpdateDatabaseConfig.ts +38 -0
  375. package/app/Actions/Dashboard/Settings/UpdateDnsConfig.ts +38 -0
  376. package/app/Actions/Dashboard/Settings/UpdateDocsConfig.ts +11 -0
  377. package/app/Actions/Dashboard/Settings/UpdateEmailConfig.ts +38 -0
  378. package/app/Actions/Dashboard/Settings/UpdateEnvConfig.ts +11 -0
  379. package/app/Actions/Dashboard/Settings/UpdateErrorsConfig.ts +11 -0
  380. package/app/Actions/Dashboard/Settings/UpdateFileSystemsConfig.ts +11 -0
  381. package/app/Actions/Dashboard/Settings/UpdateGitConfig.ts +11 -0
  382. package/app/Actions/Dashboard/Settings/UpdateHashingConfig.ts +11 -0
  383. package/app/Actions/Dashboard/Settings/UpdateLibraryConfig.ts +11 -0
  384. package/app/Actions/Dashboard/Settings/UpdateLoggerConfig.ts +11 -0
  385. package/app/Actions/Dashboard/Settings/UpdateNotificationConfig.ts +11 -0
  386. package/app/Actions/Dashboard/Settings/UpdatePaymentConfig.ts +11 -0
  387. package/app/Actions/Dashboard/Settings/UpdatePortsConfig.ts +38 -0
  388. package/app/Actions/Dashboard/Settings/UpdateQueueConfig.ts +11 -0
  389. package/app/Actions/Dashboard/Settings/UpdateSearchEngineConfig.ts +11 -0
  390. package/app/Actions/Dashboard/Settings/UpdateSecurityConfig.ts +38 -0
  391. package/app/Actions/Dashboard/Settings/UpdateServicesConfig.ts +38 -0
  392. package/app/Actions/Dashboard/Settings/UpdateStorageConfig.ts +11 -0
  393. package/app/Actions/Dashboard/Settings/UpdateTeamConfig.ts +11 -0
  394. package/app/Actions/Dashboard/Settings/UpdateUiConfig.ts +11 -0
  395. package/app/Actions/HealthAction.ts +112 -0
  396. package/app/Actions/InstallAction.ts +83 -0
  397. package/app/Actions/Locale/SetLocaleAction.ts +51 -0
  398. package/app/Actions/LogAction.ts +42 -0
  399. package/app/Actions/Logs/LogFetchStatsAction.ts +50 -0
  400. package/app/Actions/Logs/LogIndexOrmAction.ts +13 -0
  401. package/app/Actions/Logs/LogShowOrmAction.ts +17 -0
  402. package/app/Actions/Logs/LogStoreOrmAction.ts +16 -0
  403. package/app/Actions/Logs/LogUpdateOrmAction.ts +20 -0
  404. package/app/Actions/Monitoring/ErrorDestroyAction.ts +25 -0
  405. package/app/Actions/Monitoring/ErrorGroupAction.ts +21 -0
  406. package/app/Actions/Monitoring/ErrorIgnoreAction.ts +25 -0
  407. package/app/Actions/Monitoring/ErrorIndexAction.ts +14 -0
  408. package/app/Actions/Monitoring/ErrorResolveAction.ts +25 -0
  409. package/app/Actions/Monitoring/ErrorShowAction.ts +19 -0
  410. package/app/Actions/Monitoring/ErrorStatsAction.ts +14 -0
  411. package/app/Actions/Monitoring/ErrorTimelineAction.ts +14 -0
  412. package/app/Actions/Monitoring/ErrorUnresolveAction.ts +25 -0
  413. package/app/Actions/NotifyUser.ts +10 -0
  414. package/app/Actions/Password/PasswordResetAction.ts +54 -0
  415. package/app/Actions/Password/SendPasswordResetEmailAction.ts +66 -0
  416. package/app/Actions/Password/VerifyResetTokenAction.ts +27 -0
  417. package/app/Actions/Payment/CancelSubscriptionAction.ts +20 -0
  418. package/app/Actions/Payment/CreateCheckoutAction.ts +28 -0
  419. package/app/Actions/Payment/CreateInvoiceSubscription.ts +18 -0
  420. package/app/Actions/Payment/CreatePaymentIntentAction.ts +31 -0
  421. package/app/Actions/Payment/CreateSetupIntentAction.ts +20 -0
  422. package/app/Actions/Payment/CreateSubscriptionAction.ts +23 -0
  423. package/app/Actions/Payment/DeleteDefaultPaymentAction.ts +18 -0
  424. package/app/Actions/Payment/FetchActiveSubscriptionAction.ts +18 -0
  425. package/app/Actions/Payment/FetchDefaultPaymentMethodAction.ts +18 -0
  426. package/app/Actions/Payment/FetchPaymentCustomerAction.ts +18 -0
  427. package/app/Actions/Payment/FetchPaymentMethodsAction.ts +18 -0
  428. package/app/Actions/Payment/FetchProductAction.ts +15 -0
  429. package/app/Actions/Payment/FetchTransactionHistoryAction.ts +18 -0
  430. package/app/Actions/Payment/FetchUserSubscriptionsAction.ts +18 -0
  431. package/app/Actions/Payment/SetDefaultPaymentAction.ts +20 -0
  432. package/app/Actions/Payment/SetUserDefaultPaymentAction.ts +20 -0
  433. package/app/Actions/Payment/StorePaymentMethodAction.ts +20 -0
  434. package/app/Actions/Payment/StoreTransactionAction.ts +20 -0
  435. package/app/Actions/Payment/UpdateCustomerAction.ts +24 -0
  436. package/app/Actions/Payment/UpdateDefaultPaymentMethodAction.ts +18 -0
  437. package/app/Actions/Payment/UpdateSubscriptionAction.ts +22 -0
  438. package/app/Actions/Queue/FetchQueuesAction.ts +14 -0
  439. package/app/Actions/README.md +61 -0
  440. package/app/Actions/Realtime/FetchWebsocketsAction.ts +14 -0
  441. package/app/Actions/RobotsAction.ts +61 -0
  442. package/app/Actions/SendWelcomeEmail.ts +40 -0
  443. package/app/Actions/SitemapAction.ts +234 -0
  444. package/app/Actions/Storefront/AddToCartAction.ts +153 -0
  445. package/app/Actions/Storefront/CheckoutContactAction.ts +50 -0
  446. package/app/Actions/Storefront/CheckoutShippingAction.ts +61 -0
  447. package/app/Actions/Storefront/GetCartAction.ts +58 -0
  448. package/app/Actions/Storefront/PlaceOrderAction.ts +195 -0
  449. package/app/Actions/Storefront/SubmitReviewAction.ts +140 -0
  450. package/app/Actions/Storefront/UpdateCartItemAction.ts +83 -0
  451. package/app/Actions/Storefront/_shipping.ts +64 -0
  452. package/app/Actions/SubscriberEmailAction.ts +60 -0
  453. package/app/Actions/TestErrorAction.ts +163 -0
  454. package/app/Actions/UnsubscribeAction.ts +107 -0
  455. package/app/Actions/UploadTestAction.ts +57 -0
  456. package/app/Broadcasts/OrderShipped.ts +57 -0
  457. package/app/Commands/Inspire.ts +57 -0
  458. package/app/Commands/README.md +84 -0
  459. package/app/Commands.ts +38 -0
  460. package/app/Controllers/ComingSoonController.ts +9 -0
  461. package/app/Controllers/QueryController.ts +373 -0
  462. package/app/Events.ts +14 -0
  463. package/app/Gates.ts +107 -0
  464. package/app/Jobs/ExampleJob.ts +20 -0
  465. package/app/Jobs/ExampleTwoJob.ts +12 -0
  466. package/app/Jobs/PruneModelsJob.ts +61 -0
  467. package/app/Jobs/PruneQueryLogsJob.ts +51 -0
  468. package/app/Jobs/README.md +79 -0
  469. package/app/Jobs/SendCampaignJob.ts +201 -0
  470. package/app/Jobs/SendEmailJob.ts +52 -0
  471. package/app/Jobs/SendPasswordResetEmailJob.ts +44 -0
  472. package/app/Jobs/SyncSearchIndexJob.ts +64 -0
  473. package/app/Listener.ts +84 -0
  474. package/app/Listeners/Console.ts +22 -0
  475. package/app/Listeners/README.md +47 -0
  476. package/app/Mail/OrderConfirmation.ts +60 -0
  477. package/app/Mail/SubscriptionConfirmation.ts +41 -0
  478. package/app/Middleware/Abilities.ts +53 -0
  479. package/app/Middleware/Api.ts +26 -0
  480. package/app/Middleware/Auth.ts +59 -0
  481. package/app/Middleware/Can.ts +68 -0
  482. package/app/Middleware/Compress.ts +213 -0
  483. package/app/Middleware/Cors.ts +320 -0
  484. package/app/Middleware/Csrf.ts +224 -0
  485. package/app/Middleware/EnsureEmailIsVerified.ts +28 -0
  486. package/app/Middleware/Env.ts +24 -0
  487. package/app/Middleware/EnvDevelopment.ts +19 -0
  488. package/app/Middleware/EnvLocal.ts +19 -0
  489. package/app/Middleware/EnvNotDevelopment.ts +19 -0
  490. package/app/Middleware/EnvNotLocal.ts +19 -0
  491. package/app/Middleware/EnvNotProduction.ts +19 -0
  492. package/app/Middleware/EnvNotStaging.ts +19 -0
  493. package/app/Middleware/EnvProduction.ts +19 -0
  494. package/app/Middleware/EnvStaging.ts +19 -0
  495. package/app/Middleware/Guest.ts +25 -0
  496. package/app/Middleware/Logger.ts +20 -0
  497. package/app/Middleware/Maintenance.ts +36 -0
  498. package/app/Middleware/Permission.ts +42 -0
  499. package/app/Middleware/README.md +48 -0
  500. package/app/Middleware/Role.ts +42 -0
  501. package/app/Middleware/Signed.ts +31 -0
  502. package/app/Middleware/Team.ts +36 -0
  503. package/app/Middleware/Throttle.ts +96 -0
  504. package/app/Middleware.ts +35 -0
  505. package/app/Models/Activity.ts +94 -0
  506. package/app/Models/Board.ts +103 -0
  507. package/app/Models/BoardColumn.ts +87 -0
  508. package/app/Models/Campaign.ts +239 -0
  509. package/app/Models/CampaignSend.ts +107 -0
  510. package/app/Models/Card.ts +117 -0
  511. package/app/Models/CardComment.ts +68 -0
  512. package/app/Models/Comment.ts +108 -0
  513. package/app/Models/Content/Author.ts +104 -0
  514. package/app/Models/Content/Page.ts +99 -0
  515. package/app/Models/Content/Post.ts +144 -0
  516. package/app/Models/Deployment.ts +116 -0
  517. package/app/Models/EmailList.ts +126 -0
  518. package/app/Models/EmailListSubscriber.ts +91 -0
  519. package/app/Models/Error.ts +70 -0
  520. package/app/Models/FailedJob.ts +62 -0
  521. package/app/Models/Job.ts +63 -0
  522. package/app/Models/Label.ts +66 -0
  523. package/app/Models/Log.ts +110 -0
  524. package/app/Models/Notification.ts +118 -0
  525. package/app/Models/PaymentMethod.ts +98 -0
  526. package/app/Models/PaymentProduct.ts +91 -0
  527. package/app/Models/PaymentTransaction.ts +78 -0
  528. package/app/Models/README.md +31 -0
  529. package/app/Models/Release.ts +89 -0
  530. package/app/Models/Request.ts +114 -0
  531. package/app/Models/SocialPost.ts +136 -0
  532. package/app/Models/Subscriber.ts +89 -0
  533. package/app/Models/SubscriberEmail.ts +55 -0
  534. package/app/Models/Subscription.ts +153 -0
  535. package/app/Models/Tag.ts +82 -0
  536. package/app/Models/Team.ts +72 -0
  537. package/app/Models/User.ts +134 -0
  538. package/app/Models/commerce/Cart.ts +139 -0
  539. package/app/Models/commerce/CartItem.ts +137 -0
  540. package/app/Models/commerce/Category.ts +105 -0
  541. package/app/Models/commerce/Coupon.ts +181 -0
  542. package/app/Models/commerce/Customer.ts +132 -0
  543. package/app/Models/commerce/DeliveryRoute.ts +93 -0
  544. package/app/Models/commerce/DigitalDelivery.ts +105 -0
  545. package/app/Models/commerce/Driver.ts +97 -0
  546. package/app/Models/commerce/GiftCard.ts +191 -0
  547. package/app/Models/commerce/LicenseKey.ts +87 -0
  548. package/app/Models/commerce/LoyaltyPoint.ts +107 -0
  549. package/app/Models/commerce/LoyaltyReward.ts +124 -0
  550. package/app/Models/commerce/Manufacturer.ts +84 -0
  551. package/app/Models/commerce/Order.ts +142 -0
  552. package/app/Models/commerce/OrderItem.ts +51 -0
  553. package/app/Models/commerce/Payment.ts +163 -0
  554. package/app/Models/commerce/PrintDevice.ts +117 -0
  555. package/app/Models/commerce/Product.ts +148 -0
  556. package/app/Models/commerce/ProductUnit.ts +107 -0
  557. package/app/Models/commerce/ProductVariant.ts +106 -0
  558. package/app/Models/commerce/Receipt.ts +128 -0
  559. package/app/Models/commerce/Review.ts +140 -0
  560. package/app/Models/commerce/ShippingMethod.ts +97 -0
  561. package/app/Models/commerce/ShippingRate.ts +74 -0
  562. package/app/Models/commerce/ShippingZone.ts +111 -0
  563. package/app/Models/commerce/TaxRate.ts +114 -0
  564. package/app/Models/commerce/Transaction.ts +126 -0
  565. package/app/Models/commerce/WaitlistProduct.ts +149 -0
  566. package/app/Models/commerce/WaitlistRestaurant.ts +187 -0
  567. package/app/Models/realtime/Websocket.ts +77 -0
  568. package/app/Notifications/README.md +31 -0
  569. package/app/Notifications/Welcome.ts +32 -0
  570. package/app/Policies/PostPolicy.ts +131 -0
  571. package/app/README.md +23 -0
  572. package/app/Routes.ts +47 -0
  573. package/app/Scheduler.ts +28 -0
  574. package/app/Storefront/CartCookie.ts +109 -0
  575. package/package.json +3 -2
@@ -0,0 +1,91 @@
1
+ import { Action } from '@stacksjs/actions'
2
+ import { db } from '@stacksjs/database'
3
+
4
+ interface CardInput {
5
+ title?: unknown
6
+ description?: unknown
7
+ dueDate?: unknown
8
+ archived?: unknown
9
+ }
10
+
11
+ /**
12
+ * `PATCH /api/dashboard/kanban/cards/:id` (stacksjs/stacks#1846 Phase 2).
13
+ *
14
+ * Partial update for the card body: title, description, due date,
15
+ * archive flag. `position` and `columnId` are NOT updatable here —
16
+ * card moves go through `/cards/reorder` which can rewrite multiple
17
+ * rows transactionally and keep the denormalised `board_id` in sync
18
+ * when a card crosses columns on different boards (rare but possible
19
+ * if the page reordered a column move pair).
20
+ */
21
+ export default new Action({
22
+ name: 'Kanban Card Update',
23
+ description: 'Partial update of a card body (title, description, due date, archive).',
24
+ method: 'PATCH',
25
+ apiResponse: true,
26
+ async handle(request) {
27
+ const rawId = (request as any)?.params?.id ?? (request as any)?.param?.('id') ?? null
28
+ const id = Number(rawId)
29
+ if (!Number.isFinite(id) || id <= 0) {
30
+ return { error: 'Invalid card id', status: 400 }
31
+ }
32
+
33
+ const body = (request as any).jsonBody as CardInput | undefined ?? {}
34
+ const set: Record<string, unknown> = {}
35
+
36
+ if (typeof body.title === 'string') {
37
+ const title = body.title.trim()
38
+ if (!title || title.length > 300) {
39
+ return { error: '`title` must be 1-300 characters.', status: 400 }
40
+ }
41
+ set.title = title
42
+ }
43
+ if (typeof body.description === 'string' || body.description === null) {
44
+ set.description = typeof body.description === 'string' ? body.description.trim() : null
45
+ }
46
+ if (typeof body.dueDate === 'string' || body.dueDate === null) {
47
+ set.due_date = typeof body.dueDate === 'string' && body.dueDate ? body.dueDate : null
48
+ }
49
+ if (typeof body.archived === 'boolean')
50
+ set.archived = body.archived ? 1 : 0
51
+
52
+ if (Object.keys(set).length === 0) {
53
+ return { error: 'No updatable fields provided.', status: 400 }
54
+ }
55
+
56
+ try {
57
+ await db.updateTable('cards').set(set as any).where('id', '=', id).execute()
58
+
59
+ const rows = await db.unsafe(
60
+ `SELECT id, uuid, column_id, board_id, title, description, position,
61
+ created_by_user_id, due_date, archived, created_at, updated_at
62
+ FROM cards WHERE id = ? LIMIT 1`,
63
+ [id],
64
+ ).execute() as Array<Record<string, unknown>>
65
+ const r = rows?.[0]
66
+ if (!r) {
67
+ return { error: 'Card not found', status: 404 }
68
+ }
69
+ return {
70
+ card: {
71
+ id: Number(r.id),
72
+ uuid: r.uuid == null ? null : String(r.uuid),
73
+ columnId: Number(r.column_id),
74
+ boardId: Number(r.board_id),
75
+ title: String(r.title),
76
+ description: r.description == null ? null : String(r.description),
77
+ position: Number(r.position),
78
+ createdByUserId: r.created_by_user_id == null ? null : Number(r.created_by_user_id),
79
+ dueDate: r.due_date == null ? null : String(r.due_date),
80
+ archived: Number(r.archived) === 1,
81
+ createdAt: r.created_at == null ? null : String(r.created_at),
82
+ updatedAt: r.updated_at == null ? null : String(r.updated_at),
83
+ },
84
+ }
85
+ }
86
+ catch (err) {
87
+ console.error('[dashboard/kanban] CardUpdateAction failed:', err)
88
+ return { error: err instanceof Error ? err.message : 'unknown error', status: 500 }
89
+ }
90
+ },
91
+ })
@@ -0,0 +1,148 @@
1
+ import { Action } from '@stacksjs/actions'
2
+ import { db } from '@stacksjs/database'
3
+
4
+ interface ColumnReorder {
5
+ columnId: number
6
+ order: number[]
7
+ }
8
+
9
+ interface ReorderInput {
10
+ /**
11
+ * Per-column ordered lists. Each entry rewrites every card in that
12
+ * column to match the supplied order, AND sets `column_id` for any
13
+ * card that moved in from a different column (cross-column drag).
14
+ *
15
+ * Example shape:
16
+ *
17
+ * {
18
+ * columns: [
19
+ * { columnId: 1, order: [5, 3, 7] }, // Todo
20
+ * { columnId: 2, order: [4, 8] }, // In Progress
21
+ * { columnId: 3, order: [] }, // Done — emptied
22
+ * ]
23
+ * }
24
+ *
25
+ * Sending the full per-column state (not just the moved card)
26
+ * avoids the "neighbour position drift" footgun where a card-move
27
+ * leaves siblings with stale positions.
28
+ */
29
+ columns?: unknown
30
+ }
31
+
32
+ /**
33
+ * `POST /api/dashboard/kanban/cards/reorder` (stacksjs/stacks#1846 Phase 2).
34
+ *
35
+ * The drag-and-drop hot path. Rewrites card positions and column
36
+ * assignments across one or more columns of a single board in a single
37
+ * transaction. Validates that every card and every column belongs to
38
+ * the same board so a malformed payload can't reassign cards across
39
+ * boards (would break `cards.board_id` denormalisation).
40
+ *
41
+ * Returns `{ moved: <count> }` — the count is informational for
42
+ * client-side toast messages, not load-bearing.
43
+ */
44
+ export default new Action({
45
+ name: 'Kanban Cards Reorder',
46
+ description: 'Bulk-rewrite cards.{column_id, position} across one or more columns of the same board.',
47
+ method: 'POST',
48
+ apiResponse: true,
49
+ async handle(request) {
50
+ const body = (request as any).jsonBody as ReorderInput | undefined ?? {}
51
+
52
+ if (!Array.isArray(body.columns) || body.columns.length === 0) {
53
+ return { error: '`columns` must be a non-empty array.', status: 400 }
54
+ }
55
+
56
+ // Parse + validate. Each entry needs a positive integer columnId
57
+ // and a (possibly empty) array of positive integer card ids.
58
+ const reorders: ColumnReorder[] = []
59
+ const allCardIds = new Set<number>()
60
+ for (const raw of body.columns) {
61
+ if (!raw || typeof raw !== 'object')
62
+ return { error: '`columns[]` entry must be an object.', status: 400 }
63
+ const columnId = Number((raw as any).columnId)
64
+ if (!Number.isFinite(columnId) || columnId <= 0)
65
+ return { error: '`columns[].columnId` must be a positive integer.', status: 400 }
66
+ if (!Array.isArray((raw as any).order))
67
+ return { error: '`columns[].order` must be an array.', status: 400 }
68
+ const order: number[] = []
69
+ for (const v of (raw as any).order) {
70
+ const n = Number(v)
71
+ if (!Number.isFinite(n) || n <= 0)
72
+ return { error: '`columns[].order` contains an invalid card id.', status: 400 }
73
+ if (allCardIds.has(n))
74
+ return { error: 'A card id appears in more than one column.', status: 400 }
75
+ allCardIds.add(n)
76
+ order.push(n)
77
+ }
78
+ reorders.push({ columnId, order })
79
+ }
80
+
81
+ if (reorders.length === 0) {
82
+ return { moved: 0 }
83
+ }
84
+
85
+ try {
86
+ // Verify all columns belong to the same board.
87
+ const columnIds = reorders.map(r => r.columnId)
88
+ const colPlaceholders = columnIds.map(() => '?').join(',')
89
+ const colRows = await db.unsafe(
90
+ `SELECT id, board_id FROM board_columns WHERE id IN (${colPlaceholders})`,
91
+ columnIds,
92
+ ).execute() as Array<{ id: number, board_id: number }>
93
+ if (colRows.length !== columnIds.length) {
94
+ return { error: 'One or more column ids do not exist.', status: 400 }
95
+ }
96
+ const boardIds = new Set(colRows.map(r => r.board_id))
97
+ if (boardIds.size > 1) {
98
+ return { error: 'All columns in a reorder request must belong to the same board.', status: 400 }
99
+ }
100
+ const boardId = colRows[0].board_id
101
+
102
+ // Verify all cards belong to that board (prevents a malformed
103
+ // page from moving cards in from a sibling board).
104
+ if (allCardIds.size > 0) {
105
+ const cardIdList = Array.from(allCardIds)
106
+ const cardPlaceholders = cardIdList.map(() => '?').join(',')
107
+ const cardRows = await db.unsafe(
108
+ `SELECT id FROM cards WHERE id IN (${cardPlaceholders}) AND board_id = ?`,
109
+ [...cardIdList, boardId],
110
+ ).execute() as Array<{ id: number }>
111
+ if (cardRows.length !== cardIdList.length) {
112
+ return { error: 'One or more card ids do not belong to the named board.', status: 400 }
113
+ }
114
+ }
115
+
116
+ // Single transaction: for each (columnId, order) entry, set
117
+ // `column_id = columnId, position = index` on each card. Cards
118
+ // moving across columns get both columns of their row rewritten;
119
+ // cards staying put still get their position rewritten (cheap,
120
+ // idempotent).
121
+ const txOps = async (qb: any) => {
122
+ for (const { columnId, order } of reorders) {
123
+ for (let i = 0; i < order.length; i++) {
124
+ await qb.updateTable('cards')
125
+ .set({ column_id: columnId, position: i, board_id: boardId })
126
+ .where('id', '=', order[i])
127
+ .execute()
128
+ }
129
+ }
130
+ }
131
+ try {
132
+ await (db as any).transaction(txOps)
133
+ }
134
+ catch {
135
+ // Driver-specific transaction shape failed — sequential is
136
+ // safe (each UPDATE is idempotent), but the page should
137
+ // refetch on failure to confirm the final state.
138
+ await txOps(db)
139
+ }
140
+
141
+ return { moved: allCardIds.size, boardId }
142
+ }
143
+ catch (err) {
144
+ console.error('[dashboard/kanban] CardsReorderAction failed:', err)
145
+ return { error: err instanceof Error ? err.message : 'unknown error', status: 500 }
146
+ }
147
+ },
148
+ })
@@ -0,0 +1,59 @@
1
+ import { Action } from '@stacksjs/actions'
2
+ import { db } from '@stacksjs/database'
3
+
4
+ /**
5
+ * `DELETE /api/dashboard/kanban/columns/:id` (stacksjs/stacks#1846 Phase 2).
6
+ *
7
+ * Hard-deletes the column and cascade-cleans every card inside it
8
+ * (plus the pivot rows referencing those cards). Same convention as
9
+ * BoardDestroyAction — Stacks doesn't lean on DB-level FK cascade, so
10
+ * the cascade lives in this action.
11
+ *
12
+ * If you want to keep cards but remove the column, move the cards to
13
+ * a different column first via the cards/reorder endpoint, then call
14
+ * this on the empty column.
15
+ */
16
+ export default new Action({
17
+ name: 'Kanban Column Destroy',
18
+ description: 'Hard-deletes a column and its cards.',
19
+ method: 'DELETE',
20
+ apiResponse: true,
21
+ async handle(request) {
22
+ const rawId = (request as any)?.params?.id ?? (request as any)?.param?.('id') ?? null
23
+ const id = Number(rawId)
24
+ if (!Number.isFinite(id) || id <= 0) {
25
+ return { error: 'Invalid column id', status: 400 }
26
+ }
27
+
28
+ try {
29
+ const txOps = async (qb: any) => {
30
+ await qb.unsafe(
31
+ 'DELETE FROM card_labels WHERE card_id IN (SELECT id FROM cards WHERE column_id = ?)',
32
+ [id],
33
+ ).execute()
34
+ await qb.unsafe(
35
+ 'DELETE FROM card_assignees WHERE card_id IN (SELECT id FROM cards WHERE column_id = ?)',
36
+ [id],
37
+ ).execute()
38
+ // Card comments (Phase 3, stacksjs/stacks#1846).
39
+ await qb.unsafe(
40
+ 'DELETE FROM card_comments WHERE card_id IN (SELECT id FROM cards WHERE column_id = ?)',
41
+ [id],
42
+ ).execute()
43
+ await qb.deleteFrom('cards').where('column_id', '=', id).execute()
44
+ await qb.deleteFrom('board_columns').where('id', '=', id).execute()
45
+ }
46
+ try {
47
+ await (db as any).transaction(txOps)
48
+ }
49
+ catch {
50
+ await txOps(db)
51
+ }
52
+ return { deleted: true, id }
53
+ }
54
+ catch (err) {
55
+ console.error('[dashboard/kanban] ColumnDestroyAction failed:', err)
56
+ return { error: err instanceof Error ? err.message : 'unknown error', status: 500 }
57
+ }
58
+ },
59
+ })
@@ -0,0 +1,94 @@
1
+ import { Action } from '@stacksjs/actions'
2
+ import { db } from '@stacksjs/database'
3
+
4
+ interface ColumnInput {
5
+ boardId?: unknown
6
+ name?: unknown
7
+ color?: unknown
8
+ cardLimit?: unknown
9
+ }
10
+
11
+ /**
12
+ * `POST /api/dashboard/kanban/columns` (stacksjs/stacks#1846 Phase 2).
13
+ *
14
+ * Appends a new column to the end of the target board. Validates that
15
+ * `boardId` points at a real board so a typo doesn't silently create
16
+ * an orphan column row.
17
+ */
18
+ export default new Action({
19
+ name: 'Kanban Column Store',
20
+ description: 'Creates a new column on a board.',
21
+ method: 'POST',
22
+ apiResponse: true,
23
+ async handle(request) {
24
+ const body = (request as any).jsonBody as ColumnInput | undefined ?? {}
25
+
26
+ const boardId = Number(body.boardId)
27
+ if (!Number.isFinite(boardId) || boardId <= 0) {
28
+ return { error: '`boardId` is required and must be a positive integer.', status: 400 }
29
+ }
30
+ const name = typeof body.name === 'string' ? body.name.trim() : ''
31
+ if (!name || name.length > 80) {
32
+ return { error: '`name` is required and must be 1-80 characters.', status: 400 }
33
+ }
34
+ const color = typeof body.color === 'string' && body.color ? body.color : 'slate'
35
+ const cardLimit = body.cardLimit == null
36
+ ? null
37
+ : (Number.isFinite(Number(body.cardLimit)) && Number(body.cardLimit) >= 0
38
+ ? Number(body.cardLimit)
39
+ : null)
40
+
41
+ try {
42
+ // Reject orphan columns up front — a column on a deleted board
43
+ // would never surface in any sidebar or API, just rot in the DB.
44
+ const boards = await db.unsafe('SELECT id FROM boards WHERE id = ? LIMIT 1', [boardId]).execute() as Array<{ id: number }>
45
+ if (!boards?.length) {
46
+ return { error: 'Board not found.', status: 404 }
47
+ }
48
+
49
+ const maxRow = await db.unsafe(
50
+ 'SELECT COALESCE(MAX(position), -1) AS m FROM board_columns WHERE board_id = ?',
51
+ [boardId],
52
+ ).execute() as Array<{ m: number }>
53
+ const nextPosition = (Number(maxRow?.[0]?.m ?? -1) + 1) || 0
54
+
55
+ await db.insertInto('board_columns').values({
56
+ board_id: boardId,
57
+ name,
58
+ color,
59
+ card_limit: cardLimit,
60
+ position: nextPosition,
61
+ }).execute()
62
+
63
+ const rows = await db.unsafe(
64
+ `SELECT id, uuid, board_id, name, position, card_limit, color, created_at, updated_at
65
+ FROM board_columns
66
+ WHERE board_id = ? AND name = ? AND position = ?
67
+ ORDER BY id DESC
68
+ LIMIT 1`,
69
+ [boardId, name, nextPosition],
70
+ ).execute() as Array<Record<string, unknown>>
71
+ const r = rows?.[0]
72
+ if (!r) {
73
+ return { error: 'Column insert succeeded but follow-up read returned nothing.', status: 500 }
74
+ }
75
+
76
+ return {
77
+ column: {
78
+ id: Number(r.id),
79
+ uuid: r.uuid == null ? null : String(r.uuid),
80
+ boardId: Number(r.board_id),
81
+ name: String(r.name),
82
+ position: Number(r.position),
83
+ cardLimit: r.card_limit == null ? null : Number(r.card_limit),
84
+ color: String(r.color),
85
+ cards: [],
86
+ },
87
+ }
88
+ }
89
+ catch (err) {
90
+ console.error('[dashboard/kanban] ColumnStoreAction failed:', err)
91
+ return { error: err instanceof Error ? err.message : 'unknown error', status: 500 }
92
+ }
93
+ },
94
+ })
@@ -0,0 +1,89 @@
1
+ import { Action } from '@stacksjs/actions'
2
+ import { db } from '@stacksjs/database'
3
+
4
+ interface ColumnInput {
5
+ name?: unknown
6
+ color?: unknown
7
+ cardLimit?: unknown
8
+ }
9
+
10
+ /**
11
+ * `PATCH /api/dashboard/kanban/columns/:id` (stacksjs/stacks#1846 Phase 2).
12
+ *
13
+ * Partial update for name / color / card limit. `position` and
14
+ * `boardId` are NOT updatable here — moving a column between boards
15
+ * isn't a feature (would orphan its cards' denormalised `board_id`);
16
+ * reordering goes through `/columns/reorder` so transactions cover
17
+ * the whole rewrite.
18
+ */
19
+ export default new Action({
20
+ name: 'Kanban Column Update',
21
+ description: 'Partial update of a board column.',
22
+ method: 'PATCH',
23
+ apiResponse: true,
24
+ async handle(request) {
25
+ const rawId = (request as any)?.params?.id ?? (request as any)?.param?.('id') ?? null
26
+ const id = Number(rawId)
27
+ if (!Number.isFinite(id) || id <= 0) {
28
+ return { error: 'Invalid column id', status: 400 }
29
+ }
30
+
31
+ const body = (request as any).jsonBody as ColumnInput | undefined ?? {}
32
+ const set: Record<string, unknown> = {}
33
+
34
+ if (typeof body.name === 'string') {
35
+ const name = body.name.trim()
36
+ if (!name || name.length > 80) {
37
+ return { error: '`name` must be 1-80 characters.', status: 400 }
38
+ }
39
+ set.name = name
40
+ }
41
+ if (typeof body.color === 'string' && body.color)
42
+ set.color = body.color
43
+ if (body.cardLimit !== undefined) {
44
+ if (body.cardLimit === null) {
45
+ set.card_limit = null
46
+ }
47
+ else {
48
+ const n = Number(body.cardLimit)
49
+ if (!Number.isFinite(n) || n < 0) {
50
+ return { error: '`cardLimit` must be a non-negative number or null.', status: 400 }
51
+ }
52
+ set.card_limit = n
53
+ }
54
+ }
55
+
56
+ if (Object.keys(set).length === 0) {
57
+ return { error: 'No updatable fields provided.', status: 400 }
58
+ }
59
+
60
+ try {
61
+ await db.updateTable('board_columns').set(set as any).where('id', '=', id).execute()
62
+
63
+ const rows = await db.unsafe(
64
+ `SELECT id, uuid, board_id, name, position, card_limit, color, created_at, updated_at
65
+ FROM board_columns WHERE id = ? LIMIT 1`,
66
+ [id],
67
+ ).execute() as Array<Record<string, unknown>>
68
+ const r = rows?.[0]
69
+ if (!r) {
70
+ return { error: 'Column not found', status: 404 }
71
+ }
72
+ return {
73
+ column: {
74
+ id: Number(r.id),
75
+ uuid: r.uuid == null ? null : String(r.uuid),
76
+ boardId: Number(r.board_id),
77
+ name: String(r.name),
78
+ position: Number(r.position),
79
+ cardLimit: r.card_limit == null ? null : Number(r.card_limit),
80
+ color: String(r.color),
81
+ },
82
+ }
83
+ }
84
+ catch (err) {
85
+ console.error('[dashboard/kanban] ColumnUpdateAction failed:', err)
86
+ return { error: err instanceof Error ? err.message : 'unknown error', status: 500 }
87
+ }
88
+ },
89
+ })
@@ -0,0 +1,85 @@
1
+ import { Action } from '@stacksjs/actions'
2
+ import { db } from '@stacksjs/database'
3
+
4
+ interface ReorderInput {
5
+ boardId?: unknown
6
+ order?: unknown
7
+ }
8
+
9
+ /**
10
+ * `POST /api/dashboard/kanban/columns/reorder` (stacksjs/stacks#1846 Phase 2).
11
+ *
12
+ * Bulk rewrite column positions for a board. The submitted `order`
13
+ * is an array of column ids in their new display order; index becomes
14
+ * the row's new `position`. Wrapped in a transaction so a partial
15
+ * failure doesn't leave the board with a half-renumbered column row.
16
+ *
17
+ * Why scoped to a board? Two reasons:
18
+ * 1. Validation: every id in `order` must belong to the same
19
+ * board — otherwise a drag in one board could accidentally
20
+ * renumber columns in another board sharing the same row order.
21
+ * 2. Index hit: the `(board_id, position)` index gives a tight
22
+ * lookup for the post-reorder card query.
23
+ */
24
+ export default new Action({
25
+ name: 'Kanban Columns Reorder',
26
+ description: 'Bulk-rewrite `position` on a board\'s columns.',
27
+ method: 'POST',
28
+ apiResponse: true,
29
+ async handle(request) {
30
+ const body = (request as any).jsonBody as ReorderInput | undefined ?? {}
31
+
32
+ const boardId = Number(body.boardId)
33
+ if (!Number.isFinite(boardId) || boardId <= 0) {
34
+ return { error: '`boardId` is required.', status: 400 }
35
+ }
36
+ if (!Array.isArray(body.order) || body.order.length === 0) {
37
+ return { error: '`order` must be a non-empty array of column ids.', status: 400 }
38
+ }
39
+ const ids: number[] = []
40
+ for (const v of body.order) {
41
+ const n = Number(v)
42
+ if (!Number.isFinite(n) || n <= 0) {
43
+ return { error: '`order` contains an invalid id.', status: 400 }
44
+ }
45
+ ids.push(n)
46
+ }
47
+ if (new Set(ids).size !== ids.length) {
48
+ return { error: '`order` contains duplicate ids.', status: 400 }
49
+ }
50
+
51
+ try {
52
+ // Verify every column actually belongs to the named board.
53
+ // Single round-trip via a count of rows that match both criteria.
54
+ const placeholders = ids.map(() => '?').join(',')
55
+ const matchRows = await db.unsafe(
56
+ `SELECT COUNT(*) AS c FROM board_columns WHERE id IN (${placeholders}) AND board_id = ?`,
57
+ [...ids, boardId],
58
+ ).execute() as Array<{ c: number }>
59
+ const matched = Number(matchRows?.[0]?.c ?? 0)
60
+ if (matched !== ids.length) {
61
+ return { error: 'One or more column ids do not belong to the named board.', status: 400 }
62
+ }
63
+
64
+ const txOps = async (qb: any) => {
65
+ for (let i = 0; i < ids.length; i++) {
66
+ await qb.updateTable('board_columns')
67
+ .set({ position: i })
68
+ .where('id', '=', ids[i])
69
+ .execute()
70
+ }
71
+ }
72
+ try {
73
+ await (db as any).transaction(txOps)
74
+ }
75
+ catch {
76
+ await txOps(db)
77
+ }
78
+ return { reordered: ids.length }
79
+ }
80
+ catch (err) {
81
+ console.error('[dashboard/kanban] ColumnsReorderAction failed:', err)
82
+ return { error: err instanceof Error ? err.message : 'unknown error', status: 500 }
83
+ }
84
+ },
85
+ })
@@ -0,0 +1,41 @@
1
+ import { Action } from '@stacksjs/actions'
2
+ import { db } from '@stacksjs/database'
3
+
4
+ /**
5
+ * `DELETE /api/dashboard/kanban/labels/:id` (stacksjs/stacks#1846 Phase 3).
6
+ *
7
+ * Removes a label and detaches it from every card that carries it.
8
+ * The label row goes from the `labels` table; every pivot row in
9
+ * `card_labels` that references it goes too. Cards themselves are
10
+ * untouched.
11
+ */
12
+ export default new Action({
13
+ name: 'Kanban Label Destroy',
14
+ description: 'Hard-deletes a label and its card_labels pivot rows.',
15
+ method: 'DELETE',
16
+ apiResponse: true,
17
+ async handle(request) {
18
+ const rawId = (request as any)?.params?.id ?? (request as any)?.param?.('id') ?? null
19
+ const id = Number(rawId)
20
+ if (!Number.isFinite(id) || id <= 0)
21
+ return { error: 'Invalid label id', status: 400 }
22
+
23
+ try {
24
+ const txOps = async (qb: any) => {
25
+ await qb.deleteFrom('card_labels').where('label_id', '=', id).execute()
26
+ await qb.deleteFrom('labels').where('id', '=', id).execute()
27
+ }
28
+ try {
29
+ await (db as any).transaction(txOps)
30
+ }
31
+ catch {
32
+ await txOps(db)
33
+ }
34
+ return { deleted: true, id }
35
+ }
36
+ catch (err) {
37
+ console.error('[dashboard/kanban] LabelDestroyAction failed:', err)
38
+ return { error: err instanceof Error ? err.message : 'unknown error', status: 500 }
39
+ }
40
+ },
41
+ })
@@ -0,0 +1,70 @@
1
+ import { Action } from '@stacksjs/actions'
2
+ import { db } from '@stacksjs/database'
3
+
4
+ interface LabelInput {
5
+ boardId?: unknown
6
+ name?: unknown
7
+ color?: unknown
8
+ }
9
+
10
+ /**
11
+ * `POST /api/dashboard/kanban/labels` (stacksjs/stacks#1846 Phase 3).
12
+ *
13
+ * Creates a label scoped to a board. Labels are unique per
14
+ * `(board_id, name)` — the migration enforces this via a unique
15
+ * index, and the action rejects up front with a 409 rather than
16
+ * letting the UNIQUE constraint fire.
17
+ */
18
+ export default new Action({
19
+ name: 'Kanban Label Store',
20
+ description: 'Creates a label on a board.',
21
+ method: 'POST',
22
+ apiResponse: true,
23
+ async handle(request) {
24
+ const body = (request as any).jsonBody as LabelInput | undefined ?? {}
25
+
26
+ const boardId = Number(body.boardId)
27
+ if (!Number.isFinite(boardId) || boardId <= 0) {
28
+ return { error: '`boardId` is required.', status: 400 }
29
+ }
30
+ const name = typeof body.name === 'string' ? body.name.trim() : ''
31
+ if (!name || name.length > 60) {
32
+ return { error: '`name` is required and must be 1-60 characters.', status: 400 }
33
+ }
34
+ const color = typeof body.color === 'string' && body.color ? body.color : 'slate'
35
+
36
+ try {
37
+ // Reject orphan labels: the board must exist.
38
+ const boards = await db.unsafe('SELECT id FROM boards WHERE id = ? LIMIT 1', [boardId]).execute() as Array<{ id: number }>
39
+ if (!boards?.length)
40
+ return { error: 'Board not found.', status: 404 }
41
+
42
+ // Pre-check uniqueness — clearer error than the DB's
43
+ // `UNIQUE constraint failed: labels.board_id, labels.name`.
44
+ const dup = await db.unsafe(
45
+ 'SELECT id FROM labels WHERE board_id = ? AND name = ? LIMIT 1',
46
+ [boardId, name],
47
+ ).execute() as Array<{ id: number }>
48
+ if (dup?.length)
49
+ return { error: 'A label with that name already exists on this board.', status: 409 }
50
+
51
+ await db.insertInto('labels').values({ board_id: boardId, name, color }).execute()
52
+
53
+ const inserted = await db.unsafe(
54
+ 'SELECT id, board_id, name, color FROM labels WHERE board_id = ? AND name = ? LIMIT 1',
55
+ [boardId, name],
56
+ ).execute() as Array<{ id: number, board_id: number, name: string, color: string }>
57
+ const r = inserted?.[0]
58
+ if (!r)
59
+ return { error: 'Label insert succeeded but follow-up read returned nothing.', status: 500 }
60
+
61
+ return {
62
+ label: { id: r.id, boardId: r.board_id, name: r.name, color: r.color },
63
+ }
64
+ }
65
+ catch (err) {
66
+ console.error('[dashboard/kanban] LabelStoreAction failed:', err)
67
+ return { error: err instanceof Error ? err.message : 'unknown error', status: 500 }
68
+ }
69
+ },
70
+ })