Skip to content

Commit

Permalink
🛂 (billing) Add isPastDue field in workspace (#1046)
Browse files Browse the repository at this point in the history
Closes #1039

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
  - Workspaces now include additional status indicator: `isPastDue`.
- New pages for handling workspaces that are past due. Meaning, an
invoice is unpaid.

- **Bug Fixes**
- Fixed issues with workspace status checks and redirections for
suspended workspaces.

- **Refactor**
- Refactored workspace-related API functions to accommodate new status
fields.
- Improved permission checks for reading and writing typebots based on
workspace status.

- **Chores**
  - Database schema updated to include `isPastDue` field for workspaces.
- Implemented new webhook event handling for subscription and invoice
updates.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
baptisteArno committed Nov 23, 2023
1 parent 94886ca commit ca79934
Show file tree
Hide file tree
Showing 27 changed files with 450 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,17 @@ export const getLinkedTypebots = authenticatedProcedure
variables: true,
name: true,
createdAt: true,
workspaceId: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
},
},
},
},
collaborators: {
select: {
type: true,
Expand Down Expand Up @@ -97,7 +107,17 @@ export const getLinkedTypebots = authenticatedProcedure
variables: true,
name: true,
createdAt: true,
workspaceId: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
},
},
},
},
collaborators: {
select: {
type: true,
Expand Down
11 changes: 11 additions & 0 deletions apps/builder/src/features/collaboration/api/getCollaborators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ export const getCollaborators = authenticatedProcedure
},
include: {
collaborators: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
},
},
},
},
},
})
if (
Expand Down
13 changes: 12 additions & 1 deletion apps/builder/src/features/results/api/deleteResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,19 @@ export const deleteResults = authenticatedProcedure
id: typebotId,
},
select: {
workspaceId: true,
groups: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
role: true,
},
},
},
},
collaborators: {
select: {
userId: true,
Expand Down
12 changes: 11 additions & 1 deletion apps/builder/src/features/results/api/getResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,18 @@ export const getResult = authenticatedProcedure
},
select: {
id: true,
workspaceId: true,
groups: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
},
},
},
},
collaborators: {
select: {
userId: true,
Expand Down
12 changes: 11 additions & 1 deletion apps/builder/src/features/results/api/getResultLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,18 @@ export const getResultLogs = authenticatedProcedure
},
select: {
id: true,
workspaceId: true,
groups: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
},
},
},
},
collaborators: {
select: {
userId: true,
Expand Down
12 changes: 11 additions & 1 deletion apps/builder/src/features/results/api/getResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,24 @@ export const getResults = authenticatedProcedure
},
select: {
id: true,
workspaceId: true,
groups: true,
collaborators: {
select: {
userId: true,
type: true,
},
},
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
},
},
},
},
},
})
if (!typebot || (await isReadTypebotForbidden(typebot, user)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const processTelemetryEvent = authenticatedProcedure
client.capture({
distinctId: event.userId,
event: event.name,
properties: event.data,
properties: 'data' in event ? event.data : undefined,
groups,
})
})
Expand Down
13 changes: 12 additions & 1 deletion apps/builder/src/features/typebot/api/deleteTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,19 @@ export const deleteTypebot = authenticatedProcedure
},
select: {
id: true,
workspaceId: true,
groups: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
role: true,
},
},
},
},
collaborators: {
select: {
userId: true,
Expand Down
11 changes: 11 additions & 0 deletions apps/builder/src/features/typebot/api/getPublishedTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ export const getPublishedTypebot = authenticatedProcedure
include: {
collaborators: true,
publishedTypebot: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
},
},
},
},
},
})
if (
Expand Down
11 changes: 11 additions & 0 deletions apps/builder/src/features/typebot/api/getTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ export const getTypebot = authenticatedProcedure
},
include: {
collaborators: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
},
},
},
},
},
})
if (
Expand Down
8 changes: 8 additions & 0 deletions apps/builder/src/features/typebot/api/publishTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ export const publishTypebot = authenticatedProcedure
workspace: {
select: {
plan: true,
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
role: true,
},
},
},
},
},
Expand Down
12 changes: 12 additions & 0 deletions apps/builder/src/features/typebot/api/unpublishTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ export const unpublishTypebot = authenticatedProcedure
include: {
collaborators: true,
publishedTypebot: true,
workspace: {
select: {
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
role: true,
},
},
},
},
},
})
if (!existingTypebot?.publishedTypebot)
Expand Down
12 changes: 10 additions & 2 deletions apps/builder/src/features/typebot/api/updateTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ export const updateTypebot = authenticatedProcedure
id: true,
customDomain: true,
publicId: true,
workspaceId: true,
collaborators: {
select: {
userId: true,
Expand All @@ -88,7 +87,16 @@ export const updateTypebot = authenticatedProcedure
},
workspace: {
select: {
id: true,
plan: true,
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
role: true,
},
},
},
},
updatedAt: true,
Expand Down Expand Up @@ -160,7 +168,7 @@ export const updateTypebot = authenticatedProcedure
selectedThemeTemplateId: typebot.selectedThemeTemplateId,
events: typebot.events ?? undefined,
groups: typebot.groups
? await sanitizeGroups(existingTypebot.workspaceId)(typebot.groups)
? await sanitizeGroups(existingTypebot.workspace.id)(typebot.groups)
: undefined,
theme: typebot.theme ? typebot.theme : undefined,
settings: typebot.settings
Expand Down
37 changes: 18 additions & 19 deletions apps/builder/src/features/typebot/helpers/isReadTypebotForbidden.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import prisma from '@typebot.io/lib/prisma'
import { env } from '@typebot.io/env'
import { CollaboratorsOnTypebots, User } from '@typebot.io/prisma'
import { Typebot } from '@typebot.io/schemas'
import {
CollaboratorsOnTypebots,
User,
Workspace,
MemberInWorkspace,
} from '@typebot.io/prisma'

