Add webhook blocks API public endpoints

This commit is contained in:
Baptiste Arnaud
2022-11-30 13:57:28 +01:00
parent f9ffdbc4c5
commit c799717905
67 changed files with 3030 additions and 429 deletions

View File

@@ -0,0 +1 @@
export * from './router'

View File

@@ -0,0 +1,56 @@
import prisma from '@/lib/prisma'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { TRPCError } from '@trpc/server'
import { Plan } from 'db'
import { Workspace, workspaceSchema } from 'models'
import { z } from 'zod'
export const createWorkspaceProcedure = authenticatedProcedure
.meta({
openapi: {
method: 'POST',
path: '/workspaces',
protect: true,
summary: 'Create workspace',
tags: ['Workspace'],
},
})
.input(workspaceSchema.pick({ name: true }))
.output(
z.object({
workspace: workspaceSchema,
})
)
.mutation(async ({ input: { name }, ctx: { user } }) => {
const existingWorkspaceNames = (await prisma.workspace.findMany({
where: {
members: {
some: {
userId: user.id,
},
},
},
select: { name: true },
})) satisfies Pick<Workspace, 'name'>[]
if (existingWorkspaceNames.some((workspace) => workspace.name === name))
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'Workspace with same name already exists',
})
const plan =
process.env.ADMIN_EMAIL === user.email ? Plan.LIFETIME : Plan.FREE
const newWorkspace = (await prisma.workspace.create({
data: {
name,
members: { create: [{ role: 'ADMIN', userId: user.id }] },
plan,
},
})) satisfies Workspace
return {
workspace: newWorkspace,
}
})

View File

@@ -0,0 +1,33 @@
import prisma from '@/lib/prisma'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { z } from 'zod'
export const deleteWorkspaceProcedure = authenticatedProcedure
.meta({
openapi: {
method: 'DELETE',
path: '/workspaces/{workspaceId}',
protect: true,
summary: 'Delete workspace',
tags: ['Workspace'],
},
})
.input(
z.object({
workspaceId: z.string(),
})
)
.output(
z.object({
message: z.string(),
})
)
.mutation(async ({ input: { workspaceId }, ctx: { user } }) => {
await prisma.workspace.deleteMany({
where: { members: { some: { userId: user.id } }, id: workspaceId },
})
return {
message: 'Workspace deleted',
}
})

View File

@@ -0,0 +1,38 @@
import prisma from '@/lib/prisma'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { TRPCError } from '@trpc/server'
import { Workspace, workspaceSchema } from 'models'
import { z } from 'zod'
export const getWorkspaceProcedure = authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/workspaces/{workspaceId}',
protect: true,
summary: 'Get workspace',
tags: ['Workspace'],
},
})
.input(
z.object({
workspaceId: z.string(),
})
)
.output(
z.object({
workspace: workspaceSchema,
})
)
.query(async ({ input: { workspaceId }, ctx: { user } }) => {
const workspace = (await prisma.workspace.findFirst({
where: { members: { some: { userId: user.id } }, id: workspaceId },
})) satisfies Workspace | null
if (!workspace)
throw new TRPCError({ code: 'NOT_FOUND', message: 'No workspaces found' })
return {
workspace,
}
})

View File

@@ -0,0 +1,7 @@
export * from './createWorkspaceProcedure'
export * from './deleteWorkspaceProcedure'
export * from './getWorkspaceProcedure'
export * from './listInvitationsInWorkspaceProcedure'
export * from './listMembersInWorkspaceProcedure'
export * from './listWorkspacesProcedure'
export * from './updateWorkspaceProcedure'

View File

@@ -0,0 +1,43 @@
import prisma from '@/lib/prisma'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { TRPCError } from '@trpc/server'
import { WorkspaceInvitation, workspaceInvitationSchema } from 'models'
import { z } from 'zod'
export const listInvitationsInWorkspaceProcedure = authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/workspaces/{workspaceId}/invitations',
protect: true,
summary: 'List invitations in workspace',
tags: ['Workspace'],
},
})
.input(
z.object({
workspaceId: z.string(),
})
)
.output(
z.object({
invitations: z.array(workspaceInvitationSchema),
})
)
.query(async ({ input: { workspaceId }, ctx: { user } }) => {
const invitations = (await prisma.workspaceInvitation.findMany({
where: {
workspaceId,
workspace: { members: { some: { userId: user.id } } },
},
select: { createdAt: true, email: true, type: true },
})) satisfies WorkspaceInvitation[]
if (!invitations)
throw new TRPCError({
code: 'NOT_FOUND',
message: 'No invitations found',
})
return { invitations }
})

