@checkstack/maintenance-backend 0.5.2 → 0.5.4
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/CHANGELOG.md +48 -0
- package/package.json +15 -14
- package/src/index.ts +3 -0
- package/src/router.ts +54 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @checkstack/maintenance-backend
|
|
2
2
|
|
|
3
|
+
## 0.5.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [f676e11]
|
|
8
|
+
- Updated dependencies [48c2080]
|
|
9
|
+
- @checkstack/common@0.6.2
|
|
10
|
+
- @checkstack/backend-api@0.6.0
|
|
11
|
+
- @checkstack/auth-common@0.5.5
|
|
12
|
+
- @checkstack/catalog-common@1.2.7
|
|
13
|
+
- @checkstack/command-backend@0.1.9
|
|
14
|
+
- @checkstack/integration-backend@0.1.9
|
|
15
|
+
- @checkstack/integration-common@0.2.5
|
|
16
|
+
- @checkstack/maintenance-common@0.4.5
|
|
17
|
+
- @checkstack/notification-common@0.2.5
|
|
18
|
+
- @checkstack/signal-common@0.1.6
|
|
19
|
+
|
|
20
|
+
## 0.5.3
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- 9551fd7: Fix creator display in incident and maintenance status updates
|
|
25
|
+
|
|
26
|
+
- Show the creator's profile name instead of UUID in status updates
|
|
27
|
+
- For maintenances, now properly displays the creator name (was missing)
|
|
28
|
+
- For incidents, replaces UUID with human-readable profile name
|
|
29
|
+
- System-generated updates (automatic maintenance transitions) show no creator
|
|
30
|
+
|
|
31
|
+
- c208a5b: ### @checkstack/incident-backend
|
|
32
|
+
|
|
33
|
+
Added notifications for incident status changes via the "Add Update" functionality:
|
|
34
|
+
|
|
35
|
+
- Notifications are now sent when an incident is reopened (status changed from resolved)
|
|
36
|
+
- Notifications are now sent when an incident status changes to any new value
|
|
37
|
+
- Notifications are now sent when an incident is resolved via addUpdate
|
|
38
|
+
- Extracted `notifyAffectedSystems` into a reusable module with proper importance logic:
|
|
39
|
+
- Resolved incidents always use "info" importance (good news)
|
|
40
|
+
- Reopened/created/updated incidents derive importance from severity
|
|
41
|
+
|
|
42
|
+
### @checkstack/maintenance-backend
|
|
43
|
+
|
|
44
|
+
Fixed missing notification in `closeMaintenance` handler - the "Close" button now sends a "completed" notification to subscribers.
|
|
45
|
+
|
|
46
|
+
- Updated dependencies [e5079e1]
|
|
47
|
+
- Updated dependencies [9551fd7]
|
|
48
|
+
- @checkstack/catalog-common@1.2.6
|
|
49
|
+
- @checkstack/maintenance-common@0.4.4
|
|
50
|
+
|
|
3
51
|
## 0.5.2
|
|
4
52
|
|
|
5
53
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/maintenance-backend",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -10,23 +10,24 @@
|
|
|
10
10
|
"lint:code": "eslint . --max-warnings 0"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@checkstack/backend-api": "0.5.
|
|
14
|
-
"@checkstack/maintenance-common": "0.4.
|
|
15
|
-
"@checkstack/notification-common": "0.2.
|
|
16
|
-
"@checkstack/catalog-common": "1.2.
|
|
17
|
-
"@checkstack/
|
|
18
|
-
"@checkstack/
|
|
19
|
-
"@checkstack/
|
|
20
|
-
"@checkstack/integration-
|
|
13
|
+
"@checkstack/backend-api": "0.5.2",
|
|
14
|
+
"@checkstack/maintenance-common": "0.4.4",
|
|
15
|
+
"@checkstack/notification-common": "0.2.4",
|
|
16
|
+
"@checkstack/catalog-common": "1.2.6",
|
|
17
|
+
"@checkstack/auth-common": "0.5.4",
|
|
18
|
+
"@checkstack/command-backend": "0.1.8",
|
|
19
|
+
"@checkstack/signal-common": "0.1.5",
|
|
20
|
+
"@checkstack/integration-backend": "0.1.8",
|
|
21
|
+
"@checkstack/integration-common": "0.2.4",
|
|
21
22
|
"drizzle-orm": "^0.45.1",
|
|
22
23
|
"zod": "^4.2.1",
|
|
23
|
-
"@checkstack/common": "0.6.
|
|
24
|
+
"@checkstack/common": "0.6.1"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
|
-
"@checkstack/drizzle-helper": "0.0.
|
|
27
|
-
"@checkstack/scripts": "0.1.
|
|
28
|
-
"@checkstack/test-utils-backend": "0.1.
|
|
29
|
-
"@checkstack/tsconfig": "0.0.
|
|
27
|
+
"@checkstack/drizzle-helper": "0.0.3",
|
|
28
|
+
"@checkstack/scripts": "0.1.1",
|
|
29
|
+
"@checkstack/test-utils-backend": "0.1.8",
|
|
30
|
+
"@checkstack/tsconfig": "0.0.3",
|
|
30
31
|
"@orpc/server": "^1.13.2",
|
|
31
32
|
"@types/bun": "^1.0.0",
|
|
32
33
|
"drizzle-kit": "^0.31.8",
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { integrationEventExtensionPoint } from "@checkstack/integration-backend"
|
|
|
15
15
|
import { MaintenanceService } from "./service";
|
|
16
16
|
import { createRouter } from "./router";
|
|
17
17
|
import { CatalogApi } from "@checkstack/catalog-common";
|
|
18
|
+
import { AuthApi } from "@checkstack/auth-common";
|
|
18
19
|
import { registerSearchProvider } from "@checkstack/command-backend";
|
|
19
20
|
import { resolveRoute, type InferClient } from "@checkstack/common";
|
|
20
21
|
import { maintenanceHooks } from "./hooks";
|
|
@@ -105,6 +106,7 @@ export default createBackendPlugin({
|
|
|
105
106
|
|
|
106
107
|
catalogClient = rpcClient.forPlugin(CatalogApi);
|
|
107
108
|
maintenanceClient = rpcClient.forPlugin(MaintenanceApi);
|
|
109
|
+
const authClient = rpcClient.forPlugin(AuthApi);
|
|
108
110
|
|
|
109
111
|
maintenanceService = new MaintenanceService(
|
|
110
112
|
database as SafeDatabase<typeof schema>,
|
|
@@ -113,6 +115,7 @@ export default createBackendPlugin({
|
|
|
113
115
|
maintenanceService,
|
|
114
116
|
signalService,
|
|
115
117
|
catalogClient,
|
|
118
|
+
authClient,
|
|
116
119
|
logger,
|
|
117
120
|
);
|
|
118
121
|
rpc.registerRouter(router, maintenanceContract);
|
package/src/router.ts
CHANGED
|
@@ -11,16 +11,53 @@ import {
|
|
|
11
11
|
import type { SignalService } from "@checkstack/signal-common";
|
|
12
12
|
import type { MaintenanceService } from "./service";
|
|
13
13
|
import { CatalogApi } from "@checkstack/catalog-common";
|
|
14
|
+
import { AuthApi } from "@checkstack/auth-common";
|
|
14
15
|
import type { InferClient } from "@checkstack/common";
|
|
15
16
|
import { maintenanceHooks } from "./hooks";
|
|
16
17
|
import { notifyAffectedSystems } from "./notifications";
|
|
18
|
+
import type { MaintenanceUpdate } from "@checkstack/maintenance-common";
|
|
17
19
|
|
|
18
20
|
export function createRouter(
|
|
19
21
|
service: MaintenanceService,
|
|
20
22
|
signalService: SignalService,
|
|
21
23
|
catalogClient: InferClient<typeof CatalogApi>,
|
|
24
|
+
authClient: InferClient<typeof AuthApi>,
|
|
22
25
|
logger: Logger,
|
|
23
26
|
) {
|
|
27
|
+
/**
|
|
28
|
+
* Resolve user IDs to profile names for a list of updates.
|
|
29
|
+
* Falls back to undefined if the user cannot be found.
|
|
30
|
+
*/
|
|
31
|
+
async function resolveUserNames(
|
|
32
|
+
updates: MaintenanceUpdate[],
|
|
33
|
+
): Promise<MaintenanceUpdate[]> {
|
|
34
|
+
const userIds = [
|
|
35
|
+
...new Set(updates.map((u) => u.createdBy).filter(Boolean)),
|
|
36
|
+
];
|
|
37
|
+
if (userIds.length === 0) return updates;
|
|
38
|
+
|
|
39
|
+
const userMap = new Map<string, string>();
|
|
40
|
+
await Promise.all(
|
|
41
|
+
userIds.map(async (userId) => {
|
|
42
|
+
try {
|
|
43
|
+
const user = await authClient.getUserById({ userId: userId! });
|
|
44
|
+
if (user?.name) {
|
|
45
|
+
userMap.set(userId!, user.name);
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
// User not found, skip
|
|
49
|
+
}
|
|
50
|
+
}),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return updates.map((update) => ({
|
|
54
|
+
...update,
|
|
55
|
+
createdByName: update.createdBy
|
|
56
|
+
? (userMap.get(update.createdBy) ?? undefined)
|
|
57
|
+
: undefined,
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
|
|
24
61
|
const os = implement(maintenanceContract)
|
|
25
62
|
.$context<RpcContext>()
|
|
26
63
|
.use(autoAuthMiddleware);
|
|
@@ -32,8 +69,13 @@ export function createRouter(
|
|
|
32
69
|
|
|
33
70
|
getMaintenance: os.getMaintenance.handler(async ({ input }) => {
|
|
34
71
|
const result = await service.getMaintenance(input.id);
|
|
35
|
-
|
|
36
|
-
|
|
72
|
+
if (!result) {
|
|
73
|
+
// eslint-disable-next-line unicorn/no-null -- oRPC contract requires null for missing values
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
// Resolve user names for updates
|
|
77
|
+
const updatesWithNames = await resolveUserNames(result.updates);
|
|
78
|
+
return { ...result, updates: updatesWithNames };
|
|
37
79
|
}),
|
|
38
80
|
|
|
39
81
|
getMaintenancesForSystem: os.getMaintenancesForSystem.handler(
|
|
@@ -226,6 +268,16 @@ export function createRouter(
|
|
|
226
268
|
action: "closed",
|
|
227
269
|
});
|
|
228
270
|
|
|
271
|
+
// Send notifications to system subscribers
|
|
272
|
+
await notifyAffectedSystems({
|
|
273
|
+
catalogClient,
|
|
274
|
+
logger,
|
|
275
|
+
maintenanceId: result.id,
|
|
276
|
+
maintenanceTitle: result.title,
|
|
277
|
+
systemIds: result.systemIds,
|
|
278
|
+
action: "completed",
|
|
279
|
+
});
|
|
280
|
+
|
|
229
281
|
return result;
|
|
230
282
|
},
|
|
231
283
|
),
|