@stacksjs/defaults 0.70.355 → 0.70.356
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ai/skills/stacks-email/SKILL.md +38 -1
- package/app/Actions/ContactAction.ts +2 -2
- package/app/Actions/Dashboard/Analytics/EventAnalyticsAction.ts +2 -3
- package/app/Actions/Dashboard/Analytics/MarketingAnalyticsAction.ts +2 -3
- package/app/Actions/Dashboard/Analytics/SalesAnalyticsAction.ts +2 -3
- package/app/Actions/Dashboard/Analytics/WebAnalyticsAction.ts +9 -3
- package/app/Actions/Dashboard/Auth/MeAction.ts +4 -7
- package/app/Actions/Dashboard/Buddy/BuddyChatAction.ts +2 -3
- package/app/Actions/Dashboard/Cloud/CloudIndexAction.ts +8 -1
- package/app/Actions/Dashboard/Cloud/ServerlessIndexAction.ts +15 -8
- package/app/Actions/Dashboard/Commerce/CommerceCategoriesAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommerceCouponsAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommerceCustomersAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommerceDashboardAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommerceGiftCardsAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommerceOrdersAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommercePaymentsAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommercePosAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommercePosCheckoutAction.ts +75 -61
- package/app/Actions/Dashboard/Commerce/CommercePrintDevicesAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommercePrintLogsAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommerceProductDetailAction.ts +3 -4
- package/app/Actions/Dashboard/Commerce/CommerceProductsAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/CommerceTaxesAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/DeliveryRouteIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/DigitalDeliveryIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/DriverIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/LicenseKeyIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/LicenseKeyOptionsAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/ManufacturerIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/ProductUnitIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/ProductVariantIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/ProductWaitlistIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/RestaurantWaitlistIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/ReviewIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/ShippingMethodIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/ShippingRateIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Commerce/ShippingZoneIndexAction.ts +2 -4
- package/app/Actions/Dashboard/DashboardActivityAction.ts +2 -5
- package/app/Actions/Dashboard/Data/ActivityIndexAction.ts +2 -5
- package/app/Actions/Dashboard/Data/SubscriberIndexAction.ts +2 -5
- package/app/Actions/Dashboard/Data/TeamIndexAction.ts +2 -5
- package/app/Actions/Dashboard/Data/UserIndexAction.ts +2 -5
- package/app/Actions/Dashboard/Deployments/CreateDeployment.ts +23 -19
- package/app/Actions/Dashboard/Deployments/GetAverageDeploymentTime.ts +8 -2
- package/app/Actions/Dashboard/Deployments/GetDeployScript.ts +3 -6
- package/app/Actions/Dashboard/Deployments/GetDeployment.ts +4 -5
- package/app/Actions/Dashboard/Deployments/GetDeploymentCount.ts +7 -1
- package/app/Actions/Dashboard/Deployments/GetDeploymentLiveTerminalOutput.ts +10 -9
- package/app/Actions/Dashboard/Deployments/GetDeployments.ts +2 -4
- package/app/Actions/Dashboard/Deployments/GetRecentDeployments.ts +8 -2
- package/app/Actions/Dashboard/Deployments/UpdateDeployScript.ts +18 -5
- package/app/Actions/Dashboard/Email/CapturedMailIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Email/CapturedMailShowAction.ts +3 -4
- package/app/Actions/Dashboard/Infrastructure/InsightsAction.ts +15 -14
- package/app/Actions/Dashboard/Infrastructure/LogIndexAction.ts +2 -8
- package/app/Actions/Dashboard/Jobs/JobIndexAction.ts +2 -4
- package/app/Actions/Dashboard/Jobs/JobShowAction.ts +13 -8
- package/app/Actions/Dashboard/Jobs/JobStatsAction.ts +2 -4
- package/app/Actions/Dashboard/Kanban/BoardDestroyAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/BoardShowAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/BoardStoreAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/BoardUpdateAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/BoardsIndexAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/BoardsReorderAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardAssigneesSyncAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardCommentDestroyAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardCommentStoreAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardCommentUpdateAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardDestroyAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardLabelsSyncAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardShowAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardStoreAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardUpdateAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/CardsReorderAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/ColumnDestroyAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/ColumnStoreAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/ColumnUpdateAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/ColumnsReorderAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/LabelDestroyAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/LabelStoreAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/LabelUpdateAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/UsersListAction.ts +2 -3
- package/app/Actions/Dashboard/Kanban/kanban-response.ts +5 -0
- package/app/Actions/Dashboard/Library/CreateComponent.ts +15 -6
- package/app/Actions/Dashboard/Library/CreateFunction.ts +15 -6
- package/app/Actions/Dashboard/Library/DependencyIndexAction.ts +88 -77
- package/app/Actions/Dashboard/Library/GetAverageReleaseTime.ts +21 -15
- package/app/Actions/Dashboard/Library/GetComponents.ts +14 -7
- package/app/Actions/Dashboard/Library/GetDownloadCount.ts +14 -5
- package/app/Actions/Dashboard/Library/GetFunctions.ts +12 -5
- package/app/Actions/Dashboard/Library/GetReleaseCount.ts +14 -5
- package/app/Actions/Dashboard/Library/GetReleases.ts +17 -10
- package/app/Actions/Dashboard/Library/PackageIndexAction.ts +14 -7
- package/app/Actions/Dashboard/Models/ModelDestroyAction.ts +7 -5
- package/app/Actions/Dashboard/Models/ModelShowAction.ts +82 -174
- package/app/Actions/Dashboard/Models/ModelStoreAction.ts +6 -4
- package/app/Actions/Dashboard/Models/ModelUpdateAction.ts +9 -7
- package/app/Actions/Dashboard/Models/ModelsIndexAction.ts +47 -17
- package/app/Actions/Dashboard/Models/model-write.ts +20 -5
- package/app/Actions/Dashboard/Notifications/NotificationDeliveryHistoryAction.ts +46 -36
- package/app/Actions/Dashboard/Notifications/NotificationDeliveryIndexAction.ts +14 -6
- package/app/Actions/Dashboard/Notifications/NotificationDeliveryOverviewAction.ts +96 -84
- package/app/Actions/Dashboard/Notifications/NotificationDeliveryRetryAction.ts +34 -21
- package/app/Actions/Dashboard/Queries/QueryDashboardAction.ts +2 -4
- package/app/Actions/Dashboard/Queries/QueryShowAction.ts +2 -3
- package/app/Actions/Dashboard/Queue/QueueStatsAction.ts +2 -4
- package/app/Actions/Dashboard/Queue/QueueWorkersAction.ts +2 -4
- package/app/Actions/Dashboard/Rbac/PermissionDestroyAction.ts +2 -2
- package/app/Actions/Dashboard/Rbac/PermissionStoreAction.ts +2 -2
- package/app/Actions/Dashboard/Rbac/PermissionsIndexAction.ts +2 -3
- package/app/Actions/Dashboard/Rbac/RoleDestroyAction.ts +2 -2
- package/app/Actions/Dashboard/Rbac/RolePermissionsShowAction.ts +2 -2
- package/app/Actions/Dashboard/Rbac/RolePermissionsSyncAction.ts +2 -6
- package/app/Actions/Dashboard/Rbac/RoleStoreAction.ts +2 -2
- package/app/Actions/Dashboard/Rbac/RolesIndexAction.ts +4 -6
- package/app/Actions/Dashboard/Rbac/UserRolesShowAction.ts +2 -2
- package/app/Actions/Dashboard/Rbac/UserRolesSyncAction.ts +2 -9
- package/app/Actions/Dashboard/Rbac/UsersListAction.ts +2 -3
- package/app/Actions/Dashboard/Rbac/rbac-response.ts +10 -0
- package/app/Actions/Dashboard/Realtime/RealtimeStatsAction.ts +2 -4
- package/app/Actions/Dashboard/Search/GlobalSearchAction.ts +68 -55
- package/app/Actions/Dashboard/Teams/TeamInvitationDestroyAction.ts +34 -16
- package/app/Actions/Dashboard/Teams/TeamInvitationResendAction.ts +52 -29
- package/app/Actions/Dashboard/Teams/TeamInviteAction.ts +102 -71
- package/app/Actions/Dashboard/Teams/TeamMemberDestroyAction.ts +36 -17
- package/app/Actions/Dashboard/Teams/TeamMemberUpdateAction.ts +39 -26
- package/app/Actions/Dashboard/Teams/TeamPeopleIndexAction.ts +71 -58
- package/app/Actions/Dashboard/Teams/team-invitation-delivery.ts +29 -7
- package/app/Actions/Dashboard/Teams/team-member-count.ts +4 -2
- package/app/Actions/Dashboard/Teams/team-records.test.ts +2 -0
- package/app/Actions/Dashboard/Teams/team-records.ts +2 -0
- package/app/Actions/Dashboard/dashboard-response.ts +16 -0
- package/app/Actions/SendWelcomeEmail.ts +1 -1
- package/app/Actions/Teams/AcceptInvitationAction.ts +74 -51
- package/app/Actions/Teams/ShowInvitationAction.ts +21 -14
- package/app/Actions/Teams/team-response.ts +23 -0
- package/app/Mail/OrderConfirmation.ts +1 -1
- package/app/Mail/SubscriptionConfirmation.ts +1 -1
- package/app/Mail/TeamInvitation.ts +1 -1
- package/app/Models/EmailIdempotency.ts +64 -0
- package/app/Models/EmailSuppression.ts +52 -0
- package/app/Models/EmailWebhookEvent.ts +51 -0
- package/app/Models/TeamInvitation.ts +13 -0
- package/functions/data.ts +0 -1
- package/functions/jobs.ts +0 -1
- package/ide/vscode/package.json +1 -1
- package/package.json +1 -1
- package/resources/components/Dashboard/Data/DataRecords.stx +0 -4
- package/resources/components/Dashboard/Jobs/JobDetail.stx +3 -2
- package/resources/components/Dashboard/Models/ModelRecordsDashboard.stx +7 -13
- package/resources/components/Dashboard/Models/ModelsOverview.stx +1 -1
- package/views/dashboard/.discovered-models.json +30 -0
- package/views/dashboard/stores/auth.ts +15 -14
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { Subscriber } from '@stacksjs/orm'
|
|
3
3
|
import { safeGet } from '../../../../resources/functions/dashboard/data'
|
|
4
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
4
5
|
import { dateValue, daysAgoIso, numberValue, textValue } from './data-records'
|
|
5
6
|
|
|
6
7
|
export default new Action({
|
|
@@ -38,11 +39,7 @@ export default new Action({
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
catch (error) {
|
|
41
|
-
return
|
|
42
|
-
subscribers: [],
|
|
43
|
-
stats: { total: 0, subscribed: 0, unsubscribed: 0, newThisMonth: 0 },
|
|
44
|
-
error: error instanceof Error ? error.message : 'Subscribers could not be loaded.',
|
|
45
|
-
}
|
|
42
|
+
return dashboardOperationalError(error, 'Subscribers could not be loaded.', 'SubscriberIndexAction')
|
|
46
43
|
}
|
|
47
44
|
},
|
|
48
45
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { Team } from '@stacksjs/orm'
|
|
3
3
|
import { safeGet } from '../../../../resources/functions/dashboard/data'
|
|
4
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
4
5
|
import { dateValue, daysAgoIso, numberValue, textValue } from './data-records'
|
|
5
6
|
|
|
6
7
|
export default new Action({
|
|
@@ -39,11 +40,7 @@ export default new Action({
|
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
catch (error) {
|
|
42
|
-
return
|
|
43
|
-
teams: [],
|
|
44
|
-
stats: { total: 0, active: 0, members: 0, newThisMonth: 0 },
|
|
45
|
-
error: error instanceof Error ? error.message : 'Teams could not be loaded.',
|
|
46
|
-
}
|
|
43
|
+
return dashboardOperationalError(error, 'Teams could not be loaded.', 'TeamIndexAction')
|
|
47
44
|
}
|
|
48
45
|
},
|
|
49
46
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { User } from '@stacksjs/orm'
|
|
3
3
|
import { safeGet } from '../../../../resources/functions/dashboard/data'
|
|
4
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
4
5
|
import { dateValue, daysAgoIso, numberValue, textValue } from './data-records'
|
|
5
6
|
|
|
6
7
|
export default new Action({
|
|
@@ -36,11 +37,7 @@ export default new Action({
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
catch (error) {
|
|
39
|
-
return
|
|
40
|
-
users: [],
|
|
41
|
-
stats: { total: 0, newThisWeek: 0, verified: 0 },
|
|
42
|
-
error: error instanceof Error ? error.message : 'Users could not be loaded.',
|
|
43
|
-
}
|
|
40
|
+
return dashboardOperationalError(error, 'Users could not be loaded.', 'UserIndexAction')
|
|
44
41
|
}
|
|
45
42
|
},
|
|
46
43
|
})
|
|
@@ -4,6 +4,7 @@ import { join } from 'node:path'
|
|
|
4
4
|
import process from 'node:process'
|
|
5
5
|
import { Deployment } from '@stacksjs/orm'
|
|
6
6
|
import { response } from '@stacksjs/router'
|
|
7
|
+
import { dashboardOperationalError, dashboardOperationalIssue } from '../dashboard-response'
|
|
7
8
|
import { booleanValue, deploymentCommandArgs } from './deployment-input'
|
|
8
9
|
|
|
9
10
|
function gitValue(args: string[]): string {
|
|
@@ -63,10 +64,7 @@ export default new Action({
|
|
|
63
64
|
})
|
|
64
65
|
}
|
|
65
66
|
catch (error) {
|
|
66
|
-
return
|
|
67
|
-
success: false,
|
|
68
|
-
message: error instanceof Error ? error.message : 'Deployment record could not be created.',
|
|
69
|
-
}, { status: 500 })
|
|
67
|
+
return dashboardOperationalError(error, 'Deployment record could not be created.', 'CreateDeployment.record', 500)
|
|
70
68
|
}
|
|
71
69
|
}
|
|
72
70
|
|
|
@@ -81,27 +79,33 @@ export default new Action({
|
|
|
81
79
|
}
|
|
82
80
|
catch (error) {
|
|
83
81
|
if (deployment) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
try {
|
|
83
|
+
await deployment.update({
|
|
84
|
+
status: 'failed',
|
|
85
|
+
duration: 0,
|
|
86
|
+
errorLog: 'Deployment process could not be started.',
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
catch (updateError) {
|
|
90
|
+
dashboardOperationalIssue(updateError, 'Deployment failure status could not be recorded.', 'CreateDeployment.failureRecord')
|
|
91
|
+
}
|
|
89
92
|
}
|
|
90
|
-
return
|
|
91
|
-
success: false,
|
|
92
|
-
message: error instanceof Error ? error.message : 'Deployment process could not be started.',
|
|
93
|
-
}, { status: 500 })
|
|
93
|
+
return dashboardOperationalError(error, 'Deployment process could not be started.', 'CreateDeployment.process', 500)
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
if (deployment) {
|
|
97
97
|
const record = deployment
|
|
98
|
-
void child.exited
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
void child.exited
|
|
99
|
+
.then(async (exitCode) => {
|
|
100
|
+
await record.update({
|
|
101
|
+
status: exitCode === 0 ? 'success' : 'failed',
|
|
102
|
+
duration: Math.max(0, Math.round((Date.now() - startedAt) / 1000)),
|
|
103
|
+
errorLog: exitCode === 0 ? '' : `buddy deploy exited with code ${exitCode}`,
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
.catch((error) => {
|
|
107
|
+
dashboardOperationalIssue(error, 'Deployment completion could not be recorded.', 'CreateDeployment.completionRecord')
|
|
103
108
|
})
|
|
104
|
-
})
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { Deployment } from '@stacksjs/orm'
|
|
3
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
3
4
|
import { averageRecordedDuration } from './deployment-input'
|
|
4
5
|
|
|
5
6
|
export default new Action({
|
|
@@ -9,7 +10,12 @@ export default new Action({
|
|
|
9
10
|
apiResponse: true,
|
|
10
11
|
|
|
11
12
|
async handle() {
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
try {
|
|
14
|
+
const deployments = await Deployment.all()
|
|
15
|
+
return { average_seconds: averageRecordedDuration(deployments) }
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
return dashboardOperationalError(error, 'Average deployment time could not be loaded.', 'GetAverageDeploymentTime')
|
|
19
|
+
}
|
|
14
20
|
},
|
|
15
21
|
})
|
|
@@ -2,7 +2,7 @@ import { Action } from '@stacksjs/actions'
|
|
|
2
2
|
import { readFile } from 'node:fs/promises'
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
import process from 'node:process'
|
|
5
|
-
import {
|
|
5
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
6
6
|
|
|
7
7
|
export default new Action({
|
|
8
8
|
name: 'GetDeployScript',
|
|
@@ -20,11 +20,8 @@ export default new Action({
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
catch (error) {
|
|
23
|
-
if ((error as NodeJS.ErrnoException).code !== 'ENOENT')
|
|
24
|
-
return
|
|
25
|
-
message: error instanceof Error ? error.message : 'Deploy script could not be read.',
|
|
26
|
-
}, 500)
|
|
27
|
-
}
|
|
23
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT')
|
|
24
|
+
return dashboardOperationalError(error, 'Deploy script could not be read.', 'GetDeployScript', 500)
|
|
28
25
|
|
|
29
26
|
return {
|
|
30
27
|
path: 'cloud/deploy-script.ts',
|
|
@@ -2,6 +2,7 @@ import type { RequestInstance } from '@stacksjs/types'
|
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { Deployment } from '@stacksjs/orm'
|
|
4
4
|
import { response } from '@stacksjs/router'
|
|
5
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
5
6
|
|
|
6
7
|
export default new Action({
|
|
7
8
|
name: 'GetDeployment',
|
|
@@ -11,8 +12,8 @@ export default new Action({
|
|
|
11
12
|
|
|
12
13
|
async handle(request: RequestInstance) {
|
|
13
14
|
const id = Number(request.getParam('id'))
|
|
14
|
-
if (!Number.
|
|
15
|
-
return response.json({ message: 'Deployment id must be a positive
|
|
15
|
+
if (!Number.isSafeInteger(id) || id <= 0)
|
|
16
|
+
return response.json({ message: 'Deployment id must be a positive integer.' }, 400)
|
|
16
17
|
|
|
17
18
|
try {
|
|
18
19
|
const deployment = await Deployment.find(id)
|
|
@@ -24,9 +25,7 @@ export default new Action({
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
catch (error) {
|
|
27
|
-
return
|
|
28
|
-
message: error instanceof Error ? error.message : 'Deployment could not be loaded.',
|
|
29
|
-
}, 503)
|
|
28
|
+
return dashboardOperationalError(error, 'Deployment could not be loaded.', 'GetDeployment')
|
|
30
29
|
}
|
|
31
30
|
},
|
|
32
31
|
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { Deployment } from '@stacksjs/orm'
|
|
3
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
3
4
|
|
|
4
5
|
export default new Action({
|
|
5
6
|
name: 'GetDeploymentCount',
|
|
@@ -8,6 +9,11 @@ export default new Action({
|
|
|
8
9
|
apiResponse: true,
|
|
9
10
|
|
|
10
11
|
async handle() {
|
|
11
|
-
|
|
12
|
+
try {
|
|
13
|
+
return await Deployment.count()
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return dashboardOperationalError(error, 'Deployment count could not be loaded.', 'GetDeploymentCount')
|
|
17
|
+
}
|
|
12
18
|
},
|
|
13
19
|
})
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { readFile } from 'node:fs/promises'
|
|
3
|
-
import { resolve } from 'node:path'
|
|
3
|
+
import { isAbsolute, relative, resolve, sep } from 'node:path'
|
|
4
4
|
import process from 'node:process'
|
|
5
5
|
import { logging } from '@stacksjs/config'
|
|
6
|
-
import {
|
|
6
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
7
7
|
import { tailLines } from './deployment-input'
|
|
8
8
|
|
|
9
9
|
export default new Action({
|
|
@@ -15,22 +15,23 @@ export default new Action({
|
|
|
15
15
|
async handle() {
|
|
16
16
|
const configuredPath = logging.deploymentsPath || 'storage/logs/deployments.log'
|
|
17
17
|
const filePath = resolve(process.cwd(), configuredPath)
|
|
18
|
+
const relativePath = relative(process.cwd(), filePath)
|
|
19
|
+
const publicPath = relativePath && relativePath !== '..' && !relativePath.startsWith(`..${sep}`) && !isAbsolute(relativePath)
|
|
20
|
+
? relativePath
|
|
21
|
+
: 'deployments.log'
|
|
18
22
|
try {
|
|
19
23
|
return {
|
|
20
|
-
path:
|
|
24
|
+
path: publicPath,
|
|
21
25
|
output: tailLines(await readFile(filePath, 'utf8')),
|
|
22
26
|
exists: true,
|
|
23
27
|
}
|
|
24
28
|
}
|
|
25
29
|
catch (error) {
|
|
26
|
-
if ((error as NodeJS.ErrnoException).code !== 'ENOENT')
|
|
27
|
-
return
|
|
28
|
-
message: error instanceof Error ? error.message : 'Deployment output could not be read.',
|
|
29
|
-
}, 500)
|
|
30
|
-
}
|
|
30
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT')
|
|
31
|
+
return dashboardOperationalError(error, 'Deployment output could not be read.', 'GetDeploymentLiveTerminalOutput', 500)
|
|
31
32
|
|
|
32
33
|
return {
|
|
33
|
-
path:
|
|
34
|
+
path: publicPath,
|
|
34
35
|
output: '',
|
|
35
36
|
exists: false,
|
|
36
37
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { Deployment } from '@stacksjs/orm'
|
|
3
|
-
import {
|
|
3
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
4
4
|
|
|
5
5
|
export default new Action({
|
|
6
6
|
name: 'GetDeployments',
|
|
@@ -17,9 +17,7 @@ export default new Action({
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
catch (error) {
|
|
20
|
-
return
|
|
21
|
-
message: error instanceof Error ? error.message : 'Deployment records could not be loaded.',
|
|
22
|
-
}, 503)
|
|
20
|
+
return dashboardOperationalError(error, 'Deployment records could not be loaded.', 'GetDeployments')
|
|
23
21
|
}
|
|
24
22
|
},
|
|
25
23
|
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { Deployment } from '@stacksjs/orm'
|
|
3
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
3
4
|
|
|
4
5
|
export default new Action({
|
|
5
6
|
name: 'GetRecentDeployments',
|
|
@@ -8,7 +9,12 @@ export default new Action({
|
|
|
8
9
|
apiResponse: true,
|
|
9
10
|
|
|
10
11
|
async handle() {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
try {
|
|
13
|
+
const deployments = await Deployment.orderByDesc('created_at').limit(3).get()
|
|
14
|
+
return deployments.map(deployment => deployment.toJSON())
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return dashboardOperationalError(error, 'Recent deployments could not be loaded.', 'GetRecentDeployments')
|
|
18
|
+
}
|
|
13
19
|
},
|
|
14
20
|
})
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { RequestInstance } from '@stacksjs/types'
|
|
2
|
+
import { randomUUIDv7 } from 'bun'
|
|
2
3
|
import { Action } from '@stacksjs/actions'
|
|
3
|
-
import { mkdir, rename, writeFile } from 'node:fs/promises'
|
|
4
|
+
import { mkdir, rename, rm, writeFile } from 'node:fs/promises'
|
|
4
5
|
import { dirname, join } from 'node:path'
|
|
5
6
|
import process from 'node:process'
|
|
6
7
|
import { response } from '@stacksjs/router'
|
|
8
|
+
import { dashboardOperationalError, dashboardOperationalIssue } from '../dashboard-response'
|
|
7
9
|
|
|
8
10
|
export default new Action({
|
|
9
11
|
name: 'UpdateDeployScript',
|
|
@@ -29,10 +31,21 @@ export default new Action({
|
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
const filePath = join(process.cwd(), 'cloud', 'deploy-script.ts')
|
|
32
|
-
const temporaryPath = `${filePath}.${
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
const temporaryPath = `${filePath}.${randomUUIDv7()}.tmp`
|
|
35
|
+
try {
|
|
36
|
+
await mkdir(dirname(filePath), { recursive: true })
|
|
37
|
+
await writeFile(temporaryPath, content, { encoding: 'utf8', mode: 0o644 })
|
|
38
|
+
await rename(temporaryPath, filePath)
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
try {
|
|
42
|
+
await rm(temporaryPath, { force: true })
|
|
43
|
+
}
|
|
44
|
+
catch (cleanupError) {
|
|
45
|
+
dashboardOperationalIssue(cleanupError, 'Temporary deploy script could not be removed.', 'UpdateDeployScript.cleanup')
|
|
46
|
+
}
|
|
47
|
+
return dashboardOperationalError(error, 'Deploy script could not be saved.', 'UpdateDeployScript', 500)
|
|
48
|
+
}
|
|
36
49
|
|
|
37
50
|
return {
|
|
38
51
|
success: true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
|
-
import {
|
|
2
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
3
3
|
import { listCapturedMail } from './captured-mail'
|
|
4
4
|
|
|
5
5
|
export default new Action({
|
|
@@ -19,9 +19,7 @@ export default new Action({
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
catch (error) {
|
|
22
|
-
return
|
|
23
|
-
message: error instanceof Error ? error.message : 'Captured emails could not be loaded.',
|
|
24
|
-
}, 503)
|
|
22
|
+
return dashboardOperationalError(error, 'Captured emails could not be loaded.', 'CapturedMailIndexAction')
|
|
25
23
|
}
|
|
26
24
|
},
|
|
27
25
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RequestInstance } from '@stacksjs/types'
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { response } from '@stacksjs/router'
|
|
4
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
4
5
|
import { showCapturedMail } from './captured-mail'
|
|
5
6
|
|
|
6
7
|
export default new Action({
|
|
@@ -10,7 +11,7 @@ export default new Action({
|
|
|
10
11
|
apiResponse: true,
|
|
11
12
|
|
|
12
13
|
async handle(request: RequestInstance) {
|
|
13
|
-
const id = request.
|
|
14
|
+
const id = request.getParam('id')
|
|
14
15
|
if (typeof id !== 'string' || !id)
|
|
15
16
|
return response.json({ message: 'Captured email id is required.' }, 422)
|
|
16
17
|
if (!/^disk:[^/\\]+\.html$/.test(id) && !/^mem:\d+:\d+$/.test(id))
|
|
@@ -23,9 +24,7 @@ export default new Action({
|
|
|
23
24
|
return { message }
|
|
24
25
|
}
|
|
25
26
|
catch (error) {
|
|
26
|
-
return
|
|
27
|
-
message: error instanceof Error ? error.message : 'Captured email could not be loaded.',
|
|
28
|
-
}, 503)
|
|
27
|
+
return dashboardOperationalError(error, 'Captured email could not be loaded.', 'CapturedMailShowAction')
|
|
29
28
|
}
|
|
30
29
|
},
|
|
31
30
|
})
|
|
@@ -6,6 +6,7 @@ import { cache } from '@stacksjs/cache'
|
|
|
6
6
|
import { config } from '@stacksjs/config'
|
|
7
7
|
import { db } from '@stacksjs/database'
|
|
8
8
|
import { checkQueueHealth } from '@stacksjs/queue'
|
|
9
|
+
import { dashboardOperationalIssue } from '../dashboard-response'
|
|
9
10
|
import {
|
|
10
11
|
compactSql,
|
|
11
12
|
countValue,
|
|
@@ -23,14 +24,14 @@ interface SourceResult<T> {
|
|
|
23
24
|
error: string
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
async function inspectSource<T>(work: Promise<T>, fallback: T): Promise<SourceResult<T>> {
|
|
27
|
+
async function inspectSource<T>(work: Promise<T>, fallback: T, message: string, source: string): Promise<SourceResult<T>> {
|
|
27
28
|
try {
|
|
28
29
|
return { value: await work, error: '' }
|
|
29
30
|
}
|
|
30
31
|
catch (error) {
|
|
31
32
|
return {
|
|
32
33
|
value: fallback,
|
|
33
|
-
error: error
|
|
34
|
+
error: dashboardOperationalIssue(error, message, `InsightsAction.${source}`),
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
}
|
|
@@ -135,18 +136,18 @@ export default new Action({
|
|
|
135
136
|
filesystem,
|
|
136
137
|
databaseFile,
|
|
137
138
|
] = await Promise.all([
|
|
138
|
-
inspectSource(requestSummaryQuery, undefined),
|
|
139
|
-
inspectSource(requestSuccessQuery, undefined),
|
|
140
|
-
inspectSource(slowRequestsQuery, []),
|
|
141
|
-
inspectSource(querySummaryQuery, undefined),
|
|
142
|
-
inspectSource(queryStatusesQuery, []),
|
|
143
|
-
inspectSource(slowQueriesQuery, []),
|
|
144
|
-
inspectSource(errorSummaryQuery, undefined),
|
|
145
|
-
inspectSource(recentErrorsQuery, []),
|
|
146
|
-
inspectSource(checkQueueHealth(), null),
|
|
147
|
-
inspectSource(cache.getStats(), null),
|
|
148
|
-
inspectSource(filesystemQuery, null),
|
|
149
|
-
inspectSource(databaseFileQuery, null),
|
|
139
|
+
inspectSource(requestSummaryQuery, undefined, 'Request telemetry is unavailable.', 'requests.summary'),
|
|
140
|
+
inspectSource(requestSuccessQuery, undefined, 'Request telemetry is unavailable.', 'requests.success'),
|
|
141
|
+
inspectSource(slowRequestsQuery, [], 'Request telemetry is unavailable.', 'requests.slowest'),
|
|
142
|
+
inspectSource(querySummaryQuery, undefined, 'Query telemetry is unavailable.', 'queries.summary'),
|
|
143
|
+
inspectSource(queryStatusesQuery, [], 'Query telemetry is unavailable.', 'queries.statuses'),
|
|
144
|
+
inspectSource(slowQueriesQuery, [], 'Query telemetry is unavailable.', 'queries.slowest'),
|
|
145
|
+
inspectSource(errorSummaryQuery, undefined, 'Error telemetry is unavailable.', 'errors.summary'),
|
|
146
|
+
inspectSource(recentErrorsQuery, [], 'Error telemetry is unavailable.', 'errors.recent'),
|
|
147
|
+
inspectSource(checkQueueHealth(), null, 'Queue telemetry is unavailable.', 'queue'),
|
|
148
|
+
inspectSource(cache.getStats(), null, 'Cache telemetry is unavailable.', 'cache'),
|
|
149
|
+
inspectSource(filesystemQuery, null, 'Filesystem telemetry is unavailable.', 'filesystem'),
|
|
150
|
+
inspectSource(databaseFileQuery, null, 'Database file telemetry is unavailable.', 'database-file'),
|
|
150
151
|
])
|
|
151
152
|
|
|
152
153
|
const requestTotal = countValue(requestSummary.value?.total)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { RequestInstance } from '@stacksjs/types'
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { db } from '@stacksjs/database'
|
|
4
|
-
import { response } from '@stacksjs/router'
|
|
5
4
|
import { dashboardRequestValue } from '../dashboard-request'
|
|
5
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
6
6
|
import { DASHBOARD_LOG_TYPES, normalizeDashboardLog, summarizeDashboardLogTypes } from './log-dashboard'
|
|
7
7
|
|
|
8
8
|
const RANGES = ['1', '7', '30', '90', 'all'] as const
|
|
@@ -101,13 +101,7 @@ export default new Action({
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
catch (error) {
|
|
104
|
-
return
|
|
105
|
-
logs: [],
|
|
106
|
-
summary: { total: 0, error: 0, warning: 0, info: 0, success: 0 },
|
|
107
|
-
pagination: { page: 1, perPage: 25, total: 0, totalPages: 1 },
|
|
108
|
-
options: { sources: [], projects: [], types: [...DASHBOARD_LOG_TYPES], ranges: [...RANGES] },
|
|
109
|
-
error: error instanceof Error ? error.message : 'Logs could not be loaded.',
|
|
110
|
-
}, 500)
|
|
104
|
+
return dashboardOperationalError(error, 'Logs could not be loaded.', 'LogIndexAction')
|
|
111
105
|
}
|
|
112
106
|
},
|
|
113
107
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RequestInstance } from '@stacksjs/types'
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { FailedJob, Job } from '@stacksjs/orm'
|
|
4
|
-
import {
|
|
4
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
5
5
|
import { matchesJobSearch, normalizeActiveJob, normalizeFailedJob } from './job-records'
|
|
6
6
|
|
|
7
7
|
export default new Action({
|
|
@@ -43,9 +43,7 @@ export default new Action({
|
|
|
43
43
|
return { data, total, page, perPage, queues, queueConnected: true }
|
|
44
44
|
}
|
|
45
45
|
catch (error) {
|
|
46
|
-
return
|
|
47
|
-
message: error instanceof Error ? error.message : 'Job history could not be loaded.',
|
|
48
|
-
}, 503)
|
|
46
|
+
return dashboardOperationalError(error, 'Job history could not be loaded.', 'JobIndexAction')
|
|
49
47
|
}
|
|
50
48
|
},
|
|
51
49
|
})
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { RequestInstance } from '@stacksjs/types'
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { FailedJob, Job } from '@stacksjs/orm'
|
|
4
|
+
import { response } from '@stacksjs/router'
|
|
5
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
4
6
|
import { normalizeActiveJob, normalizeFailedJob, parseJobReference } from './job-records'
|
|
5
7
|
|
|
6
8
|
export default new Action({
|
|
@@ -13,17 +15,21 @@ export default new Action({
|
|
|
13
15
|
const id = Number(parsed.id)
|
|
14
16
|
|
|
15
17
|
if (!Number.isFinite(id) || id <= 0)
|
|
16
|
-
return {
|
|
18
|
+
return response.json({ message: 'Invalid job id.' }, 400)
|
|
17
19
|
|
|
18
20
|
try {
|
|
19
21
|
if (parsed.source === 'failed') {
|
|
20
22
|
const record = await FailedJob.find(id)
|
|
21
|
-
return
|
|
23
|
+
return record
|
|
24
|
+
? { job: normalizeFailedJob(record) }
|
|
25
|
+
: response.json({ message: 'Job not found.' }, 404)
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
if (parsed.source === 'job') {
|
|
25
29
|
const record = await Job.find(id)
|
|
26
|
-
return
|
|
30
|
+
return record
|
|
31
|
+
? { job: normalizeActiveJob(record) }
|
|
32
|
+
: response.json({ message: 'Job not found.' }, 404)
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
const activeRecord = await Job.find(id)
|
|
@@ -31,13 +37,12 @@ export default new Action({
|
|
|
31
37
|
return { job: normalizeActiveJob(activeRecord) }
|
|
32
38
|
|
|
33
39
|
const failedRecord = await FailedJob.find(id)
|
|
34
|
-
return
|
|
40
|
+
return failedRecord
|
|
41
|
+
? { job: normalizeFailedJob(failedRecord) }
|
|
42
|
+
: response.json({ message: 'Job not found.' }, 404)
|
|
35
43
|
}
|
|
36
44
|
catch (error) {
|
|
37
|
-
return
|
|
38
|
-
job: null,
|
|
39
|
-
error: error instanceof Error ? error.message : 'Job could not be loaded.',
|
|
40
|
-
}
|
|
45
|
+
return dashboardOperationalError(error, 'Job could not be loaded.', 'JobShowAction')
|
|
41
46
|
}
|
|
42
47
|
},
|
|
43
48
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Action } from '@stacksjs/actions'
|
|
2
2
|
import { FailedJob, Job } from '@stacksjs/orm'
|
|
3
3
|
import { getGlobalMetrics } from '@stacksjs/queue'
|
|
4
|
-
import {
|
|
4
|
+
import { dashboardOperationalError } from '../dashboard-response'
|
|
5
5
|
|
|
6
6
|
export default new Action({
|
|
7
7
|
name: 'JobStatsAction',
|
|
@@ -38,9 +38,7 @@ export default new Action({
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
|
-
return
|
|
42
|
-
message: error instanceof Error ? error.message : 'Job metrics could not be loaded.',
|
|
43
|
-
}, 503)
|
|
41
|
+
return dashboardOperationalError(error, 'Job metrics could not be loaded.', 'JobStatsAction')
|
|
44
42
|
}
|
|
45
43
|
},
|
|
46
44
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RequestInstance } from '@stacksjs/types'
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { db } from '@stacksjs/database'
|
|
4
|
-
import { kanbanError } from './kanban-response'
|
|
4
|
+
import { kanbanActionError, kanbanError } from './kanban-response'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* `DELETE /api/dashboard/kanban/boards/:id`.
|
|
@@ -60,8 +60,7 @@ export default new Action({
|
|
|
60
60
|
return { deleted: true, id }
|
|
61
61
|
}
|
|
62
62
|
catch (err) {
|
|
63
|
-
|
|
64
|
-
return kanbanError(err instanceof Error ? err.message : 'unknown error', 500)
|
|
63
|
+
return kanbanActionError(err, 'BoardDestroyAction')
|
|
65
64
|
}
|
|
66
65
|
},
|
|
67
66
|
})
|
|
@@ -2,7 +2,7 @@ import type { RequestInstance } from '@stacksjs/types'
|
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { db } from '@stacksjs/database'
|
|
4
4
|
import { modelBoolean } from './kanban-model'
|
|
5
|
-
import { kanbanError } from './kanban-response'
|
|
5
|
+
import { kanbanActionError, kanbanError } from './kanban-response'
|
|
6
6
|
|
|
7
7
|
interface BoardRow {
|
|
8
8
|
id: number
|
|
@@ -201,8 +201,7 @@ export default new Action({
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
catch (err) {
|
|
204
|
-
|
|
205
|
-
return kanbanError(err instanceof Error ? err.message : 'unknown error', 500)
|
|
204
|
+
return kanbanActionError(err, 'BoardShowAction')
|
|
206
205
|
}
|
|
207
206
|
},
|
|
208
207
|
})
|
|
@@ -2,7 +2,7 @@ import type { RequestInstance } from '@stacksjs/types'
|
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { db } from '@stacksjs/database'
|
|
4
4
|
import { Board } from '@stacksjs/orm'
|
|
5
|
-
import { kanbanError } from './kanban-response'
|
|
5
|
+
import { kanbanActionError, kanbanError } from './kanban-response'
|
|
6
6
|
|
|
7
7
|
interface BoardInput {
|
|
8
8
|
name?: unknown
|
|
@@ -77,8 +77,7 @@ export default new Action({
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
catch (err) {
|
|
80
|
-
|
|
81
|
-
return kanbanError(err instanceof Error ? err.message : 'unknown error', 500)
|
|
80
|
+
return kanbanActionError(err, 'BoardStoreAction')
|
|
82
81
|
}
|
|
83
82
|
},
|
|
84
83
|
})
|
|
@@ -2,7 +2,7 @@ import type { RequestInstance } from '@stacksjs/types'
|
|
|
2
2
|
import { Action } from '@stacksjs/actions'
|
|
3
3
|
import { Board } from '@stacksjs/orm'
|
|
4
4
|
import { modelBoolean, modelNullableString, modelNumber, modelString, refreshModel } from './kanban-model'
|
|
5
|
-
import { kanbanError } from './kanban-response'
|
|
5
|
+
import { kanbanActionError, kanbanError } from './kanban-response'
|
|
6
6
|
|
|
7
7
|
interface BoardInput {
|
|
8
8
|
name?: unknown
|
|
@@ -83,8 +83,7 @@ export default new Action({
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
catch (err) {
|
|
86
|
-
|
|
87
|
-
return kanbanError(err instanceof Error ? err.message : 'unknown error', 500)
|
|
86
|
+
return kanbanActionError(err, 'BoardUpdateAction')
|
|
88
87
|
}
|
|
89
88
|
},
|
|
90
89
|
})
|