2
0

♻️ Re-organize workspace folders

This commit is contained in:
Baptiste Arnaud
2023-03-15 08:35:16 +01:00
parent 25c367901f
commit cbc8194f19
987 changed files with 2716 additions and 2770 deletions

View File

@ -0,0 +1 @@
DATABASE_URL=postgresql://postgres:typebot@localhost:5432/typebot

View File

@ -0,0 +1 @@
# schemas

9
packages/prisma/index.ts Normal file
View File

@ -0,0 +1,9 @@
export * from '@prisma/client'
// Named export for enums to avoid vite barrel export bug (https://github.com/nrwl/nx/issues/13704)
export {
Plan,
WorkspaceRole,
GraphNavigation,
CollaborationType,
} from '@prisma/client'

View File

@ -0,0 +1,353 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma"
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
oauth_token_secret String?
oauth_token String?
refresh_token_expires_in Int?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
@@index([userId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
}
model User {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
lastActivityAt DateTime @default(now())
name String? @db.VarChar(255)
email String? @unique
emailVerified DateTime?
image String? @db.VarChar(1000)
company String?
onboardingCategories Json
graphNavigation GraphNavigation?
preferredAppAppearance String?
accounts Account[]
apiTokens ApiToken[]
CollaboratorsOnTypebots CollaboratorsOnTypebots[]
workspaces MemberInWorkspace[]
sessions Session[]
}
model ApiToken {
id String @id @default(cuid())
createdAt DateTime @default(now())
token String @unique
name String
ownerId String
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
@@index([ownerId])
}
model Workspace {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
name String @db.VarChar(255)
icon String? @db.VarChar(1000)
plan Plan @default(FREE)
stripeId String? @unique
credentials Credentials[]
customDomains CustomDomain[]
folders DashboardFolder[]
members MemberInWorkspace[]
typebots Typebot[]
invitations WorkspaceInvitation[]
additionalChatsIndex Int @default(0)
additionalStorageIndex Int @default(0)
chatsLimitFirstEmailSentAt DateTime?
storageLimitFirstEmailSentAt DateTime?
chatsLimitSecondEmailSentAt DateTime?
storageLimitSecondEmailSentAt DateTime?
claimableCustomPlan ClaimableCustomPlan?
customChatsLimit Int?
customStorageLimit Int?
customSeatsLimit Int?
}
model MemberInWorkspace {
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
userId String
workspaceId String
role WorkspaceRole
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
@@unique([userId, workspaceId])
@@index([workspaceId])
}
model WorkspaceInvitation {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
email String
workspaceId String
type WorkspaceRole
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
@@index([workspaceId])
}
model CustomDomain {
name String @id @db.VarChar(255)
createdAt DateTime @default(now())
workspaceId String
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
@@index([workspaceId])
}
model Credentials {
id String @id @default(cuid())
createdAt DateTime @default(now())
workspaceId String
data String @db.Text
name String
type String
iv String
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
@@index([workspaceId])
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
model DashboardFolder {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
name String @db.VarChar(255)
parentFolderId String?
workspaceId String
parentFolder DashboardFolder? @relation("ParentChild", fields: [parentFolderId], references: [id], onDelete: NoAction, onUpdate: NoAction)
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
childrenFolder DashboardFolder[] @relation("ParentChild")
typebots Typebot[]
@@index([workspaceId])
@@index([parentFolderId])
}
model Typebot {
id String @id @default(cuid())
version String? @db.VarChar(10)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
icon String? @db.VarChar(1000)
name String @db.VarChar(255)
folderId String?
groups Json
variables Json
edges Json
theme Json
settings Json
publicId String? @unique
customDomain String? @unique
workspaceId String
resultsTablePreferences Json?
folder DashboardFolder? @relation(fields: [folderId], references: [id])
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
collaborators CollaboratorsOnTypebots[]
invitations Invitation[]
publishedTypebot PublicTypebot?
results Result[]
webhooks Webhook[]
isArchived Boolean @default(false)
isClosed Boolean @default(false)
@@index([workspaceId])
@@index([folderId])
@@index([isArchived, createdAt(sort: Desc)])
}
model Invitation {
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
email String
typebotId String
type CollaborationType
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
@@unique([email, typebotId])
@@index([typebotId])
}
model CollaboratorsOnTypebots {
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
userId String
typebotId String
type CollaborationType
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, typebotId])
@@index([typebotId])
}
model PublicTypebot {
id String @id @default(cuid())
version String? @db.VarChar(10)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
typebotId String @unique
groups Json
variables Json
edges Json
theme Json
settings Json
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
}
model Result {
id String @id @default(cuid())
createdAt DateTime @default(now())
typebotId String
variables Json
isCompleted Boolean
hasStarted Boolean?
isArchived Boolean? @default(false)
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
answers Answer[]
logs Log[]
@@index([typebotId, isArchived, hasStarted, createdAt(sort: Desc)])
@@index([typebotId, isArchived, isCompleted])
}
model Log {
id String @id @default(cuid())
createdAt DateTime @default(now())
resultId String
status String
description String @db.Text
details String? @db.Text
result Result @relation(fields: [resultId], references: [id], onDelete: Cascade)
@@index([resultId])
}
model Answer {
createdAt DateTime @default(now()) @updatedAt
resultId String
blockId String
groupId String
variableId String?
content String @db.Text
storageUsed Int?
result Result @relation(fields: [resultId], references: [id], onDelete: Cascade)
@@unique([resultId, blockId, groupId])
@@index([groupId])
@@index([storageUsed])
}
model Coupon {
userPropertiesToUpdate Json
code String @id @unique
dateRedeemed DateTime?
}
model Webhook {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
url String? @db.VarChar(2000)
method String
queryParams Json
headers Json
body String? @db.Text
typebotId String
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
@@index([typebotId])
}
model ClaimableCustomPlan {
id String @id @default(cuid())
createdAt DateTime @default(now())
claimedAt DateTime?
name String
description String?
price Int
currency String
workspaceId String @unique
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
chatsLimit Int
storageLimit Int
seatsLimit Int
}
model ChatSession {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
state Json
}
enum WorkspaceRole {
ADMIN
MEMBER
GUEST
}
enum GraphNavigation {
MOUSE
TRACKPAD
}
enum Plan {
FREE
STARTER
PRO
LIFETIME
OFFERED
CUSTOM
UNLIMITED
}
enum CollaborationType {
READ
WRITE
FULL_ACCESS
}