export const isReadTypebotForbidden = async (
typebot: Pick<Typebot, 'workspaceId'> & {
typebot: {
collaborators: Pick<CollaboratorsOnTypebots, 'userId'>[]
} & {
workspace: Pick<Workspace, 'isQuarantined' | 'isPastDue'> & {
members: Pick<MemberInWorkspace, 'userId'>[]
}
},
user: Pick<User, 'email' | 'id'>
) => {
if (
env.ADMIN_EMAIL === user.email ||
typebot.collaborators.find(
) =>
typebot.workspace.isQuarantined ||
typebot.workspace.isPastDue ||
(env.ADMIN_EMAIL !== user.email &&
!typebot.collaborators.some(
(collaborator) => collaborator.userId === user.id
)
)
return false
const memberInWorkspace = await prisma.memberInWorkspace.findFirst({
where: {
workspaceId: typebot.workspaceId,
userId: user.id,
},
})
return memberInWorkspace === null
}
) &&
!typebot.workspace.members.some((member) => member.userId === user.id))
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import prisma from '@typebot.io/lib/prisma'
import {
CollaborationType,
CollaboratorsOnTypebots,
MemberInWorkspace,
User,
Workspace,
} from '@typebot.io/prisma'
import { Typebot } from '@typebot.io/schemas'
import { isNotDefined } from '@typebot.io/lib'