View File

@@ -0,0 +1,37 @@
import prisma from '@/lib/prisma'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { TRPCError } from '@trpc/server'
import { WorkspaceMember, workspaceMemberSchema } from 'models'
import { z } from 'zod'
export const listMembersInWorkspaceProcedure = authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/workspaces/{workspaceId}/members',
protect: true,
summary: 'List members in workspace',
tags: ['Workspace'],
},
})
.input(
z.object({
workspaceId: z.string(),
})
)
.output(
z.object({
members: z.array(workspaceMemberSchema),
})
)
.query(async ({ input: { workspaceId }, ctx: { user } }) => {
const members = (await prisma.memberInWorkspace.findMany({
where: { userId: user.id, workspaceId },
include: { user: { select: { name: true, email: true, image: true } } },
})) satisfies WorkspaceMember[]
if (!members)
throw new TRPCError({ code: 'NOT_FOUND', message: 'No members found' })
return { members }
})

View File

@@ -0,0 +1,35 @@
import prisma from '@/lib/prisma'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { TRPCError } from '@trpc/server'
import { Workspace, workspaceSchema } from 'models'
import { z } from 'zod'
export const listWorkspacesProcedure = authenticatedProcedure
.meta({
openapi: {
method: 'GET',
path: '/workspaces',
protect: true,
summary: 'List workspaces',
tags: ['Workspace'],
},
})
.input(z.void())
.output(
z.object({
workspaces: z.array(
workspaceSchema.pick({ id: true, name: true, icon: true, plan: true })
),
})
)
.query(async ({ ctx: { user } }) => {
const workspaces = (await prisma.workspace.findMany({
where: { members: { some: { userId: user.id } } },
select: { name: true, id: true, icon: true, plan: true },
})) satisfies Pick<Workspace, 'id' | 'name' | 'icon' | 'plan'>[]
if (!workspaces)
throw new TRPCError({ code: 'NOT_FOUND', message: 'No workspaces found' })
return { workspaces }
})

View File

@@ -0,0 +1,45 @@
import prisma from '@/lib/prisma'
import { authenticatedProcedure } from '@/utils/server/trpc'
import { TRPCError } from '@trpc/server'
import { Workspace, workspaceSchema } from 'models'
import { z } from 'zod'
export const updateWorkspaceProcedure = authenticatedProcedure
.meta({
openapi: {
method: 'PATCH',
path: '/workspaces/{workspaceId}',
protect: true,
summary: 'Update workspace',
tags: ['Workspace'],
},
})
.input(
z.object({
name: z.string().optional(),
icon: z.string().optional(),
workspaceId: z.string(),
})
)
.output(
z.object({
workspace: workspaceSchema,
})
)
.mutation(async ({ input: { workspaceId, ...updates }, ctx: { user } }) => {
await prisma.workspace.updateMany({
where: { members: { some: { userId: user.id } }, id: workspaceId },
data: updates,
})
const workspace = (await prisma.workspace.findFirst({
where: { members: { some: { userId: user.id } }, id: workspaceId },
})) satisfies Workspace | null
if (!workspace)
throw new TRPCError({ code: 'NOT_FOUND', message: 'Workspace not found' })
return {
workspace,
}
})

View File

@@ -0,0 +1,18 @@
import { router } from '@/utils/server/trpc'
import {
createWorkspaceProcedure,
deleteWorkspaceProcedure,
getWorkspaceProcedure,
listMembersInWorkspaceProcedure,
listWorkspacesProcedure,
updateWorkspaceProcedure,
} from './procedures'
export const workspaceRouter = router({
listWorkspaces: listWorkspacesProcedure,
getWorkspace: getWorkspaceProcedure,
listMembersInWorkspace: listMembersInWorkspaceProcedure,
createWorkspace: createWorkspaceProcedure,
updateWorkspace: updateWorkspaceProcedure,
deleteWorkspace: deleteWorkspaceProcedure,
})