diff --git a/.env.example b/.env.example index 9325f3abc..a5321cfc0 100644 --- a/.env.example +++ b/.env.example @@ -27,13 +27,17 @@ EVENT_EMITTER_MAX_LISTENERS=50 # If you don't even want an expiration, enter the value false DEL_INSTANCE=false -# Provider: postgresql | mysql +# Provider: postgresql | mysql | psql_bouncer DATABASE_PROVIDER=postgresql -DATABASE_CONNECTION_URI='postgresql://user:pass@postgres:5432/evolution?schema=public' +DATABASE_CONNECTION_URI='postgresql://user:pass@postgres:5432/evolution_db?schema=evolution_api' # Client name for the database connection # It is used to separate an API installation from another that uses the same database. DATABASE_CONNECTION_CLIENT_NAME=evolution_exchange +# Bouncer connection: used only when the database provider is set to 'psql_bouncer'. +# Defines the PostgreSQL URL with pgbouncer enabled (pgbouncer=true). +# DATABASE_BOUNCER_CONNECTION_URI=postgresql://user:pass@pgbouncer:5432/evolution_db?pgbouncer=true&schema=evolution_api + # Choose the data you want to save in the application's database DATABASE_SAVE_DATA_INSTANCE=true DATABASE_SAVE_DATA_NEW_MESSAGE=true diff --git a/Docker/scripts/deploy_database.sh b/Docker/scripts/deploy_database.sh index fde46d120..fea58ff85 100755 --- a/Docker/scripts/deploy_database.sh +++ b/Docker/scripts/deploy_database.sh @@ -6,7 +6,7 @@ if [ "$DOCKER_ENV" != "true" ]; then export_env_vars fi -if [[ "$DATABASE_PROVIDER" == "postgresql" || "$DATABASE_PROVIDER" == "mysql" ]]; then +if [[ "$DATABASE_PROVIDER" == "postgresql" || "$DATABASE_PROVIDER" == "mysql" || "$DATABASE_PROVIDER" == "psql_bouncer" ]]; then export DATABASE_URL echo "Deploying migrations for $DATABASE_PROVIDER" echo "Database URL: $DATABASE_URL" diff --git a/Docker/scripts/generate_database.sh b/Docker/scripts/generate_database.sh index 892682ef5..248c6cf23 100644 --- a/Docker/scripts/generate_database.sh +++ b/Docker/scripts/generate_database.sh @@ -6,7 +6,7 @@ if [ "$DOCKER_ENV" != "true" ]; then export_env_vars fi -if [[ "$DATABASE_PROVIDER" == "postgresql" || "$DATABASE_PROVIDER" == "mysql" ]]; then +if [[ "$DATABASE_PROVIDER" == "postgresql" || "$DATABASE_PROVIDER" == "mysql" || "$DATABASE_PROVIDER" == "psql_bouncer" ]]; then export DATABASE_URL echo "Generating database for $DATABASE_PROVIDER" echo "Database URL: $DATABASE_URL" @@ -20,4 +20,4 @@ if [[ "$DATABASE_PROVIDER" == "postgresql" || "$DATABASE_PROVIDER" == "mysql" ]] else echo "Error: Database provider $DATABASE_PROVIDER invalid." exit 1 -fi +fi \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 33918c383..1bdd557ca 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,4 +1,5 @@ services: + api: container_name: evolution_api image: evoapicloud/evolution-api:latest @@ -34,19 +35,41 @@ services: image: postgres:15 networks: - evolution-net - command: ["postgres", "-c", "max_connections=1000", "-c", "listen_addresses=*"] + command: [ + "postgres", + "-c", "max_connections=200", + "-c", "listen_addresses=*", + "-c", "shared_buffers=256MB", + "-c", "effective_cache_size=1GB", + "-c", "work_mem=4MB" + ] restart: always ports: - 5432:5432 environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - - POSTGRES_DB=evolution + - POSTGRES_DB=evolution_db - POSTGRES_HOST_AUTH_METHOD=trust volumes: - - postgres_data:/var/lib/postgresql/data - expose: - - 5432 + - postgres_data:/var/lib/postgresql/data + + # pgbouncer: + # image: edoburu/pgbouncer:latest + # environment: + # DB_HOST: postgres + # DB_USER: user + # DB_PASSWORD: pass + # POOL_MODE: transaction + # AUTH_TYPE: trust + # MAX_CLIENT_CONN: 1000 + # DEFAULT_POOL_SIZE: 25 + # depends_on: + # - postgres + # ports: + # - "6543:5432" + # networks: + # - evolution-net volumes: evolution_instances: diff --git a/prisma/postgresql-schema.prisma b/prisma/postgresql-schema.prisma index 7d2410e9c..221d69d9d 100644 --- a/prisma/postgresql-schema.prisma +++ b/prisma/postgresql-schema.prisma @@ -376,8 +376,8 @@ model TypebotSetting { debounceTime Int? @db.Integer typebotIdFallback String? @db.VarChar(100) ignoreJids Json? - splitMessages Boolean? @default(false) @db.Boolean - timePerChar Int? @default(50) @db.Integer + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer createdAt DateTime? @default(now()) @db.Timestamp updatedAt DateTime @updatedAt @db.Timestamp Fallback Typebot? @relation(fields: [typebotIdFallback], references: [id]) @@ -748,4 +748,4 @@ model EvoaiSetting { evoaiIdFallback String? @db.VarChar(100) Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique -} \ No newline at end of file +} diff --git a/prisma/psql_bouncer-schema.prisma b/prisma/psql_bouncer-schema.prisma new file mode 100644 index 000000000..4754f1656 --- /dev/null +++ b/prisma/psql_bouncer-schema.prisma @@ -0,0 +1,752 @@ +// This is your Prisma schema file, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? +// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init + +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_BOUNCER_CONNECTION_URI") + directUrl = env("DATABASE_CONNECTION_URI") +} + +enum InstanceConnectionStatus { + open + close + connecting +} + +enum DeviceMessage { + ios + android + web + unknown + desktop +} + +enum SessionStatus { + opened + closed + paused +} + +enum TriggerType { + all + keyword + none + advanced +} + +enum TriggerOperator { + contains + equals + startsWith + endsWith + regex +} + +enum OpenaiBotType { + assistant + chatCompletion +} + +enum DifyBotType { + chatBot + textGenerator + agent + workflow +} + +model Instance { + id String @id @default(cuid()) + name String @unique @db.VarChar(255) + connectionStatus InstanceConnectionStatus @default(open) + ownerJid String? @db.VarChar(100) + profileName String? @db.VarChar(100) + profilePicUrl String? @db.VarChar(500) + integration String? @db.VarChar(100) + number String? @db.VarChar(100) + businessId String? @db.VarChar(100) + token String? @db.VarChar(255) + clientName String? @db.VarChar(100) + disconnectionReasonCode Int? @db.Integer + disconnectionObject Json? @db.JsonB + disconnectionAt DateTime? @db.Timestamp + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime? @updatedAt @db.Timestamp + Chat Chat[] + Contact Contact[] + Message Message[] + Webhook Webhook? + Chatwoot Chatwoot? + Label Label[] + Proxy Proxy? + Setting Setting? + Rabbitmq Rabbitmq? + Nats Nats? + Sqs Sqs? + Websocket Websocket? + Typebot Typebot[] + Session Session? + MessageUpdate MessageUpdate[] + TypebotSetting TypebotSetting? + Media Media[] + OpenaiCreds OpenaiCreds[] + OpenaiBot OpenaiBot[] + OpenaiSetting OpenaiSetting? + Template Template[] + Dify Dify[] + DifySetting DifySetting? + IntegrationSession IntegrationSession[] + EvolutionBot EvolutionBot[] + EvolutionBotSetting EvolutionBotSetting? + Flowise Flowise[] + FlowiseSetting FlowiseSetting? + Pusher Pusher? + N8n N8n[] + N8nSetting N8nSetting[] + Evoai Evoai[] + EvoaiSetting EvoaiSetting? +} + +model Session { + id String @id @default(cuid()) + sessionId String @unique + creds String? @db.Text + createdAt DateTime @default(now()) @db.Timestamp + Instance Instance @relation(fields: [sessionId], references: [id], onDelete: Cascade) +} + +model Chat { + id String @id @default(cuid()) + remoteJid String @db.VarChar(100) + name String? @db.VarChar(100) + labels Json? @db.JsonB + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime? @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + unreadMessages Int @default(0) + + @@index([instanceId]) + @@index([remoteJid]) +} + +model Contact { + id String @id @default(cuid()) + remoteJid String @db.VarChar(100) + pushName String? @db.VarChar(100) + profilePicUrl String? @db.VarChar(500) + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime? @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + + @@unique([remoteJid, instanceId]) + @@index([remoteJid]) + @@index([instanceId]) +} + +model Message { + id String @id @default(cuid()) + key Json @db.JsonB + pushName String? @db.VarChar(100) + participant String? @db.VarChar(100) + messageType String @db.VarChar(100) + message Json @db.JsonB + contextInfo Json? @db.JsonB + source DeviceMessage + messageTimestamp Int @db.Integer + chatwootMessageId Int? @db.Integer + chatwootInboxId Int? @db.Integer + chatwootConversationId Int? @db.Integer + chatwootContactInboxSourceId String? @db.VarChar(100) + chatwootIsRead Boolean? @db.Boolean + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + MessageUpdate MessageUpdate[] + Media Media? + webhookUrl String? @db.VarChar(500) + status String? @db.VarChar(30) + + sessionId String? + session IntegrationSession? @relation(fields: [sessionId], references: [id]) + + @@index([instanceId]) +} + +model MessageUpdate { + id String @id @default(cuid()) + keyId String @db.VarChar(100) + remoteJid String @db.VarChar(100) + fromMe Boolean @db.Boolean + participant String? @db.VarChar(100) + pollUpdates Json? @db.JsonB + status String @db.VarChar(30) + Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade) + messageId String + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + + @@index([instanceId]) + @@index([messageId]) +} + +model Webhook { + id String @id @default(cuid()) + url String @db.VarChar(500) + headers Json? @db.JsonB + enabled Boolean? @default(true) @db.Boolean + events Json? @db.JsonB + webhookByEvents Boolean? @default(false) @db.Boolean + webhookBase64 Boolean? @default(false) @db.Boolean + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique + + @@index([instanceId]) +} + +model Chatwoot { + id String @id @default(cuid()) + enabled Boolean? @default(true) @db.Boolean + accountId String? @db.VarChar(100) + token String? @db.VarChar(100) + url String? @db.VarChar(500) + nameInbox String? @db.VarChar(100) + signMsg Boolean? @default(false) @db.Boolean + signDelimiter String? @db.VarChar(100) + number String? @db.VarChar(100) + reopenConversation Boolean? @default(false) @db.Boolean + conversationPending Boolean? @default(false) @db.Boolean + mergeBrazilContacts Boolean? @default(false) @db.Boolean + importContacts Boolean? @default(false) @db.Boolean + importMessages Boolean? @default(false) @db.Boolean + daysLimitImportMessages Int? @db.Integer + organization String? @db.VarChar(100) + logo String? @db.VarChar(500) + ignoreJids Json? + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Label { + id String @id @default(cuid()) + labelId String? @db.VarChar(100) + name String @db.VarChar(100) + color String @db.VarChar(100) + predefinedId String? @db.VarChar(100) + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + + @@unique([labelId, instanceId]) +} + +model Proxy { + id String @id @default(cuid()) + enabled Boolean @default(false) @db.Boolean + host String @db.VarChar(100) + port String @db.VarChar(100) + protocol String @db.VarChar(100) + username String @db.VarChar(100) + password String @db.VarChar(100) + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Setting { + id String @id @default(cuid()) + rejectCall Boolean @default(false) @db.Boolean + msgCall String? @db.VarChar(100) + groupsIgnore Boolean @default(false) @db.Boolean + alwaysOnline Boolean @default(false) @db.Boolean + readMessages Boolean @default(false) @db.Boolean + readStatus Boolean @default(false) @db.Boolean + syncFullHistory Boolean @default(false) @db.Boolean + wavoipToken String? @db.VarChar(100) + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique + + @@index([instanceId]) +} + +model Rabbitmq { + id String @id @default(cuid()) + enabled Boolean @default(false) @db.Boolean + events Json @db.JsonB + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Nats { + id String @id @default(cuid()) + enabled Boolean @default(false) @db.Boolean + events Json @db.JsonB + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Sqs { + id String @id @default(cuid()) + enabled Boolean @default(false) @db.Boolean + events Json @db.JsonB + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Websocket { + id String @id @default(cuid()) + enabled Boolean @default(false) @db.Boolean + events Json @db.JsonB + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Pusher { + id String @id @default(cuid()) + enabled Boolean @default(false) @db.Boolean + appId String @db.VarChar(100) + key String @db.VarChar(100) + secret String @db.VarChar(100) + cluster String @db.VarChar(100) + useTLS Boolean @default(false) @db.Boolean + events Json @db.JsonB + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Typebot { + id String @id @default(cuid()) + enabled Boolean @default(true) @db.Boolean + description String? @db.VarChar(255) + url String @db.VarChar(500) + typebot String @db.VarChar(100) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime? @updatedAt @db.Timestamp + ignoreJids Json? + triggerType TriggerType? + triggerOperator TriggerOperator? + triggerValue String? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + TypebotSetting TypebotSetting[] +} + +model TypebotSetting { + id String @id @default(cuid()) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + typebotIdFallback String? @db.VarChar(100) + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Fallback Typebot? @relation(fields: [typebotIdFallback], references: [id]) + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Media { + id String @id @default(cuid()) + fileName String @db.VarChar(500) + type String @db.VarChar(100) + mimetype String @db.VarChar(100) + createdAt DateTime? @default(now()) @db.Date + Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade) + messageId String @unique + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String +} + +model OpenaiCreds { + id String @id @default(cuid()) + name String? @unique @db.VarChar(255) + apiKey String? @unique @db.VarChar(255) + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + OpenaiAssistant OpenaiBot[] + OpenaiSetting OpenaiSetting? +} + +model OpenaiBot { + id String @id @default(cuid()) + enabled Boolean @default(true) @db.Boolean + description String? @db.VarChar(255) + botType OpenaiBotType + assistantId String? @db.VarChar(255) + functionUrl String? @db.VarChar(500) + model String? @db.VarChar(100) + systemMessages Json? @db.JsonB + assistantMessages Json? @db.JsonB + userMessages Json? @db.JsonB + maxTokens Int? @db.Integer + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + ignoreJids Json? + triggerType TriggerType? + triggerOperator TriggerOperator? + triggerValue String? + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + OpenaiCreds OpenaiCreds @relation(fields: [openaiCredsId], references: [id], onDelete: Cascade) + openaiCredsId String + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + OpenaiSetting OpenaiSetting[] +} + +model IntegrationSession { + id String @id @default(cuid()) + sessionId String @db.VarChar(255) + remoteJid String @db.VarChar(100) + pushName String? + status SessionStatus + awaitUser Boolean @default(false) @db.Boolean + context Json? + type String? @db.VarChar(100) + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Message Message[] + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + parameters Json? @db.JsonB + + botId String? +} + +model OpenaiSetting { + id String @id @default(cuid()) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + speechToText Boolean? @default(false) @db.Boolean + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + OpenaiCreds OpenaiCreds? @relation(fields: [openaiCredsId], references: [id]) + openaiCredsId String @unique + Fallback OpenaiBot? @relation(fields: [openaiIdFallback], references: [id]) + openaiIdFallback String? @db.VarChar(100) + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Template { + id String @id @default(cuid()) + templateId String @unique @db.VarChar(255) + name String @unique @db.VarChar(255) + template Json @db.JsonB + webhookUrl String? @db.VarChar(500) + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String +} + +model Dify { + id String @id @default(cuid()) + enabled Boolean @default(true) @db.Boolean + description String? @db.VarChar(255) + botType DifyBotType + apiUrl String? @db.VarChar(255) + apiKey String? @db.VarChar(255) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + triggerType TriggerType? + triggerOperator TriggerOperator? + triggerValue String? + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + DifySetting DifySetting[] +} + +model DifySetting { + id String @id @default(cuid()) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Fallback Dify? @relation(fields: [difyIdFallback], references: [id]) + difyIdFallback String? @db.VarChar(100) + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model EvolutionBot { + id String @id @default(cuid()) + enabled Boolean @default(true) @db.Boolean + description String? @db.VarChar(255) + apiUrl String? @db.VarChar(255) + apiKey String? @db.VarChar(255) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + triggerType TriggerType? + triggerOperator TriggerOperator? + triggerValue String? + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + EvolutionBotSetting EvolutionBotSetting[] +} + +model EvolutionBotSetting { + id String @id @default(cuid()) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Fallback EvolutionBot? @relation(fields: [botIdFallback], references: [id]) + botIdFallback String? @db.VarChar(100) + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Flowise { + id String @id @default(cuid()) + enabled Boolean @default(true) @db.Boolean + description String? @db.VarChar(255) + apiUrl String? @db.VarChar(255) + apiKey String? @db.VarChar(255) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + triggerType TriggerType? + triggerOperator TriggerOperator? + triggerValue String? + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + FlowiseSetting FlowiseSetting[] +} + +model FlowiseSetting { + id String @id @default(cuid()) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Fallback Flowise? @relation(fields: [flowiseIdFallback], references: [id]) + flowiseIdFallback String? @db.VarChar(100) + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model IsOnWhatsapp { + id String @id @default(cuid()) + remoteJid String @unique @db.VarChar(100) + jidOptions String + lid String? @db.VarChar(100) + createdAt DateTime @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp +} + +model N8n { + id String @id @default(cuid()) + enabled Boolean @default(true) @db.Boolean + description String? @db.VarChar(255) + webhookUrl String? @db.VarChar(255) + basicAuthUser String? @db.VarChar(255) + basicAuthPass String? @db.VarChar(255) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + triggerType TriggerType? + triggerOperator TriggerOperator? + triggerValue String? + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + N8nSetting N8nSetting[] +} + +model N8nSetting { + id String @id @default(cuid()) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Fallback N8n? @relation(fields: [n8nIdFallback], references: [id]) + n8nIdFallback String? @db.VarChar(100) + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} + +model Evoai { + id String @id @default(cuid()) + enabled Boolean @default(true) @db.Boolean + description String? @db.VarChar(255) + agentUrl String? @db.VarChar(255) + apiKey String? @db.VarChar(255) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + triggerType TriggerType? + triggerOperator TriggerOperator? + triggerValue String? + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String + EvoaiSetting EvoaiSetting[] +} + +model EvoaiSetting { + id String @id @default(cuid()) + expire Int? @default(0) @db.Integer + keywordFinish String? @db.VarChar(100) + delayMessage Int? @db.Integer + unknownMessage String? @db.VarChar(100) + listeningFromMe Boolean? @default(false) @db.Boolean + stopBotFromMe Boolean? @default(false) @db.Boolean + keepOpen Boolean? @default(false) @db.Boolean + debounceTime Int? @db.Integer + ignoreJids Json? + splitMessages Boolean? @default(false) @db.Boolean + timePerChar Int? @default(50) @db.Integer + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp + Fallback Evoai? @relation(fields: [evoaiIdFallback], references: [id]) + evoaiIdFallback String? @db.VarChar(100) + Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) + instanceId String @unique +} diff --git a/runWithProvider.js b/runWithProvider.js index 154538be9..b4f0dabb1 100644 --- a/runWithProvider.js +++ b/runWithProvider.js @@ -11,11 +11,28 @@ if (!DATABASE_PROVIDER) { console.warn(`DATABASE_PROVIDER is not set in the .env file, using default: ${databaseProviderDefault}`); } +// Função para determinar qual pasta de migrations usar +// Função para determinar qual pasta de migrations usar +function getMigrationsFolder(provider) { + switch (provider) { + case 'psql_bouncer': + return 'postgresql-migrations'; // psql_bouncer usa as migrations do postgresql + default: + return `${provider}-migrations`; + } +} + +const migrationsFolder = getMigrationsFolder(databaseProviderDefault); + let command = process.argv .slice(2) .join(' ') .replace(/DATABASE_PROVIDER/g, databaseProviderDefault); +// Substituir referências à pasta de migrations pela pasta correta +const migrationsPattern = new RegExp(`${databaseProviderDefault}-migrations`, 'g'); +command = command.replace(migrationsPattern, migrationsFolder); + if (command.includes('rmdir') && existsSync('prisma\\migrations')) { try { execSync('rmdir /S /Q prisma\\migrations', { stdio: 'inherit' }); @@ -32,4 +49,4 @@ try { } catch (error) { console.error(`Error executing command: ${command}`); process.exit(1); -} +} \ No newline at end of file