export const isWriteTypebotForbidden = async (
typebot: Pick<Typebot, 'workspaceId'> & {
typebot: {
collaborators: Pick<CollaboratorsOnTypebots, 'userId' | 'type'>[]
} & {
workspace: Pick<Workspace, 'isQuarantined' | 'isPastDue'> & {
members: Pick<MemberInWorkspace, 'userId' | 'role'>[]
}
},
user: Pick<User, 'id'>
) => {
if (
typebot.collaborators.find(
(collaborator) => collaborator.userId === user.id
)?.type === CollaborationType.WRITE
return (
typebot.workspace.isQuarantined ||
typebot.workspace.isPastDue ||
!(
typebot.collaborators.find(
(collaborator) => collaborator.userId === user.id
)?.type === CollaborationType.WRITE &&
typebot.workspace.members.some(
(m) => m.userId === user.id && m.role !== 'GUEST'
)
)
)
return false
const memberInWorkspace = await prisma.memberInWorkspace.findFirst({
where: {
workspaceId: typebot.workspaceId,
userId: user.id,
},
})
return isNotDefined(memberInWorkspace) || memberInWorkspace.role === 'GUEST'
}
14 changes: 13 additions & 1 deletion apps/builder/src/features/upload/api/generateUploadUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,19 @@ const parseFilePath = async ({
id: input.typebotId,
},
select: {
workspaceId: true,
workspace: {
select: {
plan: true,
isQuarantined: true,
isPastDue: true,
members: {
select: {
userId: true,
role: true,
},
},
},
},
collaborators: {
select: {
userId: true,
Expand Down
Loading

4 comments on commit ca79934

@vercel
Copy link

@vercel vercel bot commented on ca79934 Nov 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

app.typebot.io
builder-v2-git-main-typebot-io.vercel.app
builder-v2-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on ca79934 Nov 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./apps/docs

docs-typebot-io.vercel.app
docs-git-main-typebot-io.vercel.app
docs.typebot.io

@vercel
Copy link

@vercel vercel bot commented on ca79934 Nov 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on ca79934 Nov 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2 – ./apps/viewer

ai.meant.com
alphamen.pro
bet7k.online
bot.afric.ai
bot.grace.bj
bot.tobb.pro
chatgov.site
cinecorn.com
ezbooking.ai
gniorder.com
help.taxt.co
kusamint.com
p18bm940.fun
psmix.online
receita.info
rhino.cr8.ai
sheep.cr8.ai
snake.cr8.ai
svhm.mprs.in
tiger.cr8.ai
video.cr8.ai
webwhats.fun
webwhats.pro
whatsapp.web
yoda.riku.ai
zebra.cr8.ai
1nkagency.com
akademicq.com
alvodelas.com
atendente.org
bemestar.club
bot.goafk.com
bot.krdfy.com
cat.hidden.sg
cgcassets.com
chat.linky.li
cnvhub.com.br
drapamela.com
facelabko.com
filmylogy.com
gikpro.online
goldorayo.com
headsbet.info
majie.move.sg
payforbet.com
rabbit.cr8.ai
saquegov.site
shop.mexwa.my
signup.cr8.ai
start.taxt.co
cares.urlabout.me
chat.ezbooking.ai
chat.gaswadern.de
chat.gniorder.com
chat.leadmagic.io
chat.onrentme.com
chat.rojie.online
chatdocidadao.com
chatwebonline.com
consultanutri.com
dividaquitada.com
viewer-v2-typebot-io.vercel.app
mdb.assessoria.fernanda.progenbr.com
mdb.assessoria.jbatista.progenbr.com
mdb.assessoria.mauricio.progenbr.com
mdb.evento.autocadastro.progenbr.com
form.shopmercedesbenzsouthorlando.com
mdb.evento.equipeinterna.progenbr.com
bot.studiotecnicoimmobiliaremerelli.it
mdb.assessoria.boaventura.progenbr.com
mdb.assessoria.jtrebesqui.progenbr.com
pesquisa.escolamodacomproposito.com.br
anamnese.clinicaramosodontologia.com.br
gabinete.baleia.formulario.progenbr.com
mdb.assessoria.carreirinha.progenbr.com
chrome-os-inquiry-system.itschromeos.com
mdb.assessoria.paulomarques.progenbr.com
viewer-v2-git-main-typebot-io.vercel.app
main-menu-for-itschromeos.itschromeos.com
mdb.assessoria.qrcode.ademir.progenbr.com
mdb.assessoria.qrcode.arthur.progenbr.com
mdb.assessoria.qrcode.danilo.progenbr.com
mdb.assessoria.qrcode.marcao.progenbr.com
mdb.assessoria.qrcode.marcio.progenbr.com
mdb.assessoria.qrcode.aloisio.progenbr.com
mdb.assessoria.qrcode.girotto.progenbr.com
mdb.assessoria.qrcode.marinho.progenbr.com
mdb.assessoria.qrcode.rodrigo.progenbr.com
mdb.assessoria.carlosalexandre.progenbr.com
mdb.assessoria.qrcode.desideri.progenbr.com
mdb.assessoria.qrcode.fernanda.progenbr.com
mdb.assessoria.qrcode.jbatista.progenbr.com
mdb.assessoria.qrcode.mauricio.progenbr.com
mdb.assessoria.fernanda.regional.progenbr.com
mdb.assessoria.qrcode.boaventura.progenbr.com
mdb.assessoria.qrcode.jtrebesqui.progenbr.com
mdb.assessoria.qrcode.carreirinha.progenbr.com
mdb.assessoria.qrcode.paulomarques.progenbr.com
mdb.assessoria.qrcode.carlosalexandre.progenbr.com
mdb.assessoria.qrcode.fernanda.regional.progenbr.com

Please sign in to comment.