feat: add monitor status page api

This commit is contained in:
moonrailgun 2023-12-13 18:21:04 +08:00
parent e7282ef7f9
commit 669b2ed8b8
21 changed files with 174 additions and 5 deletions

View File

@ -14,6 +14,7 @@ generator json {
generator zod { generator zod {
provider = "zod-prisma" provider = "zod-prisma"
modelSuffix = "ModelSchema" modelSuffix = "ModelSchema"
imports = "./zod/schemas"
} }
model User { model User {
@ -40,10 +41,11 @@ model Workspace {
createdAt DateTime @default(now()) @db.Timestamptz(6) createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6) updatedAt DateTime @updatedAt @db.Timestamptz(6)
users WorkspacesOnUsers[] users WorkspacesOnUsers[]
websites Website[] websites Website[]
notifications Notification[] notifications Notification[]
monitors Monitor[] monitors Monitor[]
monitorStatusPages MonitorStatusPage[]
// for user currentWorkspace // for user currentWorkspace
selectedUsers User[] selectedUsers User[]
@ -303,3 +305,20 @@ model MonitorStatus {
@@id([monitorId, statusName]) @@id([monitorId, statusName])
} }
model MonitorStatusPage {
id String @id @default(cuid()) @db.VarChar(30)
workspaceId String @db.VarChar(30)
slug String @unique // url slug
title String @db.VarChar(100)
description String @default("") @db.VarChar(1000)
/// [MonitorStatusPageList]
/// @zod.custom(imports.MonitorStatusPageListSchema)
monitorList Json @default("[]") // monitor list
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
workspace Workspace @relation(fields: [workspaceId], references: [id])
@@index([slug])
}

View File

@ -13,3 +13,4 @@ export * from "./monitor"
export * from "./monitorevent" export * from "./monitorevent"
export * from "./monitordata" export * from "./monitordata"
export * from "./monitorstatus" export * from "./monitorstatus"
export * from "./monitorstatuspage"

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteWebsite, RelatedWebsiteModelSchema, CompleteNotification, RelatedNotificationModelSchema, CompleteMonitorEvent, RelatedMonitorEventModelSchema, CompleteMonitorData, RelatedMonitorDataModelSchema, CompleteMonitorStatus, RelatedMonitorStatusModelSchema } from "./index" import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteWebsite, RelatedWebsiteModelSchema, CompleteNotification, RelatedNotificationModelSchema, CompleteMonitorEvent, RelatedMonitorEventModelSchema, CompleteMonitorData, RelatedMonitorDataModelSchema, CompleteMonitorStatus, RelatedMonitorStatusModelSchema } from "./index"
// Helper schema for JSON fields // Helper schema for JSON fields

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteMonitor, RelatedMonitorModelSchema } from "./index" import { CompleteMonitor, RelatedMonitorModelSchema } from "./index"
export const MonitorDataModelSchema = z.object({ export const MonitorDataModelSchema = z.object({

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteMonitor, RelatedMonitorModelSchema } from "./index" import { CompleteMonitor, RelatedMonitorModelSchema } from "./index"
export const MonitorEventModelSchema = z.object({ export const MonitorEventModelSchema = z.object({

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteMonitor, RelatedMonitorModelSchema } from "./index" import { CompleteMonitor, RelatedMonitorModelSchema } from "./index"
// Helper schema for JSON fields // Helper schema for JSON fields

View File

@ -0,0 +1,36 @@
import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWorkspace, RelatedWorkspaceModelSchema } from "./index"
// Helper schema for JSON fields
type Literal = boolean | number | string
type Json = Literal | { [key: string]: Json } | Json[]
const literalSchema = z.union([z.string(), z.number(), z.boolean()])
const jsonSchema: z.ZodSchema<Json> = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))
export const MonitorStatusPageModelSchema = z.object({
id: z.string(),
workspaceId: z.string(),
slug: z.string(),
title: z.string(),
description: z.string(),
/**
* [MonitorStatusPageList]
*/
monitorList: imports.MonitorStatusPageListSchema,
createdAt: z.date(),
updatedAt: z.date(),
})
export interface CompleteMonitorStatusPage extends z.infer<typeof MonitorStatusPageModelSchema> {
workspace: CompleteWorkspace
}
/**
* RelatedMonitorStatusPageModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedMonitorStatusPageModelSchema: z.ZodSchema<CompleteMonitorStatusPage> = z.lazy(() => MonitorStatusPageModelSchema.extend({
workspace: RelatedWorkspaceModelSchema,
}))

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteMonitor, RelatedMonitorModelSchema } from "./index" import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteMonitor, RelatedMonitorModelSchema } from "./index"
// Helper schema for JSON fields // Helper schema for JSON fields

View File

@ -0,0 +1,7 @@
import { z } from 'zod';
export const MonitorStatusPageListSchema = z.array(
z.object({
id: z.string(),
})
);

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteTelemetrySession, RelatedTelemetrySessionModelSchema } from "./index" import { CompleteTelemetrySession, RelatedTelemetrySessionModelSchema } from "./index"
// Helper schema for JSON fields // Helper schema for JSON fields

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteTelemetryEvent, RelatedTelemetryEventModelSchema } from "./index" import { CompleteTelemetryEvent, RelatedTelemetryEventModelSchema } from "./index"
export const TelemetrySessionModelSchema = z.object({ export const TelemetrySessionModelSchema = z.object({

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteWorkspacesOnUsers, RelatedWorkspacesOnUsersModelSchema } from "./index" import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteWorkspacesOnUsers, RelatedWorkspacesOnUsersModelSchema } from "./index"
export const UserModelSchema = z.object({ export const UserModelSchema = z.object({

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteMonitor, RelatedMonitorModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema, CompleteWebsiteEventData, RelatedWebsiteEventDataModelSchema, CompleteWebsiteSessionData, RelatedWebsiteSessionDataModelSchema } from "./index" import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteMonitor, RelatedMonitorModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema, CompleteWebsiteEventData, RelatedWebsiteEventDataModelSchema, CompleteWebsiteSessionData, RelatedWebsiteSessionDataModelSchema } from "./index"
export const WebsiteModelSchema = z.object({ export const WebsiteModelSchema = z.object({

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWebsiteEventData, RelatedWebsiteEventDataModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema } from "./index" import { CompleteWebsiteEventData, RelatedWebsiteEventDataModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema } from "./index"
export const WebsiteEventModelSchema = z.object({ export const WebsiteEventModelSchema = z.object({

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteEvent, RelatedWebsiteEventModelSchema } from "./index" import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteEvent, RelatedWebsiteEventModelSchema } from "./index"
export const WebsiteEventDataModelSchema = z.object({ export const WebsiteEventDataModelSchema = z.object({

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteEvent, RelatedWebsiteEventModelSchema, CompleteWebsiteSessionData, RelatedWebsiteSessionDataModelSchema } from "./index" import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteEvent, RelatedWebsiteEventModelSchema, CompleteWebsiteSessionData, RelatedWebsiteSessionDataModelSchema } from "./index"
export const WebsiteSessionModelSchema = z.object({ export const WebsiteSessionModelSchema = z.object({

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema } from "./index" import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema } from "./index"
export const WebsiteSessionDataModelSchema = z.object({ export const WebsiteSessionDataModelSchema = z.object({

View File

@ -1,5 +1,6 @@
import * as z from "zod" import * as z from "zod"
import { CompleteWorkspacesOnUsers, RelatedWorkspacesOnUsersModelSchema, CompleteWebsite, RelatedWebsiteModelSchema, CompleteNotification, RelatedNotificationModelSchema, CompleteMonitor, RelatedMonitorModelSchema, CompleteUser, RelatedUserModelSchema } from "./index" import * as imports from "./schemas"
import { CompleteWorkspacesOnUsers, RelatedWorkspacesOnUsersModelSchema, CompleteWebsite, RelatedWebsiteModelSchema, CompleteNotification, RelatedNotificationModelSchema, CompleteMonitor, RelatedMonitorModelSchema, CompleteMonitorStatusPage, RelatedMonitorStatusPageModelSchema, CompleteUser, RelatedUserModelSchema } from "./index"
// Helper schema for JSON fields // Helper schema for JSON fields
type Literal = boolean | number | string type Literal = boolean | number | string
@ -24,6 +25,7 @@ export interface CompleteWorkspace extends z.infer<typeof WorkspaceModelSchema>
websites: CompleteWebsite[] websites: CompleteWebsite[]
notifications: CompleteNotification[] notifications: CompleteNotification[]
monitors: CompleteMonitor[] monitors: CompleteMonitor[]
monitorStatusPages: CompleteMonitorStatusPage[]
selectedUsers: CompleteUser[] selectedUsers: CompleteUser[]
} }
@ -37,5 +39,6 @@ export const RelatedWorkspaceModelSchema: z.ZodSchema<CompleteWorkspace> = z.laz
websites: RelatedWebsiteModelSchema.array(), websites: RelatedWebsiteModelSchema.array(),
notifications: RelatedNotificationModelSchema.array(), notifications: RelatedNotificationModelSchema.array(),
monitors: RelatedMonitorModelSchema.array(), monitors: RelatedMonitorModelSchema.array(),
monitorStatusPages: RelatedMonitorStatusPageModelSchema.array(),
selectedUsers: RelatedUserModelSchema.array(), selectedUsers: RelatedUserModelSchema.array(),
})) }))

View File

@ -1,4 +1,5 @@
import * as z from "zod" import * as z from "zod"
import * as imports from "./schemas"
import { CompleteUser, RelatedUserModelSchema, CompleteWorkspace, RelatedWorkspaceModelSchema } from "./index" import { CompleteUser, RelatedUserModelSchema, CompleteWorkspace, RelatedWorkspaceModelSchema } from "./index"
export const WorkspacesOnUsersModelSchema = z.object({ export const WorkspacesOnUsersModelSchema = z.object({

View File

@ -17,6 +17,7 @@ import {
} from '../../model/_schema'; } from '../../model/_schema';
import { OPENAPI_TAG } from '../../utils/const'; import { OPENAPI_TAG } from '../../utils/const';
import { OpenApiMeta } from 'trpc-openapi'; import { OpenApiMeta } from 'trpc-openapi';
import { MonitorStatusPageModelSchema } from '../../../../prisma/zod';
export const monitorRouter = router({ export const monitorRouter = router({
all: workspaceProcedure all: workspaceProcedure
@ -417,6 +418,91 @@ export const monitorRouter = router({
}, },
}); });
}), }),
createPage: workspaceOwnerProcedure
.meta(
buildMonitorOpenapi({
method: 'POST',
path: '/createStatusPage',
})
)
.input(
z.object({
slug: z.string(),
title: z.string(),
})
)
.output(MonitorStatusPageModelSchema)
.mutation(async ({ input }) => {
const { workspaceId, slug, title } = input;
const existSlugCount = await prisma.monitorStatusPage.count({
where: {
slug,
},
});
if (existSlugCount > 0) {
throw new Error('This slug has been existed');
}
const res = await prisma.monitorStatusPage.create({
data: {
workspaceId,
slug,
title,
},
});
return res;
}),
editPage: workspaceOwnerProcedure
.meta(
buildMonitorOpenapi({
method: 'PATCH',
path: '/updateStatusPage',
})
)
.input(
MonitorStatusPageModelSchema.pick({
id: true,
}).merge(
MonitorStatusPageModelSchema.pick({
slug: true,
title: true,
description: true,
monitorList: true,
}).partial()
)
)
.output(MonitorStatusPageModelSchema)
.mutation(async ({ input }) => {
const { id, workspaceId, slug, title, description, monitorList } = input;
if (slug) {
const existSlugCount = await prisma.monitorStatusPage.count({
where: {
slug,
},
});
if (existSlugCount > 0) {
throw new Error('This slug has been existed');
}
}
return prisma.monitorStatusPage.update({
where: {
id,
workspaceId,
},
data: {
slug,
title,
description,
monitorList,
},
});
}),
}); });
function buildMonitorOpenapi(meta: OpenApiMetaInfo): OpenApiMeta { function buildMonitorOpenapi(meta: OpenApiMetaInfo): OpenApiMeta {

View File

@ -10,5 +10,8 @@ declare global {
layouts: Record<string, any[]>; layouts: Record<string, any[]>;
items: any[]; items: any[];
} | null; } | null;
type MonitorStatusPageList = {
id: string;
}[];
} }
} }