tangled
alpha
login
or
join now
openstatus.dev
/
openstatus
5
fork
atom
Openstatus
www.openstatus.dev
5
fork
atom
overview
issues
pulls
pipelines
security fixes
Thomas Mol
1 year ago
8e0b4930
d626a3a0
+114
-10
3 changed files
expand all
collapse all
unified
split
apps
server
src
routes
v1
maintenance
post.ts
put.test.ts
put.ts
+38
-3
apps/server/src/routes/v1/maintenance/post.ts
···
2
2
import { trackMiddleware } from "@/libs/middlewares";
3
3
import { createRoute } from "@hono/zod-openapi";
4
4
import { Events } from "@openstatus/analytics";
5
5
-
import { db } from "@openstatus/db";
5
5
+
import { and, isNull, eq, inArray, db } from "@openstatus/db";
6
6
import {
7
7
maintenance,
8
8
maintenancesToMonitors,
9
9
} from "@openstatus/db/src/schema/maintenances";
10
10
import type { maintenanceApi } from "./index";
11
11
import { MaintenanceSchema } from "./schema";
12
12
+
import { monitor, page } from "@openstatus/db/src/schema";
12
13
13
14
const postRoute = createRoute({
14
15
method: "post",
···
43
44
const workspaceId = c.get("workspace").id;
44
45
const input = c.req.valid("json");
45
46
47
47
+
const { monitorIds, pageId } = input;
48
48
+
49
49
+
const _monitors = await db
50
50
+
.select()
51
51
+
.from(monitor)
52
52
+
.where(
53
53
+
and(
54
54
+
inArray(monitor.id, monitorIds),
55
55
+
eq(monitor.workspaceId, workspaceId),
56
56
+
isNull(monitor.deletedAt)
57
57
+
)
58
58
+
)
59
59
+
.all();
60
60
+
61
61
+
if (_monitors.length !== monitorIds.length) {
62
62
+
throw new OpenStatusApiError({
63
63
+
code: "BAD_REQUEST",
64
64
+
message: `Some of the monitors ${monitorIds.join(", ")} not found`,
65
65
+
});
66
66
+
}
67
67
+
68
68
+
const _page = await db
69
69
+
.select()
70
70
+
.from(page)
71
71
+
.where(and(eq(page.id, pageId), eq(page.workspaceId, workspaceId)))
72
72
+
.get();
73
73
+
74
74
+
if (!_page) {
75
75
+
throw new OpenStatusApiError({
76
76
+
code: "BAD_REQUEST",
77
77
+
message: `Page ${pageId} not found`,
78
78
+
});
79
79
+
}
80
80
+
46
81
const _maintenance = await db.transaction(async (tx) => {
47
82
const newMaintenance = await tx
48
83
.insert(maintenance)
···
53
88
.returning()
54
89
.get();
55
90
56
56
-
if (input.monitorIds?.length) {
91
91
+
if (monitorIds?.length) {
57
92
await tx
58
93
.insert(maintenancesToMonitors)
59
94
.values(
60
95
input.monitorIds.map((monitorId) => ({
61
96
maintenanceId: newMaintenance.id,
62
97
monitorId,
63
63
-
})),
98
98
+
}))
64
99
)
65
100
.run();
66
101
}
+30
apps/server/src/routes/v1/maintenance/put.test.ts
···
67
67
68
68
expect(res.status).toBe(401);
69
69
});
70
70
+
71
71
+
test("update with invalid monitor ids should return 400", async () => {
72
72
+
const res = await app.request("/v1/maintenance/1", {
73
73
+
method: "PUT",
74
74
+
headers: {
75
75
+
"x-openstatus-key": "1",
76
76
+
"Content-Type": "application/json",
77
77
+
},
78
78
+
body: JSON.stringify({
79
79
+
monitorIds: [999], // Non-existent monitor
80
80
+
}),
81
81
+
});
82
82
+
83
83
+
expect(res.status).toBe(400);
84
84
+
});
85
85
+
86
86
+
test("update with invalid page id should return 400", async () => {
87
87
+
const res = await app.request("/v1/maintenance/1", {
88
88
+
method: "PUT",
89
89
+
headers: {
90
90
+
"x-openstatus-key": "1",
91
91
+
"Content-Type": "application/json",
92
92
+
},
93
93
+
body: JSON.stringify({
94
94
+
pageId: 999, // Non-existent page
95
95
+
}),
96
96
+
});
97
97
+
98
98
+
expect(res.status).toBe(400);
99
99
+
});
+46
-7
apps/server/src/routes/v1/maintenance/put.ts
···
2
2
import { trackMiddleware } from "@/libs/middlewares";
3
3
import { createRoute } from "@hono/zod-openapi";
4
4
import { Events } from "@openstatus/analytics";
5
5
-
import { and, db, eq } from "@openstatus/db";
5
5
+
import { and, isNull, eq, inArray, db } from "@openstatus/db";
6
6
import {
7
7
maintenance,
8
8
maintenancesToMonitors,
9
9
} from "@openstatus/db/src/schema/maintenances";
10
10
+
import { monitor, page } from "@openstatus/db/src/schema";
10
11
import type { maintenanceApi } from "./index";
11
12
import { MaintenanceSchema, ParamsSchema } from "./schema";
12
13
···
45
46
const { id } = c.req.valid("param");
46
47
const input = c.req.valid("json");
47
48
49
49
+
const { monitorIds, pageId } = input;
50
50
+
48
51
const _maintenance = await db.query.maintenance.findFirst({
49
52
with: {
50
53
maintenancesToMonitors: true,
51
54
},
52
55
where: and(
53
56
eq(maintenance.id, Number(id)),
54
54
-
eq(maintenance.workspaceId, workspaceId),
57
57
+
eq(maintenance.workspaceId, workspaceId)
55
58
),
56
59
});
57
60
···
62
65
});
63
66
}
64
67
68
68
+
if (monitorIds?.length) {
69
69
+
const _monitors = await db
70
70
+
.select()
71
71
+
.from(monitor)
72
72
+
.where(
73
73
+
and(
74
74
+
inArray(monitor.id, monitorIds),
75
75
+
eq(monitor.workspaceId, workspaceId),
76
76
+
isNull(monitor.deletedAt)
77
77
+
)
78
78
+
)
79
79
+
.all();
80
80
+
81
81
+
if (_monitors.length !== monitorIds.length) {
82
82
+
throw new OpenStatusApiError({
83
83
+
code: "BAD_REQUEST",
84
84
+
message: `Some of the monitors ${monitorIds.join(", ")} not found`,
85
85
+
});
86
86
+
}
87
87
+
}
88
88
+
89
89
+
if (pageId) {
90
90
+
const _page = await db
91
91
+
.select()
92
92
+
.from(page)
93
93
+
.where(and(eq(page.id, pageId), eq(page.workspaceId, workspaceId)))
94
94
+
.get();
95
95
+
96
96
+
if (!_page) {
97
97
+
throw new OpenStatusApiError({
98
98
+
code: "BAD_REQUEST",
99
99
+
message: `Page ${pageId} not found`,
100
100
+
});
101
101
+
}
102
102
+
}
103
103
+
65
104
const updatedMaintenance = await db.transaction(async (tx) => {
66
105
const updated = await tx
67
106
.update(maintenance)
···
73
112
.returning()
74
113
.get();
75
114
76
76
-
if (input.monitorIds) {
115
115
+
if (monitorIds) {
77
116
// Delete existing monitor associations
78
117
await tx
79
118
.delete(maintenancesToMonitors)
···
81
120
.run();
82
121
83
122
// Add new monitor associations
84
84
-
if (input.monitorIds.length > 0) {
123
123
+
if (monitorIds.length > 0) {
85
124
await tx
86
125
.insert(maintenancesToMonitors)
87
126
.values(
88
88
-
input.monitorIds.map((monitorId) => ({
127
127
+
monitorIds.map((monitorId) => ({
89
128
maintenanceId: Number(id),
90
129
monitorId,
91
91
-
})),
130
130
+
}))
92
131
)
93
132
.run();
94
133
}
···
100
139
const data = MaintenanceSchema.parse({
101
140
...updatedMaintenance,
102
141
monitorIds:
103
103
-
input.monitorIds ??
142
142
+
monitorIds ??
104
143
_maintenance.maintenancesToMonitors.map((m) => m.monitorId),
105
144
});
106
145