Openstatus www.openstatus.dev

🔥 improve api (#722)

authored by

Thibault Le Ouay and committed by
GitHub
7e713bc8 987685f2

+137 -4
+4
apps/docs/api-reference/notification/get-notification.mdx
··· 1 + --- 2 + title: Get all notification 3 + openapi: get /notification/ 4 + ---
+4
apps/docs/api-reference/page/get-page.mdx
··· 1 + --- 2 + title: Get all your Status Page 3 + openapi: get /page/ 4 + ---
+4
apps/docs/api-reference/page/post-page:id/update.mdx
··· 1 + --- 2 + title: Add a subscriber 3 + openapi: post /page/:id/update 4 + ---
+4 -1
apps/docs/mint.json
··· 142 142 { 143 143 "group": "Notification", 144 144 "pages": [ 145 + "api-reference/notification/get-notification", 145 146 "api-reference/notification/get-notification:id", 146 147 "api-reference/notification/post-notification" 147 148 ] ··· 149 150 { 150 151 "group": "Page", 151 152 "pages": [ 153 + "api-reference/page/get-page", 152 154 "api-reference/page/get-page:id", 153 155 "api-reference/page/post-page", 154 - "api-reference/page/put-page:id" 156 + "api-reference/page/put-page:id", 157 + "api-reference/page/post-page:id/update" 155 158 ] 156 159 }, 157 160 {
+1
apps/server/package.json
··· 13 13 "dependencies": { 14 14 "@hono/sentry": "1.0.0", 15 15 "@hono/zod-openapi": "0.8.3", 16 + "@openstatus/analytics": "workspace:^", 16 17 "@openstatus/db": "workspace:*", 17 18 "@openstatus/emails": "workspace:*", 18 19 "@openstatus/notification-discord": "workspace:*",
+2
apps/server/src/env.ts
··· 12 12 UPSTASH_REDIS_REST_TOKEN: z.string().min(1), 13 13 FLY_REGION: z.enum(flyRegions), 14 14 CRON_SECRET: z.string(), 15 + JITSU_WRITE_KEY: z.string().optional(), 16 + JITSU_HOST: z.string().optional(), 15 17 }, 16 18 17 19 /**
+13 -3
apps/server/src/v1/monitor.ts
··· 1 1 import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; 2 2 3 + import { trackAnalytics } from "@openstatus/analytics"; 3 4 import { db, eq, sql } from "@openstatus/db"; 4 5 import { 5 6 flyRegions, ··· 63 64 .default([]) 64 65 .openapi({ 65 66 example: ["ams"], 66 - description: "The regions to use", 67 + description: "Where we should monitor it", 67 68 }), 68 69 name: z 69 70 .string() ··· 127 128 }), 128 129 regions: regionInput.openapi({ 129 130 example: "ams", 130 - description: "The regions to use", 131 + description: "The regions where we should monitor your endpoint", 131 132 }), 132 133 name: z.string().openapi({ 133 134 example: "Documenso", ··· 140 141 method: z.enum(monitorMethods).default("GET").openapi({ example: "GET" }), 141 142 body: z.string().openapi({ 142 143 example: "Hello World", 143 - description: "The body", 144 + description: "The body of your request", 144 145 }), 145 146 active: z.boolean().default(false).openapi({ 146 147 description: "If the monitor is active", ··· 346 347 347 348 const data = MonitorSchema.parse(_newMonitor); 348 349 350 + if (env.JITSU_WRITE_KEY) { 351 + trackAnalytics({ 352 + event: "Monitor Created", 353 + url: input.url, 354 + periodicity: input.periodicity, 355 + api: true, 356 + workspaceId: String(workspaceId), 357 + }); 358 + } 349 359 return c.json(data); 350 360 }); 351 361
+59
apps/server/src/v1/notification.ts
··· 76 76 }) 77 77 .nullish(), 78 78 }); 79 + 80 + const getAllRoute = createRoute({ 81 + method: "get", 82 + tags: ["notification"], 83 + description: "Get a notification", 84 + path: "/", 85 + 86 + responses: { 87 + 200: { 88 + content: { 89 + "application/json": { 90 + schema: z.array(NotificationSchema), 91 + }, 92 + }, 93 + description: "Get all your workspace notification", 94 + }, 95 + 400: { 96 + content: { 97 + "application/json": { 98 + schema: ErrorSchema, 99 + }, 100 + }, 101 + description: "Returns an error", 102 + }, 103 + }, 104 + }); 105 + 106 + notificationApi.openapi(getAllRoute, async (c) => { 107 + const workspaceId = Number(c.get("workspaceId")); 108 + 109 + const result = await db 110 + .select() 111 + .from(notification) 112 + .where(and(eq(page.workspaceId, workspaceId))) 113 + .all(); 114 + 115 + if (!result) return c.json({ code: 404, message: "Not Found" }, 404); 116 + const data = []; 117 + 118 + for (const r of result) { 119 + const linkedMonitors = await db 120 + .select() 121 + .from(notificationsToMonitors) 122 + .where(eq(notificationsToMonitors.notificationId, r.id)) 123 + .all(); 124 + 125 + const monitorsId = linkedMonitors.map((m) => m.monitorId); 126 + 127 + const p = NotificationSchema.parse({ 128 + ...result, 129 + payload: JSON.parse(r.data || "{}"), 130 + monitors: monitorsId, 131 + }); 132 + data.push(p); 133 + } 134 + 135 + return c.json(data); 136 + }); 137 + 79 138 const getRoute = createRoute({ 80 139 method: "get", 81 140 tags: ["notification"],
+40
apps/server/src/v1/page.ts
··· 307 307 return c.json(data); 308 308 }); 309 309 310 + const getAllRoute = createRoute({ 311 + method: "get", 312 + tags: ["page"], 313 + description: "Get all your status page", 314 + path: "/", 315 + responses: { 316 + 200: { 317 + content: { 318 + "application/json": { 319 + schema: z.array(PageSchema), 320 + }, 321 + }, 322 + description: "Get an Status page", 323 + }, 324 + 400: { 325 + content: { 326 + "application/json": { 327 + schema: ErrorSchema, 328 + }, 329 + }, 330 + description: "Returns an error", 331 + }, 332 + }, 333 + }); 334 + 335 + pageApi.openapi(getAllRoute, async (c) => { 336 + const workspaceId = Number(c.get("workspaceId")); 337 + 338 + const result = await db 339 + .select() 340 + .from(page) 341 + .where(and(eq(page.workspaceId, workspaceId))) 342 + .get(); 343 + 344 + if (!result) return c.json({ code: 404, message: "Not Found" }, 404); 345 + const data = z.array(PageSchema).parse(result); 346 + 347 + return c.json(data); 348 + }); 349 + 310 350 const postRoute = createRoute({ 311 351 method: "post", 312 352 tags: ["page"],
+3
packages/analytics/src/type.ts
··· 8 8 event: "Monitor Created"; 9 9 url: string; 10 10 periodicity: string; 11 + api?: boolean; 12 + workspaceId?: string; 11 13 } 12 14 | { 13 15 event: "Page Created"; 14 16 slug: string; 17 + api?: boolean; 15 18 } 16 19 | { event: "User Upgraded"; email: string } 17 20 | { event: "User Signed In" }
+3
pnpm-lock.yaml
··· 43 43 '@hono/zod-openapi': 44 44 specifier: 0.8.3 45 45 version: 0.8.3(hono@4.0.0)(zod@3.22.2) 46 + '@openstatus/analytics': 47 + specifier: workspace:^ 48 + version: link:../../packages/analytics 46 49 '@openstatus/db': 47 50 specifier: workspace:* 48 51 version: link:../../packages/db