View File

@ -0,0 +1,27 @@
{
"name": "@typebot.io/prisma",
"license": "AGPL-3.0-or-later",
"version": "0.1.0",
"main": "./index.ts",
"types": "./index.ts",
"private": true,
"scripts": {
"dev": "tsx scripts/studio.ts",
"db:generate": "tsx scripts/db-generate.ts",
"db:push": "tsx scripts/db-push.ts",
"migrate:deploy": "tsx scripts/migrate-deploy.ts",
"migrate:dev": "prisma migrate dev --create-only --schema postgresql/schema.prisma",
"db:migrate": "pnpm migrate:deploy"
},
"dependencies": {
"@prisma/client": "4.11.0"
},
"devDependencies": {
"@types/node": "18.15.3",
"dotenv": "16.0.3",
"prisma": "4.11.0",
"@typebot.io/tsconfig": "workspace:*",
"tsx": "3.12.5",
"typescript": "4.9.5"
}
}

View File

@ -0,0 +1,201 @@
-- CreateEnum
CREATE TYPE "Plan" AS ENUM ('FREE', 'PRO', 'LIFETIME', 'OFFERED');
-- CreateTable
CREATE TABLE "Account" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"type" TEXT NOT NULL,
"provider" TEXT NOT NULL,
"providerAccountId" TEXT NOT NULL,
"refresh_token" TEXT,
"access_token" TEXT,
"expires_at" INTEGER,
"token_type" TEXT,
"scope" TEXT,
"id_token" TEXT,
"session_state" TEXT,
"oauth_token_secret" TEXT,
"oauth_token" TEXT,
"refresh_token_expires_in" INTEGER,
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Session" (
"id" TEXT NOT NULL,
"sessionToken" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"name" TEXT,
"email" TEXT,
"emailVerified" TIMESTAMP(3),
"image" TEXT,
"plan" "Plan" NOT NULL DEFAULT E'FREE',
"stripeId" TEXT,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Credentials" (
"id" TEXT NOT NULL,
"ownerId" TEXT NOT NULL,
"data" TEXT NOT NULL,
"name" TEXT NOT NULL,
"type" TEXT NOT NULL,
"iv" TEXT NOT NULL,
CONSTRAINT "Credentials_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "VerificationToken" (
"identifier" TEXT NOT NULL,
"token" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL
);
-- CreateTable
CREATE TABLE "DashboardFolder" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"name" TEXT NOT NULL,
"ownerId" TEXT NOT NULL,
"parentFolderId" TEXT,
CONSTRAINT "DashboardFolder_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Typebot" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"name" TEXT NOT NULL,
"ownerId" TEXT NOT NULL,
"publishedTypebotId" TEXT,
"folderId" TEXT,
"blocks" JSONB[],
"variables" JSONB[],
"edges" JSONB[],
"theme" JSONB NOT NULL,
"settings" JSONB NOT NULL,
"publicId" TEXT,
CONSTRAINT "Typebot_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PublicTypebot" (
"id" TEXT NOT NULL,
"typebotId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"blocks" JSONB[],
"variables" JSONB[],
"edges" JSONB[],
"theme" JSONB NOT NULL,
"settings" JSONB NOT NULL,
"publicId" TEXT,
CONSTRAINT "PublicTypebot_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Result" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"typebotId" TEXT NOT NULL,
"isCompleted" BOOLEAN NOT NULL,
CONSTRAINT "Result_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Answer" (
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"resultId" TEXT NOT NULL,
"stepId" TEXT NOT NULL,
"blockId" TEXT NOT NULL,
"content" TEXT NOT NULL
);
-- CreateTable
CREATE TABLE "Coupon" (
"userPropertiesToUpdate" JSONB NOT NULL,
"code" TEXT NOT NULL,
"dateRedeemed" TIMESTAMP(3),
CONSTRAINT "Coupon_pkey" PRIMARY KEY ("code")
);
-- CreateIndex
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");
-- CreateIndex
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "User_stripeId_key" ON "User"("stripeId");
-- CreateIndex
CREATE UNIQUE INDEX "Credentials_name_type_ownerId_key" ON "Credentials"("name", "type", "ownerId");
-- CreateIndex
CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token");
-- CreateIndex
CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token");
-- CreateIndex
CREATE UNIQUE INDEX "Typebot_publicId_key" ON "Typebot"("publicId");
-- CreateIndex
CREATE UNIQUE INDEX "PublicTypebot_typebotId_key" ON "PublicTypebot"("typebotId");
-- CreateIndex
CREATE UNIQUE INDEX "PublicTypebot_publicId_key" ON "PublicTypebot"("publicId");
-- CreateIndex
CREATE UNIQUE INDEX "Answer_resultId_blockId_stepId_key" ON "Answer"("resultId", "blockId", "stepId");
-- AddForeignKey
ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Credentials" ADD CONSTRAINT "Credentials_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "DashboardFolder" ADD CONSTRAINT "DashboardFolder_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "DashboardFolder" ADD CONSTRAINT "DashboardFolder_parentFolderId_fkey" FOREIGN KEY ("parentFolderId") REFERENCES "DashboardFolder"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Typebot" ADD CONSTRAINT "Typebot_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Typebot" ADD CONSTRAINT "Typebot_folderId_fkey" FOREIGN KEY ("folderId") REFERENCES "DashboardFolder"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PublicTypebot" ADD CONSTRAINT "PublicTypebot_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Result" ADD CONSTRAINT "Result_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Answer" ADD CONSTRAINT "Answer_resultId_fkey" FOREIGN KEY ("resultId") REFERENCES "Result"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "Answer" ADD COLUMN "variableId" TEXT;
-- AlterTable
ALTER TABLE "Result" ADD COLUMN "prefilledVariables" JSONB[];

View File

@ -0,0 +1,30 @@
/*
Warnings:
- A unique constraint covering the columns `[customDomain]` on the table `PublicTypebot` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[customDomain]` on the table `Typebot` will be added. If there are existing duplicate values, this will fail.
*/
-- AlterTable
ALTER TABLE "PublicTypebot" ADD COLUMN "customDomain" TEXT;
-- AlterTable
ALTER TABLE "Typebot" ADD COLUMN "customDomain" TEXT;
-- CreateTable
CREATE TABLE "CustomDomain" (
"ownerId" TEXT NOT NULL,
"name" TEXT NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "CustomDomain_name_key" ON "CustomDomain"("name");
-- CreateIndex
CREATE UNIQUE INDEX "PublicTypebot_customDomain_key" ON "PublicTypebot"("customDomain");
-- CreateIndex
CREATE UNIQUE INDEX "Typebot_customDomain_key" ON "Typebot"("customDomain");
-- AddForeignKey
ALTER TABLE "CustomDomain" ADD CONSTRAINT "CustomDomain_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,16 @@
/*
Warnings:
- A unique constraint covering the columns `[code]` on the table `Coupon` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[id,ownerId]` on the table `DashboardFolder` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[id,ownerId]` on the table `Typebot` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateIndex
CREATE UNIQUE INDEX "Coupon_code_key" ON "Coupon"("code");
-- CreateIndex
CREATE UNIQUE INDEX "DashboardFolder_id_ownerId_key" ON "DashboardFolder"("id", "ownerId");
-- CreateIndex
CREATE UNIQUE INDEX "Typebot_id_ownerId_key" ON "Typebot"("id", "ownerId");

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "apiToken" TEXT;

View File

@ -0,0 +1,9 @@
-- AlterTable
ALTER TABLE "DashboardFolder" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "PublicTypebot" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "Result" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

View File

@ -0,0 +1,31 @@
-- CreateEnum
CREATE TYPE "CollaborationType" AS ENUM ('READ', 'WRITE');
-- CreateTable
CREATE TABLE "Invitation" (
"email" TEXT NOT NULL,
"typebotId" TEXT NOT NULL,
"type" "CollaborationType" NOT NULL
);
-- CreateTable
CREATE TABLE "CollaboratorsOnTypebots" (
"userId" TEXT NOT NULL,
"typebotId" TEXT NOT NULL,
"type" "CollaborationType" NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "Invitation_email_typebotId_key" ON "Invitation"("email", "typebotId");
-- CreateIndex
CREATE UNIQUE INDEX "CollaboratorsOnTypebots_userId_typebotId_key" ON "CollaboratorsOnTypebots"("userId", "typebotId");
-- AddForeignKey
ALTER TABLE "Invitation" ADD CONSTRAINT "Invitation_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CollaboratorsOnTypebots" ADD CONSTRAINT "CollaboratorsOnTypebots_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CollaboratorsOnTypebots" ADD CONSTRAINT "CollaboratorsOnTypebots_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,13 @@
-- AlterTable
ALTER TABLE "Credentials" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "CustomDomain" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "Invitation" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "User" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "lastActivityAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

View File

@ -0,0 +1,15 @@
-- CreateTable
CREATE TABLE "Webhook" (
"id" TEXT NOT NULL,
"url" TEXT,
"method" TEXT NOT NULL,
"queryParams" JSONB[],
"headers" JSONB[],
"body" TEXT,
"typebotId" TEXT NOT NULL,
CONSTRAINT "Webhook_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Webhook" ADD CONSTRAINT "Webhook_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,14 @@
-- CreateTable
CREATE TABLE "Log" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"resultId" TEXT NOT NULL,
"status" TEXT NOT NULL,
"description" TEXT NOT NULL,
"details" TEXT,
CONSTRAINT "Log_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Log" ADD CONSTRAINT "Log_resultId_fkey" FOREIGN KEY ("resultId") REFERENCES "Result"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,5 @@
-- DropIndex
DROP INDEX "CustomDomain_name_key";
-- AlterTable
ALTER TABLE "CustomDomain" ADD CONSTRAINT "CustomDomain_pkey" PRIMARY KEY ("name");

View File

@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "company" TEXT,
ADD COLUMN "onboardingCategories" TEXT[];

View File

@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Result"
RENAME COLUMN "prefilledVariables" TO "variables"

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Typebot" ADD COLUMN "icon" TEXT;

View File

@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "GraphNavigation" AS ENUM ('MOUSE', 'TRACKPAD');
-- AlterTable
ALTER TABLE "User" ADD COLUMN "graphNavigation" "GraphNavigation";

View File

@ -0,0 +1,84 @@
-- CreateEnum
CREATE TYPE "WorkspaceRole" AS ENUM ('ADMIN', 'MEMBER', 'GUEST');
-- AlterEnum
ALTER TYPE "CollaborationType" ADD VALUE 'FULL_ACCESS';
-- AlterEnum
ALTER TYPE "Plan" ADD VALUE 'TEAM';
-- AlterTable
ALTER TABLE "Credentials" ADD COLUMN "workspaceId" TEXT,
ALTER COLUMN "ownerId" DROP NOT NULL;
-- AlterTable
ALTER TABLE "CustomDomain" ADD COLUMN "workspaceId" TEXT,
ALTER COLUMN "ownerId" DROP NOT NULL;
-- AlterTable
ALTER TABLE "DashboardFolder" ADD COLUMN "workspaceId" TEXT,
ALTER COLUMN "ownerId" DROP NOT NULL;
-- AlterTable
ALTER TABLE "Typebot" ADD COLUMN "workspaceId" TEXT,
ALTER COLUMN "ownerId" DROP NOT NULL;
-- AlterTable
ALTER TABLE "User" ALTER COLUMN "plan" DROP NOT NULL;
-- CreateTable
CREATE TABLE "Workspace" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"icon" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"plan" "Plan" NOT NULL DEFAULT E'FREE',
"stripeId" TEXT,
CONSTRAINT "Workspace_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "MemberInWorkspace" (
"userId" TEXT NOT NULL,
"workspaceId" TEXT NOT NULL,
"role" "WorkspaceRole" NOT NULL
);
-- CreateTable
CREATE TABLE "WorkspaceInvitation" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"email" TEXT NOT NULL,
"workspaceId" TEXT NOT NULL,
"type" "WorkspaceRole" NOT NULL,
CONSTRAINT "WorkspaceInvitation_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Workspace_stripeId_key" ON "Workspace"("stripeId");
-- CreateIndex
CREATE UNIQUE INDEX "MemberInWorkspace_userId_workspaceId_key" ON "MemberInWorkspace"("userId", "workspaceId");
-- AddForeignKey
ALTER TABLE "MemberInWorkspace" ADD CONSTRAINT "MemberInWorkspace_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MemberInWorkspace" ADD CONSTRAINT "MemberInWorkspace_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WorkspaceInvitation" ADD CONSTRAINT "WorkspaceInvitation_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CustomDomain" ADD CONSTRAINT "CustomDomain_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Credentials" ADD CONSTRAINT "Credentials_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "DashboardFolder" ADD CONSTRAINT "DashboardFolder_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Typebot" ADD CONSTRAINT "Typebot_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,50 @@
/*
Warnings:
- You are about to drop the column `ownerId` on the `Credentials` table. All the data in the column will be lost.
- You are about to drop the column `ownerId` on the `CustomDomain` table. All the data in the column will be lost.
- You are about to drop the column `ownerId` on the `DashboardFolder` table. All the data in the column will be lost.
- You are about to drop the column `ownerId` on the `Typebot` table. All the data in the column will be lost.
- You are about to drop the column `plan` on the `User` table. All the data in the column will be lost.
- You are about to drop the column `stripeId` on the `User` table. All the data in the column will be lost.
*/
-- DropForeignKey
ALTER TABLE "Credentials" DROP CONSTRAINT "Credentials_ownerId_fkey";
-- DropForeignKey
ALTER TABLE "CustomDomain" DROP CONSTRAINT "CustomDomain_ownerId_fkey";
-- DropForeignKey
ALTER TABLE "DashboardFolder" DROP CONSTRAINT "DashboardFolder_ownerId_fkey";
-- DropForeignKey
ALTER TABLE "Typebot" DROP CONSTRAINT "Typebot_ownerId_fkey";
-- DropIndex
DROP INDEX "Credentials_name_type_ownerId_key";
-- DropIndex
DROP INDEX "DashboardFolder_id_ownerId_key";
-- DropIndex
DROP INDEX "Typebot_id_ownerId_key";
-- DropIndex
DROP INDEX "User_stripeId_key";
-- AlterTable
ALTER TABLE "Credentials" DROP COLUMN "ownerId";
-- AlterTable
ALTER TABLE "CustomDomain" DROP COLUMN "ownerId";
-- AlterTable
ALTER TABLE "DashboardFolder" DROP COLUMN "ownerId";
-- AlterTable
ALTER TABLE "Typebot" DROP COLUMN "ownerId";
-- AlterTable
ALTER TABLE "User" DROP COLUMN "plan",
DROP COLUMN "stripeId";

View File

@ -0,0 +1,23 @@
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- CreateTable
CREATE TABLE "ApiToken" (
"id" TEXT NOT NULL,
"token" TEXT NOT NULL,
"name" TEXT NOT NULL,
"ownerId" TEXT NOT NULL,
"lastUsedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ApiToken_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "ApiToken_token_key" ON "ApiToken"("token");
-- AddForeignKey
ALTER TABLE "ApiToken" ADD CONSTRAINT "ApiToken_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
INSERT INTO "ApiToken" (id, "ownerId", token, name) SELECT uuid_generate_v4(), u.id, u."apiToken", 'Default' FROM "User" u;
ALTER TABLE "User" DROP COLUMN "apiToken";

View File

@ -0,0 +1,10 @@
-- DropIndex
DROP INDEX "PublicTypebot_customDomain_key";
-- DropIndex
DROP INDEX "PublicTypebot_publicId_key";
-- AlterTable
ALTER TABLE "PublicTypebot" DROP COLUMN "customDomain",
DROP COLUMN "name",
DROP COLUMN "publicId";

View File

@ -0,0 +1,20 @@
/*
Warnings:
- Made the column `workspaceId` on table `Credentials` required. This step will fail if there are existing NULL values in that column.
- Made the column `workspaceId` on table `CustomDomain` required. This step will fail if there are existing NULL values in that column.
- Made the column `workspaceId` on table `DashboardFolder` required. This step will fail if there are existing NULL values in that column.
- Made the column `workspaceId` on table `Typebot` required. This step will fail if there are existing NULL values in that column.
*/
-- AlterTable
ALTER TABLE "Credentials" ALTER COLUMN "workspaceId" SET NOT NULL;
-- AlterTable
ALTER TABLE "CustomDomain" ALTER COLUMN "workspaceId" SET NOT NULL;
-- AlterTable
ALTER TABLE "DashboardFolder" ALTER COLUMN "workspaceId" SET NOT NULL;
-- AlterTable
ALTER TABLE "Typebot" ALTER COLUMN "workspaceId" SET NOT NULL;

View File

@ -0,0 +1,33 @@
DROP INDEX "Answer_resultId_blockId_stepId_key";
ALTER TABLE "Answer"
RENAME COLUMN "stepId" TO "groupId";
ALTER TABLE "PublicTypebot"
RENAME COLUMN "blocks" TO "groups";
ALTER TABLE "PublicTypebot"
ALTER COLUMN groups TYPE JSONB USING to_json(groups);
ALTER TABLE "PublicTypebot"
ALTER COLUMN edges TYPE JSONB USING to_json(edges);
ALTER TABLE "Typebot"
RENAME COLUMN "blocks" TO "groups";
ALTER TABLE "Typebot"
ALTER COLUMN groups TYPE JSONB USING to_json(groups);
ALTER TABLE "Typebot"
ALTER COLUMN edges TYPE JSONB USING to_json(edges);
UPDATE "Typebot" t
SET groups = REPLACE(REPLACE(REPLACE(t.groups::text, '"blockId":', '"groupId":'), '"steps":', '"blocks":'), '"stepId":', '"blockId":')::jsonb,
edges = REPLACE(REPLACE(t.edges::text, '"blockId":', '"groupId":'), '"stepId":', '"blockId":')::jsonb;
UPDATE "PublicTypebot" t
SET groups = REPLACE(REPLACE(REPLACE(t.groups::text, '"blockId":', '"groupId":'), '"steps":', '"blocks":'), '"stepId":', '"blockId":')::jsonb,
edges = REPLACE(REPLACE(t.edges::text, '"blockId":', '"groupId":'), '"stepId":', '"blockId":')::jsonb;
-- CreateIndex
CREATE UNIQUE INDEX "Answer_resultId_blockId_groupId_key" ON "Answer"("resultId", "blockId", "groupId");

View File

@ -0,0 +1,22 @@
/*
Warnings:
- Made the column `groups` on table `PublicTypebot` required. This step will fail if there are existing NULL values in that column.
- Made the column `edges` on table `PublicTypebot` required. This step will fail if there are existing NULL values in that column.
- Made the column `groups` on table `Typebot` required. This step will fail if there are existing NULL values in that column.
- Made the column `edges` on table `Typebot` required. This step will fail if there are existing NULL values in that column.
*/
-- AlterTable
ALTER TABLE "Answer" ADD COLUMN "storageUsed" INTEGER;
-- AlterTable
ALTER TABLE "PublicTypebot" ALTER COLUMN "groups" SET NOT NULL,
ALTER COLUMN "edges" SET NOT NULL;
-- AlterTable
ALTER TABLE "Result" ADD COLUMN "hasStarted" BOOLEAN;
-- AlterTable
ALTER TABLE "Typebot" ALTER COLUMN "groups" SET NOT NULL,
ALTER COLUMN "edges" SET NOT NULL;

View File

@ -0,0 +1,5 @@
-- CreateIndex
CREATE INDEX "Answer_resultId_idx" ON "Answer"("resultId");
-- CreateIndex
CREATE INDEX "Log_resultId_idx" ON "Log"("resultId");

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Result" ADD COLUMN "isArchived" BOOLEAN;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Typebot" ADD COLUMN "resultsTablePreferences" JSONB;

View File

@ -0,0 +1,12 @@
-- Update old answers
UPDATE "Answer" a
SET "blockId" = a."groupId",
"groupId" = a."blockId"
WHERE "createdAt" < '2022-06-10 22:00:00 UTC'
AND NOT EXISTS (
SELECT 1
FROM "Answer"
WHERE "resultId" = a."resultId"
AND "blockId" = a."groupId"
AND "groupId" = a."blockId"
);

View File

@ -0,0 +1,18 @@
BEGIN;
UPDATE "Workspace" SET "plan" = 'PRO' WHERE "plan" = 'TEAM';
CREATE TYPE "Plan_new" AS ENUM ('FREE', 'STARTER', 'PRO', 'LIFETIME', 'OFFERED');
ALTER TABLE "Workspace" ALTER COLUMN "plan" DROP DEFAULT;
ALTER TABLE "Workspace" ALTER COLUMN "plan" TYPE "Plan_new" USING ("plan"::text::"Plan_new");
ALTER TYPE "Plan" RENAME TO "Plan_old";
ALTER TYPE "Plan_new" RENAME TO "Plan";
DROP TYPE "Plan_old";
ALTER TABLE "Workspace" ALTER COLUMN "plan" SET DEFAULT 'FREE';
UPDATE "Workspace" SET "plan" = 'STARTER' WHERE "plan" = 'PRO';
COMMIT;
ALTER TABLE "Workspace" ADD COLUMN "additionalChatsIndex" INTEGER NOT NULL DEFAULT 0,
ADD COLUMN "additionalStorageIndex" INTEGER NOT NULL DEFAULT 0,
ADD COLUMN "chatsLimitFirstEmailSentAt" TIMESTAMP(3),
ADD COLUMN "chatsLimitSecondEmailSentAt" TIMESTAMP(3),
ADD COLUMN "storageLimitFirstEmailSentAt" TIMESTAMP(3),
ADD COLUMN "storageLimitSecondEmailSentAt" TIMESTAMP(3);

View File

@ -0,0 +1,5 @@
-- DropForeignKey
ALTER TABLE "Result" DROP CONSTRAINT "Result_typebotId_fkey";
-- AddForeignKey
ALTER TABLE "Result" ADD CONSTRAINT "Result_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE NO ACTION ON UPDATE CASCADE;

View File

@ -0,0 +1,11 @@
-- DropForeignKey
ALTER TABLE "Result" DROP CONSTRAINT "Result_typebotId_fkey";
-- AlterTable
ALTER TABLE "Result" ALTER COLUMN "isArchived" SET DEFAULT false;
-- AlterTable
ALTER TABLE "Typebot" ADD COLUMN "isArchived" BOOLEAN NOT NULL DEFAULT false;
-- AddForeignKey
ALTER TABLE "Result" ADD CONSTRAINT "Result_typebotId_fkey" FOREIGN KEY ("typebotId") REFERENCES "Typebot"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Typebot" ADD COLUMN "isClosed" BOOLEAN NOT NULL DEFAULT false;

View File

@ -0,0 +1,2 @@
-- DropIndex
DROP INDEX "Answer_resultId_idx";

View File

@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX CONCURRENTLY "Result_typebotId_idx" ON "Result"("typebotId");

View File

@ -0,0 +1,30 @@
-- AlterEnum
ALTER TYPE "Plan" ADD VALUE 'CUSTOM';
-- AlterTable
ALTER TABLE "Workspace" ADD COLUMN "customChatsLimit" INTEGER,
ADD COLUMN "customSeatsLimit" INTEGER,
ADD COLUMN "customStorageLimit" INTEGER;
-- CreateTable
CREATE TABLE "ClaimableCustomPlan" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"claimedAt" TIMESTAMP(3),
"name" TEXT NOT NULL,
"description" TEXT,
"price" INTEGER NOT NULL,
"currency" TEXT NOT NULL,
"workspaceId" TEXT NOT NULL,
"chatsLimit" INTEGER NOT NULL,
"storageLimit" INTEGER NOT NULL,
"seatsLimit" INTEGER NOT NULL,
CONSTRAINT "ClaimableCustomPlan_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "ClaimableCustomPlan_workspaceId_key" ON "ClaimableCustomPlan"("workspaceId");
-- AddForeignKey
ALTER TABLE "ClaimableCustomPlan" ADD CONSTRAINT "ClaimableCustomPlan_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX CONCURRENTLY "Answer_groupId_idx" ON "Answer"("groupId");

View File

@ -0,0 +1,9 @@
-- CreateTable
CREATE TABLE "ChatSession" (
"id" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"state" JSONB NOT NULL,
CONSTRAINT "ChatSession_pkey" PRIMARY KEY ("id")
);

View File

@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX CONCURRENTLY "Typebot_workspaceId_idx" ON "Typebot"("workspaceId");

View File

@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX CONCURRENTLY "Result_createdAt_idx" ON "Result"("createdAt");

View File

@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX CONCURRENTLY "Result_hasStarted_idx" ON "Result"("hasStarted");

View File

@ -0,0 +1,23 @@
-- DropIndex
DROP INDEX IF EXISTS "Result_createdAt_idx";
-- DropIndex
DROP INDEX IF EXISTS "Result_hasStarted_idx";
-- DropIndex
DROP INDEX IF EXISTS "Result_typebotId_idx";
-- CreateIndex
CREATE INDEX IF NOT EXISTS "Answer_storageUsed_idx" ON "Answer"("storageUsed")
WHERE
"storageUsed" IS NOT NULL;
-- CreateIndex
CREATE INDEX IF NOT EXISTS "Result_typebotId_createdAt_idx" ON "Result"("typebotId", "createdAt" DESC NULLS LAST)
WHERE
"hasStarted" = true;
-- CreateIndex
CREATE INDEX IF NOT EXISTS "Result_createdAt_typebotId_idx" ON "Result"("createdAt" DESC NULLS LAST, "typebotId")
WHERE
"hasStarted" = true;

View File

@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX IF NOT EXISTS "Result_typebotId_idx" ON "Result"("typebotId");

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "preferredAppAppearance" TEXT;

View File

@ -0,0 +1,16 @@
-- Set background to white for all themes that have no background color set
UPDATE
"Typebot" t
SET
"theme" = jsonb_set(
jsonb_set(
t."theme",
'{general,background,type}',
'"Color"'
),
'{general,background,content}',
'"#FFFFFF"'
),
"updatedAt" = now()
WHERE
t."theme" -> 'general' -> 'background' ->> 'type' = 'None'

View File

@ -0,0 +1,2 @@
-- AlterEnum
ALTER TYPE "Plan" ADD VALUE 'UNLIMITED';

View File

@ -0,0 +1,8 @@
/*
Warnings:
- You are about to drop the column `publishedTypebotId` on the `Typebot` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "Typebot" DROP COLUMN "publishedTypebotId";

View File

@ -0,0 +1,26 @@
ALTER TABLE
"PublicTypebot"
ALTER COLUMN
variables TYPE JSONB USING array_to_json(variables);
ALTER TABLE
"Result"
ALTER COLUMN
variables TYPE JSONB USING array_to_json(variables);
ALTER TABLE
"Typebot"
ALTER COLUMN
variables TYPE JSONB USING array_to_json(variables);
ALTER TABLE
"User"
ALTER COLUMN
"onboardingCategories" TYPE JSONB USING array_to_json("onboardingCategories");
ALTER TABLE
"Webhook"
ALTER COLUMN
"queryParams" TYPE JSONB USING array_to_json("queryParams"),
ALTER COLUMN
"headers" TYPE JSONB USING array_to_json("headers");

View File

@ -0,0 +1,25 @@
set statement_timeout to 300000;
-- AlterTable
UPDATE "PublicTypebot" SET "variables" = '[]' WHERE "variables" IS NULL;
ALTER TABLE "PublicTypebot" ALTER COLUMN "variables" SET NOT NULL;
-- AlterTable
UPDATE "Result" SET "variables" = '[]' WHERE "variables" IS NULL;
ALTER TABLE "Result" ALTER COLUMN "variables" SET NOT NULL;
-- AlterTable
UPDATE "Typebot" SET "variables" = '[]' WHERE "variables" IS NULL;
ALTER TABLE "Typebot" ALTER COLUMN "variables" SET NOT NULL;
-- AlterTable
UPDATE "User" SET "onboardingCategories" = '[]' WHERE "onboardingCategories" IS NULL;
ALTER TABLE "User" ALTER COLUMN "onboardingCategories" SET NOT NULL;
-- AlterTable
UPDATE "Webhook" SET "queryParams" = '[]' WHERE "queryParams" IS NULL;
UPDATE "Webhook" SET "headers" = '[]' WHERE "headers" IS NULL;
ALTER TABLE "Webhook" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ALTER COLUMN "queryParams" SET NOT NULL,
ALTER COLUMN "headers" SET NOT NULL;

View File

@ -0,0 +1,25 @@
/*
Warnings:
- You are about to drop the column `lastUsedAt` on the `ApiToken` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "ApiToken" DROP COLUMN "lastUsedAt";
-- AlterTable
ALTER TABLE "CollaboratorsOnTypebots" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "Invitation" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "MemberInWorkspace" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "Workspace" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "WorkspaceInvitation" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

View File

@ -0,0 +1,11 @@
-- AlterTable
ALTER TABLE
"PublicTypebot"
ADD
COLUMN "version" TEXT;
-- AlterTable
ALTER TABLE
"Typebot"
ADD
COLUMN "version" TEXT;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Result" DROP COLUMN "updatedAt";

View File

@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"

View File

@ -0,0 +1,332 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
oauth_token_secret String?
oauth_token String?
refresh_token_expires_in Int?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
lastActivityAt DateTime @default(now())
name String?
email String? @unique
emailVerified DateTime?
image String?
company String?
onboardingCategories Json
graphNavigation GraphNavigation?
preferredAppAppearance String?
accounts Account[]
apiTokens ApiToken[]
CollaboratorsOnTypebots CollaboratorsOnTypebots[]
workspaces MemberInWorkspace[]
sessions Session[]
}
model ApiToken {
id String @id @default(cuid())
createdAt DateTime @default(now())
token String @unique
name String
ownerId String
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
}
model Workspace {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
name String
icon String?
plan Plan @default(FREE)
stripeId String? @unique
credentials Credentials[]
customDomains CustomDomain[]
folders DashboardFolder[]
members MemberInWorkspace[]
typebots Typebot[]
invitations WorkspaceInvitation[]
additionalChatsIndex Int @default(0)
additionalStorageIndex Int @default(0)
chatsLimitFirstEmailSentAt DateTime?
storageLimitFirstEmailSentAt DateTime?
chatsLimitSecondEmailSentAt DateTime?
storageLimitSecondEmailSentAt DateTime?
claimableCustomPlan ClaimableCustomPlan?
customChatsLimit Int?
customStorageLimit Int?
customSeatsLimit Int?
}
model MemberInWorkspace {
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
userId String
workspaceId String
role WorkspaceRole
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
@@unique([userId, workspaceId])
}
model WorkspaceInvitation {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
email String
workspaceId String
type WorkspaceRole
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
}
model CustomDomain {
name String @id
createdAt DateTime @default(now())
workspaceId String
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
}
model Credentials {
id String @id @default(cuid())
createdAt DateTime @default(now())
workspaceId String
data String
name String
type String
iv String
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
model DashboardFolder {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
name String
parentFolderId String?
workspaceId String
parentFolder DashboardFolder? @relation("ParentChild", fields: [parentFolderId], references: [id])
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
childrenFolder DashboardFolder[] @relation("ParentChild")
typebots Typebot[]
}
model Typebot {
id String @id @default(cuid())
version String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
icon String?
name String
folderId String?
groups Json
variables Json
edges Json
theme Json
settings Json
publicId String? @unique
customDomain String? @unique
workspaceId String
resultsTablePreferences Json?
folder DashboardFolder? @relation(fields: [folderId], references: [id])
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
collaborators CollaboratorsOnTypebots[]
invitations Invitation[]
publishedTypebot PublicTypebot?
results Result[]
webhooks Webhook[]
isArchived Boolean @default(false)
isClosed Boolean @default(false)
@@index([workspaceId])
@@index([isArchived, createdAt(sort: Desc)])
}
model Invitation {
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
email String
typebotId String
type CollaborationType
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
@@unique([email, typebotId])
}
model CollaboratorsOnTypebots {
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
userId String
typebotId String
type CollaborationType
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, typebotId])
}
model PublicTypebot {
id String @id @default(cuid())
version String?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
typebotId String @unique
groups Json
variables Json
edges Json
theme Json
settings Json
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
}
model Result {
id String @id @default(cuid())
createdAt DateTime @default(now())
typebotId String
variables Json
isCompleted Boolean
hasStarted Boolean?
isArchived Boolean? @default(false)
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
answers Answer[]
logs Log[]
@@index([typebotId, hasStarted, createdAt(sort: Desc)])
@@index([typebotId, isCompleted])
}
model Log {
id String @id @default(cuid())
createdAt DateTime @default(now())
resultId String
status String
description String
details String?
result Result @relation(fields: [resultId], references: [id], onDelete: Cascade)
@@index([resultId])
}
model Answer {
createdAt DateTime @default(now()) @updatedAt
resultId String
blockId String
groupId String
variableId String?
content String
storageUsed Int?
result Result @relation(fields: [resultId], references: [id], onDelete: Cascade)
@@unique([resultId, blockId, groupId])
@@index([groupId])
@@index([storageUsed])
}
model Coupon {
userPropertiesToUpdate Json
code String @id @unique
dateRedeemed DateTime?
}
model Webhook {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
url String?
method String
queryParams Json
headers Json
body String?
typebotId String
typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
}
model ClaimableCustomPlan {
id String @id @default(cuid())
createdAt DateTime @default(now())
claimedAt DateTime?
name String
description String?
price Int
currency String
workspaceId String @unique
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
chatsLimit Int
storageLimit Int
seatsLimit Int
}
model ChatSession {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
state Json
}
enum WorkspaceRole {
ADMIN
MEMBER
GUEST
}
enum GraphNavigation {
MOUSE
TRACKPAD
}
enum Plan {
FREE
STARTER
PRO
LIFETIME
OFFERED
CUSTOM
UNLIMITED
}
enum CollaborationType {
READ
WRITE
FULL_ACCESS
}

View File

@ -0,0 +1,3 @@
import { executePrismaCommand } from './executeCommand'
executePrismaCommand('prisma generate', { force: true })

View File

@ -0,0 +1,3 @@
import { executePrismaCommand } from './executeCommand'
executePrismaCommand('prisma db push --skip-generate')

View File

@ -0,0 +1,48 @@
import { exec } from 'child_process'
import { join } from 'path'
require('dotenv').config({
override: true,
path: join(__dirname, `../.env`),
})
const postgesqlSchemaPath = join(__dirname, '../postgresql/schema.prisma')
const mysqlSchemaPath = join(__dirname, '../mysql/schema.prisma')
type Options = {
force?: boolean
}
export const executePrismaCommand = (command: string, options?: Options) => {
const databaseUrl =
process.env.DATABASE_URL ?? (options?.force ? 'postgresql://' : undefined)
if (!databaseUrl) {
console.error('Could not find DATABASE_URL in environment')
return
}
if (databaseUrl?.startsWith('mysql://')) {
console.log('Executing for MySQL schema')
executeCommand(`${command} --schema ${mysqlSchemaPath}`)
}
if (databaseUrl?.startsWith('postgresql://')) {
console.log('Executing for PostgreSQL schema')
executeCommand(`${command} --schema ${postgesqlSchemaPath}`)
}
}
const executeCommand = (command: string) => {
exec(command, (error, stdout, stderr) => {
if (error) {
console.log(error.message)
return
}
if (stderr) {
console.log(stderr)
return
}
console.log(stdout)
})
}

View File

@ -0,0 +1,4 @@
import { executePrismaCommand } from './executeCommand'
if (process.env.DATABASE_URL?.startsWith('postgresql://'))
executePrismaCommand('prisma migrate deploy')

View File

@ -0,0 +1,4 @@
import { executePrismaCommand } from './executeCommand'
if (process.env.DATABASE_URL?.startsWith('postgresql://'))
executePrismaCommand('prisma migrate dev --create-only')

View File

@ -0,0 +1,3 @@
import { executePrismaCommand } from './executeCommand'
executePrismaCommand('cross-env BROWSER=none prisma studio')

View File

@ -0,0 +1,5 @@
{
"extends": "@typebot.io/tsconfig/base.json",
"include": ["**/*.ts"],
"exclude": ["node_modules"]
}