From 2ed1e08d0d76af36fb2345c76180e7eaff7f4837 Mon Sep 17 00:00:00 2001
From: Hung Phan Viet
Date: Sat, 14 Nov 2026 10:15:00 +0700
Subject: [PATCH 1/6] fix(messaging): handle blocked accounts, contact scan
limits and failed sends
---
.../public-spec-operations.test.ts.snap | 10 +
.../__tests__/api-parity-manifest.json | 3 +
.../authorize-workspace-access.test.ts | 16 +
...oadcast-public-resource-send-limit.test.ts | 47 +
.../broadcast-status-reason.test.tsx | 69 +
.../cancel-contact-scan-action.test.ts | 89 +
.../cancel-contact-scan-button.test.tsx | 194 +
.../__tests__/chat-layout-mobile.test.tsx | 4 +
apps/builder/__tests__/chat-realtime.test.tsx | 22 +
apps/builder/__tests__/chat-store.test.ts | 115 +
.../__tests__/contact-scan-form.test.tsx | 3 +
.../__tests__/contact-scan-public-api.test.ts | 49 +-
.../__tests__/disconnect-meta-actions.test.ts | 10 +
.../message-input-client-id.test.tsx | 248 +-
.../message-input-thread-control.test.tsx | 4 +
.../message-item-send-error.test.tsx | 120 +
apps/builder/__tests__/message-list.test.tsx | 3 +
.../__tests__/messages-public-api.test.ts | 53 +
.../builder/__tests__/public-spec-mcp.test.ts | 1 +
.../__tests__/resend-message-button.test.tsx | 187 +
.../resume-broadcast-dialog.test.tsx | 54 +-
.../__tests__/send-queue-notice.test.tsx | 77 +
apps/builder/messages/ar.json | 36 +-
apps/builder/messages/az.json | 36 +-
apps/builder/messages/da.json | 36 +-
apps/builder/messages/de.json | 36 +-
apps/builder/messages/en.json | 36 +-
apps/builder/messages/es.json | 36 +-
apps/builder/messages/fi.json | 36 +-
apps/builder/messages/fr.json | 36 +-
apps/builder/messages/he.json | 36 +-
apps/builder/messages/id.json | 36 +-
apps/builder/messages/it.json | 36 +-
apps/builder/messages/ja.json | 36 +-
apps/builder/messages/nl.json | 36 +-
apps/builder/messages/pt-BR.json | 36 +-
apps/builder/messages/pt-PT.json | 36 +-
apps/builder/messages/ro.json | 36 +-
apps/builder/messages/sv.json | 36 +-
apps/builder/messages/tr.json | 36 +-
apps/builder/messages/vi.json | 36 +-
apps/builder/messages/zh-CN.json | 36 +-
apps/builder/messages/zh-TW.json | 36 +-
.../src/features/broadcasts/api/public.ts | 4 +-
.../broadcasts/broadcast-detail-dialog.tsx | 14 +-
.../features/broadcasts/broadcasts-table.tsx | 14 +-
.../components/broadcast-runs-view.tsx | 2 +
.../components/broadcast-status-reason.tsx | 41 +
.../components/resume-broadcast-dialog.tsx | 76 +-
.../features/broadcasts/schema/resource.ts | 19 +
.../builder/src/features/chat/chat-layout.tsx | 2 +
.../src/features/chat/chat-realtime.tsx | 4 +
.../src/features/chat/store/chat-store.ts | 88 +
.../actions/cancel-contact-scan.action.ts | 39 +
.../src/features/contact-scan/api/public.ts | 23 +
.../components/cancel-contact-scan-button.tsx | 101 +
.../components/contact-scan-form.tsx | 13 +
.../components/contact-scan-status-panel.tsx | 17 +-
.../contact-scan/lib/contact-scan-history.ts | 8 +-
.../lib/get-contact-scan-status.ts | 17 +-
.../features/contact-scan/lib/status-copy.ts | 1 +
.../features/contact-scan/schema/action.ts | 12 +
.../features/contact-scan/schema/public.ts | 17 +
.../src/features/contact-scan/schema/query.ts | 13 +-
.../actions/disconnect-instagram.ts | 9 +
.../messages/actions/resend-message.action.ts | 34 +
.../src/features/messages/api/public.ts | 25 +
.../messages/components/message-input.tsx | 167 +-
.../messages/components/message-item.tsx | 14 +-
.../components/resend-message-button.tsx | 96 +
.../messages/components/send-queue-notice.tsx | 65 +
.../messages/components/send-queue-runner.tsx | 57 +
.../messages/lib/__tests__/send-queue.test.ts | 359 +
.../src/features/messages/lib/send-queue.ts | 321 +
.../messages/lib/use-send-queue-runner.ts | 118 +
.../src/features/messages/message-list.tsx | 4 +
.../src/features/messages/schema/mutation.ts | 9 +
.../src/features/messages/schema/public.ts | 7 +
.../components/item/item-conversation.tsx | 2 +
.../builder/src/lib/orpc/orpc-error-helper.ts | 12 +
.../workspace/authorize-workspace-access.ts | 9 +
apps/cli/README.md | 2 +
.../__tests__/account-send-blocked.test.ts | 190 +
.../__tests__/contact-scan-engine.test.ts | 287 +-
.../contact-scan-graph-error.test.ts | 199 +-
.../contact-scan-instagram-adapter.test.ts | 226 +-
.../contact-scan-messenger-adapter.test.ts | 156 +-
.../__tests__/contact-scan-pacing.test.ts | 70 +
.../__tests__/send-message-handler.test.ts | 172 +
.../src/chat/handlers/account-send-blocked.ts | 91 +
.../channel-send-error-reconcilers.ts | 18 +-
.../chat/handlers/channel-send-error-types.ts | 3 +
.../messenger-thread-control-rejection.ts | 11 +-
apps/worker/src/chat/handlers/send-message.ts | 330 +-
.../handlers/contact-scan/adapter.ts | 46 +-
.../contact-scan/adapters/instagram.ts | 62 +-
.../contact-scan/adapters/messenger.ts | 37 +-
.../handlers/contact-scan/engine.ts | 265 +-
.../handlers/contact-scan/graph-error.ts | 181 +-
.../handlers/contact-scan/pacing.ts | 55 +
.../handlers/contact-scan/usage-signal.ts | 69 +
docs/broadcasts.md | 31 +
docs/contact-scan.md | 66 +-
.../__tests__/error-mapper-reason.test.ts | 59 +
.../src/lib/error-mapper.ts | 46 +-
.../__tests__/error-mapper-reason.test.ts | 59 +
.../instagram/src/lib/error-mapper.ts | 44 +-
.../messenger/__tests__/error-mapper.test.ts | 57 +-
.../messenger/__tests__/usage-minutes.test.ts | 37 +
integrations/messenger/src/apis/usage.ts | 10 +
.../src/handlers/bulk-thread-control.ts | 5 +-
.../messenger/src/lib/error-mapper.ts | 53 +-
.../__tests__/error-mapper-reason.test.ts | 38 +
integrations/whatsapp/src/lib/error-mapper.ts | 14 +
.../__tests__/error-mapper-reason.test.ts | 27 +
integrations/zalo/src/lib/error-mapper.ts | 12 +
.../broadcast-service-transitions.test.ts | 3 +
.../__tests__/contact-scan-run-status.test.ts | 52 +
.../__tests__/contact-scan.service.test.ts | 146 +-
.../broadcast-stop-blocked-account-db.test.ts | 389 +
.../__tests__/message-create-outgoing.test.ts | 132 +-
.../__tests__/message-resend-outgoing.test.ts | 281 +
packages/business/src/broadcast/service.ts | 143 +-
.../business/src/broadcast/status-reason.ts | 32 +
.../business/src/contact-scan/constants.ts | 15 +-
packages/business/src/contact-scan/index.ts | 1 +
.../business/src/contact-scan/run-status.ts | 26 +
packages/business/src/contact-scan/service.ts | 111 +-
.../business/src/message/create-outgoing.ts | 87 +-
.../business/src/message/resend-outgoing.ts | 136 +
packages/business/src/message/service.ts | 2 +
.../__tests__/messenger-teardown.test.ts | 8 +
.../connections/src/messenger-teardown.ts | 6 +
.../coexist-sync-run-type-scoping.test.ts | 32 +
.../integration/contact-scan-cancel.test.ts | 196 +
.../contact-scan-retry-or-fail.test.ts | 180 +
.../message-resendable-partial.test.ts | 69 +
.../sharded-message-repository.test.ts | 81 +
.../migration.sql | 4 +
.../snapshot.json | 77911 ++++++++++++++++
packages/database/src/partials/broadcast.ts | 14 +
.../database/src/partials/coexist-sync-run.ts | 16 +-
packages/database/src/partials/message.ts | 58 +
packages/database/src/relations/broadcast.ts | 6 +
.../src/repositories/broadcast/repository.ts | 109 +-
.../coexist-sync-run/repository.ts | 111 +
.../message/message-repository.ts | 13 +
packages/database/src/schema/broadcast.ts | 12 +
.../repository/sharded-message-repository.ts | 15 +
.../__tests__/channel-error-reason.test.ts | 76 +
packages/sdk/src/lib/channel-error-codes.ts | 33 +
packages/sdk/src/lib/channel-error.ts | 11 +
packages/sdk/src/lib/schemas.ts | 2 +
.../__tests__/contact-scan-job-ids.test.ts | 56 +
.../integration/contact-scan-job-ids.ts | 13 +-
155 files changed, 86504 insertions(+), 1079 deletions(-)
create mode 100644 apps/builder/__tests__/broadcast-status-reason.test.tsx
create mode 100644 apps/builder/__tests__/cancel-contact-scan-action.test.ts
create mode 100644 apps/builder/__tests__/cancel-contact-scan-button.test.tsx
create mode 100644 apps/builder/__tests__/resend-message-button.test.tsx
create mode 100644 apps/builder/__tests__/send-queue-notice.test.tsx
create mode 100644 apps/builder/src/features/broadcasts/components/broadcast-status-reason.tsx
create mode 100644 apps/builder/src/features/contact-scan/actions/cancel-contact-scan.action.ts
create mode 100644 apps/builder/src/features/contact-scan/components/cancel-contact-scan-button.tsx
create mode 100644 apps/builder/src/features/messages/actions/resend-message.action.ts
create mode 100644 apps/builder/src/features/messages/components/resend-message-button.tsx
create mode 100644 apps/builder/src/features/messages/components/send-queue-notice.tsx
create mode 100644 apps/builder/src/features/messages/components/send-queue-runner.tsx
create mode 100644 apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts
create mode 100644 apps/builder/src/features/messages/lib/send-queue.ts
create mode 100644 apps/builder/src/features/messages/lib/use-send-queue-runner.ts
create mode 100644 apps/worker/__tests__/account-send-blocked.test.ts
create mode 100644 apps/worker/__tests__/contact-scan-pacing.test.ts
create mode 100644 apps/worker/src/chat/handlers/account-send-blocked.ts
create mode 100644 apps/worker/src/integration/handlers/contact-scan/pacing.ts
create mode 100644 apps/worker/src/integration/handlers/contact-scan/usage-signal.ts
create mode 100644 integrations/instagram-facebook/__tests__/error-mapper-reason.test.ts
create mode 100644 integrations/instagram/__tests__/error-mapper-reason.test.ts
create mode 100644 integrations/messenger/__tests__/usage-minutes.test.ts
create mode 100644 integrations/whatsapp/__tests__/error-mapper-reason.test.ts
create mode 100644 integrations/zalo/__tests__/error-mapper-reason.test.ts
create mode 100644 packages/business/__tests__/contact-scan-run-status.test.ts
create mode 100644 packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts
create mode 100644 packages/business/__tests__/message-resend-outgoing.test.ts
create mode 100644 packages/business/src/broadcast/status-reason.ts
create mode 100644 packages/business/src/contact-scan/run-status.ts
create mode 100644 packages/business/src/message/resend-outgoing.ts
create mode 100644 packages/database/__tests__/integration/contact-scan-cancel.test.ts
create mode 100644 packages/database/__tests__/integration/contact-scan-retry-or-fail.test.ts
create mode 100644 packages/database/__tests__/message-resendable-partial.test.ts
create mode 100644 packages/database/drizzle/20261113171821_broadcast_status_reason/migration.sql
create mode 100644 packages/database/drizzle/20261113171821_broadcast_status_reason/snapshot.json
create mode 100644 packages/sdk/__tests__/channel-error-reason.test.ts
create mode 100644 packages/worker-config/__tests__/contact-scan-job-ids.test.ts
diff --git a/apps/builder/__tests__/__snapshots__/public-spec-operations.test.ts.snap b/apps/builder/__tests__/__snapshots__/public-spec-operations.test.ts.snap
index a76e82c830..3f2adf40e3 100644
--- a/apps/builder/__tests__/__snapshots__/public-spec-operations.test.ts.snap
+++ b/apps/builder/__tests__/__snapshots__/public-spec-operations.test.ts.snap
@@ -1182,6 +1182,11 @@ exports[`public API spec — operation naming guard > operation list (operationI
"operationId": "contacts.upsert",
"path": "/v1/contacts/{identifier}/upsert",
},
+ {
+ "method": "POST",
+ "operationId": "contactScans.cancel",
+ "path": "/v1/contact-scans/cancel",
+ },
{
"method": "POST",
"operationId": "contactScans.create",
@@ -2387,6 +2392,11 @@ exports[`public API spec — operation naming guard > operation list (operationI
"operationId": "messages.requestWhatsappCallPermission",
"path": "/v1/conversations/{conversationId}/whatsapp-call-permission",
},
+ {
+ "method": "POST",
+ "operationId": "messages.resend",
+ "path": "/v1/conversations/{conversationId}/messages/{messageId}/resend",
+ },
{
"method": "POST",
"operationId": "messages.sendWhatsappTemplate",
diff --git a/apps/builder/__tests__/api-parity-manifest.json b/apps/builder/__tests__/api-parity-manifest.json
index efe0a62c34..28a2458650 100644
--- a/apps/builder/__tests__/api-parity-manifest.json
+++ b/apps/builder/__tests__/api-parity-manifest.json
@@ -64,6 +64,7 @@
"contact-notes/create-contact-note.action:createContactNoteAction": "covered:contact-notes",
"contact-notes/delete-contact-note.action:deleteContactNoteAction": "covered:contact-notes",
"contact-notes/edit-contact-note.action:editContactNoteAction": "covered:contact-notes",
+ "contact-scan/cancel-contact-scan.action:cancelContactScanAction": "covered:contact-scan",
"contact-scan/schedule-contact-scan.action:scheduleContactScanAction": "covered:contact-scan",
"contact-sequences/update-contact-sequence.action:updateContactSequenceAction": "covered:contact-sequences",
"contacts/add-contact-custom-field.action:addContactCustomFieldAction": "covered:contacts",
@@ -349,6 +350,8 @@
"messages/delete-message.action:deleteMessageAction": "covered:messages",
"messages/edit-message.action:editMessage": "covered:messages",
"messages/edit-message.action:editMessageAction": "covered:messages",
+ "messages/resend-message.action:resendMessage": "covered:messages",
+ "messages/resend-message.action:resendMessageAction": "covered:messages",
"messages/generate-call-ai-summary.action:generateCallAiSummaryAction": "covered:messages",
"messages/get-call-recording-url.action:getCallRecordingUrlAction": "covered:messages",
"messages/get-call-summary.action:getCallSummaryAction": "covered:messages",
diff --git a/apps/builder/__tests__/authorize-workspace-access.test.ts b/apps/builder/__tests__/authorize-workspace-access.test.ts
index d17cf8db92..5c4b38511c 100644
--- a/apps/builder/__tests__/authorize-workspace-access.test.ts
+++ b/apps/builder/__tests__/authorize-workspace-access.test.ts
@@ -295,6 +295,22 @@ describe("assertWorkspaceOwnerAccessForMethod", () => {
).toBe(false)
})
+ test("allows cancelling a contact scan on a trial-expired workspace (UI parity), never for a read_only token", async () => {
+ isCloud.mockReturnValue(true)
+ getAccessState.mockResolvedValue({ blocked: true, reason: "status" })
+
+ await expect(
+ assertWorkspaceOwnerAccessForMethod({
+ method: "POST",
+ ownerId: "owner-1",
+ path: "/v1/contact-scans/cancel",
+ }),
+ ).resolves.toBeUndefined()
+ expect(
+ isReadOnlyTokenAllowedMethod("POST", "/v1/contact-scans/cancel"),
+ ).toBe(false)
+ })
+
test("blocks a different POST path for a trial-expired workspace", async () => {
isCloud.mockReturnValue(true)
getAccessState.mockResolvedValue({ blocked: true, reason: "status" })
diff --git a/apps/builder/__tests__/broadcast-public-resource-send-limit.test.ts b/apps/builder/__tests__/broadcast-public-resource-send-limit.test.ts
index ef4b1c975d..65718584c7 100644
--- a/apps/builder/__tests__/broadcast-public-resource-send-limit.test.ts
+++ b/apps/builder/__tests__/broadcast-public-resource-send-limit.test.ts
@@ -65,3 +65,50 @@ describe("publicBroadcastResource send limit fields", () => {
expect(result.success && result.data.targets?.[0]?.inboxId).toBe("5")
})
})
+
+describe("publicBroadcastResource status reason", () => {
+ const base = {
+ id: "1",
+ name: "Broadcast",
+ status: "cancelled",
+ schedulesType: "now",
+ schedulesAt: new Date(),
+ flowId: null,
+ contactCount: 5,
+ audienceRangeStart: null,
+ audienceRangeEnd: null,
+ sendRatePerMinute: null,
+ }
+
+ test("exposes the three status reason fields", () => {
+ expect(Object.keys(publicBroadcastResource.shape)).toEqual(
+ expect.arrayContaining([
+ "statusReason",
+ "statusErrorMessage",
+ "statusInboxId",
+ ]),
+ )
+ })
+
+ test("parses a system-stopped broadcast and keeps the values", () => {
+ const result = publicBroadcastResource.parse({
+ ...base,
+ statusReason: "accountSendRestricted",
+ statusErrorMessage: "restricted",
+ statusInboxId: "9",
+ })
+ expect(result.statusReason).toBe("accountSendRestricted")
+ expect(result.statusErrorMessage).toBe("restricted")
+ expect(result.statusInboxId).toBe("9")
+ })
+
+ test("a customer-stopped broadcast has null reason fields", () => {
+ const result = publicBroadcastResource.parse({
+ ...base,
+ statusReason: null,
+ statusErrorMessage: null,
+ statusInboxId: null,
+ })
+ expect(result.statusReason).toBeNull()
+ })
+})
diff --git a/apps/builder/__tests__/broadcast-status-reason.test.tsx b/apps/builder/__tests__/broadcast-status-reason.test.tsx
new file mode 100644
index 0000000000..151a49320c
--- /dev/null
+++ b/apps/builder/__tests__/broadcast-status-reason.test.tsx
@@ -0,0 +1,69 @@
+import { act } from "react"
+import { createRoot, type Root } from "react-dom/client"
+import { afterEach, describe, expect, test, vi } from "vitest"
+import { BroadcastStatusReason } from "@/features/broadcasts/components/broadcast-status-reason"
+
+/** Echoes the key (and params) back so assertions never depend on English copy. */
+vi.mock("next-intl", () => ({
+ useTranslations: () => (key: string, values?: { name?: string }) =>
+ values?.name ? `${key}:${values.name}` : key,
+}))
+
+let container: HTMLDivElement | null = null
+let root: Root | null = null
+
+const render = (
+ broadcast: Parameters[0]["broadcast"],
+) => {
+ Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true })
+ container = document.createElement("div")
+ document.body.append(container)
+ root = createRoot(container)
+ act(() => {
+ root?.render( )
+ })
+ return container
+}
+
+afterEach(() => {
+ act(() => root?.unmount())
+ container?.remove()
+ container = null
+ root = null
+})
+
+describe("BroadcastStatusReason", () => {
+ test("renders nothing without a status reason", () => {
+ const el = render({
+ statusReason: null,
+ statusErrorMessage: null,
+ statusInbox: null,
+ })
+ expect(el.textContent).toBe("")
+ })
+
+ test("renders the reason, the page and the provider error as a tooltip", () => {
+ const el = render({
+ statusReason: "accountPolicyBlocked",
+ statusErrorMessage: "(#2022) blocked",
+ statusInbox: { id: "1", name: "Spring page" },
+ })
+ expect(el.textContent).toContain(
+ "broadcasts.statusReason.accountPolicyBlocked",
+ )
+ expect(el.textContent).toContain("broadcasts.statusReason.page:Spring page")
+ expect(el.querySelector("p")?.getAttribute("title")).toBe("(#2022) blocked")
+ })
+
+ test("drops the page line when the inbox was deleted", () => {
+ const el = render({
+ statusReason: "accountSendRestricted",
+ statusErrorMessage: null,
+ statusInbox: null,
+ })
+ expect(el.textContent).toContain(
+ "broadcasts.statusReason.accountSendRestricted",
+ )
+ expect(el.textContent).not.toContain("broadcasts.statusReason.page")
+ })
+})
diff --git a/apps/builder/__tests__/cancel-contact-scan-action.test.ts b/apps/builder/__tests__/cancel-contact-scan-action.test.ts
new file mode 100644
index 0000000000..da40890925
--- /dev/null
+++ b/apps/builder/__tests__/cancel-contact-scan-action.test.ts
@@ -0,0 +1,89 @@
+// @vitest-environment node
+import { beforeEach, describe, expect, test, vi } from "vitest"
+
+const mockCancel = vi.fn()
+const mockRequireUnrestrictedContactsScope = vi.fn()
+const clientUsed = vi.hoisted(() => ({ name: "" }))
+
+vi.mock("@chatbotx.io/business", () => ({
+ contactScanService: { cancel: (...args: unknown[]) => mockCancel(...args) },
+}))
+
+vi.mock("@/features/common/schema", () => ({ workspaceIdrequestParams: [] }))
+
+// Cancel must keep working after the trial expires (invariant 14), so it must
+// be built on the allow-expired client and never on the plain one.
+vi.mock("@/lib/safe-action", () => {
+ const chain = (name: string) => ({
+ bindArgsSchemas: () => ({
+ inputSchema: () => ({
+ action: (fn: unknown) => {
+ clientUsed.name = name
+ return fn
+ },
+ }),
+ }),
+ })
+ return {
+ workspaceActionClientAllowExpired: chain("allowExpired"),
+ workspaceActionClient: chain("plain"),
+ }
+})
+
+vi.mock(
+ "@/features/contact-scan/lib/require-unrestricted-contacts-scope",
+ () => ({
+ requireUnrestrictedContactsScope: (...args: unknown[]) =>
+ mockRequireUnrestrictedContactsScope(...args),
+ }),
+)
+
+const { cancelContactScanAction: untyped } = await import(
+ "@/features/contact-scan/actions/cancel-contact-scan.action"
+)
+const cancelContactScanAction = untyped as unknown as (props: {
+ bindArgsParsedInputs: [string]
+ parsedInput: { inboxId: string }
+}) => Promise
+
+const run = () =>
+ cancelContactScanAction({
+ bindArgsParsedInputs: ["ws-1"],
+ parsedInput: { inboxId: "inbox-1" },
+ })
+
+describe("cancelContactScanAction", () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ mockRequireUnrestrictedContactsScope.mockResolvedValue(undefined)
+ mockCancel.mockResolvedValue({ cancelled: true })
+ })
+
+ test("is built on the allow-expired client", () => {
+ expect(clientUsed.name).toBe("allowExpired")
+ })
+
+ test("checks the contacts scope, then cancels the inbox's scan", async () => {
+ await expect(run()).resolves.toEqual({ cancelled: true })
+
+ expect(mockRequireUnrestrictedContactsScope).toHaveBeenCalledWith("ws-1")
+ expect(mockCancel).toHaveBeenCalledWith({
+ workspaceId: "ws-1",
+ inboxId: "inbox-1",
+ })
+ })
+
+ test("an assigned-only member is denied and nothing is cancelled", async () => {
+ mockRequireUnrestrictedContactsScope.mockRejectedValue(
+ new Error("contactScanForbidden"),
+ )
+
+ await expect(run()).rejects.toThrow("contactScanForbidden")
+ expect(mockCancel).not.toHaveBeenCalled()
+ })
+
+ test("passes cancelled:false through when nothing is running", async () => {
+ mockCancel.mockResolvedValue({ cancelled: false })
+ await expect(run()).resolves.toEqual({ cancelled: false })
+ })
+})
diff --git a/apps/builder/__tests__/cancel-contact-scan-button.test.tsx b/apps/builder/__tests__/cancel-contact-scan-button.test.tsx
new file mode 100644
index 0000000000..9cc1b62208
--- /dev/null
+++ b/apps/builder/__tests__/cancel-contact-scan-button.test.tsx
@@ -0,0 +1,194 @@
+import { act } from "react"
+import { createRoot, type Root } from "react-dom/client"
+import { afterEach, describe, expect, test, vi } from "vitest"
+import { CancelContactScanButton } from "@/features/contact-scan/components/cancel-contact-scan-button"
+
+/** Echoes the key back so assertions never depend on the English copy. */
+vi.mock("next-intl", () => ({
+ useTranslations: () => (key: string) => key,
+}))
+
+const toast = vi.hoisted(() => ({
+ error: vi.fn(),
+ success: vi.fn(),
+ info: vi.fn(),
+}))
+vi.mock("sonner", () => ({ toast }))
+
+const invalidateQueries = vi.hoisted(() => vi.fn())
+vi.mock("@tanstack/react-query", () => ({
+ useQueryClient: () => ({ invalidateQueries }),
+}))
+
+vi.mock("@/lib/orpc/query", () => ({
+ orpc: {
+ contactScanAPIs: {
+ getContactScanStatusAuthenticatedAPI: {
+ key: (args: unknown) => ["contact-scan-status", args],
+ },
+ },
+ },
+}))
+
+type ActionOptions = {
+ onSuccess?: (args: { data?: { cancelled: boolean } }) => void
+ onError?: (args: { error: { serverError?: string } }) => void
+}
+const execute = vi.hoisted(() => vi.fn())
+const actionState = vi.hoisted(() => ({
+ options: {} as ActionOptions,
+ isPending: false,
+}))
+const bind = vi.hoisted(() => vi.fn(() => ({})))
+
+vi.mock("@/features/contact-scan/actions/cancel-contact-scan.action", () => ({
+ cancelContactScanAction: { bind },
+}))
+
+vi.mock("next-safe-action/hooks", () => ({
+ useAction: (_action: unknown, options: ActionOptions) => {
+ actionState.options = options
+ return { execute, isPending: actionState.isPending }
+ },
+}))
+
+vi.mock("@chatbotx.io/ui/components/ui/dialog", () => ({
+ Dialog: ({
+ open,
+ children,
+ }: {
+ open: boolean
+ children: React.ReactNode
+ }) => {children}
,
+ DialogTrigger: ({ render }: { render: React.ReactElement }) => render,
+ DialogContent: ({ children }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ DialogHeader: ({ children }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ DialogTitle: ({ children }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ DialogDescription: ({ children }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ DialogFooter: ({ children }: { children: React.ReactNode }) => (
+ {children}
+ ),
+ DialogClose: ({ render }: { render: React.ReactElement }) => render,
+}))
+
+vi.mock("@chatbotx.io/ui/components/ui/button", () => ({
+ Button: ({
+ children,
+ ...rest
+ }: React.ButtonHTMLAttributes) => (
+ {children}
+ ),
+}))
+
+let container: HTMLDivElement | null = null
+let root: Root | null = null
+
+function renderButton() {
+ Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true })
+ container = document.createElement("div")
+ document.body.append(container)
+ root = createRoot(container)
+ act(() => {
+ root?.render(
+ ,
+ )
+ })
+ // biome-ignore lint/style/noNonNullAssertion: assigned synchronously above
+ return container!
+}
+
+const buttonWithText = (el: HTMLElement, text: string) =>
+ Array.from(el.querySelectorAll("button")).find((b) =>
+ b.textContent?.includes(text),
+ ) as HTMLButtonElement | undefined
+
+afterEach(() => {
+ if (root) {
+ act(() => root?.unmount())
+ }
+ container?.remove()
+ container = null
+ root = null
+ actionState.isPending = false
+ vi.clearAllMocks()
+})
+
+describe("CancelContactScanButton", () => {
+ test("binds the action to the workspace and asks for confirmation text", () => {
+ const el = renderButton()
+
+ expect(bind).toHaveBeenCalledWith(null, "ws-1")
+ expect(el.textContent).toContain("contactScan.cancel.title")
+ expect(el.textContent).toContain("contactScan.cancel.description")
+ expect(buttonWithText(el, "contactScan.cancel.keep")).toBeDefined()
+ })
+
+ test("confirming executes the action for this inbox", () => {
+ const el = renderButton()
+
+ act(() => {
+ buttonWithText(el, "contactScan.cancel.confirm")?.click()
+ })
+
+ expect(execute).toHaveBeenCalledWith({ inboxId: "inbox-1" })
+ })
+
+ test("the confirm button is disabled while the request is pending", () => {
+ actionState.isPending = true
+ const el = renderButton()
+
+ expect(buttonWithText(el, "contactScan.cancel.confirm")?.disabled).toBe(
+ true,
+ )
+ })
+
+ test("a cancelled scan toasts success and refreshes the status query", () => {
+ renderButton()
+
+ act(() => {
+ actionState.options.onSuccess?.({ data: { cancelled: true } })
+ })
+
+ expect(toast.success).toHaveBeenCalledWith("contactScan.cancel.success")
+ expect(invalidateQueries).toHaveBeenCalledWith({
+ queryKey: [
+ "contact-scan-status",
+ { input: { workspaceId: "ws-1", inboxId: "inbox-1" } },
+ ],
+ })
+ })
+
+ test("nothing running is reported as info, not an error, and still refreshes", () => {
+ renderButton()
+
+ act(() => {
+ actionState.options.onSuccess?.({ data: { cancelled: false } })
+ })
+
+ expect(toast.info).toHaveBeenCalledWith("contactScan.cancel.notRunning")
+ expect(toast.error).not.toHaveBeenCalled()
+ expect(invalidateQueries).toHaveBeenCalledTimes(1)
+ })
+
+ test("a server error shows its message, else a generic one", () => {
+ renderButton()
+
+ act(() => {
+ actionState.options.onError?.({ error: { serverError: "Forbidden" } })
+ })
+ act(() => {
+ actionState.options.onError?.({ error: {} })
+ })
+
+ expect(toast.error).toHaveBeenNthCalledWith(1, "Forbidden")
+ expect(toast.error).toHaveBeenNthCalledWith(2, "contactScan.cancel.failed")
+ })
+})
diff --git a/apps/builder/__tests__/chat-layout-mobile.test.tsx b/apps/builder/__tests__/chat-layout-mobile.test.tsx
index ce06dfab94..c1eede1610 100644
--- a/apps/builder/__tests__/chat-layout-mobile.test.tsx
+++ b/apps/builder/__tests__/chat-layout-mobile.test.tsx
@@ -12,6 +12,10 @@ vi.mock("@/features/chat/chat-realtime", () => ({
ChatRealtime: () =>
,
}))
+vi.mock("@/features/messages/components/send-queue-runner", () => ({
+ SendQueueRunner: () => null,
+}))
+
const { mockMobileState } = vi.hoisted(() => ({
mockMobileState: {
isOverridden: false,
diff --git a/apps/builder/__tests__/chat-realtime.test.tsx b/apps/builder/__tests__/chat-realtime.test.tsx
index 7c0745a66d..7a2ae1eece 100644
--- a/apps/builder/__tests__/chat-realtime.test.tsx
+++ b/apps/builder/__tests__/chat-realtime.test.tsx
@@ -22,6 +22,7 @@ const chatStoreState = {
handleNewMessages: vi.fn(),
markMessagesDeleted: vi.fn(),
markMessageFailed: vi.fn(),
+ settleSendResult: vi.fn(),
assignMessageCommentId: vi.fn(),
updateMessageText: vi.fn(),
updateMessageContentAttributes: vi.fn(),
@@ -177,6 +178,27 @@ describe("ChatRealtime — chat event parity", () => {
)
})
+ test("messageFailed is also the composer queue's answer, success (null) included", async () => {
+ await render()
+ act(() =>
+ emit("messageFailed", { messageId: "m1", clientId: "c1", error: null }),
+ )
+ act(() =>
+ emit("messageFailed", { messageId: "m2", clientId: "c2", error: "boom" }),
+ )
+
+ expect(chatStoreState.settleSendResult).toHaveBeenNthCalledWith(1, {
+ messageId: "m1",
+ clientId: "c1",
+ error: null,
+ })
+ expect(chatStoreState.settleSendResult).toHaveBeenNthCalledWith(2, {
+ messageId: "m2",
+ clientId: "c2",
+ error: "boom",
+ })
+ })
+
test("messageUpdated updates the message text/attachment fields", async () => {
await render()
act(() =>
diff --git a/apps/builder/__tests__/chat-store.test.ts b/apps/builder/__tests__/chat-store.test.ts
index 555cce83ca..d477c9516a 100644
--- a/apps/builder/__tests__/chat-store.test.ts
+++ b/apps/builder/__tests__/chat-store.test.ts
@@ -2252,3 +2252,118 @@ describe("createChatStore seed invariant check", () => {
expect(loggerWarnMock).not.toHaveBeenCalled()
})
})
+
+describe("chat store send queues", () => {
+ const queued = (clientId: string) => ({
+ clientId,
+ input: { text: clientId } as never,
+ })
+
+ test("a queue is created on first use and survives switching the active conversation", async () => {
+ const store = createChatStore()
+ const { enqueueSend } = await import(
+ "../src/features/messages/lib/send-queue"
+ )
+
+ store
+ .getState()
+ .updateSendQueue("conv-1", (queue) => enqueueSend(queue, queued("a")))
+ store.setState({ activeConversationId: "conv-2" })
+
+ expect(store.getState().sendQueues["conv-1"]?.waiting).toHaveLength(1)
+ })
+
+ test("queues of different conversations are independent", async () => {
+ const store = createChatStore()
+ const { enqueueSend } = await import(
+ "../src/features/messages/lib/send-queue"
+ )
+
+ store
+ .getState()
+ .updateSendQueue("conv-1", (queue) => enqueueSend(queue, queued("a")))
+ store
+ .getState()
+ .updateSendQueue("conv-2", (queue) => enqueueSend(queue, queued("b")))
+
+ expect(store.getState().sendQueues["conv-1"]?.waiting[0]?.clientId).toBe(
+ "a",
+ )
+ expect(store.getState().sendQueues["conv-2"]?.waiting[0]?.clientId).toBe(
+ "b",
+ )
+ })
+
+ test("a result settles the matching in-flight message in whichever queue holds it", async () => {
+ const store = createChatStore()
+ const { enqueueSend, markSendSubmitted } = await import(
+ "../src/features/messages/lib/send-queue"
+ )
+ store
+ .getState()
+ .updateSendQueue("conv-1", (queue) =>
+ markSendSubmitted(enqueueSend(queue, queued("a")), "a", 0),
+ )
+
+ store
+ .getState()
+ .settleSendResult({ clientId: "a", messageId: "m-a", error: null })
+
+ expect(store.getState().sendQueues["conv-1"]?.inFlight).toBeNull()
+ })
+
+ test("a drained queue is dropped once its gap is over, so the map keeps only live conversations", async () => {
+ vi.useFakeTimers({ toFake: ["Date"] })
+ try {
+ const store = createChatStore()
+ const { enqueueSend, markSendSubmitted } = await import(
+ "../src/features/messages/lib/send-queue"
+ )
+ store
+ .getState()
+ .updateSendQueue("conv-1", (queue) =>
+ markSendSubmitted(enqueueSend(queue, queued("a")), "a", 0),
+ )
+ store.getState().settleSendResult({ clientId: "a", error: null })
+ // Still inside the 500 ms gap: kept so the next message waits for it.
+ expect(store.getState().sendQueues["conv-1"]).toBeDefined()
+
+ vi.advanceTimersByTime(1000)
+ store.getState().updateSendQueue("conv-2", (queue) => queue)
+
+ expect(store.getState().sendQueues["conv-1"]).toBeUndefined()
+ expect(store.getState().sendQueues["conv-2"]).toBeUndefined()
+ } finally {
+ vi.useRealTimers()
+ }
+ })
+
+ test("a failure result holds the queue only when messages wait behind it", async () => {
+ const store = createChatStore()
+ const { enqueueSend, markSendSubmitted } = await import(
+ "../src/features/messages/lib/send-queue"
+ )
+ store
+ .getState()
+ .updateSendQueue("conv-1", (queue) =>
+ markSendSubmitted(
+ enqueueSend(enqueueSend(queue, queued("a")), queued("b")),
+ "a",
+ 0,
+ ),
+ )
+
+ store.getState().settleSendResult({ clientId: "a", error: "refused" })
+
+ expect(store.getState().sendQueues["conv-1"]?.holdReason).toBe("failed")
+ })
+
+ test("a result nobody is waiting for keeps the state reference", () => {
+ const store = createChatStore()
+ const before = store.getState()
+
+ store.getState().settleSendResult({ clientId: "stray", error: null })
+
+ expect(store.getState()).toBe(before)
+ })
+})
diff --git a/apps/builder/__tests__/contact-scan-form.test.tsx b/apps/builder/__tests__/contact-scan-form.test.tsx
index 0c6c4a8fb9..b6341dd760 100644
--- a/apps/builder/__tests__/contact-scan-form.test.tsx
+++ b/apps/builder/__tests__/contact-scan-form.test.tsx
@@ -43,6 +43,9 @@ vi.mock("sonner", () => ({
vi.mock("@/features/contact-scan/actions/schedule-contact-scan.action", () => ({
scheduleContactScanAction: vi.fn(),
}))
+vi.mock("@/features/contact-scan/actions/cancel-contact-scan.action", () => ({
+ cancelContactScanAction: { bind: vi.fn(() => vi.fn()) },
+}))
// The form renders with no inboxes configured — its visibility in the
// Import submenu is `contacts-list-action.tsx`'s job, not this form's —
diff --git a/apps/builder/__tests__/contact-scan-public-api.test.ts b/apps/builder/__tests__/contact-scan-public-api.test.ts
index 3432e82a2d..f165351f48 100644
--- a/apps/builder/__tests__/contact-scan-public-api.test.ts
+++ b/apps/builder/__tests__/contact-scan-public-api.test.ts
@@ -25,10 +25,12 @@ const {
workspaceTokenAuthAPIForScope,
capturedProcedures,
possibleErrorsOnListingResource,
+ possibleErrorsOnMutatingResource,
possibleErrorsOnSchedulingContactScan,
getContactScanStatus,
listContactScanHistoryRows,
contactScanServiceSchedule,
+ contactScanServiceCancel,
} = vi.hoisted(() => {
const capturedProcedures: CapturedProcedure[] = []
const possibleErrorsOnListingResource = {
@@ -37,6 +39,9 @@ const {
status: 400,
},
}
+ const possibleErrorsOnMutatingResource = {
+ notFound: { message: "Not found", status: 404 },
+ }
const possibleErrorsOnSchedulingContactScan = {
businessError: {
message: "An error occurred while processing your request",
@@ -55,6 +60,7 @@ const {
const getContactScanStatus = vi.fn()
const listContactScanHistoryRows = vi.fn()
const contactScanServiceSchedule = vi.fn()
+ const contactScanServiceCancel = vi.fn()
const makeProcedure = (route: RouteConfig) => {
const record: CapturedProcedure = { route }
@@ -85,10 +91,12 @@ const {
),
capturedProcedures,
possibleErrorsOnListingResource,
+ possibleErrorsOnMutatingResource,
possibleErrorsOnSchedulingContactScan,
getContactScanStatus,
listContactScanHistoryRows,
contactScanServiceSchedule,
+ contactScanServiceCancel,
}
})
@@ -96,6 +104,7 @@ vi.mock("@/orpc", () => ({ workspaceTokenAuthAPIForScope }))
vi.mock("@/lib/orpc/orpc-error-helper", () => ({
possibleErrorsOnListingResource,
+ possibleErrorsOnMutatingResource,
possibleErrorsOnSchedulingContactScan,
}))
@@ -108,7 +117,10 @@ vi.mock("@/features/contact-scan/lib/contact-scan-history", () => ({
}))
vi.mock("@chatbotx.io/business", () => ({
- contactScanService: { schedule: contactScanServiceSchedule },
+ contactScanService: {
+ schedule: contactScanServiceSchedule,
+ cancel: contactScanServiceCancel,
+ },
}))
await import("@/features/contact-scan/api/public")
@@ -253,3 +265,38 @@ describe("POST /v1/contact-scans", () => {
expect(procedure.errors).toBe(possibleErrorsOnSchedulingContactScan)
})
})
+
+describe("POST /v1/contact-scans/cancel", () => {
+ const procedure = findProcedure("POST", "/v1/contact-scans/cancel")
+
+ test("cancels the token workspace's scan for the inbox", async () => {
+ contactScanServiceCancel.mockResolvedValueOnce({ cancelled: true })
+
+ await expect(
+ procedure.handler?.({
+ context: { workspace: { id: "workspace-1" } },
+ input: { inboxId: "inbox-1", workspaceId: "attacker-workspace" },
+ }),
+ ).resolves.toEqual({ cancelled: true })
+
+ expect(contactScanServiceCancel).toHaveBeenCalledWith({
+ workspaceId: "workspace-1",
+ inboxId: "inbox-1",
+ })
+ })
+
+ test("reports cancelled:false (not an error) when nothing is running", async () => {
+ contactScanServiceCancel.mockResolvedValueOnce({ cancelled: false })
+
+ await expect(
+ procedure.handler?.({
+ context: { workspace: { id: "workspace-1" } },
+ input: { inboxId: "inbox-1" },
+ }),
+ ).resolves.toEqual({ cancelled: false })
+ })
+
+ test("declares the mutating-resource errors", () => {
+ expect(procedure.errors).toBe(possibleErrorsOnMutatingResource)
+ })
+})
diff --git a/apps/builder/__tests__/disconnect-meta-actions.test.ts b/apps/builder/__tests__/disconnect-meta-actions.test.ts
index aad63824d7..08296a0cb8 100644
--- a/apps/builder/__tests__/disconnect-meta-actions.test.ts
+++ b/apps/builder/__tests__/disconnect-meta-actions.test.ts
@@ -21,6 +21,7 @@ const mocks = vi.hoisted(() => {
callback(tx),
),
coexistTearDownForIntegration: vi.fn().mockResolvedValue(undefined),
+ contactScanCancel: vi.fn().mockResolvedValue(undefined),
connectionStateDisconnect: vi.fn().mockResolvedValue(undefined),
findOrFail: vi.fn(),
instagramExists: vi.fn().mockResolvedValue(false),
@@ -65,6 +66,7 @@ vi.mock("@chatbotx.io/business", () => ({
coexistService: {
tearDownForIntegration: mocks.coexistTearDownForIntegration,
},
+ contactScanService: { cancelForIntegration: mocks.contactScanCancel },
instagramIntegrationService: {
existsForPage: mocks.instagramExists,
findByIdForWorkspace: mocks.findOrFail,
@@ -264,6 +266,14 @@ describe("Meta disconnect actions", () => {
expect(mocks.instagramFacebookDisconnect).toHaveBeenCalledWith(
instagramFacebookRow.auth,
)
+ // The contact scan supports both Instagram variants, so a Facebook-backed
+ // one is cancelled too (unlike coexist, which is native-only).
+ expect(mocks.contactScanCancel).toHaveBeenCalledWith({
+ channel: "instagram",
+ integrationId: "instagram-1",
+ tx: mocks.tx,
+ })
+ expect(mocks.coexistTearDownForIntegration).not.toHaveBeenCalled()
expect(mocks.metaCapiDeleteByIntegration).toHaveBeenCalledWith(
{
workspaceId: "workspace-1",
diff --git a/apps/builder/__tests__/message-input-client-id.test.tsx b/apps/builder/__tests__/message-input-client-id.test.tsx
index 1a458de98f..e7c54cd26d 100644
--- a/apps/builder/__tests__/message-input-client-id.test.tsx
+++ b/apps/builder/__tests__/message-input-client-id.test.tsx
@@ -1,10 +1,18 @@
import { TOUCH_DEVICE_MEDIA_QUERY } from "@chatbotx.io/ui/hooks/use-touch-device"
-import { act, cloneElement, forwardRef } from "react"
+import { act, cloneElement, forwardRef, useSyncExternalStore } from "react"
import { createRoot, type Root } from "react-dom/client"
import { useForm } from "react-hook-form"
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"
import { WebchatMessageInput } from "@/features/integration-webchat/webchat-message-input"
import { MessageInput } from "@/features/messages/components/message-input"
+import { SendQueueRunner } from "@/features/messages/components/send-queue-runner"
+import {
+ AGENT_SEND_CONFIRM_TIMEOUT_MS,
+ AGENT_SEND_GAP_MS,
+ createSendQueue,
+ type SendQueue,
+} from "@/features/messages/lib/send-queue"
+import type { CreateMessageWithRoutingBypassRequest } from "@/features/messages/schema/mutation"
const defaultMatchMedia = window.matchMedia
let isTouchDevice = false
@@ -93,9 +101,15 @@ vi.mock("@/features/conversations/actions/disable-bot.action", () => ({
vi.mock("@/features/conversations/hooks/use-thread-control", () => ({
useThreadControl: () => null,
}))
+// The queue runner calls the action directly; the form only `.bind()`s it.
vi.mock("@/features/messages/actions/create-message.action", () => ({
- createMessageAction: { bind: () => "create-message" },
+ createMessageAction: Object.assign(
+ (_workspaceId: string, _conversationId: string, input: unknown) =>
+ action.executeAsync(input),
+ { bind: () => "create-message" },
+ ),
}))
+vi.mock("@/hooks/routing", () => ({ useWorkspaceId: () => "1" }))
vi.mock("@/features/messages/actions/create-webchat-message.action", () => ({
createWebchatMessageAction: {},
}))
@@ -163,9 +177,28 @@ vi.mock("@/features/messages/components/emoji-picker", () => ({
default: () => null,
}))
+type InboxSendQueue = SendQueue
+const storeListeners = new Set<() => void>()
+let storeVersion = 0
+const notifyStore = () => {
+ storeVersion += 1
+ for (const listener of storeListeners) {
+ listener()
+ }
+}
+
+/** The composer plus the runner the chat layout mounts beside it. */
+const InboxComposer = () => (
+ <>
+
+
+ >
+)
+
const inboxStore = {
activeConversationId: "conversation-1",
appendMessage: vi.fn(),
+ markMessagesDeleted: vi.fn(),
conversations: [
{
botEnabled: true,
@@ -179,17 +212,42 @@ const inboxStore = {
markMessageFailed: vi.fn(),
messages: [],
replyToMessage: null,
+ sendQueues: {} as Record,
setReplyToMessage: vi.fn(),
updateConversation: vi.fn(),
updateConversationViaMessage: vi.fn(),
+ // The same shape as the real store's action: a pure update on one queue.
+ updateSendQueue: (
+ conversationId: string,
+ update: (queue: InboxSendQueue) => InboxSendQueue,
+ ) => {
+ inboxStore.sendQueues = {
+ ...inboxStore.sendQueues,
+ [conversationId]: update(
+ inboxStore.sendQueues[conversationId] ??
+ createSendQueue(),
+ ),
+ }
+ notifyStore()
+ },
}
vi.mock("@/features/chat/store/chat-store-provider", () => ({
- useChatStore: (selector: (state: typeof inboxStore) => unknown) =>
- selector(inboxStore),
+ // Subscribes to the mutable store so queue updates re-render the composer.
+ useChatStore: (selector: (state: typeof inboxStore) => unknown) => {
+ useSyncExternalStore(
+ (listener) => {
+ storeListeners.add(listener)
+ return () => storeListeners.delete(listener)
+ },
+ () => storeVersion,
+ )
+ return selector(inboxStore)
+ },
}))
const guestStore = {
appendMessage: vi.fn(),
+ markMessagesDeleted: vi.fn(),
guestConversationId: "1:00000000-0000-0000-0000-000000000000",
markMessageFailed: vi.fn(),
sendMessage: vi.fn(),
@@ -325,11 +383,13 @@ describe("message composers", () => {
guestStore.markMessageFailed.mockClear()
guestStore.sendMessage.mockClear()
inboxStore.appendMessage.mockClear()
+ inboxStore.markMessagesDeleted.mockClear()
inboxStore.markMessageFailed.mockClear()
inboxStore.setReplyToMessage.mockClear()
inboxStore.updateConversationViaMessage.mockClear()
inboxStore.replyToMessage = null
inboxStore.isPrivateReply = false
+ inboxStore.sendQueues = {}
ids.next = 1
container = document.createElement("div")
document.body.appendChild(container)
@@ -342,10 +402,154 @@ describe("message composers", () => {
window.matchMedia = defaultMatchMedia
})
- test("submits every rapid inbox message independently", async () => {
- act(() => root.render( ))
+ test("sends rapid inbox messages one at a time, each after the previous one's result", async () => {
+ vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout", "Date"] })
+ try {
+ act(() => root.render( ))
+ const textarea = await submitMessages(["1", "2", "3"])
- await expectRapidSubmissions()
+ // Only the first goes out; the rest wait for its answer.
+ expect(action.executeAsync).toHaveBeenCalledTimes(1)
+ expect(textarea.value).toBe("")
+
+ for (const expected of ["1", "2", "3"]) {
+ const input = getSubmittedMessage(
+ action.executeAsync.mock.calls.at(-1)?.[0],
+ )
+ expect(input.text).toBe(expected)
+ await act(async () => {
+ action.resolveRequests.at(-1)?.({ data: {} })
+ await Promise.resolve()
+ })
+ // The channel accepts it (the realtime answer), then the 500 ms gap.
+ act(() => {
+ inboxStore.updateSendQueue("conversation-1", (queue) =>
+ queue.inFlight?.clientId === input.clientId
+ ? {
+ ...queue,
+ inFlight: null,
+ nextAllowedAt: Date.now() + AGENT_SEND_GAP_MS,
+ }
+ : queue,
+ )
+ })
+ const expectedCalls = Number(expected) + (expected === "3" ? 0 : 1)
+ if (expected !== "3") {
+ expect(action.executeAsync).toHaveBeenCalledTimes(Number(expected))
+ await act(async () => {
+ await vi.advanceTimersByTimeAsync(AGENT_SEND_GAP_MS)
+ })
+ }
+ expect(action.executeAsync).toHaveBeenCalledTimes(expectedCalls)
+ }
+ } finally {
+ vi.useRealTimers()
+ }
+ })
+
+ test("a failed inbox message holds the ones queued behind it and locks the composer", async () => {
+ act(() => root.render( ))
+
+ const textarea = await submitMessages(["1", "2", "3"])
+ // The server refuses the first one while the other two are still queued.
+ await act(async () => {
+ action.resolveRequests[0]?.({ serverError: "Send failed" })
+ await Promise.resolve()
+ })
+
+ await vi.waitFor(() => {
+ expect(container.querySelector('[role="alert"]')).not.toBeNull()
+ })
+ // Held: nothing after the failed one went out, and the send button is off.
+ expect(action.executeAsync).toHaveBeenCalledTimes(1)
+ expect(
+ container
+ .querySelector('[aria-label="Send message"]')
+ ?.hasAttribute("disabled"),
+ ).toBe(true)
+ expect(container.textContent).toContain("messages.sendQueue.failed")
+
+ await act(async () => {
+ setTextareaValue(textarea, "4")
+ textarea.dispatchEvent(
+ new KeyboardEvent("keydown", {
+ bubbles: true,
+ cancelable: true,
+ key: "Enter",
+ }),
+ )
+ await Promise.resolve()
+ })
+ expect(action.executeAsync).toHaveBeenCalledTimes(1)
+ expect(textarea.value).toBe("4")
+ })
+
+ test("discarding the held messages unlocks the composer", async () => {
+ act(() => root.render( ))
+ await submitMessages(["1", "2"])
+ await act(async () => {
+ action.resolveRequests[0]?.({ serverError: "Send failed" })
+ await Promise.resolve()
+ })
+ await vi.waitFor(() => {
+ expect(container.querySelector('[role="alert"]')).not.toBeNull()
+ })
+
+ const discard = Array.from(container.querySelectorAll("button")).find(
+ (button) => button.textContent === "messages.sendQueue.discard",
+ )
+ act(() => {
+ discard?.dispatchEvent(new MouseEvent("click", { bubbles: true }))
+ })
+
+ expect(container.querySelector('[role="alert"]')).toBeNull()
+ expect(inboxStore.sendQueues["conversation-1"]?.waiting).toEqual([])
+ // The dropped message's row leaves the thread instead of looking sent.
+ const dropped = inboxStore.markMessagesDeleted.mock.calls.at(-1)?.[0]
+ expect(dropped).toHaveLength(1)
+ expect(
+ inboxStore.appendMessage.mock.calls.map(([row]) => row.id),
+ ).toContain(dropped?.[0])
+ })
+
+ test("a lost answer stops the queue after 30 s and waits for the person, never sending the next by itself", async () => {
+ vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout", "Date"] })
+ try {
+ act(() => root.render( ))
+ await submitMessages(["1", "2"])
+ expect(action.executeAsync).toHaveBeenCalledTimes(1)
+
+ await act(async () => {
+ action.resolveRequests.at(-1)?.({ data: {} })
+ await vi.advanceTimersByTimeAsync(AGENT_SEND_CONFIRM_TIMEOUT_MS)
+ })
+
+ expect(container.textContent).toContain("messages.sendQueue.unconfirmed")
+ expect(action.executeAsync).toHaveBeenCalledTimes(1)
+
+ const proceed = Array.from(container.querySelectorAll("button")).find(
+ (button) => button.textContent === "messages.sendQueue.continue",
+ )
+ await act(async () => {
+ proceed?.dispatchEvent(new MouseEvent("click", { bubbles: true }))
+ await vi.advanceTimersByTimeAsync(1)
+ })
+
+ expect(action.executeAsync).toHaveBeenCalledTimes(2)
+ } finally {
+ vi.useRealTimers()
+ }
+ })
+
+ test("queued messages survive a conversation switch", async () => {
+ act(() => root.render( ))
+ await submitMessages(["1", "2"])
+
+ inboxStore.activeConversationId = "conversation-2"
+ act(() => notifyStore())
+
+ expect(inboxStore.sendQueues["conversation-1"]?.waiting).toHaveLength(1)
+ inboxStore.activeConversationId = "conversation-1"
})
test("submits every rapid webchat message independently", async () => {
@@ -357,7 +561,7 @@ describe("message composers", () => {
})
test("submits an inbox message when Enter is pressed on a desktop keyboard", async () => {
- act(() => root.render( ))
+ act(() => root.render( ))
const textarea = container.querySelector("textarea")
if (!textarea) {
throw new Error("Message composer did not render a textarea")
@@ -378,7 +582,7 @@ describe("message composers", () => {
test("does not submit an inbox message when Enter is pressed on a touch device", async () => {
isTouchDevice = true
- act(() => root.render( ))
+ act(() => root.render( ))
const textarea = container.querySelector("textarea")
if (!textarea) {
throw new Error("Message composer did not render a textarea")
@@ -399,7 +603,7 @@ describe("message composers", () => {
test("submits an inbox message when Cmd+Enter is pressed on a touch device", async () => {
isTouchDevice = true
- act(() => root.render( ))
+ act(() => root.render( ))
const textarea = container.querySelector("textarea")
if (!textarea) {
throw new Error("Message composer did not render a textarea")
@@ -461,13 +665,13 @@ describe("message composers", () => {
expect(event.defaultPrevented).toBe(false)
})
- test("marks an optimistic inbox message failed and keeps its reply target on a server error", async () => {
+ test("marks an optimistic inbox message failed on a server error; the reply target was already consumed at send time", async () => {
inboxStore.replyToMessage = {
createdAt: new Date("2026-01-01T00:00:00Z"),
id: "message-1",
} as never
action.executeAsync.mockResolvedValueOnce({ serverError: "Send failed" })
- act(() => root.render( ))
+ act(() => root.render( ))
await submitMessages(["hello"])
@@ -482,13 +686,16 @@ describe("message composers", () => {
submittedMessage.clientId,
"Send failed",
)
- expect(inboxStore.setReplyToMessage).not.toHaveBeenCalled()
+ expect(inboxStore.setReplyToMessage).toHaveBeenCalledWith(null)
+ expect(submittedMessage).toMatchObject({
+ replyToMessageId: "message-1",
+ })
expect(disableBotExecute).not.toHaveBeenCalled()
})
- test("keeps selected media on an inbox server error", async () => {
+ test("clears selected media at send time and still sends it", async () => {
action.executeAsync.mockResolvedValueOnce({ serverError: "Send failed" })
- act(() => root.render( ))
+ act(() => root.render( ))
const mediaLibraryButton = container.querySelector(
'[aria-label="mediaLibrary.openMediaLibrary"]',
)
@@ -518,12 +725,15 @@ describe("message composers", () => {
})
expect(
container.querySelector('[data-testid="media-file-preview"]'),
- ).not.toBeNull()
+ ).toBeNull()
+ expect(action.executeAsync.mock.calls[0]?.[0]).toMatchObject({
+ mediaFileIds: ["1"],
+ })
})
test("catches a rejected inbox send and marks its optimistic message failed", async () => {
action.executeAsync.mockRejectedValueOnce(new Error("Network offline"))
- act(() => root.render( ))
+ act(() => root.render( ))
await submitMessages(["hello"])
@@ -545,7 +755,7 @@ describe("message composers", () => {
id: "message-1",
} as never
action.executeAsync.mockResolvedValueOnce({ data: {} })
- act(() => root.render( ))
+ act(() => root.render( ))
await submitMessages(["hello"])
@@ -560,7 +770,7 @@ describe("message composers", () => {
test("disables the bot after a successful inbox send", async () => {
action.executeAsync.mockResolvedValueOnce({ data: {} })
- act(() => root.render( ))
+ act(() => root.render( ))
await submitMessages(["hello"])
diff --git a/apps/builder/__tests__/message-input-thread-control.test.tsx b/apps/builder/__tests__/message-input-thread-control.test.tsx
index bd1e94890d..b5116ef2c7 100644
--- a/apps/builder/__tests__/message-input-thread-control.test.tsx
+++ b/apps/builder/__tests__/message-input-thread-control.test.tsx
@@ -95,6 +95,9 @@ const storeState = {
replyToMessage: null,
isPrivateReply: false,
messages: [],
+ markMessageFailed: vi.fn(),
+ sendQueues: {},
+ updateSendQueue: vi.fn(),
activeConversationId: "conv-1",
conversations: [
{
@@ -111,6 +114,7 @@ const storeState = {
},
],
}
+vi.mock("@/hooks/routing", () => ({ useWorkspaceId: () => "ws-1" }))
vi.mock("@/features/chat/store/chat-store-provider", () => ({
useChatStore: (selector: (state: typeof storeState) => unknown) =>
selector(storeState),
diff --git a/apps/builder/__tests__/message-item-send-error.test.tsx b/apps/builder/__tests__/message-item-send-error.test.tsx
index 63a7437556..d985291db1 100644
--- a/apps/builder/__tests__/message-item-send-error.test.tsx
+++ b/apps/builder/__tests__/message-item-send-error.test.tsx
@@ -27,6 +27,13 @@ vi.mock("@/features/messages/components/whatsapp-call-card", () => ({
WhatsappCallCard: () => audioCall
,
}))
+// Comment rows render the reply/like/hide actions, which read the chat store;
+// this file is about the send-error affordances, so a stub keeps it store-free.
+vi.mock("@/features/messages/components/message-actions", () => ({
+ MessageActions: () => null,
+ MessageActionsEditor: () => null,
+}))
+
let container: HTMLDivElement | null = null
let root: Root | null = null
@@ -69,6 +76,7 @@ const makeMessage = (overrides: Partial = {}) =>
deletedAt: null,
attributes: null,
contentAttributes: null,
+ contactInboxId: "ci-1",
attachments: [],
...overrides,
}) as unknown as MessageResourceWithRelations
@@ -162,3 +170,115 @@ describe("MessageItem call-failure affordance", () => {
expect(el.querySelector(".text-destructive")).toBeNull()
})
})
+
+describe("MessageItem Resend control", () => {
+ const renderResend = () =>
+ vi.fn((_: unknown) => )
+
+ test("is offered for a failed outgoing direct message", () => {
+ const resend = renderResend()
+ const el = renderComponent(
+ ,
+ )
+
+ expect(el.querySelector('[data-testid="resend"]')).not.toBeNull()
+ expect(resend).toHaveBeenCalledTimes(1)
+ })
+
+ test.each([
+ ["a message that did not fail", { sendError: null, senderType: "user" }],
+ ["a bot message", { sendError: "x", senderType: "bot" }],
+ [
+ "a message the channel already accepted",
+ { sendError: "x", senderType: "user", sourceId: "mid-1" },
+ ],
+ [
+ "a public comment reply",
+ { sendError: "x", senderType: "user", type: "comment" },
+ ],
+ ])("is not offered for %s", (_name, overrides) => {
+ const resend = renderResend()
+ const el = renderComponent(
+ ),
+ })}
+ renderResend={resend}
+ />,
+ )
+
+ expect(el.querySelector('[data-testid="resend"]')).toBeNull()
+ expect(resend).not.toHaveBeenCalled()
+ })
+
+ test("is offered for a failed private reply (a comment delivered as a DM)", () => {
+ const el = renderComponent(
+ }
+ />,
+ )
+
+ expect(el.querySelector('[data-testid="resend"]')).not.toBeNull()
+ })
+
+ test("is not offered for a row the server never accepted (an optimistic row has no contact inbox)", () => {
+ const el = renderComponent(
+ }
+ />,
+ )
+
+ expect(el.querySelector('[data-testid="resend"]')).toBeNull()
+ })
+
+ test("is never offered in the guest view", () => {
+ const el = renderComponent(
+ }
+ />,
+ )
+
+ expect(el.querySelector('[data-testid="resend"]')).toBeNull()
+ })
+
+ test("renders nothing extra when the view passes no Resend control", () => {
+ const el = renderComponent(
+ ,
+ )
+
+ expect(el.querySelector('[data-testid="resend"]')).toBeNull()
+ })
+})
diff --git a/apps/builder/__tests__/message-list.test.tsx b/apps/builder/__tests__/message-list.test.tsx
index 250bd556fe..a5c4bdb9f0 100644
--- a/apps/builder/__tests__/message-list.test.tsx
+++ b/apps/builder/__tests__/message-list.test.tsx
@@ -91,6 +91,9 @@ vi.mock("@/features/conversations/components/conversation-info", () => ({
ConversationInfo: () => null,
}))
+vi.mock("@/features/messages/components/resend-message-button", () => ({
+ ResendMessageButton: () => null,
+}))
vi.mock("@/features/messages/components/message-item", () => ({
MessageItem: () => null,
}))
diff --git a/apps/builder/__tests__/messages-public-api.test.ts b/apps/builder/__tests__/messages-public-api.test.ts
index dc48044365..5ca48b4125 100644
--- a/apps/builder/__tests__/messages-public-api.test.ts
+++ b/apps/builder/__tests__/messages-public-api.test.ts
@@ -98,6 +98,11 @@ vi.mock("@/features/messages/actions/delete-message.action", () => ({
deleteMessage,
}))
+const resendMessage = vi.fn()
+vi.mock("@/features/messages/actions/resend-message.action", () => ({
+ resendMessage,
+}))
+
const changeMessageAttributes = vi.fn()
vi.mock("@/features/messages/actions/change-message-attributes.action", () => ({
changeMessageAttributes,
@@ -403,6 +408,54 @@ describe("DELETE /v1/conversations/{conversationId}/messages/{messageId}", () =>
})
})
+describe("POST /v1/conversations/{conversationId}/messages/{messageId}/resend", () => {
+ const procedure = findProcedure(
+ "POST",
+ "/v1/conversations/{conversationId}/messages/{messageId}/resend",
+ )
+
+ test("is a 202 under the Messages tag", () => {
+ expect(procedure.route.successStatus).toBe(202)
+ expect(procedure.route.tags).toContain("Messages")
+ })
+
+ test("delegates to resendMessage with the id field it expects and returns its result", async () => {
+ const createdAt = new Date("2026-01-01T00:00:00Z")
+ resendMessage.mockResolvedValueOnce({ id: "msg-1", queued: true })
+
+ const result = await procedure.handler?.({
+ context,
+ input: { conversationId: "conv-1", messageId: "msg-1", createdAt },
+ })
+
+ expect(resendMessage).toHaveBeenCalledWith({
+ workspaceId: "ws-1",
+ conversationId: "conv-1",
+ parsedInput: { id: "msg-1", createdAt },
+ })
+ expect(result).toEqual({ id: "msg-1", queued: true })
+ })
+
+ test("checks the caller may see the conversation first, and resends nothing when it may not", async () => {
+ conversationService.findByOrFail.mockRejectedValueOnce(
+ new Error("Conversation not found"),
+ )
+
+ await expect(
+ procedure.handler?.({
+ context,
+ input: {
+ conversationId: "conv-1",
+ messageId: "msg-1",
+ createdAt: new Date("2026-01-01T00:00:00Z"),
+ },
+ }),
+ ).rejects.toThrow("Conversation not found")
+
+ expect(resendMessage).not.toHaveBeenCalled()
+ })
+})
+
describe("POST /v1/conversations/{conversationId}/messages/{messageId}/attributes", () => {
const procedure = findProcedure(
"POST",
diff --git a/apps/builder/__tests__/public-spec-mcp.test.ts b/apps/builder/__tests__/public-spec-mcp.test.ts
index 5b3a80117e..718e36661b 100644
--- a/apps/builder/__tests__/public-spec-mcp.test.ts
+++ b/apps/builder/__tests__/public-spec-mcp.test.ts
@@ -292,6 +292,7 @@ describe("x-mcp outbound policy", () => {
"leaderboards.publish",
"leaderboards.triggerRewards",
"messages.create",
+ "messages.resend",
"messages.sendWhatsappTemplate",
"messengerChannels.sendCapiTestEvent",
"miniApps.publishWhatsapp",
diff --git a/apps/builder/__tests__/resend-message-button.test.tsx b/apps/builder/__tests__/resend-message-button.test.tsx
new file mode 100644
index 0000000000..f511e3e413
--- /dev/null
+++ b/apps/builder/__tests__/resend-message-button.test.tsx
@@ -0,0 +1,187 @@
+import { act } from "react"
+import { createRoot, type Root } from "react-dom/client"
+import { afterEach, describe, expect, test, vi } from "vitest"
+import { ResendMessageButton } from "@/features/messages/components/resend-message-button"
+import type { SendQueue } from "@/features/messages/lib/send-queue"
+import {
+ createSendQueue,
+ enqueueSend,
+ failSendSubmit,
+ markResendSubmitted,
+ markSendSubmitted,
+} from "@/features/messages/lib/send-queue"
+
+vi.mock("next-intl", () => ({
+ useTranslations: () => (key: string) => key,
+}))
+
+const toast = vi.hoisted(() => ({ error: vi.fn() }))
+vi.mock("sonner", () => ({ toast }))
+
+const resendAction = vi.hoisted(() => vi.fn())
+vi.mock("@/features/messages/actions/resend-message.action", () => ({
+ resendMessageAction: resendAction,
+}))
+
+const store = vi.hoisted(() => ({
+ markMessageFailed: vi.fn(),
+ updateSendQueue: vi.fn(),
+ updateAllSendQueues: vi.fn(),
+}))
+vi.mock("@/features/chat/store/chat-store-provider", () => ({
+ useChatStore: (selector: (state: typeof store) => unknown) => selector(store),
+}))
+
+const MESSAGE = {
+ id: "msg-1",
+ createdAt: new Date("2026-07-09T08:37:21.108Z"),
+ conversationId: "conv-1",
+ workspaceId: "ws-1",
+ clientId: "c-1",
+ sendError: "(#10) permission denied",
+}
+
+let container: HTMLDivElement | null = null
+let root: Root | null = null
+
+const render = () => {
+ Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true })
+ container = document.createElement("div")
+ document.body.append(container)
+ root = createRoot(container)
+ act(() => {
+ root?.render( )
+ })
+ // biome-ignore lint/style/noNonNullAssertion: assigned synchronously above
+ return container!
+}
+
+afterEach(() => {
+ act(() => root?.unmount())
+ container?.remove()
+ container = null
+ root = null
+ vi.clearAllMocks()
+})
+
+const press = async (el: HTMLElement) => {
+ await act(() => {
+ el.querySelector("button")?.click()
+ return Promise.resolve()
+ })
+}
+
+const lastQueueUpdate = (index: number) => {
+ const [conversationId, update] = store.updateSendQueue.mock.calls[index] as [
+ string,
+ (queue: SendQueue) => SendQueue,
+ ]
+ return { conversationId, update }
+}
+
+describe("ResendMessageButton", () => {
+ test("is labelled with the shared Resend key", () => {
+ expect(render().textContent).toContain("actions.resend")
+ })
+
+ test("pressing it resends this message by id and createdAt in its workspace and conversation", async () => {
+ resendAction.mockResolvedValue({ data: { id: "msg-1", queued: true } })
+ await press(render())
+
+ expect(resendAction).toHaveBeenCalledWith("ws-1", "conv-1", {
+ id: "msg-1",
+ createdAt: MESSAGE.createdAt,
+ })
+ })
+
+ test("the badge clears and the queue tracks the message BEFORE the request returns", async () => {
+ let finish: (value: unknown) => void = () => undefined
+ resendAction.mockReturnValue(
+ new Promise((resolve) => {
+ finish = resolve
+ }),
+ )
+ const el = render()
+ await press(el)
+
+ expect(store.markMessageFailed).toHaveBeenCalledWith(
+ "msg-1",
+ undefined,
+ null,
+ )
+ const { conversationId, update } = lastQueueUpdate(0)
+ expect(conversationId).toBe("conv-1")
+ expect(update(createSendQueue()).inFlight?.messageId).toBe("msg-1")
+ expect(el.querySelector("button")?.disabled).toBe(true)
+
+ await act(async () => finish({ data: { id: "msg-1", queued: true } }))
+ expect(toast.error).not.toHaveBeenCalled()
+ expect(store.markMessageFailed).toHaveBeenCalledTimes(1)
+ })
+
+ test("a refusal (409) restores the failure and the hold, and shows the server message", async () => {
+ resendAction.mockResolvedValue({
+ serverError: "This message cannot be resent",
+ })
+ await press(render())
+
+ expect(toast.error).toHaveBeenCalledWith("This message cannot be resent")
+ expect(store.markMessageFailed).toHaveBeenLastCalledWith(
+ "msg-1",
+ undefined,
+ "(#10) permission denied",
+ )
+ const held = failSendSubmit(
+ markSendSubmitted(
+ enqueueSend(createSendQueue(), { clientId: "c-1", input: {} }),
+ "c-1",
+ 0,
+ ),
+ "c-1",
+ )
+ const tracked = markResendSubmitted(
+ held,
+ { messageId: "msg-1", clientId: "c-1" },
+ 0,
+ )
+ const [restore] = store.updateAllSendQueues.mock.calls.at(-1) as [
+ (queue: SendQueue) => SendQueue,
+ ]
+ expect(restore(tracked).inFlight).toBeNull()
+ expect(restore(tracked).holdReason).toBe("failed")
+ })
+
+ test("a queue held for this message in ANOTHER conversation (a private reply) is unlocked too, an unrelated one is left alone", async () => {
+ resendAction.mockResolvedValue({ data: { id: "msg-1", queued: true } })
+ await press(render())
+
+ const [track] = store.updateAllSendQueues.mock.calls[0] as [
+ (queue: SendQueue) => SendQueue,
+ ]
+ const held = failSendSubmit(
+ markSendSubmitted(
+ enqueueSend(createSendQueue(), {
+ clientId: "c-1",
+ input: {},
+ }),
+ "c-1",
+ 0,
+ ),
+ "c-1",
+ )
+ // Held for a submit refused by clientId only; the row's clientId matches.
+ expect(track(held).holdReason).toBeNull()
+ const unrelated = createSendQueue()
+ expect(track(unrelated)).toBe(unrelated)
+ })
+
+ test("a thrown error falls back to its message, then to the generic one", async () => {
+ resendAction.mockRejectedValue(new Error("network down"))
+ await press(render())
+ expect(toast.error).toHaveBeenCalledWith("network down")
+
+ resendAction.mockRejectedValue("boom")
+ await press(container as HTMLElement)
+ expect(toast.error).toHaveBeenLastCalledWith("messages.unknownError")
+ })
+})
diff --git a/apps/builder/__tests__/resume-broadcast-dialog.test.tsx b/apps/builder/__tests__/resume-broadcast-dialog.test.tsx
index 41470e958b..20969d6aa9 100644
--- a/apps/builder/__tests__/resume-broadcast-dialog.test.tsx
+++ b/apps/builder/__tests__/resume-broadcast-dialog.test.tsx
@@ -1,4 +1,3 @@
-import type { BroadcastModel } from "@chatbotx.io/database/types"
import { act, useCallback, useState } from "react"
import { createRoot, type Root } from "react-dom/client"
import { useForm, useFormContext } from "react-hook-form"
@@ -6,6 +5,9 @@ import { afterEach, describe, expect, test, vi } from "vitest"
import { useBroadcastTransitionActionCallbacks } from "@/features/broadcasts/components/broadcast-transition-dialog"
import { ResumeBroadcastDialog } from "@/features/broadcasts/components/resume-broadcast-dialog"
import type { BroadcastPlanLimitOutcome } from "@/features/broadcasts/lib/broadcast-plan-limit"
+import type { BroadcastResourceWithRelations } from "@/features/broadcasts/schema/resource"
+
+type BroadcastModel = BroadcastResourceWithRelations
/** Echoes the key back so assertions never depend on the English copy. */
vi.mock("next-intl", () => ({
@@ -338,3 +340,53 @@ describe("ResumeBroadcastDialog for a repeating broadcast", () => {
expect(text).not.toContain("broadcasts.resumeDialog.templateDescription")
})
})
+
+describe("ResumeBroadcastDialog for a broadcast the system stopped", () => {
+ const BLOCKED = {
+ ...BROADCAST,
+ statusReason: "accountPolicyBlocked",
+ statusErrorMessage: "(#2022) commerce messaging disabled",
+ statusInboxId: "inbox-1",
+ statusInbox: { id: "inbox-1", name: "Spring page" },
+ } as BroadcastModel
+
+ test("shows the reason, page name, provider error and the continue-anyway label", () => {
+ const el = renderDialog(BLOCKED)
+ const text = el.textContent ?? ""
+
+ expect(el.querySelector('[role="alert"]')).not.toBeNull()
+ expect(text).toContain("broadcasts.resumeDialog.blocked.title")
+ expect(text).toContain("broadcasts.statusReason.accountPolicyBlocked")
+ expect(text).toContain("Spring page")
+ expect(text).toContain("(#2022) commerce messaging disabled")
+ expect(text).toContain("broadcasts.resumeDialog.blocked.description")
+ expect(text).toContain("broadcasts.resumeDialog.blocked.confirm")
+ expect(text).not.toContain("actions.resume")
+ expect(text).not.toContain("broadcasts.resumeDialog.description")
+ })
+
+ test("omits the page line when the page was deleted", () => {
+ const el = renderDialog({ ...BLOCKED, statusInbox: null } as BroadcastModel)
+ expect(el.textContent).not.toContain(
+ "broadcasts.resumeDialog.blocked.pageLabel",
+ )
+ expect(el.querySelector('[role="alert"]')).not.toBeNull()
+ })
+
+ test("also warns for a paused repeating series", () => {
+ const el = renderDialog({ ...BLOCKED, ...REPEATING } as BroadcastModel)
+ expect(el.querySelector('[role="alert"]')).not.toBeNull()
+ expect(el.textContent).not.toContain(
+ "broadcasts.resumeDialog.templateDescription",
+ )
+ })
+
+ test("a manually stopped broadcast shows no warning and the normal label", () => {
+ const el = renderDialog()
+ expect(el.querySelector('[role="alert"]')).toBeNull()
+ expect(el.textContent).toContain("actions.resume")
+ expect(el.textContent).not.toContain(
+ "broadcasts.resumeDialog.blocked.confirm",
+ )
+ })
+})
diff --git a/apps/builder/__tests__/send-queue-notice.test.tsx b/apps/builder/__tests__/send-queue-notice.test.tsx
new file mode 100644
index 0000000000..8303d5e4fd
--- /dev/null
+++ b/apps/builder/__tests__/send-queue-notice.test.tsx
@@ -0,0 +1,77 @@
+import { act } from "react"
+import { createRoot, type Root } from "react-dom/client"
+import { afterEach, describe, expect, test, vi } from "vitest"
+import { SendQueueNotice } from "@/features/messages/components/send-queue-notice"
+
+vi.mock("next-intl", () => ({
+ useTranslations: () => (key: string, values?: { count?: number }) =>
+ values?.count === undefined ? key : `${key}:${values.count}`,
+}))
+
+let container: HTMLDivElement | null = null
+let root: Root | null = null
+
+const render = (props: Parameters[0]) => {
+ Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true })
+ container = document.createElement("div")
+ document.body.append(container)
+ root = createRoot(container)
+ act(() => {
+ root?.render( )
+ })
+ // biome-ignore lint/style/noNonNullAssertion: assigned synchronously above
+ return container!
+}
+
+const buttonWithText = (el: HTMLElement, text: string) =>
+ Array.from(el.querySelectorAll("button")).find((b) => b.textContent === text)
+
+afterEach(() => {
+ act(() => root?.unmount())
+ container?.remove()
+ container = null
+ root = null
+})
+
+describe("SendQueueNotice", () => {
+ test("after a failure it says how many are held and offers only Discard (the resend is on the failed message)", () => {
+ const onDiscard = vi.fn()
+ const onContinue = vi.fn()
+ const el = render({
+ heldCount: 3,
+ reason: "failed",
+ onContinue,
+ onDiscard,
+ })
+
+ expect(el.getAttribute("role")).toBeNull()
+ expect(el.querySelector('[role="alert"]')).not.toBeNull()
+ expect(el.textContent).toContain("messages.sendQueue.failed:3")
+ expect(buttonWithText(el, "messages.sendQueue.continue")).toBeUndefined()
+
+ act(() => {
+ buttonWithText(el, "messages.sendQueue.discard")?.click()
+ })
+ expect(onDiscard).toHaveBeenCalledTimes(1)
+ expect(onContinue).not.toHaveBeenCalled()
+ })
+
+ test("after a lost answer it offers to send the rest or discard them", () => {
+ const onDiscard = vi.fn()
+ const onContinue = vi.fn()
+ const el = render({
+ heldCount: 2,
+ reason: "unconfirmed",
+ onContinue,
+ onDiscard,
+ })
+
+ expect(el.textContent).toContain("messages.sendQueue.unconfirmed:2")
+
+ act(() => {
+ buttonWithText(el, "messages.sendQueue.continue")?.click()
+ })
+ expect(onContinue).toHaveBeenCalledTimes(1)
+ expect(onDiscard).not.toHaveBeenCalled()
+ })
+})
diff --git a/apps/builder/messages/ar.json b/apps/builder/messages/ar.json
index 5a13e181f8..e7cf20c475 100644
--- a/apps/builder/messages/ar.json
+++ b/apps/builder/messages/ar.json
@@ -526,6 +526,11 @@
"paused": "متوقف مؤقتًا",
"ended": "منتهٍ"
},
+ "statusReason": {
+ "accountPolicyBlocked": "تم الإيقاف تلقائيًا: تم حظر حساب القناة من الإرسال بعد مخالفة للسياسات.",
+ "accountSendRestricted": "تم الإيقاف تلقائيًا: حساب القناة مقيّد مؤقتًا من الإرسال.",
+ "page": "الصفحة: {name}"
+ },
"stats": {
"sent": "مُرسَل",
"delivered": "مُسلَّم",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "سيعود \"{name}\" إلى التكرار من الموعد المجدول التالي. تم تخطي عمليات التشغيل أثناء الإيقاف."
+ "templateDescription": "سيعود \"{name}\" إلى التكرار من الموعد المجدول التالي. تم تخطي عمليات التشغيل أثناء الإيقاف.",
+ "blocked": {
+ "title": "تم الإيقاف لأن حساب القناة لا يستطيع الإرسال",
+ "description": "إذا كان الحساب لا يزال محظورًا، ستفشل الرسالة الأولى وسيتوقف البث مرة أخرى. قد يؤدي الإرسال أثناء الحظر إلى تقييد أشد.",
+ "pageLabel": "الصفحة",
+ "errorLabel": "الخطأ من القناة",
+ "confirm": "استئناف على أي حال"
+ }
},
"planLimitDialog": {
"title": "ترقية خطتك",
@@ -4582,6 +4594,12 @@
"cardEnding": "بطاقة تنتهي بـ {lastFourDigits}",
"notCharged": "لم يتم الخصم بعد. اخصمه عبر مزود الدفع.",
"reference": "المرجع {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "فشل إرسال رسالة. أعد إرسالها لمتابعة الإرسال.",
+ "unconfirmed": "تعذّر تأكيد إرسال آخر رسالة. اختر ما إذا كنت تريد متابعة الإرسال.",
+ "continue": "متابعة الإرسال",
+ "discard": "إغلاق"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "تم إلغاء آخر عملية مسح قبل اكتمالها."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "تم الإلغاء"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "إلغاء المسح",
+ "title": "هل تريد إلغاء هذا المسح؟",
+ "description": "يتوقف المسح ويتم الاحتفاظ بالعملاء الذين تم استيرادهم بالفعل. لا يزال عليك الانتظار 24 ساعة من بدء هذا المسح قبل أن تتمكن من مسح صندوق الوارد هذا مرة أخرى.",
+ "keep": "متابعة المسح",
+ "confirm": "إلغاء المسح",
+ "success": "تم إلغاء المسح.",
+ "notRunning": "لا توجد عملية مسح قيد التشغيل لصندوق الوارد هذا.",
+ "failed": "تعذّر إلغاء المسح. يرجى المحاولة مرة أخرى."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/az.json b/apps/builder/messages/az.json
index d26068b2a4..9eb658bcc3 100644
--- a/apps/builder/messages/az.json
+++ b/apps/builder/messages/az.json
@@ -568,6 +568,11 @@
"paused": "Dayandırılıb",
"ended": "Bitib"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Avtomatik dayandırıldı: kanal hesabı siyasət pozuntusuna görə göndərməkdən bloklandı.",
+ "accountSendRestricted": "Avtomatik dayandırıldı: kanal hesabının göndərməsi müvəqqəti məhdudlaşdırılıb.",
+ "page": "Səhifə: {name}"
+ },
"stats": {
"sent": "Göndərilib",
"delivered": "Çatdırılıb",
@@ -716,7 +721,14 @@
"resumeDialog": {
"title": "Kütləvi göndərişə davam et",
"description": "\"{name}\" hələ onu almamış alıcılara göndərilməyə davam edəcək.",
- "templateDescription": "\"{name}\" növbəti planlaşdırılmış vaxtdan yenidən təkrarlanır. Fasilə zamanı icralar keçildi."
+ "templateDescription": "\"{name}\" növbəti planlaşdırılmış vaxtdan yenidən təkrarlanır. Fasilə zamanı icralar keçildi.",
+ "blocked": {
+ "title": "Kanal hesabı göndərə bilmədiyi üçün dayandırıldı",
+ "description": "Hesab hələ də bloklanıbsa, ilk mesaj uğursuz olacaq və yayım yenidən dayanacaq. Bloklu ikən göndərmək daha ağır məhdudiyyətə səbəb ola bilər.",
+ "pageLabel": "Səhifə",
+ "errorLabel": "Kanaldan gələn xəta",
+ "confirm": "Yenə də davam et"
+ }
},
"planLimitDialog": {
"title": "Planınızı yüksəldin",
@@ -5264,6 +5276,12 @@
"cardEnding": "Sonu {lastFourDigits} olan kart",
"notCharged": "Hələ çıxılmayıb. Ödəniş provayderiniz vasitəsilə çıxın.",
"reference": "İstinad {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Mesaj göndərilmədi. Göndərməyə davam etmək üçün onu yenidən göndərin.",
+ "unconfirmed": "Son mesajın göndərildiyini təsdiqləyə bilmədik. Göndərməyə davam edib-etməyəcəyinizi seçin.",
+ "continue": "Göndərməyə davam et",
+ "discard": "Bağla"
}
},
"instagram": {
@@ -6796,7 +6814,8 @@
"total": "Yoxlanmış müştərilərin ümumi sayı: {count}",
"waitCooldown": "Bu funksiyadan yenidən istifadə etmək üçün daha 24 saat gözləməlisiniz.",
"failed": "Son yoxlama uğursuz oldu. Gözləmə müddəti bitdikdən sonra yenidən cəhd edə bilərsiniz.",
- "partial": "Son yoxlama qismən tamamlandı, bəzi söhbətləri idxal etmək mümkün olmadı."
+ "partial": "Son yoxlama qismən tamamlandı, bəzi söhbətləri idxal etmək mümkün olmadı.",
+ "cancelled": "Son skan bitmədən ləğv edildi."
},
"errors": {
"contactScanFromTimeInvalid": "Yoxlanacaq dövrün başlama vaxtı keçmişdə olmalıdır.",
@@ -6822,9 +6841,20 @@
"running": "İcra olunur",
"succeeded": "Uğurlu",
"partial": "Qismən tamamlanıb",
- "failed": "Uğursuz"
+ "failed": "Uğursuz",
+ "cancelled": "Ləğv edildi"
},
"empty": "Hələ yoxlama aparılmayıb."
+ },
+ "cancel": {
+ "button": "Skanı ləğv et",
+ "title": "Bu skan ləğv edilsin?",
+ "description": "Skan dayanır və artıq idxal edilmiş müştərilər saxlanılır. Bu gələn qutusunu yenidən skan etmək üçün yenə də bu skanın başlanmasından 24 saat gözləməlisiniz.",
+ "keep": "Skana davam et",
+ "confirm": "Skanı ləğv et",
+ "success": "Skan ləğv edildi.",
+ "notRunning": "Bu gələn qutusu üçün işləyən skan yoxdur.",
+ "failed": "Skan ləğv edilə bilmədi. Yenidən cəhd edin."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/da.json b/apps/builder/messages/da.json
index 3ea1754413..a2d33dd9a3 100644
--- a/apps/builder/messages/da.json
+++ b/apps/builder/messages/da.json
@@ -526,6 +526,11 @@
"paused": "På pause",
"ended": "Afsluttet"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Stoppet automatisk: kanalkontoen blev blokeret fra at sende efter en overtrædelse af reglerne.",
+ "accountSendRestricted": "Stoppet automatisk: kanalkontoen er midlertidigt begrænset i at sende.",
+ "page": "Side: {name}"
+ },
"stats": {
"sent": "Sendt",
"delivered": "Leveret",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" gentages igen fra næste planlagte tidspunkt. Kørsler under pausen blev sprunget over."
+ "templateDescription": "\"{name}\" gentages igen fra næste planlagte tidspunkt. Kørsler under pausen blev sprunget over.",
+ "blocked": {
+ "title": "Stoppet, fordi kanalkontoen ikke kan sende",
+ "description": "Hvis kontoen stadig er blokeret, mislykkes den første besked, og udsendelsen stopper igen. At sende, mens kontoen er blokeret, kan føre til en strengere begrænsning.",
+ "pageLabel": "Side",
+ "errorLabel": "Fejl fra kanalen",
+ "confirm": "Genoptag alligevel"
+ }
},
"planLimitDialog": {
"title": "Opgrader dit abonnement",
@@ -4582,6 +4594,12 @@
"cardEnding": "Kort, der ender på {lastFourDigits}",
"notCharged": "Ikke trukket endnu. Træk beløbet via din betalingsudbyder.",
"reference": "Reference {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "En besked kunne ikke sendes. Send den igen for at fortsætte.",
+ "unconfirmed": "Vi kunne ikke bekræfte, at den sidste besked blev sendt. Vælg, om du vil fortsætte.",
+ "continue": "Fortsæt med at sende",
+ "discard": "Afvis"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "Den seneste scanning blev annulleret, før den var færdig."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Annulleret"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Annuller scanning",
+ "title": "Annuller denne scanning?",
+ "description": "Scanningen stopper, og allerede importerede kunder bevares. Du skal stadig vente 24 timer fra start af denne scanning, før du kan scanne denne indbakke igen.",
+ "keep": "Fortsæt scanning",
+ "confirm": "Annuller scanning",
+ "success": "Scanningen er annulleret.",
+ "notRunning": "Der kører ingen scanning for denne indbakke.",
+ "failed": "Scanningen kunne ikke annulleres. Prøv igen."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/de.json b/apps/builder/messages/de.json
index 42e71dce11..b0c030a3d5 100644
--- a/apps/builder/messages/de.json
+++ b/apps/builder/messages/de.json
@@ -526,6 +526,11 @@
"paused": "Pausiert",
"ended": "Beendet"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Automatisch gestoppt: Das Kanalkonto wurde nach einem Richtlinienverstoß am Senden gehindert.",
+ "accountSendRestricted": "Automatisch gestoppt: Das Kanalkonto ist vorübergehend am Senden eingeschränkt.",
+ "page": "Seite: {name}"
+ },
"stats": {
"sent": "Gesendet",
"delivered": "Zugestellt",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "„{name}“ wiederholt sich wieder ab dem nächsten geplanten Zeitpunkt. Läufe während der Pause wurden übersprungen."
+ "templateDescription": "„{name}“ wiederholt sich wieder ab dem nächsten geplanten Zeitpunkt. Läufe während der Pause wurden übersprungen.",
+ "blocked": {
+ "title": "Gestoppt, weil das Kanalkonto nicht senden kann",
+ "description": "Ist das Konto weiterhin gesperrt, schlägt die erste Nachricht fehl und der Broadcast stoppt erneut. Senden trotz Sperre kann zu einer stärkeren Einschränkung führen.",
+ "pageLabel": "Seite",
+ "errorLabel": "Fehler vom Kanal",
+ "confirm": "Trotzdem fortsetzen"
+ }
},
"planLimitDialog": {
"title": "Tarif upgraden",
@@ -4582,6 +4594,12 @@
"cardEnding": "Karte mit Endung {lastFourDigits}",
"notCharged": "Noch nicht belastet. Belasten Sie sie über Ihren Zahlungsanbieter.",
"reference": "Referenz {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Eine Nachricht konnte nicht gesendet werden. Sende sie erneut, um fortzufahren.",
+ "unconfirmed": "Wir konnten nicht bestätigen, dass die letzte Nachricht gesendet wurde. Wähle, ob du weitersenden möchtest.",
+ "continue": "Weitersenden",
+ "discard": "Schließen"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "Der letzte Scan wurde vor dem Abschluss abgebrochen."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Abgebrochen"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Scan abbrechen",
+ "title": "Diesen Scan abbrechen?",
+ "description": "Der Scan wird gestoppt, bereits importierte Kunden bleiben erhalten. Sie müssen ab dem Start dieses Scans trotzdem 24 Stunden warten, bevor Sie diesen Posteingang erneut scannen können.",
+ "keep": "Weiter scannen",
+ "confirm": "Scan abbrechen",
+ "success": "Scan abgebrochen.",
+ "notRunning": "Für diesen Posteingang läuft kein Scan.",
+ "failed": "Der Scan konnte nicht abgebrochen werden. Bitte versuchen Sie es erneut."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/en.json b/apps/builder/messages/en.json
index 54a3cd8589..65108b7d35 100644
--- a/apps/builder/messages/en.json
+++ b/apps/builder/messages/en.json
@@ -568,6 +568,11 @@
"paused": "Paused",
"ended": "Ended"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Stopped automatically: the channel account was blocked from sending after a policy violation.",
+ "accountSendRestricted": "Stopped automatically: the channel account is temporarily restricted from sending.",
+ "page": "Page: {name}"
+ },
"stats": {
"sent": "Sent",
"delivered": "Delivered",
@@ -716,7 +721,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" starts repeating again from its next scheduled time. Runs during the pause were skipped."
+ "templateDescription": "\"{name}\" starts repeating again from its next scheduled time. Runs during the pause were skipped.",
+ "blocked": {
+ "title": "Stopped because the channel account cannot send",
+ "description": "If the account is still blocked, the first message will fail and the broadcast will stop again. Sending while blocked can lead to a heavier restriction.",
+ "pageLabel": "Page",
+ "errorLabel": "Error from the channel",
+ "confirm": "Resume anyway"
+ }
},
"planLimitDialog": {
"title": "Upgrade your plan",
@@ -5264,6 +5276,12 @@
"cardEnding": "Card ending {lastFourDigits}",
"notCharged": "Not charged yet. Charge it with your payment provider.",
"reference": "Reference {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "A message failed to send. Resend it to continue sending.",
+ "unconfirmed": "We couldn't confirm the last message was sent. Choose whether to keep sending.",
+ "continue": "Keep sending",
+ "discard": "Dismiss"
}
},
"instagram": {
@@ -6796,7 +6814,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "The last scan was cancelled before it finished."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6822,9 +6841,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Cancelled"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Cancel scan",
+ "title": "Cancel this scan?",
+ "description": "The scan stops and customers already imported are kept. You still have to wait 24 hours from when this scan started before you can scan this inbox again.",
+ "keep": "Keep scanning",
+ "confirm": "Cancel scan",
+ "success": "Scan cancelled.",
+ "notRunning": "No scan is running for this inbox.",
+ "failed": "Could not cancel the scan. Please try again."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/es.json b/apps/builder/messages/es.json
index dfcd516437..7e8677d400 100644
--- a/apps/builder/messages/es.json
+++ b/apps/builder/messages/es.json
@@ -526,6 +526,11 @@
"paused": "En pausa",
"ended": "Finalizada"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Detenido automáticamente: la cuenta del canal fue bloqueada para enviar tras una infracción de las políticas.",
+ "accountSendRestricted": "Detenido automáticamente: la cuenta del canal tiene el envío restringido temporalmente.",
+ "page": "Página: {name}"
+ },
"stats": {
"sent": "Enviado",
"delivered": "Entregado",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "«{name}» vuelve a repetirse desde su próxima hora programada. Las ejecuciones durante la pausa se omitieron."
+ "templateDescription": "«{name}» vuelve a repetirse desde su próxima hora programada. Las ejecuciones durante la pausa se omitieron.",
+ "blocked": {
+ "title": "Detenido porque la cuenta del canal no puede enviar",
+ "description": "Si la cuenta sigue bloqueada, el primer mensaje fallará y la difusión se detendrá de nuevo. Enviar mientras está bloqueada puede provocar una restricción más severa.",
+ "pageLabel": "Página",
+ "errorLabel": "Error del canal",
+ "confirm": "Reanudar de todos modos"
+ }
},
"planLimitDialog": {
"title": "Mejora tu plan",
@@ -4582,6 +4594,12 @@
"cardEnding": "Tarjeta terminada en {lastFourDigits}",
"notCharged": "Aún no se ha cobrado. Cóbralo con tu proveedor de pagos.",
"reference": "Referencia {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "No se pudo enviar un mensaje. Reenvíalo para seguir enviando.",
+ "unconfirmed": "No pudimos confirmar que el último mensaje se envió. Elige si quieres seguir enviando.",
+ "continue": "Seguir enviando",
+ "discard": "Descartar"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "El último escaneo se canceló antes de terminar."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Cancelado"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Cancelar escaneo",
+ "title": "¿Cancelar este escaneo?",
+ "description": "El escaneo se detiene y los clientes ya importados se conservan. Aun así, debes esperar 24 horas desde que empezó este escaneo para volver a escanear esta bandeja.",
+ "keep": "Seguir escaneando",
+ "confirm": "Cancelar escaneo",
+ "success": "Escaneo cancelado.",
+ "notRunning": "No hay ningún escaneo en curso para esta bandeja.",
+ "failed": "No se pudo cancelar el escaneo. Inténtalo de nuevo."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/fi.json b/apps/builder/messages/fi.json
index 30b4d8ec96..139cac4255 100644
--- a/apps/builder/messages/fi.json
+++ b/apps/builder/messages/fi.json
@@ -526,6 +526,11 @@
"paused": "Tauolla",
"ended": "Päättynyt"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Pysäytetty automaattisesti: kanavan tili estettiin lähettämästä käytäntörikkomuksen vuoksi.",
+ "accountSendRestricted": "Pysäytetty automaattisesti: kanavan tilin lähettämistä on tilapäisesti rajoitettu.",
+ "page": "Sivu: {name}"
+ },
"stats": {
"sent": "Lähetetty",
"delivered": "Toimitettu",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" alkaa toistua uudelleen seuraavasta ajastetusta ajankohdasta. Tauon aikaiset ajot ohitettiin."
+ "templateDescription": "\"{name}\" alkaa toistua uudelleen seuraavasta ajastetusta ajankohdasta. Tauon aikaiset ajot ohitettiin.",
+ "blocked": {
+ "title": "Pysäytetty, koska kanavan tili ei voi lähettää",
+ "description": "Jos tili on edelleen estetty, ensimmäinen viesti epäonnistuu ja lähetys pysähtyy uudelleen. Lähettäminen eston aikana voi johtaa ankarampaan rajoitukseen.",
+ "pageLabel": "Sivu",
+ "errorLabel": "Kanavan virhe",
+ "confirm": "Jatka silti"
+ }
},
"planLimitDialog": {
"title": "Päivitä tilauksesi",
@@ -4582,6 +4594,12 @@
"cardEnding": "Kortti, joka päättyy {lastFourDigits}",
"notCharged": "Ei vielä veloitettu. Veloita maksupalveluntarjoajasi kautta.",
"reference": "Viite {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Viestin lähetys epäonnistui. Lähetä se uudelleen jatkaaksesi.",
+ "unconfirmed": "Emme voineet vahvistaa, että viimeisin viesti lähetettiin. Valitse, jatketaanko lähettämistä.",
+ "continue": "Jatka lähettämistä",
+ "discard": "Hylkää"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "Viimeisin skannaus peruttiin ennen valmistumista."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Peruttu"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Peruuta skannaus",
+ "title": "Perutaanko tämä skannaus?",
+ "description": "Skannaus pysähtyy ja jo tuodut asiakkaat säilyvät. Sinun on silti odotettava 24 tuntia tämän skannauksen alusta ennen kuin voit skannata tämän postilaatikon uudelleen.",
+ "keep": "Jatka skannausta",
+ "confirm": "Peruuta skannaus",
+ "success": "Skannaus peruttu.",
+ "notRunning": "Tälle postilaatikolle ei ole käynnissä skannausta.",
+ "failed": "Skannausta ei voitu perua. Yritä uudelleen."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/fr.json b/apps/builder/messages/fr.json
index 2c3b5fac6e..cee6e1f1a8 100644
--- a/apps/builder/messages/fr.json
+++ b/apps/builder/messages/fr.json
@@ -526,6 +526,11 @@
"paused": "En pause",
"ended": "Terminé"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Arrêté automatiquement : le compte du canal a été bloqué en envoi après une violation des règles.",
+ "accountSendRestricted": "Arrêté automatiquement : le compte du canal est temporairement limité en envoi.",
+ "page": "Page : {name}"
+ },
"stats": {
"sent": "Envoyé",
"delivered": "Distribué",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "« {name} » reprend à partir de sa prochaine échéance. Les envois pendant la pause ont été ignorés."
+ "templateDescription": "« {name} » reprend à partir de sa prochaine échéance. Les envois pendant la pause ont été ignorés.",
+ "blocked": {
+ "title": "Arrêté car le compte du canal ne peut pas envoyer",
+ "description": "Si le compte est toujours bloqué, le premier message échouera et la diffusion s'arrêtera de nouveau. Envoyer alors que le compte est bloqué peut entraîner une restriction plus sévère.",
+ "pageLabel": "Page",
+ "errorLabel": "Erreur du canal",
+ "confirm": "Reprendre quand même"
+ }
},
"planLimitDialog": {
"title": "Mettre votre forfait à niveau",
@@ -4582,6 +4594,12 @@
"cardEnding": "Carte se terminant par {lastFourDigits}",
"notCharged": "Pas encore débité. Débitez-le via votre prestataire de paiement.",
"reference": "Référence {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Un message n'a pas pu être envoyé. Renvoyez-le pour continuer.",
+ "unconfirmed": "Nous n'avons pas pu confirmer l'envoi du dernier message. Choisissez de continuer ou non.",
+ "continue": "Continuer l'envoi",
+ "discard": "Ignorer"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "Le dernier scan a été annulé avant la fin."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Annulé"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Annuler le scan",
+ "title": "Annuler ce scan ?",
+ "description": "Le scan s'arrête et les clients déjà importés sont conservés. Vous devez tout de même attendre 24 heures après le début de ce scan avant de pouvoir scanner de nouveau cette boîte de réception.",
+ "keep": "Continuer le scan",
+ "confirm": "Annuler le scan",
+ "success": "Scan annulé.",
+ "notRunning": "Aucun scan n'est en cours pour cette boîte de réception.",
+ "failed": "Impossible d'annuler le scan. Veuillez réessayer."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/he.json b/apps/builder/messages/he.json
index 94724d2fe4..402117e0e8 100644
--- a/apps/builder/messages/he.json
+++ b/apps/builder/messages/he.json
@@ -2227,6 +2227,12 @@
"cardEnding": "כרטיס המסתיים ב-{lastFourDigits}",
"notCharged": "עדיין לא חויב. חייב דרך ספק התשלומים שלך.",
"reference": "אסמכתה {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "שליחת הודעה נכשלה. שלח אותה שוב כדי להמשיך.",
+ "unconfirmed": "לא הצלחנו לאשר שההודעה האחרונה נשלחה. בחר אם להמשיך לשלוח.",
+ "continue": "המשך לשלוח",
+ "discard": "סגור"
}
},
"instagram": {
@@ -3759,7 +3765,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "הסריקה האחרונה בוטלה לפני שהסתיימה."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -3785,9 +3792,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "בוטל"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "ביטול סריקה",
+ "title": "לבטל את הסריקה הזו?",
+ "description": "הסריקה נעצרת והלקוחות שכבר יובאו נשמרים. עדיין צריך להמתין 24 שעות מתחילת הסריקה הזו לפני שאפשר לסרוק שוב את תיבת הדואר הזו.",
+ "keep": "המשך סריקה",
+ "confirm": "ביטול סריקה",
+ "success": "הסריקה בוטלה.",
+ "notRunning": "אין סריקה פועלת עבור תיבת הדואר הזו.",
+ "failed": "לא ניתן היה לבטל את הסריקה. נסו שוב."
}
},
"auditLogs": {
@@ -7652,6 +7670,11 @@
"paused": "מושהה",
"ended": "הסתיים"
},
+ "statusReason": {
+ "accountPolicyBlocked": "נעצר אוטומטית: חשבון הערוץ נחסם מלשלוח בעקבות הפרת מדיניות.",
+ "accountSendRestricted": "נעצר אוטומטית: חשבון הערוץ מוגבל זמנית מלשלוח.",
+ "page": "עמוד: {name}"
+ },
"stats": {
"sent": "נשלח",
"delivered": "נמסר",
@@ -7800,7 +7823,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" יחזור על עצמו שוב מהמועד המתוזמן הבא. הרצות בזמן ההשהיה דולגו."
+ "templateDescription": "\"{name}\" יחזור על עצמו שוב מהמועד המתוזמן הבא. הרצות בזמן ההשהיה דולגו.",
+ "blocked": {
+ "title": "נעצר כי חשבון הערוץ לא יכול לשלוח",
+ "description": "אם החשבון עדיין חסום, ההודעה הראשונה תיכשל והשידור ייעצר שוב. שליחה בזמן החסימה עלולה להוביל להגבלה חמורה יותר.",
+ "pageLabel": "עמוד",
+ "errorLabel": "שגיאה מהערוץ",
+ "confirm": "המשך בכל זאת"
+ }
},
"planLimitDialog": {
"title": "שדרוג התוכנית",
diff --git a/apps/builder/messages/id.json b/apps/builder/messages/id.json
index a1e76b6046..9f3438fb9e 100644
--- a/apps/builder/messages/id.json
+++ b/apps/builder/messages/id.json
@@ -526,6 +526,11 @@
"paused": "Dijeda",
"ended": "Berakhir"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Dihentikan otomatis: akun kanal diblokir dari pengiriman karena pelanggaran kebijakan.",
+ "accountSendRestricted": "Dihentikan otomatis: akun kanal dibatasi sementara dari pengiriman.",
+ "page": "Halaman: {name}"
+ },
"stats": {
"sent": "Terkirim",
"delivered": "Tersampaikan",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" berulang kembali mulai waktu terjadwal berikutnya. Eksekusi selama jeda telah dilewati."
+ "templateDescription": "\"{name}\" berulang kembali mulai waktu terjadwal berikutnya. Eksekusi selama jeda telah dilewati.",
+ "blocked": {
+ "title": "Dihentikan karena akun kanal tidak dapat mengirim",
+ "description": "Jika akun masih diblokir, pesan pertama akan gagal dan siaran akan berhenti lagi. Mengirim saat diblokir dapat menyebabkan pembatasan yang lebih berat.",
+ "pageLabel": "Halaman",
+ "errorLabel": "Galat dari kanal",
+ "confirm": "Tetap lanjutkan"
+ }
},
"planLimitDialog": {
"title": "Tingkatkan paket Anda",
@@ -4582,6 +4594,12 @@
"cardEnding": "Kartu berakhiran {lastFourDigits}",
"notCharged": "Belum ditagih. Tagih melalui penyedia pembayaran Anda.",
"reference": "Referensi {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Sebuah pesan gagal terkirim. Kirim ulang untuk melanjutkan.",
+ "unconfirmed": "Kami tidak dapat memastikan pesan terakhir terkirim. Pilih apakah akan terus mengirim.",
+ "continue": "Lanjutkan pengiriman",
+ "discard": "Tutup"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "Pemindaian terakhir dibatalkan sebelum selesai."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Dibatalkan"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Batalkan pemindaian",
+ "title": "Batalkan pemindaian ini?",
+ "description": "Pemindaian berhenti dan pelanggan yang sudah diimpor tetap disimpan. Anda tetap harus menunggu 24 jam sejak pemindaian ini dimulai sebelum dapat memindai kotak masuk ini lagi.",
+ "keep": "Lanjutkan pemindaian",
+ "confirm": "Batalkan pemindaian",
+ "success": "Pemindaian dibatalkan.",
+ "notRunning": "Tidak ada pemindaian yang berjalan untuk kotak masuk ini.",
+ "failed": "Pemindaian tidak dapat dibatalkan. Silakan coba lagi."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/it.json b/apps/builder/messages/it.json
index f68a3d3e9e..82a997e6d5 100644
--- a/apps/builder/messages/it.json
+++ b/apps/builder/messages/it.json
@@ -2204,6 +2204,11 @@
"paused": "In pausa",
"ended": "Terminata"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Interrotto automaticamente: l'account del canale è stato bloccato dall'invio dopo una violazione delle norme.",
+ "accountSendRestricted": "Interrotto automaticamente: l'account del canale è temporaneamente limitato nell'invio.",
+ "page": "Pagina: {name}"
+ },
"stats": {
"sent": "Inviato",
"delivered": "Consegnato",
@@ -2352,7 +2357,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "«{name}» riprende a ripetersi dal prossimo orario pianificato. Le esecuzioni durante la pausa sono state saltate."
+ "templateDescription": "«{name}» riprende a ripetersi dal prossimo orario pianificato. Le esecuzioni durante la pausa sono state saltate.",
+ "blocked": {
+ "title": "Interrotto perché l'account del canale non può inviare",
+ "description": "Se l'account è ancora bloccato, il primo messaggio fallirà e la trasmissione si interromperà di nuovo. Inviare mentre è bloccato può causare una restrizione più severa.",
+ "pageLabel": "Pagina",
+ "errorLabel": "Errore dal canale",
+ "confirm": "Riprendi comunque"
+ }
},
"planLimitDialog": {
"title": "Aggiorna il tuo piano",
@@ -4582,6 +4594,12 @@
"cardEnding": "Carta che termina con {lastFourDigits}",
"notCharged": "Non ancora addebitato. Addebitalo tramite il tuo fornitore di pagamenti.",
"reference": "Riferimento {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Un messaggio non è stato inviato. Invialo di nuovo per continuare.",
+ "unconfirmed": "Non siamo riusciti a confermare l'invio dell'ultimo messaggio. Scegli se continuare a inviare.",
+ "continue": "Continua a inviare",
+ "discard": "Ignora"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "L'ultima scansione è stata annullata prima del termine."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Annullata"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Annulla scansione",
+ "title": "Annullare questa scansione?",
+ "description": "La scansione si ferma e i clienti già importati vengono mantenuti. Devi comunque attendere 24 ore dall'avvio di questa scansione prima di poter scansionare di nuovo questa casella.",
+ "keep": "Continua la scansione",
+ "confirm": "Annulla scansione",
+ "success": "Scansione annullata.",
+ "notRunning": "Nessuna scansione è in corso per questa casella.",
+ "failed": "Impossibile annullare la scansione. Riprova."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/ja.json b/apps/builder/messages/ja.json
index 532e56a98a..13737841f2 100644
--- a/apps/builder/messages/ja.json
+++ b/apps/builder/messages/ja.json
@@ -526,6 +526,11 @@
"paused": "一時停止中",
"ended": "終了"
},
+ "statusReason": {
+ "accountPolicyBlocked": "自動停止: ポリシー違反によりチャネルアカウントの送信がブロックされました。",
+ "accountSendRestricted": "自動停止: チャネルアカウントの送信が一時的に制限されています。",
+ "page": "ページ: {name}"
+ },
"stats": {
"sent": "送信済み",
"delivered": "配信済み",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "「{name}」は次の予定時刻から再び繰り返されます。一時停止中の実行はスキップされました。"
+ "templateDescription": "「{name}」は次の予定時刻から再び繰り返されます。一時停止中の実行はスキップされました。",
+ "blocked": {
+ "title": "チャネルアカウントが送信できないため停止しました",
+ "description": "アカウントがまだブロックされている場合、最初のメッセージは失敗し、配信は再び停止します。ブロック中に送信すると、より厳しい制限につながる可能性があります。",
+ "pageLabel": "ページ",
+ "errorLabel": "チャネルからのエラー",
+ "confirm": "それでも再開"
+ }
},
"planLimitDialog": {
"title": "プランをアップグレード",
@@ -4559,6 +4571,12 @@
"cardEnding": "末尾 {lastFourDigits} のカード",
"notCharged": "まだ請求されていません。決済プロバイダーで請求してください。",
"reference": "参照番号 {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "メッセージを送信できませんでした。再送信すると続行できます。",
+ "unconfirmed": "最後のメッセージが送信されたか確認できませんでした。送信を続けるか選択してください。",
+ "continue": "送信を続ける",
+ "discard": "閉じる"
}
},
"instagram": {
@@ -6091,7 +6109,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "前回のスキャンは完了前にキャンセルされました。"
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6117,9 +6136,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "キャンセル済み"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "スキャンをキャンセル",
+ "title": "このスキャンをキャンセルしますか?",
+ "description": "スキャンは停止し、取り込み済みの顧客は保持されます。このインボックスを再度スキャンするには、このスキャンの開始から24時間待つ必要があります。",
+ "keep": "スキャンを続ける",
+ "confirm": "スキャンをキャンセル",
+ "success": "スキャンをキャンセルしました。",
+ "notRunning": "このインボックスで実行中のスキャンはありません。",
+ "failed": "スキャンをキャンセルできませんでした。もう一度お試しください。"
}
},
"auditLogs": {
diff --git a/apps/builder/messages/nl.json b/apps/builder/messages/nl.json
index 6f8991abae..014491adbe 100644
--- a/apps/builder/messages/nl.json
+++ b/apps/builder/messages/nl.json
@@ -526,6 +526,11 @@
"paused": "Gepauzeerd",
"ended": "Beëindigd"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Automatisch gestopt: het kanaalaccount is geblokkeerd voor verzenden na een beleidsovertreding.",
+ "accountSendRestricted": "Automatisch gestopt: het kanaalaccount is tijdelijk beperkt in verzenden.",
+ "page": "Pagina: {name}"
+ },
"stats": {
"sent": "Verzonden",
"delivered": "Afgeleverd",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" herhaalt zich weer vanaf het volgende geplande tijdstip. Uitvoeringen tijdens de pauze zijn overgeslagen."
+ "templateDescription": "\"{name}\" herhaalt zich weer vanaf het volgende geplande tijdstip. Uitvoeringen tijdens de pauze zijn overgeslagen.",
+ "blocked": {
+ "title": "Gestopt omdat het kanaalaccount niet kan verzenden",
+ "description": "Als het account nog steeds geblokkeerd is, mislukt het eerste bericht en stopt de broadcast opnieuw. Verzenden terwijl het account geblokkeerd is kan tot een zwaardere beperking leiden.",
+ "pageLabel": "Pagina",
+ "errorLabel": "Fout van het kanaal",
+ "confirm": "Toch hervatten"
+ }
},
"planLimitDialog": {
"title": "Upgrade je abonnement",
@@ -4582,6 +4594,12 @@
"cardEnding": "Kaart eindigend op {lastFourDigits}",
"notCharged": "Nog niet afgeschreven. Schrijf af via je betaalprovider.",
"reference": "Referentie {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Een bericht kon niet worden verzonden. Verstuur het opnieuw om door te gaan.",
+ "unconfirmed": "We konden niet bevestigen dat het laatste bericht is verzonden. Kies of je wilt doorgaan met verzenden.",
+ "continue": "Doorgaan met verzenden",
+ "discard": "Sluiten"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "De laatste scan is geannuleerd voordat hij klaar was."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Geannuleerd"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Scan annuleren",
+ "title": "Deze scan annuleren?",
+ "description": "De scan stopt en reeds geïmporteerde klanten blijven behouden. U moet nog steeds 24 uur wachten vanaf het begin van deze scan voordat u deze inbox opnieuw kunt scannen.",
+ "keep": "Blijven scannen",
+ "confirm": "Scan annuleren",
+ "success": "Scan geannuleerd.",
+ "notRunning": "Er loopt geen scan voor deze inbox.",
+ "failed": "De scan kon niet worden geannuleerd. Probeer het opnieuw."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/pt-BR.json b/apps/builder/messages/pt-BR.json
index d6fd96f2b9..7231566f1d 100644
--- a/apps/builder/messages/pt-BR.json
+++ b/apps/builder/messages/pt-BR.json
@@ -526,6 +526,11 @@
"paused": "Pausada",
"ended": "Encerrada"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Parado automaticamente: a conta do canal foi bloqueada para envio após uma violação de política.",
+ "accountSendRestricted": "Parado automaticamente: a conta do canal está temporariamente restrita para envio.",
+ "page": "Página: {name}"
+ },
"stats": {
"sent": "Enviado",
"delivered": "Entregue",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" volta a se repetir a partir do próximo horário agendado. As execuções durante a pausa foram ignoradas."
+ "templateDescription": "\"{name}\" volta a se repetir a partir do próximo horário agendado. As execuções durante a pausa foram ignoradas.",
+ "blocked": {
+ "title": "Parado porque a conta do canal não pode enviar",
+ "description": "Se a conta ainda estiver bloqueada, a primeira mensagem falhará e a transmissão será interrompida novamente. Enviar enquanto bloqueada pode levar a uma restrição mais severa.",
+ "pageLabel": "Página",
+ "errorLabel": "Erro do canal",
+ "confirm": "Retomar mesmo assim"
+ }
},
"planLimitDialog": {
"title": "Faça upgrade do seu plano",
@@ -4559,6 +4571,12 @@
"cardEnding": "Cartão final {lastFourDigits}",
"notCharged": "Ainda não cobrado. Faça a cobrança pelo seu provedor de pagamento.",
"reference": "Referência {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Uma mensagem não foi enviada. Reenvie-a para continuar.",
+ "unconfirmed": "Não foi possível confirmar o envio da última mensagem. Escolha se quer continuar enviando.",
+ "continue": "Continuar enviando",
+ "discard": "Dispensar"
}
},
"instagram": {
@@ -5747,7 +5765,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "A última verificação foi cancelada antes de terminar."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -5773,9 +5792,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Cancelada"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Cancelar verificação",
+ "title": "Cancelar esta verificação?",
+ "description": "A verificação é interrompida e os clientes já importados são mantidos. Você ainda precisa esperar 24 horas desde o início desta verificação para verificar esta caixa de entrada novamente.",
+ "keep": "Continuar verificando",
+ "confirm": "Cancelar verificação",
+ "success": "Verificação cancelada.",
+ "notRunning": "Nenhuma verificação está em andamento nesta caixa de entrada.",
+ "failed": "Não foi possível cancelar a verificação. Tente novamente."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/pt-PT.json b/apps/builder/messages/pt-PT.json
index 861885a9fc..1ee1511d7b 100644
--- a/apps/builder/messages/pt-PT.json
+++ b/apps/builder/messages/pt-PT.json
@@ -526,6 +526,11 @@
"paused": "Pausada",
"ended": "Encerrada"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Parado automaticamente: a conta do canal foi bloqueada para envio após uma violação de política.",
+ "accountSendRestricted": "Parado automaticamente: a conta do canal está temporariamente restringida para envio.",
+ "page": "Página: {name}"
+ },
"stats": {
"sent": "Enviado",
"delivered": "Entregue",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" volta a se repetir a partir do próximo horário agendado. As execuções durante a pausa foram ignoradas."
+ "templateDescription": "\"{name}\" volta a se repetir a partir do próximo horário agendado. As execuções durante a pausa foram ignoradas.",
+ "blocked": {
+ "title": "Parado porque a conta do canal não pode enviar",
+ "description": "Se a conta continuar bloqueada, a primeira mensagem falhará e a difusão será interrompida novamente. Enviar enquanto bloqueada pode levar a uma restrição mais severa.",
+ "pageLabel": "Página",
+ "errorLabel": "Erro do canal",
+ "confirm": "Retomar mesmo assim"
+ }
},
"planLimitDialog": {
"title": "Atualize o seu plano",
@@ -4582,6 +4594,12 @@
"cardEnding": "Cartão terminado em {lastFourDigits}",
"notCharged": "Ainda não cobrado. Cobre através do seu prestador de pagamentos.",
"reference": "Referência {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Uma mensagem não foi enviada. Reenvie-a para continuar.",
+ "unconfirmed": "Não foi possível confirmar o envio da última mensagem. Escolha se quer continuar a enviar.",
+ "continue": "Continuar a enviar",
+ "discard": "Dispensar"
}
},
"instagram": {
@@ -6110,7 +6128,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "A última verificação foi cancelada antes de terminar."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6136,9 +6155,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Cancelada"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Cancelar verificação",
+ "title": "Cancelar esta verificação?",
+ "description": "A verificação é interrompida e os clientes já importados são mantidos. Ainda tem de esperar 24 horas desde o início desta verificação para verificar esta caixa de entrada novamente.",
+ "keep": "Continuar a verificar",
+ "confirm": "Cancelar verificação",
+ "success": "Verificação cancelada.",
+ "notRunning": "Não está em curso nenhuma verificação nesta caixa de entrada.",
+ "failed": "Não foi possível cancelar a verificação. Tente novamente."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/ro.json b/apps/builder/messages/ro.json
index 210a616e31..31a143eb7a 100644
--- a/apps/builder/messages/ro.json
+++ b/apps/builder/messages/ro.json
@@ -1923,6 +1923,11 @@
"paused": "Întrerupt",
"ended": "Încheiat"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Oprit automat: contul canalului a fost blocat la trimitere după o încălcare a politicilor.",
+ "accountSendRestricted": "Oprit automat: contul canalului este restricționat temporar la trimitere.",
+ "page": "Pagină: {name}"
+ },
"stats": {
"sent": "Trimis",
"delivered": "Livrat",
@@ -2071,7 +2076,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "„{name}” se repetă din nou de la următoarea oră programată. Rulările din timpul pauzei au fost omise."
+ "templateDescription": "„{name}” se repetă din nou de la următoarea oră programată. Rulările din timpul pauzei au fost omise.",
+ "blocked": {
+ "title": "Oprit deoarece contul canalului nu poate trimite",
+ "description": "Dacă contul este în continuare blocat, primul mesaj va eșua, iar difuzarea se va opri din nou. Trimiterea cât timp contul este blocat poate duce la o restricție mai severă.",
+ "pageLabel": "Pagină",
+ "errorLabel": "Eroare de la canal",
+ "confirm": "Reia oricum"
+ }
},
"planLimitDialog": {
"title": "Actualizează planul",
@@ -4582,6 +4594,12 @@
"cardEnding": "Card care se termină în {lastFourDigits}",
"notCharged": "Nedebitat încă. Debitați prin furnizorul de plăți.",
"reference": "Referință {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Un mesaj nu a putut fi trimis. Retrimite-l pentru a continua.",
+ "unconfirmed": "Nu am putut confirma că ultimul mesaj a fost trimis. Alege dacă vrei să continui trimiterea.",
+ "continue": "Continuă trimiterea",
+ "discard": "Închide"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "Ultima scanare a fost anulată înainte de a se termina."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Anulată"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Anulează scanarea",
+ "title": "Anulezi această scanare?",
+ "description": "Scanarea se oprește, iar clienții deja importați sunt păstrați. Trebuie totuși să aștepți 24 de ore de la începutul acestei scanări înainte de a putea scana din nou această căsuță.",
+ "keep": "Continuă scanarea",
+ "confirm": "Anulează scanarea",
+ "success": "Scanare anulată.",
+ "notRunning": "Nu rulează nicio scanare pentru această căsuță.",
+ "failed": "Scanarea nu a putut fi anulată. Încearcă din nou."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/sv.json b/apps/builder/messages/sv.json
index f5723f7580..5f33b9bba0 100644
--- a/apps/builder/messages/sv.json
+++ b/apps/builder/messages/sv.json
@@ -763,6 +763,11 @@
"paused": "Pausad",
"ended": "Avslutad"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Stoppad automatiskt: kanalkontot blockerades från att skicka efter ett regelbrott.",
+ "accountSendRestricted": "Stoppad automatiskt: kanalkontot är tillfälligt begränsat från att skicka.",
+ "page": "Sida: {name}"
+ },
"telegramAllContacts": {
"description": "Använd den här meddelandetypen om du vill skicka ett utskick till dina Telegram-kontakter.",
"title": "Telegram"
@@ -840,7 +845,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" börjar upprepas igen från nästa schemalagda tidpunkt. Körningar under pausen hoppades över."
+ "templateDescription": "\"{name}\" börjar upprepas igen från nästa schemalagda tidpunkt. Körningar under pausen hoppades över.",
+ "blocked": {
+ "title": "Stoppad eftersom kanalkontot inte kan skicka",
+ "description": "Om kontot fortfarande är blockerat misslyckas det första meddelandet och utskicket stoppas igen. Att skicka medan kontot är blockerat kan leda till en strängare begränsning.",
+ "pageLabel": "Sida",
+ "errorLabel": "Fel från kanalen",
+ "confirm": "Återuppta ändå"
+ }
},
"planLimitDialog": {
"title": "Uppgradera ditt abonnemang",
@@ -1483,7 +1495,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "Den senaste skanningen avbröts innan den var klar."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -1509,9 +1522,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "Avbruten"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Avbryt skanning",
+ "title": "Avbryta den här skanningen?",
+ "description": "Skanningen stoppas och redan importerade kunder behålls. Du måste fortfarande vänta 24 timmar från att den här skanningen startade innan du kan skanna den här inkorgen igen.",
+ "keep": "Fortsätt skanna",
+ "confirm": "Avbryt skanning",
+ "success": "Skanningen avbröts.",
+ "notRunning": "Ingen skanning pågår för den här inkorgen.",
+ "failed": "Det gick inte att avbryta skanningen. Försök igen."
}
},
"contactAdReferrals": {
@@ -5723,6 +5747,12 @@
"cardEnding": "Kort som slutar på {lastFourDigits}",
"notCharged": "Inte debiterat än. Debitera via din betalleverantör.",
"reference": "Referens {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Ett meddelande kunde inte skickas. Skicka det igen för att fortsätta.",
+ "unconfirmed": "Vi kunde inte bekräfta att det senaste meddelandet skickades. Välj om du vill fortsätta skicka.",
+ "continue": "Fortsätt skicka",
+ "discard": "Avfärda"
}
},
"messenger": {
diff --git a/apps/builder/messages/tr.json b/apps/builder/messages/tr.json
index fd76c7c569..0b59a80139 100644
--- a/apps/builder/messages/tr.json
+++ b/apps/builder/messages/tr.json
@@ -526,6 +526,11 @@
"paused": "Duraklatıldı",
"ended": "Sona erdi"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Otomatik olarak durduruldu: kanal hesabının gönderimi, bir politika ihlali nedeniyle engellendi.",
+ "accountSendRestricted": "Otomatik olarak durduruldu: kanal hesabının gönderimi geçici olarak kısıtlandı.",
+ "page": "Sayfa: {name}"
+ },
"stats": {
"sent": "Gönderildi",
"delivered": "Teslim Edildi",
@@ -674,7 +679,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "\"{name}\" bir sonraki planlanan zamandan itibaren yeniden tekrarlanır. Duraklatma sırasındaki çalıştırmalar atlandı."
+ "templateDescription": "\"{name}\" bir sonraki planlanan zamandan itibaren yeniden tekrarlanır. Duraklatma sırasındaki çalıştırmalar atlandı.",
+ "blocked": {
+ "title": "Kanal hesabı gönderemediği için durduruldu",
+ "description": "Hesap hâlâ engelliyse ilk mesaj başarısız olur ve yayın yeniden durur. Engelliyken göndermek daha ağır bir kısıtlamaya yol açabilir.",
+ "pageLabel": "Sayfa",
+ "errorLabel": "Kanaldan gelen hata",
+ "confirm": "Yine de devam et"
+ }
},
"planLimitDialog": {
"title": "Planınızı yükseltin",
@@ -4582,6 +4594,12 @@
"cardEnding": "{lastFourDigits} ile biten kart",
"notCharged": "Henüz tahsil edilmedi. Ödeme sağlayıcınız üzerinden tahsil edin.",
"reference": "Referans {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Bir mesaj gönderilemedi. Devam etmek için yeniden gönderin.",
+ "unconfirmed": "Son mesajın gönderildiği doğrulanamadı. Göndermeye devam edip etmeyeceğinizi seçin.",
+ "continue": "Göndermeye devam et",
+ "discard": "Kapat"
}
},
"instagram": {
@@ -6114,7 +6132,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "Son tarama bitmeden iptal edildi."
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6140,9 +6159,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "İptal edildi"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "Taramayı iptal et",
+ "title": "Bu tarama iptal edilsin mi?",
+ "description": "Tarama durur ve içe aktarılan müşteriler korunur. Bu gelen kutusunu yeniden taramak için yine de bu taramanın başlangıcından itibaren 24 saat beklemeniz gerekir.",
+ "keep": "Taramaya devam et",
+ "confirm": "Taramayı iptal et",
+ "success": "Tarama iptal edildi.",
+ "notRunning": "Bu gelen kutusu için çalışan bir tarama yok.",
+ "failed": "Tarama iptal edilemedi. Lütfen tekrar deneyin."
}
},
"auditLogs": {
diff --git a/apps/builder/messages/vi.json b/apps/builder/messages/vi.json
index 8f3e82e1ce..a534349e62 100644
--- a/apps/builder/messages/vi.json
+++ b/apps/builder/messages/vi.json
@@ -568,6 +568,11 @@
"paused": "Tạm dừng",
"ended": "Đã kết thúc"
},
+ "statusReason": {
+ "accountPolicyBlocked": "Đã tự động dừng: tài khoản kênh bị chặn gửi tin do vi phạm chính sách.",
+ "accountSendRestricted": "Đã tự động dừng: tài khoản kênh đang bị hạn chế gửi tin tạm thời.",
+ "page": "Trang: {name}"
+ },
"stats": {
"sent": "Đã gửi",
"delivered": "Đã giao",
@@ -716,7 +721,14 @@
"resumeDialog": {
"title": "Tiếp tục broadcast",
"description": "\"{name}\" sẽ tiếp tục gửi đến những người nhận chưa nhận được tin.",
- "templateDescription": "\"{name}\" sẽ lặp lại trở lại từ lần gửi theo lịch tiếp theo. Các lần gửi trong thời gian tạm dừng đã bị bỏ qua."
+ "templateDescription": "\"{name}\" sẽ lặp lại trở lại từ lần gửi theo lịch tiếp theo. Các lần gửi trong thời gian tạm dừng đã bị bỏ qua.",
+ "blocked": {
+ "title": "Đã dừng vì tài khoản kênh không thể gửi tin",
+ "description": "Nếu tài khoản vẫn đang bị chặn, tin đầu tiên sẽ lỗi và chiến dịch sẽ dừng lại. Gửi khi đang bị chặn có thể dẫn đến hạn chế nặng hơn.",
+ "pageLabel": "Trang",
+ "errorLabel": "Lỗi từ kênh",
+ "confirm": "Vẫn tiếp tục"
+ }
},
"planLimitDialog": {
"title": "Nâng cấp gói của bạn",
@@ -4624,6 +4636,12 @@
"cardEnding": "Thẻ đuôi {lastFourDigits}",
"notCharged": "Chưa trừ tiền. Hãy trừ tiền qua cổng thanh toán của bạn.",
"reference": "Mã tham chiếu {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "Một tin nhắn gửi thất bại. Hãy gửi lại để tiếp tục gửi.",
+ "unconfirmed": "Chưa xác nhận được tin nhắn cuối đã gửi. Hãy chọn có tiếp tục gửi hay không.",
+ "continue": "Tiếp tục gửi",
+ "discard": "Bỏ qua"
}
},
"instagram": {
@@ -5819,7 +5837,8 @@
"total": "Tổng số khách hàng quét được: {count}",
"waitCooldown": "Bạn phải chờ sau 24h tiếp theo mới tiếp tục sử dụng được tính năng này.",
"failed": "Lượt quét gần nhất đã thất bại. Bạn có thể thử lại sau khi hết thời gian chờ.",
- "partial": "Lượt quét gần nhất chỉ hoàn tất một phần — một số cuộc hội thoại không thể nhập được."
+ "partial": "Lượt quét gần nhất chỉ hoàn tất một phần — một số cuộc hội thoại không thể nhập được.",
+ "cancelled": "Lần quét gần nhất đã bị hủy trước khi hoàn tất."
},
"errors": {
"contactScanFromTimeInvalid": "Thời gian quét từ phải ở trong quá khứ.",
@@ -5845,9 +5864,20 @@
"running": "Đang chạy",
"succeeded": "Thành công",
"partial": "Một phần",
- "failed": "Thất bại"
+ "failed": "Thất bại",
+ "cancelled": "Đã hủy"
},
"empty": "Chưa có lượt quét nào được chạy."
+ },
+ "cancel": {
+ "button": "Hủy quét",
+ "title": "Hủy lần quét này?",
+ "description": "Việc quét sẽ dừng và các khách hàng đã nhập được giữ lại. Bạn vẫn phải đợi 24 giờ kể từ lúc lần quét này bắt đầu mới quét lại hộp thư này được.",
+ "keep": "Tiếp tục quét",
+ "confirm": "Hủy quét",
+ "success": "Đã hủy lần quét.",
+ "notRunning": "Hộp thư này hiện không có lần quét nào đang chạy.",
+ "failed": "Không thể hủy lần quét. Vui lòng thử lại."
}
},
"errorLogs": {
diff --git a/apps/builder/messages/zh-CN.json b/apps/builder/messages/zh-CN.json
index af3aee276e..7d6395fc9b 100644
--- a/apps/builder/messages/zh-CN.json
+++ b/apps/builder/messages/zh-CN.json
@@ -951,6 +951,11 @@
"paused": "已暂停",
"ended": "已结束"
},
+ "statusReason": {
+ "accountPolicyBlocked": "已自动停止:渠道账号因违反政策而被禁止发送。",
+ "accountSendRestricted": "已自动停止:渠道账号的发送功能被暂时限制。",
+ "page": "主页:{name}"
+ },
"telegramAllContacts": {
"description": "如果您想向您的Telegram 联系人发送广播,请使用此消息类型。",
"title": "Telegram"
@@ -1028,7 +1033,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "“{name}”将从下一个计划时间起重新重复。暂停期间的运行已被跳过。"
+ "templateDescription": "“{name}”将从下一个计划时间起重新重复。暂停期间的运行已被跳过。",
+ "blocked": {
+ "title": "因渠道账号无法发送而停止",
+ "description": "如果账号仍被封禁,第一条消息会失败,群发将再次停止。在封禁期间继续发送可能导致更严厉的限制。",
+ "pageLabel": "主页",
+ "errorLabel": "渠道返回的错误",
+ "confirm": "仍然继续"
+ }
},
"planLimitDialog": {
"title": "升级您的套餐",
@@ -1671,7 +1683,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "上一次扫描在完成前已被取消。"
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -1697,9 +1710,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "已取消"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "取消扫描",
+ "title": "取消此次扫描?",
+ "description": "扫描将停止,已导入的客户会保留。自本次扫描开始起,仍需等待24小时才能再次扫描此收件箱。",
+ "keep": "继续扫描",
+ "confirm": "取消扫描",
+ "success": "扫描已取消。",
+ "notRunning": "此收件箱当前没有正在运行的扫描。",
+ "failed": "无法取消扫描,请重试。"
}
},
"contactAdReferrals": {
@@ -5723,6 +5747,12 @@
"cardEnding": "尾号 {lastFourDigits} 的卡",
"notCharged": "尚未扣款,请通过您的支付服务商扣款。",
"reference": "参考号 {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "有一条消息发送失败。请重新发送以继续。",
+ "unconfirmed": "无法确认最后一条消息是否已发送。请选择是否继续发送。",
+ "continue": "继续发送",
+ "discard": "忽略"
}
},
"messenger": {
diff --git a/apps/builder/messages/zh-TW.json b/apps/builder/messages/zh-TW.json
index ae15ed6db9..8144246a54 100644
--- a/apps/builder/messages/zh-TW.json
+++ b/apps/builder/messages/zh-TW.json
@@ -1905,6 +1905,12 @@
"cardEnding": "末四碼 {lastFourDigits} 的卡",
"notCharged": "尚未扣款,請透過您的金流服務商扣款。",
"reference": "參考編號 {referenceId}"
+ },
+ "sendQueue": {
+ "failed": "有一則訊息傳送失敗。請重新傳送以繼續。",
+ "unconfirmed": "無法確認最後一則訊息是否已傳送。請選擇是否繼續傳送。",
+ "continue": "繼續傳送",
+ "discard": "忽略"
}
},
"productCategories": {
@@ -2480,6 +2486,11 @@
"paused": "已暫停",
"ended": "已結束"
},
+ "statusReason": {
+ "accountPolicyBlocked": "已自動停止:頻道帳號因違反政策而被禁止傳送。",
+ "accountSendRestricted": "已自動停止:頻道帳號的傳送功能暫時受到限制。",
+ "page": "粉絲專頁:{name}"
+ },
"stats": {
"sent": "已傳送",
"delivered": "已交付",
@@ -2628,7 +2639,14 @@
"resumeDialog": {
"title": "Resume broadcast",
"description": "\"{name}\" will continue sending to recipients who have not received it yet.",
- "templateDescription": "「{name}」將從下一個排定時間起重新重複。暫停期間的執行已被略過。"
+ "templateDescription": "「{name}」將從下一個排定時間起重新重複。暫停期間的執行已被略過。",
+ "blocked": {
+ "title": "因頻道帳號無法傳送而停止",
+ "description": "如果帳號仍被封鎖,第一則訊息會失敗,群發將再次停止。在封鎖期間繼續傳送可能導致更嚴厲的限制。",
+ "pageLabel": "粉絲專頁",
+ "errorLabel": "頻道回傳的錯誤",
+ "confirm": "仍然繼續"
+ }
},
"planLimitDialog": {
"title": "升級您的方案",
@@ -6160,7 +6178,8 @@
"total": "Total customers scanned: {count}",
"waitCooldown": "You must wait another 24 hours before you can use this feature again.",
"failed": "The last scan failed. You can try again once the cooldown ends.",
- "partial": "The last scan finished partially — some conversations could not be imported."
+ "partial": "The last scan finished partially — some conversations could not be imported.",
+ "cancelled": "上一次掃描在完成前已被取消。"
},
"errors": {
"contactScanFromTimeInvalid": "Scan-from time must be in the past.",
@@ -6186,9 +6205,20 @@
"running": "Running",
"succeeded": "Succeeded",
"partial": "Partial",
- "failed": "Failed"
+ "failed": "Failed",
+ "cancelled": "已取消"
},
"empty": "No scans have been run yet."
+ },
+ "cancel": {
+ "button": "取消掃描",
+ "title": "取消此次掃描?",
+ "description": "掃描將停止,已匯入的客戶會保留。自本次掃描開始起,仍需等待24小時才能再次掃描此收件匣。",
+ "keep": "繼續掃描",
+ "confirm": "取消掃描",
+ "success": "掃描已取消。",
+ "notRunning": "此收件匣目前沒有正在執行的掃描。",
+ "failed": "無法取消掃描,請重試。"
}
},
"auditLogs": {
diff --git a/apps/builder/src/features/broadcasts/api/public.ts b/apps/builder/src/features/broadcasts/api/public.ts
index 3c9cb1885e..58f91b0d56 100644
--- a/apps/builder/src/features/broadcasts/api/public.ts
+++ b/apps/builder/src/features/broadcasts/api/public.ts
@@ -392,7 +392,7 @@ export const broadcastsPublicRouter = {
path: BROADCAST_STOP_TOKEN_PATH,
summary: "Stop broadcast",
description:
- "Stops a broadcast while it is sending and returns its id. On a repeating broadcast (status `recurring`) it pauses the schedule: no new runs start, a run already sending carries on. Allowed even when the workspace trial has expired, like the builder. Call `broadcasts.get` to confirm its state first, or use `broadcasts.moveToDraft` for scheduled broadcasts.",
+ "Stops a broadcast while it is sending and returns its id. On a repeating broadcast (status `recurring`) it pauses the schedule: no new runs start, a run already sending carries on. Allowed even when the workspace trial has expired, like the builder. Call `broadcasts.get` to confirm its state first, or use `broadcasts.moveToDraft` for scheduled broadcasts. The system also stops a broadcast on its own when the channel page is blocked from sending: the broadcast then has a `statusReason` (and `statusErrorMessage`, `statusInboxId`) in `broadcasts.get`.",
tags: ["Broadcasts"],
spec: mcpSpec({ visibility: "default" }),
})
@@ -419,7 +419,7 @@ export const broadcastsPublicRouter = {
path: "/v1/broadcasts/{id}/resume",
summary: "Resume stopped broadcast",
description:
- "Resumes sending a stopped broadcast where it left off. On a paused repeating broadcast it restarts the schedule and returns `nextRunAt`; slots that passed while it was paused are not sent. Only matches a broadcast whose status is `cancelled`; 404 otherwise. Use `broadcasts.stop` to pause a sending broadcast.",
+ "Resumes sending a stopped broadcast where it left off. On a paused repeating broadcast it restarts the schedule and returns `nextRunAt`; slots that passed while it was paused are not sent. Only matches a broadcast whose status is `cancelled`; 404 otherwise. Use `broadcasts.stop` to pause a sending broadcast. A broadcast the system stopped (it has a `statusReason`) is resumed the same way and is not blocked, but if the channel page is still blocked from sending the first message fails and it stops again, and sending while blocked can lead to a heavier restriction: check the page is unblocked first. Resuming clears `statusReason`.",
tags: ["Broadcasts"],
})
.input(
diff --git a/apps/builder/src/features/broadcasts/broadcast-detail-dialog.tsx b/apps/builder/src/features/broadcasts/broadcast-detail-dialog.tsx
index 89dc13e1bb..fb57ccd9c8 100644
--- a/apps/builder/src/features/broadcasts/broadcast-detail-dialog.tsx
+++ b/apps/builder/src/features/broadcasts/broadcast-detail-dialog.tsx
@@ -27,6 +27,7 @@ import { BroadcastDetailField } from "./components/broadcast-detail-field"
import { BroadcastDetailFlows } from "./components/broadcast-detail-flows"
import { BroadcastDetailTemplates } from "./components/broadcast-detail-templates"
import { BroadcastStatusBadge } from "./components/broadcast-status-badge"
+import { BroadcastStatusReason } from "./components/broadcast-status-reason"
import { useBroadcastTemplateDetails } from "./hooks/use-broadcast-template-details"
import {
resolveBroadcastPageFlows,
@@ -131,11 +132,14 @@ export function BroadcastDetailDialog({
+
+
+
+
}
/>
),
cell: ({ row }) => (
-
+
+
+
+
),
enableSorting: false,
enableHiding: false,
diff --git a/apps/builder/src/features/broadcasts/components/broadcast-runs-view.tsx b/apps/builder/src/features/broadcasts/components/broadcast-runs-view.tsx
index 24bd9c0574..a0f41658ba 100644
--- a/apps/builder/src/features/broadcasts/components/broadcast-runs-view.tsx
+++ b/apps/builder/src/features/broadcasts/components/broadcast-runs-view.tsx
@@ -21,6 +21,7 @@ import { BroadcastRunGroup } from "./broadcast-run-group"
import { BroadcastRunUpcoming } from "./broadcast-run-upcoming"
import { BroadcastSeriesSummary } from "./broadcast-series-summary"
import { BroadcastStatusBadge } from "./broadcast-status-badge"
+import { BroadcastStatusReason } from "./broadcast-status-reason"
const GROUPS_PER_PAGE = 31
const SKELETON_ROW_KEYS = ["a", "b", "c", "d"] as const
@@ -88,6 +89,7 @@ export function BroadcastRunsView({
status={broadcast.status}
/>
+
{broadcast.recurrence?.pausedAt && (
+}
+
+/**
+ * Why the system stopped a broadcast (a blocked channel page), in red under
+ * the status. Renders nothing for a broadcast a person stopped or that runs.
+ */
+export function BroadcastStatusReason({
+ broadcast,
+}: BroadcastStatusReasonProps) {
+ const t = useTranslations()
+
+ if (!broadcast.statusReason) {
+ return null
+ }
+
+ return (
+
+ {t(`broadcasts.statusReason.${broadcast.statusReason}`)}
+ {broadcast.statusInbox && (
+
+ {t("broadcasts.statusReason.page", {
+ name: broadcast.statusInbox.name,
+ })}
+
+ )}
+
+ )
+}
diff --git a/apps/builder/src/features/broadcasts/components/resume-broadcast-dialog.tsx b/apps/builder/src/features/broadcasts/components/resume-broadcast-dialog.tsx
index 80fbd7153a..09d7aa53c9 100644
--- a/apps/builder/src/features/broadcasts/components/resume-broadcast-dialog.tsx
+++ b/apps/builder/src/features/broadcasts/components/resume-broadcast-dialog.tsx
@@ -5,7 +5,6 @@ import {
BROADCAST_MAX_SEND_RATE_PER_MINUTE,
isRecurringTemplate,
} from "@chatbotx.io/database/partials"
-import type { BroadcastModel } from "@chatbotx.io/database/types"
import { InputNumberField } from "@chatbotx.io/ui/components/form/input-number-field"
import { Button } from "@chatbotx.io/ui/components/ui/button"
import {
@@ -29,11 +28,12 @@ import {
type ResumeBroadcastSchema,
resumeBroadcastSchema,
} from "../schema/action"
+import type { BroadcastResourceWithRelations } from "../schema/resource"
import { BroadcastPlanLimitDialog } from "./broadcast-plan-limit-dialog"
import { useBroadcastTransitionActionCallbacks } from "./broadcast-transition-dialog"
const resolveResumeFormDefaults = (
- broadcast: BroadcastModel | null,
+ broadcast: BroadcastResourceWithRelations | null,
): ResumeBroadcastSchema => ({
sendRatePerMinute: broadcast?.sendRatePerMinute ?? null,
})
@@ -42,13 +42,55 @@ const resumeBroadcastDialogSchema = resumeBroadcastSchema.transform((data) => ({
sendRatePerMinute: data.sendRatePerMinute ?? null,
}))
+/** Shown when the system stopped the broadcast: resuming overrides a warning. */
+function BlockedAccountWarning({
+ broadcast,
+}: {
+ broadcast: BroadcastResourceWithRelations
+}) {
+ const t = useTranslations()
+
+ return (
+
+
+ {t("broadcasts.resumeDialog.blocked.title")}
+
+ {broadcast.statusReason && (
+
{t(`broadcasts.statusReason.${broadcast.statusReason}`)}
+ )}
+ {broadcast.statusInbox && (
+
+
+ {t("broadcasts.resumeDialog.blocked.pageLabel")}:
+ {" "}
+ {broadcast.statusInbox.name}
+
+ )}
+ {broadcast.statusErrorMessage && (
+
+
+ {t("broadcasts.resumeDialog.blocked.errorLabel")}:
+ {" "}
+ {broadcast.statusErrorMessage}
+
+ )}
+
+ {t("broadcasts.resumeDialog.blocked.description")}
+
+
+ )
+}
+
export function ResumeBroadcastDialog({
broadcast,
open,
onOpenChange,
onSuccess,
}: {
- broadcast: BroadcastModel | null
+ broadcast: BroadcastResourceWithRelations | null
open: boolean
onOpenChange: (open: boolean) => void
onSuccess?: () => void
@@ -98,15 +140,21 @@ export function ResumeBroadcastDialog({
>
{t("broadcasts.resumeDialog.title")}
-
- {t(
- broadcast && isRecurringTemplate(broadcast)
- ? "broadcasts.resumeDialog.templateDescription"
- : "broadcasts.resumeDialog.description",
- { name: broadcast?.name ?? "" },
- )}
-
+ {/* A system-stopped broadcast shows the warning below instead of the reassuring copy. */}
+ {!broadcast?.statusReason && (
+
+ {t(
+ broadcast && isRecurringTemplate(broadcast)
+ ? "broadcasts.resumeDialog.templateDescription"
+ : "broadcasts.resumeDialog.description",
+ { name: broadcast?.name ?? "" },
+ )}
+
+ )}
+ {broadcast?.statusReason && (
+
+ )}
)}
- {t("actions.resume")}
+ {t(
+ broadcast?.statusReason
+ ? "broadcasts.resumeDialog.blocked.confirm"
+ : "actions.resume",
+ )}
diff --git a/apps/builder/src/features/broadcasts/schema/resource.ts b/apps/builder/src/features/broadcasts/schema/resource.ts
index ae33b11e8f..fd9216a1a6 100644
--- a/apps/builder/src/features/broadcasts/schema/resource.ts
+++ b/apps/builder/src/features/broadcasts/schema/resource.ts
@@ -1,3 +1,4 @@
+import { broadcastStatusReasons } from "@chatbotx.io/database/partials"
import {
broadcastModel,
createSelectSchema,
@@ -45,6 +46,8 @@ type BroadcastRecurrenceSummary = Pick<
export type BroadcastResourceWithRelations = BroadcastResource & {
recurrence?: BroadcastRecurrenceSummary | null
parent?: Pick | null
+ /** The page whose send error stopped the broadcast (see `statusReason`); null once that page is deleted. */
+ statusInbox?: Pick | null
flow?: Pick | null
integrationWhatsapp?: Pick | null
integrationMessenger?: Pick | null
@@ -66,6 +69,22 @@ export const publicBroadcastResource = createSelectSchema(broadcastModel)
sendRatePerMinute: true,
})
.extend({
+ statusReason: z
+ .enum(broadcastStatusReasons.options)
+ .nullish()
+ .describe(
+ "Set when the system (not a person) stopped the broadcast: `accountPolicyBlocked` or `accountSendRestricted` — the channel page is blocked from sending, so every recipient would fail. Cleared on resume. Check the page is unblocked before resuming: if it is not, the first message fails and the broadcast stops again.",
+ ),
+ statusErrorMessage: z
+ .string()
+ .nullish()
+ .describe("The provider's error text behind `statusReason`."),
+ statusInboxId: z
+ .string()
+ .nullish()
+ .describe(
+ "The inbox (channel page) whose send error caused `statusReason`.",
+ ),
parentBroadcastId: z
.string()
.nullish()
diff --git a/apps/builder/src/features/chat/chat-layout.tsx b/apps/builder/src/features/chat/chat-layout.tsx
index 3641c16aee..337f14383a 100644
--- a/apps/builder/src/features/chat/chat-layout.tsx
+++ b/apps/builder/src/features/chat/chat-layout.tsx
@@ -17,6 +17,7 @@ import { useIsMobileState } from "@chatbotx.io/ui/hooks/use-mobile"
import { Loader2Icon } from "lucide-react"
import { useTranslations } from "next-intl"
import { useEffect, useState } from "react"
+import { SendQueueRunner } from "@/features/messages/components/send-queue-runner"
import { useConversationIdParam } from "../conversations/hooks/use-conversation-id-param"
import type { ConversationResource } from "../conversations/schema/resource"
import { useCallPlaybackStore } from "../messages/store/call-playback-store"
@@ -127,6 +128,7 @@ export const ChatLayout = (props: ChatLayoutProps) => {
user goes back to the list, and the realtime socket must not go with it.
*/}
+
{/*
The VoIP provider (single `useWhatsappVoipCall` peer/hook instance),
the call panel and `WhatsappCallInfoSheet` now
diff --git a/apps/builder/src/features/chat/chat-realtime.tsx b/apps/builder/src/features/chat/chat-realtime.tsx
index 9c8ee50ae4..a8f188595e 100644
--- a/apps/builder/src/features/chat/chat-realtime.tsx
+++ b/apps/builder/src/features/chat/chat-realtime.tsx
@@ -41,6 +41,7 @@ export function ChatRealtime() {
patchContactInboxThreadControl,
resumeConversationHeadRefresh,
scheduleConversationHeadRefresh,
+ settleSendResult,
updateContact,
updateConversations,
updateMessageContentAttributes,
@@ -57,6 +58,7 @@ export function ChatRealtime() {
patchContactInboxThreadControl: state.patchContactInboxThreadControl,
resumeConversationHeadRefresh: state.resumeConversationHeadRefresh,
scheduleConversationHeadRefresh: state.scheduleConversationHeadRefresh,
+ settleSendResult: state.settleSendResult,
updateContact: state.updateContact,
updateConversations: state.updateConversations,
updateMessageContentAttributes: state.updateMessageContentAttributes,
@@ -227,6 +229,8 @@ export function ChatRealtime() {
event.data.clientId,
event.data.error,
)
+ // The same event is the composer queue's answer for the message it sent.
+ settleSendResult(event.data)
},
messageUpdated: (event) => {
flushPendingCreatedMessages()
diff --git a/apps/builder/src/features/chat/store/chat-store.ts b/apps/builder/src/features/chat/store/chat-store.ts
index 5d8a3a8080..059fd3ec1c 100644
--- a/apps/builder/src/features/chat/store/chat-store.ts
+++ b/apps/builder/src/features/chat/store/chat-store.ts
@@ -22,6 +22,14 @@ import {
parseThreadControlEvent,
type ThreadControlSnapshotPatch,
} from "@/features/conversations/utils/thread-control"
+import {
+ createSendQueue,
+ isSendQueueIdle,
+ type SendQueue,
+ type SendResultSignal,
+ settleSend,
+} from "@/features/messages/lib/send-queue"
+import type { CreateMessageWithRoutingBypassRequest } from "@/features/messages/schema/mutation"
import type {
MessageResource,
MessageResourceWithRelations,
@@ -183,6 +191,10 @@ export type ChatState = {
// active facebook post (for comment conversations)
activePost: PostDetails | null
+
+ // Per-conversation composer send queue. Deliberately outside the message
+ // thread state: switching conversations must not lose queued messages.
+ sendQueues: Record>
}
// `messages`/`nextCursorMessage`/`hasNextMessagePage`/`messagesConversationId`
// must be seeded together or not at all: a `messages` seed without its
@@ -299,6 +311,24 @@ export type ChatActions = {
clientId: string | undefined,
error: string | null,
) => void
+ // Applies a change to one conversation's composer send queue.
+ updateSendQueue: (
+ conversationId: string,
+ update: (
+ queue: SendQueue,
+ ) => SendQueue,
+ ) => void
+ // Applies a change to every conversation's queue. A private reply is queued
+ // under the comment's conversation but stored (and resent) under the DM's, so
+ // the queue a resend must unlock is not always the message's own.
+ updateAllSendQueues: (
+ update: (
+ queue: SendQueue,
+ conversationId: string,
+ ) => SendQueue,
+ ) => void
+ // Feeds the channel's answer for a message into every send queue.
+ settleSendResult: (signal: SendResultSignal) => void
assignMessageCommentId: (messageId: string, commentId: string) => void
updateMessageContentAttributes: (
messageId: string,
@@ -572,6 +602,15 @@ const warnIfActiveConversationUnlisted = (
}
}
+/** Drops queues with nothing left to do, so the map holds only live conversations. */
+const pruneIdleSendQueues = (
+ queues: ChatState["sendQueues"],
+ now: number,
+): ChatState["sendQueues"] =>
+ Object.fromEntries(
+ Object.entries(queues).filter(([, queue]) => !isSendQueueIdle(queue, now)),
+ )
+
export const createChatStore = (initialState: ChatStoreInitialState = {}) => {
warnIfActiveConversationUnlisted(initialState)
@@ -607,6 +646,7 @@ export const createChatStore = (initialState: ChatStoreInitialState = {}) => {
...conversationListDefaults(),
filters: {},
...messageThreadDefaults(),
+ sendQueues: {},
...restInitialState,
...messagesSeed,
@@ -1146,6 +1186,54 @@ export const createChatStore = (initialState: ChatStoreInitialState = {}) => {
})
},
+ updateSendQueue: (conversationId, update) => {
+ set((state) => ({
+ sendQueues: pruneIdleSendQueues(
+ {
+ ...state.sendQueues,
+ [conversationId]: update(
+ state.sendQueues[conversationId] ??
+ createSendQueue(),
+ ),
+ },
+ Date.now(),
+ ),
+ }))
+ },
+
+ updateAllSendQueues: (update) => {
+ set((state) => {
+ let changed = false
+ const sendQueues: ChatState["sendQueues"] = {}
+ for (const [conversationId, queue] of Object.entries(
+ state.sendQueues,
+ )) {
+ const next = update(queue, conversationId)
+ changed ||= next !== queue
+ sendQueues[conversationId] = next
+ }
+ return changed ? { sendQueues } : state
+ })
+ },
+
+ settleSendResult: (signal) => {
+ const now = Date.now()
+ set((state) => {
+ let changed = false
+ const sendQueues: ChatState["sendQueues"] = {}
+ for (const [conversationId, queue] of Object.entries(
+ state.sendQueues,
+ )) {
+ const settled = settleSend(queue, signal, now)
+ changed ||= settled !== queue
+ sendQueues[conversationId] = settled
+ }
+ return changed
+ ? { sendQueues: pruneIdleSendQueues(sendQueues, now) }
+ : state
+ })
+ },
+
assignMessageCommentId: (messageId, commentId) => {
set(
(state) =>
diff --git a/apps/builder/src/features/contact-scan/actions/cancel-contact-scan.action.ts b/apps/builder/src/features/contact-scan/actions/cancel-contact-scan.action.ts
new file mode 100644
index 0000000000..7455c12282
--- /dev/null
+++ b/apps/builder/src/features/contact-scan/actions/cancel-contact-scan.action.ts
@@ -0,0 +1,39 @@
+"use server"
+
+import { contactScanService } from "@chatbotx.io/business"
+import {
+ type WorkspaceIdRequestParams,
+ workspaceIdrequestParams,
+} from "@/features/common/schema"
+import { workspaceActionClientAllowExpired } from "@/lib/safe-action"
+import { requireUnrestrictedContactsScope } from "../lib/require-unrestricted-contacts-scope"
+import {
+ type CancelContactScanRequest,
+ type CancelContactScanResponse,
+ cancelContactScanRequest,
+} from "../schema/action"
+
+/**
+ * Allowed after the trial expires (invariant 14: cancel, like delete and
+ * disconnect, must keep working). An assigned-only member is denied, as for
+ * scheduling and reading the status.
+ */
+export const cancelContactScanAction = workspaceActionClientAllowExpired
+ .bindArgsSchemas(workspaceIdrequestParams)
+ .inputSchema(cancelContactScanRequest)
+ .action(
+ async ({
+ bindArgsParsedInputs: [workspaceId],
+ parsedInput,
+ }: {
+ bindArgsParsedInputs: WorkspaceIdRequestParams
+ parsedInput: CancelContactScanRequest
+ }): Promise => {
+ await requireUnrestrictedContactsScope(workspaceId)
+
+ return await contactScanService.cancel({
+ workspaceId,
+ inboxId: parsedInput.inboxId,
+ })
+ },
+ )
diff --git a/apps/builder/src/features/contact-scan/api/public.ts b/apps/builder/src/features/contact-scan/api/public.ts
index 660e294fe5..7dbb3101bf 100644
--- a/apps/builder/src/features/contact-scan/api/public.ts
+++ b/apps/builder/src/features/contact-scan/api/public.ts
@@ -1,12 +1,15 @@
import { contactScanService } from "@chatbotx.io/business"
import {
possibleErrorsOnListingResource,
+ possibleErrorsOnMutatingResource,
possibleErrorsOnSchedulingContactScan,
} from "@/lib/orpc/orpc-error-helper"
import { workspaceTokenAuthAPIForScope } from "@/orpc"
import { listContactScanHistoryRows } from "../lib/contact-scan-history"
import { getContactScanStatus } from "../lib/get-contact-scan-status"
import {
+ cancelContactScanPublicRequest,
+ cancelContactScanPublicResponse,
getContactScanStatusPublicRequest,
getContactScanStatusResponse,
listContactScansPublicRequest,
@@ -84,4 +87,24 @@ export const contactScanPublicRouter = {
scanFromAt: input.scanFromAt,
}),
),
+
+ cancel: workspaceTokenAuthAPI
+ .route({
+ method: "POST",
+ path: "/v1/contact-scans/cancel",
+ summary: "Cancel running Automatic Customer Scan for inbox",
+ description:
+ "Stops the inbox's running scan; contacts already imported are kept. Returns `cancelled: false` (not an error) when nothing is running, so it is safe to call repeatedly. A cancelled scan still counts toward the 24-hour cooldown before the next one (`contactScans.getStatus` shows `availability`), and its status reads `cancelled`. Use `contactScans.getStatus` first to see whether a scan is running.",
+ tags: ["Contacts"],
+ })
+ .input(cancelContactScanPublicRequest)
+ .output(cancelContactScanPublicResponse)
+ .errors(possibleErrorsOnMutatingResource)
+ .handler(
+ async ({ context, input }) =>
+ await contactScanService.cancel({
+ workspaceId: context.workspace.id,
+ inboxId: input.inboxId,
+ }),
+ ),
}
diff --git a/apps/builder/src/features/contact-scan/components/cancel-contact-scan-button.tsx b/apps/builder/src/features/contact-scan/components/cancel-contact-scan-button.tsx
new file mode 100644
index 0000000000..81987a57ee
--- /dev/null
+++ b/apps/builder/src/features/contact-scan/components/cancel-contact-scan-button.tsx
@@ -0,0 +1,101 @@
+"use client"
+
+import { Button } from "@chatbotx.io/ui/components/ui/button"
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@chatbotx.io/ui/components/ui/dialog"
+import { useQueryClient } from "@tanstack/react-query"
+import { Loader2Icon } from "lucide-react"
+import { useTranslations } from "next-intl"
+import { useAction } from "next-safe-action/hooks"
+import { useState } from "react"
+import { toast } from "sonner"
+import { orpc } from "@/lib/orpc/query"
+import { cancelContactScanAction } from "../actions/cancel-contact-scan.action"
+
+type CancelContactScanButtonProps = {
+ workspaceId: string
+ inboxId: string
+}
+
+/**
+ * Cancel for the running scan of one inbox, behind a confirmation. Cancelling is
+ * idempotent server-side (`cancelled: false` when nothing was running), so a
+ * double click or a scan that just finished is reported, not an error.
+ */
+export function CancelContactScanButton({
+ workspaceId,
+ inboxId,
+}: CancelContactScanButtonProps) {
+ const t = useTranslations()
+ const queryClient = useQueryClient()
+ const [open, setOpen] = useState(false)
+
+ const { execute, isPending } = useAction(
+ cancelContactScanAction.bind(null, workspaceId),
+ {
+ onSuccess: ({ data }) => {
+ setOpen(false)
+ if (data?.cancelled) {
+ toast.success(t("contactScan.cancel.success"))
+ } else {
+ toast.info(t("contactScan.cancel.notRunning"))
+ }
+ queryClient.invalidateQueries({
+ queryKey:
+ orpc.contactScanAPIs.getContactScanStatusAuthenticatedAPI.key({
+ input: { workspaceId, inboxId },
+ }),
+ })
+ },
+ onError: ({ error }) => {
+ toast.error(error.serverError ?? t("contactScan.cancel.failed"))
+ },
+ },
+ )
+
+ return (
+
+
+ {t("contactScan.cancel.button")}
+
+ }
+ />
+
+
+ {t("contactScan.cancel.title")}
+
+ {t("contactScan.cancel.description")}
+
+
+
+
+ {t("contactScan.cancel.keep")}
+
+ }
+ />
+ execute({ inboxId })}
+ type="button"
+ variant="destructive"
+ >
+ {isPending && }
+ {t("contactScan.cancel.confirm")}
+
+
+
+
+ )
+}
diff --git a/apps/builder/src/features/contact-scan/components/contact-scan-form.tsx b/apps/builder/src/features/contact-scan/components/contact-scan-form.tsx
index 1fe9090efa..432d0cf4e6 100644
--- a/apps/builder/src/features/contact-scan/components/contact-scan-form.tsx
+++ b/apps/builder/src/features/contact-scan/components/contact-scan-form.tsx
@@ -19,12 +19,14 @@ import { scheduleContactScanAction } from "../actions/schedule-contact-scan.acti
import { DATE_TIME_FORMAT_OPTIONS } from "../lib/constants"
import { scheduleContactScanRequest } from "../schema/action"
import type { GetContactScanStatusResponse } from "../schema/query"
+import { CancelContactScanButton } from "./cancel-contact-scan-button"
import { ContactScanStatusPanel } from "./contact-scan-status-panel"
/** The panel keeps polling until the run settles — or there was never one. */
const SETTLED_STATUSES: GetContactScanStatusResponse["status"][] = [
"succeeded",
"partial",
+ "cancelled",
"failed",
"idle",
]
@@ -159,6 +161,17 @@ export function ContactScanForm({ workspaceId }: { workspaceId: string }) {
+ {/* A running scan can be cancelled; the button disappears once it settles. */}
+ {inboxId &&
+ (data?.status === "init" || data?.status === "running") && (
+
+
+
+ )}
+
{/* Only actionable state gets a button: a centered "Automatic Scan"
submit when a new scan is allowed. When a scan is already running
or the 24h cooldown is active, the status panel above explains
diff --git a/apps/builder/src/features/contact-scan/components/contact-scan-status-panel.tsx b/apps/builder/src/features/contact-scan/components/contact-scan-status-panel.tsx
index f517e8479f..b95fe24df6 100644
--- a/apps/builder/src/features/contact-scan/components/contact-scan-status-panel.tsx
+++ b/apps/builder/src/features/contact-scan/components/contact-scan-status-panel.tsx
@@ -56,13 +56,16 @@ export function ContactScanStatusPanel({ data }: ContactScanStatusPanelProps) {
{statusMessage()}
- {(status === "succeeded" || status === "partial") && latest && (
-
- {t("contactScan.status.total", {
- count: latest.importedContactCount,
- })}
-
- )}
+ {(status === "succeeded" ||
+ status === "partial" ||
+ status === "cancelled") &&
+ latest && (
+
+ {t("contactScan.status.total", {
+ count: latest.importedContactCount,
+ })}
+
+ )}
{!availability.canScan && availability.blockedReason === "cooldown" && (
diff --git a/apps/builder/src/features/contact-scan/lib/contact-scan-history.ts b/apps/builder/src/features/contact-scan/lib/contact-scan-history.ts
index 056d298863..87bc61e00e 100644
--- a/apps/builder/src/features/contact-scan/lib/contact-scan-history.ts
+++ b/apps/builder/src/features/contact-scan/lib/contact-scan-history.ts
@@ -1,7 +1,6 @@
import { contactScanService } from "@chatbotx.io/business"
import type { ContactScanChannel } from "@chatbotx.io/utils/channel"
import type {
- ContactScanRunStatus,
ListContactScanHistoryItem,
ListContactScanHistoryResponse,
} from "../schema/query"
@@ -29,12 +28,9 @@ export async function listContactScanHistoryRows(input: {
data: data.map(
(item): ListContactScanHistoryItem => ({
...item,
- // A `type='contact_scan'` row can never carry the WhatsApp-only
- // `waiting` status, nor any channel outside `CONTACT_SCAN_CHANNELS`
- // — narrow both to the wire's scan-only types here, same as
- // `getContactScanStatus`.
+ // A `type='contact_scan'` row can never carry a channel outside
+ // `CONTACT_SCAN_CHANNELS` — narrow it to the wire's scan-only type.
channel: item.channel as ContactScanChannel,
- status: item.status as ContactScanRunStatus,
}),
),
pageCount,
diff --git a/apps/builder/src/features/contact-scan/lib/get-contact-scan-status.ts b/apps/builder/src/features/contact-scan/lib/get-contact-scan-status.ts
index 900957bbb1..ca03514aaf 100644
--- a/apps/builder/src/features/contact-scan/lib/get-contact-scan-status.ts
+++ b/apps/builder/src/features/contact-scan/lib/get-contact-scan-status.ts
@@ -1,6 +1,5 @@
import { contactScanService } from "@chatbotx.io/business"
import type {
- ContactScanRunStatus,
GetContactScanStatusRequest,
GetContactScanStatusResponse,
} from "../schema/query"
@@ -14,19 +13,5 @@ export async function getContactScanStatus(
input: GetContactScanStatusRequest,
): Promise {
const { workspaceId, inboxId } = input
- const view = await contactScanService.getStatus({ workspaceId, inboxId })
-
- return {
- // `CoexistRunStatus` structurally carries `waiting` (WhatsApp-only), but
- // a `type='contact_scan'` row can never be set to it — narrowing to the
- // wire's scan-only status type here is safe (see schema/query.ts).
- status: view.status as GetContactScanStatusResponse["status"],
- latest: view.latest
- ? {
- ...view.latest,
- status: view.latest.status as ContactScanRunStatus,
- }
- : null,
- availability: view.availability,
- }
+ return await contactScanService.getStatus({ workspaceId, inboxId })
}
diff --git a/apps/builder/src/features/contact-scan/lib/status-copy.ts b/apps/builder/src/features/contact-scan/lib/status-copy.ts
index 3f981a0236..beeaebe20d 100644
--- a/apps/builder/src/features/contact-scan/lib/status-copy.ts
+++ b/apps/builder/src/features/contact-scan/lib/status-copy.ts
@@ -26,6 +26,7 @@ export const contactScanStatusCopy = {
running: { key: "contactScan.status.running", tone: "info" },
succeeded: { key: "contactScan.status.finished", tone: "success" },
partial: { key: "contactScan.status.partial", tone: "warning" },
+ cancelled: { key: "contactScan.status.cancelled", tone: "warning" },
failed: { key: "contactScan.status.failed", tone: "destructive" },
} satisfies Record
diff --git a/apps/builder/src/features/contact-scan/schema/action.ts b/apps/builder/src/features/contact-scan/schema/action.ts
index da6d6bc201..478603f5a2 100644
--- a/apps/builder/src/features/contact-scan/schema/action.ts
+++ b/apps/builder/src/features/contact-scan/schema/action.ts
@@ -26,3 +26,15 @@ export const scheduleContactScanResponse = z.object({
export type ScheduleContactScanResponse = z.infer<
typeof scheduleContactScanResponse
>
+
+export const cancelContactScanRequest = z.object({
+ inboxId: zodBigintAsString(),
+})
+export type CancelContactScanRequest = z.infer
+
+export const cancelContactScanResponse = z.object({
+ cancelled: z.boolean(),
+})
+export type CancelContactScanResponse = z.infer<
+ typeof cancelContactScanResponse
+>
diff --git a/apps/builder/src/features/contact-scan/schema/public.ts b/apps/builder/src/features/contact-scan/schema/public.ts
index 6697233776..1c6e4352fc 100644
--- a/apps/builder/src/features/contact-scan/schema/public.ts
+++ b/apps/builder/src/features/contact-scan/schema/public.ts
@@ -2,6 +2,7 @@ import { zodBigintAsString } from "@chatbotx.io/utils"
import { contactScanChannels } from "@chatbotx.io/utils/channel"
import { z } from "zod"
import { publicListRequest, publicListResponse } from "@/lib/public-api/list"
+import { cancelContactScanResponse } from "./action"
import { contactScanRunStatus, getContactScanStatusRequest } from "./query"
export const getContactScanStatusPublicRequest =
@@ -22,6 +23,22 @@ export const scheduleContactScanPublicRequest = z.object({
),
})
+export const cancelContactScanPublicRequest = z.object({
+ inboxId: zodBigintAsString().describe(
+ "Inbox id. Get it from `inboxes.list`.",
+ ),
+})
+
+export const cancelContactScanPublicResponse = cancelContactScanResponse.extend(
+ {
+ cancelled: z
+ .boolean()
+ .describe(
+ "`true` when a running scan was cancelled; `false` when the inbox has no running scan (not an error).",
+ ),
+ },
+)
+
export const scheduleContactScanPublicResponse = z.object({
runId: z.string(),
})
diff --git a/apps/builder/src/features/contact-scan/schema/query.ts b/apps/builder/src/features/contact-scan/schema/query.ts
index d369bdf1ff..ab86913935 100644
--- a/apps/builder/src/features/contact-scan/schema/query.ts
+++ b/apps/builder/src/features/contact-scan/schema/query.ts
@@ -1,5 +1,5 @@
import {
- coexistScanRunStatuses,
+ contactScanRunStatuses,
contactScanViewStatuses,
} from "@chatbotx.io/database/partials"
import { getSortingStateParser } from "@chatbotx.io/ui/lib/parsers"
@@ -20,14 +20,11 @@ export type GetContactScanStatusRequest = z.infer<
>
/**
- * Statuses a *stored* scan run can carry. Narrower than the DB column's full
- * `coexistRunStatus` enum (which also carries `waiting`, WhatsApp-only —
- * `schema/coexist-sync-run.ts`) because a `type='contact_scan'` row can never
- * be set to it (`ContactScanService.schedule`/the worker engine never write
- * it). `queries/get-contact-scan-status.query.ts` narrows the service's
- * wider `CoexistRunStatus` value down to this wire type at the boundary.
+ * Statuses a scan run is shown as: the stored scan statuses plus the derived
+ * `cancelled` (`resolveContactScanRunStatus` in `@chatbotx.io/business`). The
+ * service already returns this type, so no narrowing cast is needed.
*/
-export const contactScanRunStatus = z.enum(coexistScanRunStatuses)
+export const contactScanRunStatus = z.enum(contactScanRunStatuses)
export type ContactScanRunStatus = z.infer
export const contactScanRunResource = z.object({
diff --git a/apps/builder/src/features/integration-instagram/actions/disconnect-instagram.ts b/apps/builder/src/features/integration-instagram/actions/disconnect-instagram.ts
index 0253254f94..aabd70c0e4 100644
--- a/apps/builder/src/features/integration-instagram/actions/disconnect-instagram.ts
+++ b/apps/builder/src/features/integration-instagram/actions/disconnect-instagram.ts
@@ -1,5 +1,6 @@
import {
coexistService,
+ contactScanService,
instagramIntegrationService,
messengerIntegrationService,
workspaceService,
@@ -81,6 +82,14 @@ export const disconnectInstagram = async (ctx: {
})
}
+ // The contact scan supports both Instagram variants, so unlike coexist
+ // this is not gated on the integration type.
+ await contactScanService.cancelForIntegration({
+ channel: "instagram",
+ integrationId: integrationInstagram.id,
+ tx,
+ })
+
// Polymorphic FK cleanup — stale MetaCapiEvent rows would keep occupying
// the (workspaceId, channel, sourceKey) dedup slot after a reconnect.
await metaCapiEventRepository.deleteByIntegration(
diff --git a/apps/builder/src/features/messages/actions/resend-message.action.ts b/apps/builder/src/features/messages/actions/resend-message.action.ts
new file mode 100644
index 0000000000..100b97d41e
--- /dev/null
+++ b/apps/builder/src/features/messages/actions/resend-message.action.ts
@@ -0,0 +1,34 @@
+"use server"
+
+import { messageService } from "@chatbotx.io/business"
+import { zodBigintAsString } from "@chatbotx.io/utils"
+import { workspaceActionClient } from "@/lib/safe-action"
+import {
+ type ResendMessageRequest,
+ resendMessageRequest,
+} from "../schema/mutation"
+
+/** Shared by the builder action and the public route: one service call. */
+export const resendMessage = async (props: {
+ workspaceId: string
+ conversationId: string
+ parsedInput: ResendMessageRequest
+}) =>
+ await messageService.resendOutgoing({
+ workspaceId: props.workspaceId,
+ conversationId: props.conversationId,
+ messageId: props.parsedInput.id,
+ createdAt: props.parsedInput.createdAt,
+ })
+
+export const resendMessageAction = workspaceActionClient
+ .bindArgsSchemas([zodBigintAsString(), zodBigintAsString()])
+ .inputSchema(resendMessageRequest)
+ .action(async (props) => {
+ const {
+ bindArgsParsedInputs: [workspaceId, conversationId],
+ parsedInput,
+ } = props
+
+ return await resendMessage({ workspaceId, conversationId, parsedInput })
+ })
diff --git a/apps/builder/src/features/messages/api/public.ts b/apps/builder/src/features/messages/api/public.ts
index cdbcec7c2f..95be27fbcd 100644
--- a/apps/builder/src/features/messages/api/public.ts
+++ b/apps/builder/src/features/messages/api/public.ts
@@ -16,6 +16,7 @@ import {
import { changeMessageAttributes } from "@/features/messages/actions/change-message-attributes.action"
import { deleteMessage } from "@/features/messages/actions/delete-message.action"
import { editMessage } from "@/features/messages/actions/edit-message.action"
+import { resendMessage } from "@/features/messages/actions/resend-message.action"
import { getWhatsappFlowResponseView } from "@/features/messages/lib/get-whatsapp-flow-response"
import { sendWhatsappTemplateToConversation } from "@/features/messages/lib/send-whatsapp-template"
import { listMessages } from "@/features/messages/queries"
@@ -34,6 +35,7 @@ import {
possibleErrorsOnDeletingResource,
possibleErrorsOnFindingResource,
possibleErrorsOnMutatingResource,
+ possibleErrorsOnResendingMessage,
productMessageUnresolvable,
} from "@/lib/orpc/orpc-error-helper"
import {
@@ -50,6 +52,7 @@ import {
messageIdPathParam,
messageIdWithCreatedAtParam,
requestCallPermissionPublicRequest,
+ resendMessagePublicResponse,
sendWhatsappTemplatePublicRequest,
} from "../schema/public"
@@ -311,6 +314,28 @@ export const messagesPublicRouter = {
})
}),
+ resend: workspaceTokenAuthAPI
+ .route({
+ method: "POST",
+ path: "/v1/conversations/{conversationId}/messages/{messageId}/resend",
+ summary: "Resend failed message",
+ description:
+ "Queues a message that failed to send for delivery again, whole (a message with several parts or files is resent in full). Only an outgoing message sent by a person or the API that failed and never reached the channel qualifies; a bot or flow message, a message that was delivered, and a public comment reply are refused with 409 `messageNotResendable`, as is a second resend while the first is queued. A private reply is resent as a DM. Use `messages.list` to find a failed message (its `sendError` is set) and its `messageId`/`createdAt`; the result shows up on the message as it is sent or fails again.",
+ successStatus: 202,
+ tags: ["Messages"],
+ })
+ .input(messageIdWithCreatedAtParam)
+ .output(resendMessagePublicResponse)
+ .errors(possibleErrorsOnResendingMessage)
+ .handler(async ({ context, input }) => {
+ await assertConversationAccessForCaller(context, input.conversationId)
+ return await resendMessage({
+ workspaceId: context.workspace.id,
+ conversationId: input.conversationId,
+ parsedInput: { id: input.messageId, createdAt: input.createdAt },
+ })
+ }),
+
changeAttributes: workspaceTokenAuthAPI
.route({
method: "POST",
diff --git a/apps/builder/src/features/messages/components/message-input.tsx b/apps/builder/src/features/messages/components/message-input.tsx
index 1ff2d85635..e55e6d6396 100644
--- a/apps/builder/src/features/messages/components/message-input.tsx
+++ b/apps/builder/src/features/messages/components/message-input.tsx
@@ -26,7 +26,6 @@ import {
XIcon,
} from "lucide-react"
import { useTranslations } from "next-intl"
-import { useAction } from "next-safe-action/hooks"
import {
type KeyboardEvent,
useCallback,
@@ -37,12 +36,7 @@ import {
} from "react"
import { Controller, useWatch } from "react-hook-form"
import { toast } from "sonner"
-import { disableBotAction } from "@/features/conversations/actions/disable-bot.action"
import { useThreadControl } from "@/features/conversations/hooks/use-thread-control"
-import {
- BOT_DISABLE_DURATION_MS,
- isConversationActive,
-} from "@/features/conversations/utils/bot-state"
import { InboxIcon } from "@/features/inboxes/components/inbox-icon"
import { MediaLibraryTrigger } from "@/features/media-library/components/media-library-trigger"
import type { ListFilesResponse } from "@/features/media-library/schema"
@@ -52,12 +46,18 @@ import { authClient } from "@/lib/auth/auth-client"
import { shouldSendOnEnter } from "@/lib/keyboard/should-send-on-enter"
import { useChatStore } from "../../chat/store/chat-store-provider"
import { createMessageAction } from "../actions/create-message.action"
-import { flattenValidationErrors } from "../lib/validation-errors"
+import {
+ discardHeldSends,
+ enqueueSend,
+ isSendQueueLocked,
+ resumeSendQueue,
+} from "../lib/send-queue"
import { createMessageWithRoutingBypassRequest } from "../schema/mutation"
import type { MessageResource } from "../schema/resource"
import { FileUploadPreview } from "./file-upload"
import { InputMenu } from "./input-menu"
import { MediaFilePreview } from "./media-file-preview"
+import { SendQueueNotice } from "./send-queue-notice"
import { ThreadControlLockedComposer } from "./thread-control-locked-composer"
const CHANNEL_WINDOW_SECONDS: Record = {
@@ -98,28 +98,18 @@ export const MessageInput = () => {
const {
appendMessage,
+ markMessagesDeleted,
updateConversationViaMessage,
activeConversationId,
conversations,
- updateConversation,
replyToMessage,
setReplyToMessage,
isPrivateReply,
- markMessageFailed,
messages,
+ sendQueues,
+ updateSendQueue,
} = useChatStore((state) => state)
- const replyToMessageRef = useRef(replyToMessage)
- const selectedMediaFilesRef = useRef(selectedMediaFiles)
-
- useEffect(() => {
- replyToMessageRef.current = replyToMessage
- }, [replyToMessage])
-
- useEffect(() => {
- selectedMediaFilesRef.current = selectedMediaFiles
- }, [selectedMediaFiles])
-
const lastContactComment = useMemo(() => {
for (let i = messages.length - 1; i >= 0; i--) {
const m = messages[i]
@@ -189,25 +179,6 @@ export const MessageInput = () => {
// handover take). Drives the highlighted notice + the send-gate bypass.
const takeOverOnSend = Boolean(threadControl?.inlineReplyTakesOver)
- const { execute: disableBot } = useAction(
- disableBotAction.bind(null, conversation?.workspaceId ?? ""),
- {
- onSuccess: () => {
- if (conversation) {
- updateConversation(conversation.id, {
- botEnabled: false,
- botResumeAt: new Date(Date.now() + BOT_DISABLE_DURATION_MS),
- })
- }
- },
- onError: ({ error }) => {
- if (error.serverError) {
- toast.error(error.serverError)
- }
- },
- },
- )
-
const defaultValues = useMemo(
() => ({
text: "",
@@ -220,7 +191,7 @@ export const MessageInput = () => {
[],
)
- const { form, action } = useHookFormAction(
+ const { form } = useHookFormAction(
createMessageAction.bind(
null,
conversation?.workspaceId ?? "",
@@ -390,7 +361,17 @@ export const MessageInput = () => {
],
)
+ const sendQueue = activeConversationId
+ ? sendQueues[activeConversationId]
+ : undefined
+ // Messages are held behind a failed (or unconfirmed) one: sending more would
+ // only pile on, so the composer waits for the person's decision.
+ const isSendLocked = sendQueue ? isSendQueueLocked(sendQueue) : false
+
const sendMessage = useCallback(async () => {
+ if (isSendLocked) {
+ return
+ }
// Same check as the server, done here so the agent sees which channel
// refuses the images before anything is sent.
if (channelType) {
@@ -412,7 +393,6 @@ export const MessageInput = () => {
}
}
- const submittedFiles = form.getValues("files")
const replyTarget = replyToMessage ?? lastContactComment
const values = {
...form.getValues(),
@@ -428,82 +408,42 @@ export const MessageInput = () => {
return
}
+ if (!conversation) {
+ return
+ }
+
+ // Everything the message needs is in `parsed.data` (files, media, reply
+ // target, routing bypass), so the composer can be cleared at once: the
+ // queue sends it, in order, when its turn comes.
const optimisticMessageId = appendOptimistic(parsed.data)
+ updateSendQueue(conversation.id, (queue) =>
+ enqueueSend(queue, {
+ clientId: values.clientId,
+ input: parsed.data,
+ optimisticMessageId,
+ }),
+ )
form.setValue("text", "")
+ form.setValue("files", [])
+ form.setValue("mediaFileIds", [])
+ setSelectedMediaFiles([])
+ setReplyToMessage(null)
textareaRef.current?.focus()
-
- try {
- const result = await action.executeAsync(parsed.data)
- if (result?.serverError) {
- markMessageFailed(
- optimisticMessageId ?? "",
- parsed.data.clientId,
- result.serverError,
- )
- toast.error(result.serverError)
- return
- }
-
- if (result?.validationErrors) {
- const validationErrors = flattenValidationErrors(
- result.validationErrors,
- )
- for (const validationError of validationErrors) {
- form.setError(validationError.path as never, {
- message: validationError.message,
- })
- }
- const errorMessage =
- validationErrors[0]?.message ?? t("messages.unknownError")
- markMessageFailed(
- optimisticMessageId ?? "",
- parsed.data.clientId,
- errorMessage,
- )
- toast.error(errorMessage)
- return
- }
-
- if (form.getValues("files") === submittedFiles) {
- form.setValue("files", [])
- }
- if (selectedMediaFilesRef.current === selectedMediaFiles) {
- form.setValue("mediaFileIds", [])
- setSelectedMediaFiles([])
- }
- if (replyToMessageRef.current === replyToMessage) {
- setReplyToMessage(null)
- }
- if (result?.data && conversation && isConversationActive(conversation)) {
- disableBot({ ids: [conversation.id] })
- }
- } catch (error) {
- const errorMessage =
- error instanceof Error ? error.message : t("messages.unknownError")
- markMessageFailed(
- optimisticMessageId ?? "",
- parsed.data.clientId,
- errorMessage,
- )
- toast.error(errorMessage)
- }
}, [
- action,
appendOptimistic,
bypassThreadControlLock,
channelType,
conversation,
- disableBot,
form,
imageLimitMessage,
isPrivateReply,
+ isSendLocked,
lastContactComment,
- markMessageFailed,
replyToMessage,
replyKind,
selectedMediaFiles,
setReplyToMessage,
- t,
+ updateSendQueue,
])
// Memoize keyboard handler
@@ -679,6 +619,27 @@ export const MessageInput = () => {
{t("conversationRouting.composer.aiStandbyHint")}
)}
+ {sendQueue && isSendLocked && activeConversationId && (
+
+ updateSendQueue(activeConversationId, (queue) =>
+ resumeSendQueue(queue, Date.now()),
+ )
+ }
+ onDiscard={() => {
+ // The rows shown for the dropped messages must go too, or they
+ // would sit in the thread looking sent.
+ markMessagesDeleted(
+ sendQueue.waiting.flatMap((item) =>
+ item.optimisticMessageId ? [item.optimisticMessageId] : [],
+ ),
+ )
+ updateSendQueue(activeConversationId, discardHeldSends)
+ }}
+ reason={sendQueue.holdReason}
+ />
+ )}
{replyToMessage && (
{isPrivateReply ? (
@@ -827,7 +788,9 @@ export const MessageInput = () => {
aria-label="Send message"
className="px-2 py-1.5 [&_svg]:size-5"
disabled={
- !form.formState.isValid || form.formState.isSubmitting
+ !form.formState.isValid ||
+ form.formState.isSubmitting ||
+ isSendLocked
}
type="submit"
variant="ghost"
diff --git a/apps/builder/src/features/messages/components/message-item.tsx b/apps/builder/src/features/messages/components/message-item.tsx
index 7ebdec6896..d2292cc2b2 100644
--- a/apps/builder/src/features/messages/components/message-item.tsx
+++ b/apps/builder/src/features/messages/components/message-item.tsx
@@ -1,5 +1,6 @@
"use client"
+import { isResendableMessage } from "@chatbotx.io/database/partials"
import type {
MessageButtonTemplate,
MessageStoryReplyEntity,
@@ -53,7 +54,7 @@ import {
import Image from "next/image"
import Link from "next/link"
import { useTranslations } from "next-intl"
-import { useState } from "react"
+import { type ReactNode, useState } from "react"
import { useCopyToClipboard } from "usehooks-ts"
import type { AttachmentResource } from "@/features/attachments/schema/resource"
import { useAttachmentSource } from "@/features/attachments/utils"
@@ -115,6 +116,12 @@ type MessageItemProps = {
* and the guest view keep their existing behaviour.
*/
canPrivateReply?: (message: MessageItemProps["message"]) => boolean
+ /**
+ * The inbox's Resend control, offered next to the error badge of a message
+ * that can be sent again. Passed in (not rendered here) because it needs the
+ * chat store, which the guest webchat view does not have.
+ */
+ renderResend?: (message: MessageItemProps["message"]) => ReactNode
}
export const MessageItem = (props: MessageItemProps) => {
@@ -127,6 +134,7 @@ export const MessageItem = (props: MessageItemProps) => {
onReply,
onPrivateReply,
canPrivateReply,
+ renderResend,
onDelete,
onEdit,
} = props
@@ -328,6 +336,10 @@ export const MessageItem = (props: MessageItemProps) => {
label={t("sendFailed")}
/>
)}
+ {!guestDisplay &&
+ renderResend &&
+ isResendableMessage(message) &&
+ renderResend(message)}
{/* Meta can terminate an ANSWERED call with no audio (e.g. error
138021), so this badge isn't gated on the call having been missed. */}
{whatsappCall?.failureReason && (
diff --git a/apps/builder/src/features/messages/components/resend-message-button.tsx b/apps/builder/src/features/messages/components/resend-message-button.tsx
new file mode 100644
index 0000000000..e175ad458f
--- /dev/null
+++ b/apps/builder/src/features/messages/components/resend-message-button.tsx
@@ -0,0 +1,96 @@
+"use client"
+
+import { Button } from "@chatbotx.io/ui/components/ui/button"
+import { Loader2Icon, RotateCcwIcon } from "lucide-react"
+import { useTranslations } from "next-intl"
+import { useState } from "react"
+import { toast } from "sonner"
+import { useChatStore } from "../../chat/store/chat-store-provider"
+import { resendMessageAction } from "../actions/resend-message.action"
+import {
+ failResendSubmit,
+ isHeldBy,
+ markResendSubmitted,
+} from "../lib/send-queue"
+import type { MessageResource } from "../schema/resource"
+
+type ResendMessageButtonProps = {
+ message: Pick<
+ MessageResource,
+ | "id"
+ | "createdAt"
+ | "conversationId"
+ | "workspaceId"
+ | "sendError"
+ | "clientId"
+ >
+}
+
+/**
+ * Sends a failed message again. Only offered where the service would accept it
+ * (`isResendableMessage`). The error badge clears and the composer queue starts
+ * tracking the resent message *before* the request goes out: the worker can
+ * answer faster than the response returns, and that answer must find the
+ * message already in flight. A refused request puts the failure back.
+ */
+export function ResendMessageButton({ message }: ResendMessageButtonProps) {
+ const t = useTranslations()
+ const markMessageFailed = useChatStore((state) => state.markMessageFailed)
+ const updateSendQueue = useChatStore((state) => state.updateSendQueue)
+ const updateAllSendQueues = useChatStore((state) => state.updateAllSendQueues)
+ const [isPending, setIsPending] = useState(false)
+
+ const resend = async () => {
+ setIsPending(true)
+ markMessageFailed(message.id, undefined, null)
+ const ref = { messageId: message.id, clientId: message.clientId }
+ const now = Date.now()
+ // The queue held for this message may belong to another conversation (a
+ // private reply); the message's own queue tracks it either way.
+ updateAllSendQueues((queue) =>
+ isHeldBy(queue, ref) ? markResendSubmitted(queue, ref, now) : queue,
+ )
+ updateSendQueue(message.conversationId, (queue) =>
+ markResendSubmitted(queue, ref, now),
+ )
+ const restore = (error: string) => {
+ markMessageFailed(message.id, undefined, message.sendError)
+ updateAllSendQueues((queue) => failResendSubmit(queue, message.id))
+ toast.error(error)
+ }
+ try {
+ const result = await resendMessageAction(
+ message.workspaceId,
+ message.conversationId,
+ { id: message.id, createdAt: message.createdAt },
+ )
+ if (result?.serverError) {
+ restore(result.serverError)
+ }
+ } catch (error) {
+ restore(
+ error instanceof Error ? error.message : t("messages.unknownError"),
+ )
+ } finally {
+ setIsPending(false)
+ }
+ }
+
+ return (
+
+ {isPending ? (
+
+ ) : (
+
+ )}
+ {t("actions.resend")}
+
+ )
+}
diff --git a/apps/builder/src/features/messages/components/send-queue-notice.tsx b/apps/builder/src/features/messages/components/send-queue-notice.tsx
new file mode 100644
index 0000000000..4b6a58b08b
--- /dev/null
+++ b/apps/builder/src/features/messages/components/send-queue-notice.tsx
@@ -0,0 +1,65 @@
+"use client"
+
+import { Button } from "@chatbotx.io/ui/components/ui/button"
+import { AlertTriangleIcon } from "lucide-react"
+import { useTranslations } from "next-intl"
+import {
+ SEND_QUEUE_HOLD_REASONS,
+ type SendQueueHoldReason,
+} from "../lib/send-queue"
+
+type SendQueueNoticeProps = {
+ heldCount: number
+ reason: SendQueueHoldReason | null
+ onContinue: () => void
+ onDiscard: () => void
+}
+
+/**
+ * Shown while messages typed after a failed (or unconfirmed) one are held back.
+ * A failed message is resent from its own row; an unconfirmed one needs the
+ * person to say whether to go on. Either way the held messages can be dropped.
+ */
+export function SendQueueNotice({
+ heldCount,
+ reason,
+ onContinue,
+ onDiscard,
+}: SendQueueNoticeProps) {
+ const t = useTranslations()
+ const isUnconfirmed = reason === SEND_QUEUE_HOLD_REASONS.unconfirmed
+
+ return (
+
+
+
+
+ {t(
+ isUnconfirmed
+ ? "messages.sendQueue.unconfirmed"
+ : "messages.sendQueue.failed",
+ { count: heldCount },
+ )}
+
+
+
+ {isUnconfirmed && (
+
+ {t("messages.sendQueue.continue")}
+
+ )}
+
+ {t("messages.sendQueue.discard")}
+
+
+
+ )
+}
diff --git a/apps/builder/src/features/messages/components/send-queue-runner.tsx b/apps/builder/src/features/messages/components/send-queue-runner.tsx
new file mode 100644
index 0000000000..0f51379124
--- /dev/null
+++ b/apps/builder/src/features/messages/components/send-queue-runner.tsx
@@ -0,0 +1,57 @@
+"use client"
+
+import { useAction } from "next-safe-action/hooks"
+import { useCallback } from "react"
+import { toast } from "sonner"
+import { useChatStore } from "@/features/chat/store/chat-store-provider"
+import { disableBotAction } from "@/features/conversations/actions/disable-bot.action"
+import {
+ BOT_DISABLE_DURATION_MS,
+ isConversationActive,
+} from "@/features/conversations/utils/bot-state"
+import { useWorkspaceId } from "@/hooks/routing"
+import { useSendQueueRunner } from "../lib/use-send-queue-runner"
+
+/**
+ * Mounted once beside `ChatRealtime`, outside the panes: on mobile the message
+ * pane unmounts when the user goes back to the list, and queued messages must
+ * keep going out. Once the server has queued a message, a human reply pauses
+ * the conversation's bot.
+ */
+export function SendQueueRunner() {
+ const workspaceId = useWorkspaceId()
+ const conversations = useChatStore((state) => state.conversations)
+ const updateConversation = useChatStore((state) => state.updateConversation)
+
+ const { execute: disableBot } = useAction(
+ disableBotAction.bind(null, workspaceId),
+ {
+ onSuccess: ({ input }) => {
+ for (const id of input.ids) {
+ updateConversation(id, {
+ botEnabled: false,
+ botResumeAt: new Date(Date.now() + BOT_DISABLE_DURATION_MS),
+ })
+ }
+ },
+ onError: ({ error }) => {
+ if (error.serverError) {
+ toast.error(error.serverError)
+ }
+ },
+ },
+ )
+
+ const onSubmitted = useCallback(
+ (conversationId: string) => {
+ const target = conversations.find((item) => item.id === conversationId)
+ if (target && isConversationActive(target)) {
+ disableBot({ ids: [target.id] })
+ }
+ },
+ [conversations, disableBot],
+ )
+
+ useSendQueueRunner({ onSubmitted })
+ return null
+}
diff --git a/apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts b/apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts
new file mode 100644
index 0000000000..e98b3239ef
--- /dev/null
+++ b/apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts
@@ -0,0 +1,359 @@
+import { describe, expect, test } from "vitest"
+import {
+ AGENT_SEND_CONFIRM_TIMEOUT_MS,
+ AGENT_SEND_GAP_MS,
+ createSendQueue,
+ discardHeldSends,
+ enqueueSend,
+ expireInFlightSend,
+ failResendSubmit,
+ failSendSubmit,
+ isSendQueueLocked,
+ markResendSubmitted,
+ markSendSubmitted,
+ nextSendToSubmit,
+ nextSendWakeAt,
+ type QueuedSend,
+ resumeSendQueue,
+ type SendQueue,
+ settleSend,
+} from "../send-queue"
+
+type Input = { text: string }
+
+const send = (clientId: string): QueuedSend
=> ({
+ clientId,
+ input: { text: clientId },
+})
+
+const queueWith = (...ids: string[]): SendQueue
=>
+ ids.reduce(
+ (queue, id) => enqueueSend(queue, send(id)),
+ createSendQueue
(),
+ )
+
+/** Submits the head of the queue at `now`, as the runner does. */
+const submitNext = (queue: SendQueue
, now: number): SendQueue
=> {
+ const next = nextSendToSubmit(queue, now)
+ if (!next) {
+ throw new Error("nothing to submit")
+ }
+ return markSendSubmitted(queue, next.clientId, now)
+}
+
+describe("send queue order and gap", () => {
+ test("an idle queue sends the first message at once", () => {
+ expect(nextSendToSubmit(queueWith("a", "b"), 0)?.clientId).toBe("a")
+ })
+
+ test("the next message waits for the previous one's result", () => {
+ const queue = submitNext(queueWith("a", "b", "c"), 0)
+
+ expect(nextSendToSubmit(queue, 10_000)).toBeNull()
+ })
+
+ test("after the result it waits the gap, then sends in order", () => {
+ let queue = submitNext(queueWith("a", "b", "c"), 0)
+ queue = settleSend(queue, { clientId: "a", error: null }, 100)
+
+ expect(nextSendToSubmit(queue, 100 + AGENT_SEND_GAP_MS - 1)).toBeNull()
+ expect(nextSendToSubmit(queue, 100 + AGENT_SEND_GAP_MS)?.clientId).toBe("b")
+
+ queue = submitNext(queue, 100 + AGENT_SEND_GAP_MS)
+ queue = settleSend(queue, { clientId: "b", error: null }, 700)
+ expect(nextSendToSubmit(queue, 700 + AGENT_SEND_GAP_MS)?.clientId).toBe("c")
+ })
+
+ test("the gap is 500 ms", () => {
+ expect(AGENT_SEND_GAP_MS).toBe(500)
+ })
+
+ test("a result is matched by message id as well as client id", () => {
+ const submitted = submitNext(queueWith("a"), 0)
+ const queue: SendQueue
= {
+ ...submitted,
+ inFlight: { clientId: "a", messageId: "m-1", startedAt: 0 },
+ }
+
+ const settled = settleSend(queue, { messageId: "m-1", error: null }, 5)
+
+ expect(settled.inFlight).toBeNull()
+ })
+
+ test("a result for a message that is not the one in flight changes nothing", () => {
+ const queue = submitNext(queueWith("a", "b"), 0)
+
+ expect(settleSend(queue, { clientId: "other", error: null }, 5)).toBe(queue)
+ expect(settleSend(queue, { messageId: "m-9", error: "boom" }, 5)).toBe(
+ queue,
+ )
+ })
+
+ test("a result with nothing in flight changes nothing", () => {
+ const queue = queueWith("a")
+ expect(settleSend(queue, { clientId: "a", error: null }, 5)).toBe(queue)
+ })
+})
+
+describe("a failure holds what was already queued behind it", () => {
+ test("later messages are held and the queue is locked", () => {
+ let queue = submitNext(queueWith("a", "b", "c"), 0)
+ queue = settleSend(queue, { clientId: "a", error: "refused" }, 10)
+
+ expect(queue.holdReason).toBe("failed")
+ expect(isSendQueueLocked(queue)).toBe(true)
+ expect(queue.waiting.map((item) => item.clientId)).toEqual(["b", "c"])
+ expect(nextSendToSubmit(queue, 1_000_000)).toBeNull()
+ })
+
+ test("a failure with nothing behind it still locks, so a newer message cannot overtake the failed one", () => {
+ let queue = submitNext(queueWith("a"), 0)
+ queue = settleSend(queue, { clientId: "a", error: "refused" }, 10)
+
+ expect(queue.holdReason).toBe("failed")
+ expect(isSendQueueLocked(queue)).toBe(true)
+
+ queue = enqueueSend(queue, send("b"))
+ expect(nextSendToSubmit(queue, 10)).toBeNull()
+ })
+
+ test("a resend while another message is in flight does not take its place", () => {
+ let queue = submitNext(queueWith("b", "c"), 0)
+
+ queue = markResendSubmitted(queue, { messageId: "m-a" }, 20)
+
+ expect(queue.inFlight?.clientId).toBe("b")
+ expect(settleSend(queue, { messageId: "m-a", error: null }, 30)).toBe(queue)
+ })
+
+ test("a refused resend puts the hold back", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = settleSend(
+ queue,
+ { clientId: "a", messageId: "m-a", error: "refused" },
+ 10,
+ )
+ queue = markResendSubmitted(queue, { messageId: "m-a" }, 20)
+
+ queue = failResendSubmit(queue, "m-a")
+
+ expect(queue.inFlight).toBeNull()
+ expect(queue.holdReason).toBe("failed")
+ expect(queue.waiting.map((item) => item.clientId)).toEqual(["b"])
+ })
+
+ test("resending a different failed message does not lift a hold that belongs to another", () => {
+ let queue = submitNext(queueWith("a", "c"), 0)
+ queue = settleSend(
+ queue,
+ { clientId: "a", messageId: "m-a", error: "refused" },
+ 10,
+ )
+
+ queue = markResendSubmitted(queue, { messageId: "m-old" }, 20)
+ expect(queue.holdReason).toBe("failed")
+ expect(queue.inFlight?.messageId).toBe("m-old")
+
+ queue = settleSend(queue, { messageId: "m-old", error: null }, 30)
+ expect(nextSendToSubmit(queue, 10_000)).toBeNull()
+
+ queue = markResendSubmitted(queue, { messageId: "m-a" }, 40)
+ expect(queue.holdReason).toBeNull()
+ })
+
+ test("a hold from a refused submit (only the clientId known) is lifted by resending that row", () => {
+ let queue = submitNext(queueWith("a", "c"), 0)
+ queue = failSendSubmit(queue, "a")
+
+ queue = markResendSubmitted(queue, { messageId: "m-a", clientId: "a" }, 20)
+
+ expect(queue.holdReason).toBeNull()
+ expect(queue.inFlight?.messageId).toBe("m-a")
+ })
+
+ test("resending the held message while another one is in flight lifts the hold now, so the queue is not stranded", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = settleSend(
+ queue,
+ { clientId: "a", messageId: "m-a", error: "refused" },
+ 10,
+ )
+ queue = markResendSubmitted(queue, { messageId: "m-old" }, 20)
+
+ queue = markResendSubmitted(queue, { messageId: "m-a", clientId: "a" }, 25)
+
+ expect(queue.holdReason).toBeNull()
+ expect(queue.inFlight?.messageId).toBe("m-old")
+ queue = settleSend(queue, { messageId: "m-old", error: null }, 30)
+ expect(nextSendToSubmit(queue, 30 + AGENT_SEND_GAP_MS)?.clientId).toBe("b")
+ })
+
+ test("a refused resend on a queue that was not held leaves it unlocked", () => {
+ let queue = markResendSubmitted(
+ createSendQueue
(),
+ { messageId: "m-old" },
+ 0,
+ )
+
+ queue = failResendSubmit(queue, "m-old")
+
+ expect(queue.inFlight).toBeNull()
+ expect(queue.holdReason).toBeNull()
+ expect(isSendQueueLocked(queue)).toBe(false)
+ })
+
+ test("a refused resend of another message keeps the hold that was never lifted", () => {
+ let queue = submitNext(queueWith("a", "c"), 0)
+ queue = settleSend(
+ queue,
+ { clientId: "a", messageId: "m-a", error: "refused" },
+ 10,
+ )
+ queue = markResendSubmitted(queue, { messageId: "m-old" }, 20)
+
+ queue = failResendSubmit(queue, "m-old")
+
+ expect(queue.holdReason).toBe("failed")
+ expect(queue.heldBy?.messageId).toBe("m-a")
+ })
+
+ test("a refused resend that was never tracked changes nothing", () => {
+ const queue = submitNext(queueWith("b"), 0)
+ expect(failResendSubmit(queue, "m-a")).toBe(queue)
+ })
+
+ test("a successful resend lets the held messages continue, after its own result and gap", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = settleSend(
+ queue,
+ { clientId: "a", messageId: "m-a", error: "refused" },
+ 10,
+ )
+
+ queue = markResendSubmitted(queue, { messageId: "m-a" }, 20)
+ expect(queue.holdReason).toBeNull()
+ expect(isSendQueueLocked(queue)).toBe(false)
+ // The resent message is in flight, so "b" still waits for it.
+ expect(nextSendToSubmit(queue, 20)).toBeNull()
+
+ queue = settleSend(queue, { messageId: "m-a", error: null }, 100)
+ expect(nextSendToSubmit(queue, 100 + AGENT_SEND_GAP_MS)?.clientId).toBe("b")
+ })
+
+ test("a resend that fails again holds the queue again", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = settleSend(
+ queue,
+ { clientId: "a", messageId: "m-a", error: "refused" },
+ 10,
+ )
+ queue = markResendSubmitted(queue, { messageId: "m-a" }, 20)
+
+ queue = settleSend(queue, { messageId: "m-a", error: "refused again" }, 30)
+
+ expect(queue.holdReason).toBe("failed")
+ expect(queue.waiting.map((item) => item.clientId)).toEqual(["b"])
+ })
+
+ test("the person can discard the held messages", () => {
+ let queue = submitNext(queueWith("a", "b", "c"), 0)
+ queue = settleSend(queue, { clientId: "a", error: "refused" }, 10)
+
+ queue = discardHeldSends(queue)
+
+ expect(queue.waiting).toEqual([])
+ expect(queue.holdReason).toBeNull()
+ })
+
+ test("a refused submit (rejection, validation, network) holds like a failure", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+
+ queue = failSendSubmit(queue, "a")
+
+ expect(queue.inFlight).toBeNull()
+ expect(queue.holdReason).toBe("failed")
+ expect(queue.waiting.map((item) => item.clientId)).toEqual(["b"])
+ })
+
+ test("a refused submit for a message that is not in flight changes nothing", () => {
+ const queue = submitNext(queueWith("a", "b"), 0)
+ expect(failSendSubmit(queue, "b")).toBe(queue)
+ })
+})
+
+describe("a lost answer", () => {
+ test("after 30 s the queue stops waiting but does NOT send the next message by itself", () => {
+ const queue = submitNext(queueWith("a", "b"), 0)
+
+ const expired = expireInFlightSend(queue, AGENT_SEND_CONFIRM_TIMEOUT_MS)
+
+ expect(expired.holdReason).toBe("unconfirmed")
+ expect(isSendQueueLocked(expired)).toBe(true)
+ expect(
+ nextSendToSubmit(expired, 10 * AGENT_SEND_CONFIRM_TIMEOUT_MS),
+ ).toBeNull()
+ })
+
+ test("before the deadline nothing expires", () => {
+ const queue = submitNext(queueWith("a", "b"), 0)
+ expect(expireInFlightSend(queue, AGENT_SEND_CONFIRM_TIMEOUT_MS - 1)).toBe(
+ queue,
+ )
+ })
+
+ test("the person chooses to continue and the next message goes", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = expireInFlightSend(queue, AGENT_SEND_CONFIRM_TIMEOUT_MS)
+
+ queue = resumeSendQueue(queue, 40_000)
+
+ expect(queue.holdReason).toBeNull()
+ expect(nextSendToSubmit(queue, 40_000)?.clientId).toBe("b")
+ })
+
+ test("an expiry with nothing behind it still asks before the next message goes", () => {
+ let queue = submitNext(queueWith("a"), 0)
+ queue = expireInFlightSend(queue, AGENT_SEND_CONFIRM_TIMEOUT_MS)
+
+ expect(queue.holdReason).toBe("unconfirmed")
+ expect(queue.inFlight).toBeNull()
+ expect(isSendQueueLocked(queue)).toBe(true)
+ })
+
+ test("a late answer after the expiry changes nothing", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = expireInFlightSend(queue, AGENT_SEND_CONFIRM_TIMEOUT_MS)
+
+ expect(settleSend(queue, { clientId: "a", error: null }, 40_000)).toBe(
+ queue,
+ )
+ })
+
+ test("the timeout is 30 s", () => {
+ expect(AGENT_SEND_CONFIRM_TIMEOUT_MS).toBe(30_000)
+ })
+})
+
+describe("when the runner should look again", () => {
+ test("while waiting for a result: at the confirmation deadline", () => {
+ const queue = submitNext(queueWith("a", "b"), 1000)
+ expect(nextSendWakeAt(queue, 1000)).toBe(
+ 1000 + AGENT_SEND_CONFIRM_TIMEOUT_MS,
+ )
+ })
+
+ test("after a result with messages waiting: at the end of the gap", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = settleSend(queue, { clientId: "a", error: null }, 100)
+
+ expect(nextSendWakeAt(queue, 100)).toBe(100 + AGENT_SEND_GAP_MS)
+ })
+
+ test("a held or empty queue never wakes by itself", () => {
+ let held = submitNext(queueWith("a", "b"), 0)
+ held = settleSend(held, { clientId: "a", error: "refused" }, 10)
+
+ expect(nextSendWakeAt(held, 10)).toBeNull()
+ expect(nextSendWakeAt(createSendQueue (), 10)).toBeNull()
+ })
+})
diff --git a/apps/builder/src/features/messages/lib/send-queue.ts b/apps/builder/src/features/messages/lib/send-queue.ts
new file mode 100644
index 0000000000..0154fb7a4b
--- /dev/null
+++ b/apps/builder/src/features/messages/lib/send-queue.ts
@@ -0,0 +1,321 @@
+/**
+ * Pure state machine behind the composer's per-conversation send queue.
+ *
+ * Messages typed in quick succession are sent one at a time: the next one waits
+ * for the previous one's result from the channel (the `messageFailed` realtime
+ * event, `error: null` meaning accepted) and a short gap, so they reach the
+ * customer in order. A failure holds the messages that were already queued
+ * behind it. In-memory only (a page reload starts clean), single tab: it orders
+ * what this tab sends, not what other tabs or API clients send.
+ */
+
+/** Pause between a message being accepted and the next one being sent. */
+export const AGENT_SEND_GAP_MS = 500
+/** How long to wait for a result before asking the person to decide. */
+export const AGENT_SEND_CONFIRM_TIMEOUT_MS = 30_000
+
+export type QueuedSend = {
+ /** Client-generated id, echoed back by the server in the result event. */
+ clientId: string
+ input: TInput
+ /** The optimistic row shown in the list, marked failed if the submit fails. */
+ optimisticMessageId?: string | undefined
+}
+
+/** A send handed to the server, waiting for the channel's answer. */
+export type InFlightSend = {
+ clientId?: string | undefined
+ /** Known for a resend; learned from the result event otherwise. */
+ messageId?: string | undefined
+ startedAt: number
+ /** The hold a resend lifted, put back if the server refuses the resend. */
+ liftedHold?: { reason: SendQueueHoldReason; heldBy: MessageRef | null }
+}
+
+/** Why queued messages are not being sent. */
+export const SEND_QUEUE_HOLD_REASONS = {
+ /** The message ahead of them failed: resend it (or discard them). */
+ failed: "failed",
+ /** No answer arrived in time: the person decides whether to go on. */
+ unconfirmed: "unconfirmed",
+} as const
+export type SendQueueHoldReason =
+ (typeof SEND_QUEUE_HOLD_REASONS)[keyof typeof SEND_QUEUE_HOLD_REASONS]
+
+export type SendQueue = {
+ waiting: QueuedSend[]
+ inFlight: InFlightSend | null
+ /** Earliest time the next message may be sent (the gap after the last one). */
+ nextAllowedAt: number
+ /** Set while the composer is held behind a failure / lost answer. */
+ holdReason: SendQueueHoldReason | null
+ /** The message the hold is for: only resending it lifts the hold. */
+ heldBy: MessageRef | null
+}
+
+/** A message by whichever ids are known (the row's, or the submit's). */
+type MessageRef = {
+ clientId?: string | undefined
+ messageId?: string | undefined
+}
+
+export type SendResultSignal = {
+ messageId?: string | undefined
+ clientId?: string | undefined
+ /** `null`: the channel accepted it. A string: it failed. */
+ error: string | null
+}
+
+export const createSendQueue = (): SendQueue => ({
+ waiting: [],
+ inFlight: null,
+ nextAllowedAt: 0,
+ holdReason: null,
+ heldBy: null,
+})
+
+/** Nothing waiting, in flight or held, and the gap after the last send is over. */
+export const isSendQueueIdle = (
+ queue: SendQueue,
+ now: number,
+): boolean =>
+ queue.waiting.length === 0 &&
+ queue.inFlight === null &&
+ queue.holdReason === null &&
+ now >= queue.nextAllowedAt
+
+/**
+ * The composer locks while the queue is held, even with nothing waiting: a
+ * message typed now would reach the customer before the failed one is resent.
+ */
+export const isSendQueueLocked = (queue: SendQueue): boolean =>
+ queue.holdReason !== null
+
+export const enqueueSend = (
+ queue: SendQueue,
+ item: QueuedSend,
+): SendQueue => ({ ...queue, waiting: [...queue.waiting, item] })
+
+/** The message to submit now, or `null` (busy, held, gap not over, or empty). */
+export const nextSendToSubmit = (
+ queue: SendQueue,
+ now: number,
+): QueuedSend | null => {
+ if (queue.inFlight !== null || queue.holdReason !== null) {
+ return null
+ }
+ if (now < queue.nextAllowedAt) {
+ return null
+ }
+ return queue.waiting[0] ?? null
+}
+
+export const markSendSubmitted = (
+ queue: SendQueue,
+ clientId: string,
+ now: number,
+): SendQueue => ({
+ ...queue,
+ waiting: queue.waiting.filter((item) => item.clientId !== clientId),
+ inFlight: { clientId, startedAt: now },
+})
+
+/**
+ * A resent message becomes the one in flight. When it is the message the hold
+ * is for, the hold is lifted: held messages go once it is accepted (or hold
+ * again if it fails). Resending some other failed message does not lift a hold
+ * that belongs to a different one, or the held messages would overtake it.
+ * While another message is still in flight the resend is not tracked at all.
+ */
+export const markResendSubmitted = (
+ queue: SendQueue,
+ message: { messageId: string; clientId?: string | null | undefined },
+ now: number,
+): SendQueue => {
+ const { messageId } = message
+ if (queue.inFlight !== null) {
+ // Another message is in flight, so this resend is not tracked. If it is
+ // the very message the hold is for, the hold goes now: it is queued again, and
+ // keeping the hold would strand what is queued behind it.
+ return queue.holdReason !== null &&
+ queue.heldBy !== null &&
+ sameMessage(queue.heldBy, {
+ messageId,
+ clientId: message.clientId ?? undefined,
+ })
+ ? { ...queue, holdReason: null, heldBy: null }
+ : queue
+ }
+ const liftsHold =
+ queue.holdReason !== null &&
+ (queue.heldBy === null ||
+ sameMessage(queue.heldBy, {
+ messageId,
+ clientId: message.clientId ?? undefined,
+ }))
+ return {
+ ...queue,
+ inFlight: {
+ messageId,
+ startedAt: now,
+ ...(liftsHold && queue.holdReason !== null
+ ? { liftedHold: { reason: queue.holdReason, heldBy: queue.heldBy } }
+ : {}),
+ },
+ holdReason: liftsHold ? null : queue.holdReason,
+ heldBy: liftsHold ? null : queue.heldBy,
+ }
+}
+
+/**
+ * The server refused a resend: back to exactly the state before the click, the
+ * hold it lifted (if any) included. A queue that was not held stays unlocked.
+ */
+export const failResendSubmit = (
+ queue: SendQueue,
+ messageId: string,
+): SendQueue => {
+ if (queue.inFlight?.messageId !== messageId) {
+ return queue
+ }
+ const lifted = queue.inFlight.liftedHold
+ return {
+ ...queue,
+ inFlight: null,
+ holdReason: lifted?.reason ?? queue.holdReason,
+ heldBy: lifted ? lifted.heldBy : queue.heldBy,
+ }
+}
+
+/** True when this queue is held for the given message. */
+export const isHeldBy = (
+ queue: SendQueue,
+ message: MessageRef,
+): boolean =>
+ queue.holdReason !== null &&
+ queue.heldBy !== null &&
+ sameMessage(queue.heldBy, message)
+
+const sameMessage = (a: MessageRef, b: MessageRef): boolean =>
+ (a.clientId !== undefined && a.clientId === b.clientId) ||
+ (a.messageId !== undefined && a.messageId === b.messageId)
+
+/** Holds the queue for `culprit`; an existing hold keeps its own culprit. */
+const holdQueue = (
+ queue: SendQueue,
+ reason: SendQueueHoldReason,
+ culprit: MessageRef,
+): SendQueue => ({
+ ...queue,
+ inFlight: null,
+ holdReason: queue.holdReason ?? reason,
+ heldBy: queue.holdReason === null ? culprit : queue.heldBy,
+})
+
+const matchesInFlight = (
+ inFlight: InFlightSend,
+ signal: SendResultSignal,
+): boolean =>
+ (signal.clientId !== undefined && signal.clientId === inFlight.clientId) ||
+ (signal.messageId !== undefined && signal.messageId === inFlight.messageId)
+
+/**
+ * Applies the channel's answer. A result for a message that is not the one in
+ * flight (another tab's, an old retry, the clearing of an error) changes
+ * nothing.
+ */
+export const settleSend = (
+ queue: SendQueue,
+ signal: SendResultSignal,
+ now: number,
+): SendQueue => {
+ if (!(queue.inFlight && matchesInFlight(queue.inFlight, signal))) {
+ return queue
+ }
+ if (signal.error === null) {
+ return {
+ ...queue,
+ inFlight: null,
+ nextAllowedAt: now + AGENT_SEND_GAP_MS,
+ }
+ }
+ return holdQueue(queue, SEND_QUEUE_HOLD_REASONS.failed, {
+ clientId: queue.inFlight.clientId,
+ messageId: signal.messageId ?? queue.inFlight.messageId,
+ })
+}
+
+/** The server refused the submit itself (rejection, validation, network). */
+export const failSendSubmit = (
+ queue: SendQueue,
+ clientId: string,
+): SendQueue =>
+ queue.inFlight?.clientId === clientId
+ ? holdQueue(queue, SEND_QUEUE_HOLD_REASONS.failed, { clientId })
+ : queue
+
+/** The time at which the in-flight message stops being waited for, if any. */
+export const sendConfirmDeadline = (
+ queue: SendQueue,
+): number | null =>
+ queue.inFlight
+ ? queue.inFlight.startedAt + AGENT_SEND_CONFIRM_TIMEOUT_MS
+ : null
+
+/**
+ * No answer in time: stop waiting, but never send the next message by itself
+ * (the one in flight may well have been delivered).
+ */
+export const expireInFlightSend = (
+ queue: SendQueue,
+ now: number,
+): SendQueue => {
+ const deadline = sendConfirmDeadline(queue)
+ if (deadline === null || now < deadline) {
+ return queue
+ }
+ return holdQueue(queue, SEND_QUEUE_HOLD_REASONS.unconfirmed, {
+ clientId: queue.inFlight?.clientId,
+ messageId: queue.inFlight?.messageId,
+ })
+}
+
+/** The person chose to go on after an unconfirmed message. */
+export const resumeSendQueue = (
+ queue: SendQueue,
+ now: number,
+): SendQueue => ({
+ ...queue,
+ holdReason: null,
+ heldBy: null,
+ nextAllowedAt: now,
+})
+
+/** Drops the held messages (and the hold); the failed one is untouched. */
+export const discardHeldSends = (
+ queue: SendQueue,
+): SendQueue => ({
+ ...queue,
+ waiting: [],
+ holdReason: null,
+ heldBy: null,
+})
+
+/**
+ * When the runner should look at this queue again, or `null` when only an
+ * event (a result, a click) can move it: the end of the gap before the next
+ * message, or the confirmation deadline of the one in flight.
+ */
+export const nextSendWakeAt = (
+ queue: SendQueue,
+ now: number,
+): number | null => {
+ const deadline = sendConfirmDeadline(queue)
+ if (deadline !== null) {
+ return deadline
+ }
+ if (queue.holdReason === null && queue.waiting.length > 0) {
+ return Math.max(queue.nextAllowedAt, now)
+ }
+ return null
+}
diff --git a/apps/builder/src/features/messages/lib/use-send-queue-runner.ts b/apps/builder/src/features/messages/lib/use-send-queue-runner.ts
new file mode 100644
index 0000000000..f698222592
--- /dev/null
+++ b/apps/builder/src/features/messages/lib/use-send-queue-runner.ts
@@ -0,0 +1,118 @@
+"use client"
+
+import { useTranslations } from "next-intl"
+import { useCallback, useEffect, useState } from "react"
+import { toast } from "sonner"
+import { useWorkspaceId } from "@/hooks/routing"
+import { useChatStore } from "../../chat/store/chat-store-provider"
+import { createMessageAction } from "../actions/create-message.action"
+import type { CreateMessageWithRoutingBypassRequest } from "../schema/mutation"
+import {
+ expireInFlightSend,
+ failSendSubmit,
+ markSendSubmitted,
+ nextSendToSubmit,
+ nextSendWakeAt,
+ type QueuedSend,
+} from "./send-queue"
+import { flattenValidationErrors } from "./validation-errors"
+
+/**
+ * Runs the composer's send queues: submits the next message of each
+ * conversation when its turn comes and expires one that never got an answer.
+ * Mounted once by the composer, it serves every conversation's queue, so
+ * switching conversations neither loses nor stalls queued messages.
+ *
+ * The answer itself arrives as a realtime event (`settleSendResult`); this only
+ * hands messages to the server and wakes itself at the next gap or deadline.
+ */
+export const useSendQueueRunner = (props: {
+ /** Called once the server has queued a message for delivery. */
+ onSubmitted: (conversationId: string) => void
+}): void => {
+ const { onSubmitted } = props
+ const t = useTranslations()
+ const workspaceId = useWorkspaceId()
+ const sendQueues = useChatStore((state) => state.sendQueues)
+ const updateSendQueue = useChatStore((state) => state.updateSendQueue)
+ const markMessageFailed = useChatStore((state) => state.markMessageFailed)
+ // Bumped by a timer to re-evaluate the queues when a gap or deadline passes.
+ const [tick, setTick] = useState(0)
+
+ const submit = useCallback(
+ async (
+ conversationId: string,
+ item: QueuedSend,
+ ): Promise => {
+ const fail = (message: string) => {
+ updateSendQueue(conversationId, (queue) =>
+ failSendSubmit(queue, item.clientId),
+ )
+ markMessageFailed(
+ item.optimisticMessageId ?? "",
+ item.clientId,
+ message,
+ )
+ toast.error(message)
+ }
+
+ try {
+ const result = await createMessageAction(
+ workspaceId,
+ conversationId,
+ item.input,
+ )
+ if (result?.serverError) {
+ fail(result.serverError)
+ return
+ }
+ if (result?.validationErrors) {
+ fail(
+ flattenValidationErrors(result.validationErrors)[0]?.message ??
+ t("messages.unknownError"),
+ )
+ return
+ }
+ onSubmitted(conversationId)
+ } catch (error) {
+ fail(
+ error instanceof Error ? error.message : t("messages.unknownError"),
+ )
+ }
+ },
+ [markMessageFailed, onSubmitted, t, updateSendQueue, workspaceId],
+ )
+
+ // biome-ignore lint/correctness/useExhaustiveDependencies: `tick` re-runs the evaluation when a timer fires
+ useEffect(() => {
+ const timers: ReturnType[] = []
+ const now = Date.now()
+ for (const [conversationId, queue] of Object.entries(sendQueues)) {
+ if (expireInFlightSend(queue, now) !== queue) {
+ updateSendQueue(conversationId, (current) =>
+ expireInFlightSend(current, Date.now()),
+ )
+ continue
+ }
+ const next = nextSendToSubmit(queue, now)
+ if (next) {
+ updateSendQueue(conversationId, (current) =>
+ markSendSubmitted(current, next.clientId, Date.now()),
+ )
+ submit(conversationId, next)
+ continue
+ }
+ const wakeAt = nextSendWakeAt(queue, now)
+ if (wakeAt !== null) {
+ timers.push(
+ setTimeout(() => setTick((value) => value + 1), wakeAt - now),
+ )
+ }
+ }
+ return () => {
+ for (const timer of timers) {
+ clearTimeout(timer)
+ }
+ }
+ }, [sendQueues, submit, tick, updateSendQueue])
+}
diff --git a/apps/builder/src/features/messages/message-list.tsx b/apps/builder/src/features/messages/message-list.tsx
index e2a47ea945..b8bfe6579a 100644
--- a/apps/builder/src/features/messages/message-list.tsx
+++ b/apps/builder/src/features/messages/message-list.tsx
@@ -21,6 +21,7 @@ import { changeMessageAttributesAction } from "./actions/change-message-attribut
import { deleteMessageAction } from "./actions/delete-message.action"
import { editMessageAction } from "./actions/edit-message.action"
import { MessageItem } from "./components/message-item"
+import { ResendMessageButton } from "./components/resend-message-button"
import { canPrivateReplyToComment } from "./lib/private-reply"
import type { MessageResourceWithRelations } from "./schema/resource"
@@ -332,6 +333,9 @@ export function MessageList() {
onEdit={handleEditMessage}
onPrivateReply={handlePrivateReplyComment}
onReply={handleReplyComment}
+ renderResend={(failed) => (
+
+ )}
/>
)}
diff --git a/apps/builder/src/features/messages/schema/mutation.ts b/apps/builder/src/features/messages/schema/mutation.ts
index 05b62a186e..1bef811bbf 100644
--- a/apps/builder/src/features/messages/schema/mutation.ts
+++ b/apps/builder/src/features/messages/schema/mutation.ts
@@ -170,6 +170,9 @@ export type CreateMessageRequest = z.infer
export const createMessageWithRoutingBypassRequest = createMessageRequest.and(
z.object({ bypassThreadControlLock: bypassField }),
)
+export type CreateMessageWithRoutingBypassRequest = z.infer<
+ typeof createMessageWithRoutingBypassRequest
+>
export const createWebchatMessageRequest = z
.union([
@@ -220,6 +223,12 @@ export const deleteMessageRequest = z.object({
})
export type DeleteMessageRequest = z.infer
+export const resendMessageRequest = z.object({
+ id: z.string().min(1),
+ createdAt: z.coerce.date(),
+})
+export type ResendMessageRequest = z.infer
+
export const editMessageRequest = z.object({
messageId: zodBigintAsString().describe("Message id."),
createdAt: z.coerce
diff --git a/apps/builder/src/features/messages/schema/public.ts b/apps/builder/src/features/messages/schema/public.ts
index 7d42f71888..69d02e86b3 100644
--- a/apps/builder/src/features/messages/schema/public.ts
+++ b/apps/builder/src/features/messages/schema/public.ts
@@ -55,6 +55,13 @@ export const messageIdWithCreatedAtParam = messageIdPathParam.and(
}),
)
+export const resendMessagePublicResponse = z.object({
+ id: z.string().describe("The message that was queued again."),
+ queued: z
+ .literal(true)
+ .describe("Always true: the message is queued for delivery again."),
+})
+
// Kept in sync with `editMessage`'s return shape
// (`@/features/messages/actions/edit-message.action.ts`) via the
// `satisfies`-style check in that file's test — oRPC output schemas silently
diff --git a/apps/builder/src/features/pipelines/components/item/item-conversation.tsx b/apps/builder/src/features/pipelines/components/item/item-conversation.tsx
index f93b167b0c..ea19346cfa 100644
--- a/apps/builder/src/features/pipelines/components/item/item-conversation.tsx
+++ b/apps/builder/src/features/pipelines/components/item/item-conversation.tsx
@@ -15,6 +15,7 @@ import {
ChatStoreProvider,
useChatStore,
} from "@/features/chat/store/chat-store-provider"
+import { SendQueueRunner } from "@/features/messages/components/send-queue-runner"
import { useCallPlaybackStore } from "@/features/messages/store/call-playback-store"
type ItemConversationProps = {
@@ -34,6 +35,7 @@ export function ItemConversation(props: ItemConversationProps) {
return (
+
)
diff --git a/apps/builder/src/lib/orpc/orpc-error-helper.ts b/apps/builder/src/lib/orpc/orpc-error-helper.ts
index bf502a344b..622373078a 100644
--- a/apps/builder/src/lib/orpc/orpc-error-helper.ts
+++ b/apps/builder/src/lib/orpc/orpc-error-helper.ts
@@ -363,6 +363,18 @@ export const possibleErrorsOnPeekingImportHeaders = {
},
} satisfies ErrorMap
+/** Resending a failed message: only a failed, undelivered DM can be resent (409). */
+export const possibleErrorsOnResendingMessage = {
+ notFound,
+ businessError,
+ messageNotResendable: {
+ message:
+ "The message cannot be resent: it did not fail, was already delivered, was not sent by a person or the API, is a public comment reply, or is already being resent.",
+ status: 409,
+ },
+ ...possibleIdempotencyErrors,
+} satisfies ErrorMap
+
/** Starting a contact import: only one import may run per workspace (409). */
export const possibleErrorsOnStartingContactImport = {
notFound,
diff --git a/apps/builder/src/lib/workspace/authorize-workspace-access.ts b/apps/builder/src/lib/workspace/authorize-workspace-access.ts
index 06c7a8a213..9892eac773 100644
--- a/apps/builder/src/lib/workspace/authorize-workspace-access.ts
+++ b/apps/builder/src/lib/workspace/authorize-workspace-access.ts
@@ -197,12 +197,21 @@ export const BROADCAST_STOP_TOKEN_PATH = "/v1/broadcasts/{id}/stop"
export const MARKETING_MESSAGE_STOP_TOKEN_PATH =
"/v1/marketing-messages/campaigns/{id}/stop"
+/**
+ * Cancelling an Automatic Customer Scan must stay possible on a trial-expired
+ * or over-limit workspace, like the builder's `cancelContactScanAction`
+ * (`workspaceActionClientAllowExpired`). It only stops work. Gate-only
+ * allow-list: a `read_only` token still cannot call it.
+ */
+export const CONTACT_SCAN_CANCEL_TOKEN_PATH = "/v1/contact-scans/cancel"
+
const READ_ONLY_POST_PATHS = new Set([
CONVERSATIONS_LIST_POST_PATH,
FILTER_VALUE_LABELS_POST_PATH,
FILTER_VALUE_LABELS_TOKEN_PATH,
BROADCAST_STOP_TOKEN_PATH,
MARKETING_MESSAGE_STOP_TOKEN_PATH,
+ CONTACT_SCAN_CANCEL_TOKEN_PATH,
BROADCAST_AUDIENCE_PREVIEW_TOKEN_PATH,
// Template uninstall and its cancel remove or give back copies: a
// delete/cancel-type action, open on a trial-expired workspace like the UI
diff --git a/apps/cli/README.md b/apps/cli/README.md
index 8155e07b2f..791568405b 100644
--- a/apps/cli/README.md
+++ b/apps/cli/README.md
@@ -327,6 +327,7 @@ chatbotx conversations messages update --createdAt
# [--newAttachmentPath --newAttachmentPublicUrl --newAttachmentMimeType
# --newAttachmentName --newAttachmentSize --removeAttachment]
chatbotx conversations message delete --createdAt
+chatbotx conversations resend add --createdAt # Resend a failed message (409 if it did not fail or was delivered)
chatbotx conversations attribute add --createdAt # [--liked --hidden]
# Appointment booking link (scope `appointments`; `--send true` also needs `inbox`)
@@ -819,6 +820,7 @@ AI moderation itself is configured on the automation: `hideComments.aiModeration
chatbotx contact-scans status --inboxId # Latest Automatic Customer Scan status for inbox
chatbotx contact-scans list # [--page --perPage]
chatbotx contact-scans create --inboxId --scanFromAt
+chatbotx contact-scans cancel --inboxId # Cancel running Automatic Customer Scan for inbox
```
---
diff --git a/apps/worker/__tests__/account-send-blocked.test.ts b/apps/worker/__tests__/account-send-blocked.test.ts
new file mode 100644
index 0000000000..7e042dde69
--- /dev/null
+++ b/apps/worker/__tests__/account-send-blocked.test.ts
@@ -0,0 +1,190 @@
+import { beforeEach, describe, expect, test, vi } from "vitest"
+
+const mocks = vi.hoisted(() => ({
+ stopSendingForBlockedAccount: vi.fn(),
+ setIfAbsent: vi.fn(),
+ del: vi.fn(),
+ syncThreadOwner: vi.fn(),
+ loggerError: vi.fn(),
+ loggerWarn: vi.fn(),
+}))
+
+vi.mock("@chatbotx.io/business", () => ({
+ broadcastService: {
+ stopSendingForBlockedAccount: mocks.stopSendingForBlockedAccount,
+ },
+ threadControlService: { recordEvent: vi.fn() },
+}))
+vi.mock("@chatbotx.io/redis", () => ({
+ casStore: { setIfAbsent: mocks.setIfAbsent, del: mocks.del },
+}))
+vi.mock("@chatbotx.io/channel-registry/thread-control", () => ({
+ syncThreadOwner: mocks.syncThreadOwner,
+}))
+vi.mock("@chatbotx.io/integration-messenger", () => ({
+ isThreadControlRejection: () => false,
+}))
+vi.mock("../src/lib/logger", () => ({
+ logger: {
+ warn: mocks.loggerWarn,
+ error: mocks.loggerError,
+ info: vi.fn(),
+ },
+}))
+
+const { reconcileChannelSendError } = await import(
+ "../src/chat/handlers/channel-send-error-reconcilers"
+)
+const { ChannelError, ChannelErrorCategory, ChannelErrorReason } = await import(
+ "@chatbotx.io/sdk"
+)
+
+const conversation = { id: "conv-1", workspaceId: "ws-1" }
+const blockedError = () =>
+ new ChannelError("page blocked", ChannelErrorCategory.UNKNOWN, {
+ code: 2022,
+ reason: ChannelErrorReason.ACCOUNT_POLICY_BLOCKED,
+ })
+const broadcastMetadata = {
+ type: "broadcast" as const,
+ broadcastId: "b-1",
+ contactInboxId: "ci-1",
+}
+
+let inboxCounter = 0
+// A fresh inbox per test keeps the in-process burst window from leaking across tests.
+const run = (
+ error: unknown,
+ overrides: { metadata?: unknown; channel?: string; inboxId?: string } = {},
+) => {
+ const inboxId = overrides.inboxId ?? `inbox-${++inboxCounter}`
+ return reconcileChannelSendError({
+ error,
+ conversation,
+ contactInbox: {
+ id: "ci-1",
+ inboxId,
+ channel: overrides.channel ?? "instagram",
+ },
+ contentAttributes: undefined,
+ metadata: "metadata" in overrides ? overrides.metadata : broadcastMetadata,
+ } as never)
+}
+
+describe("account-send-blocked reconciler", () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ mocks.setIfAbsent.mockResolvedValue(true)
+ mocks.del.mockResolvedValue(undefined)
+ mocks.stopSendingForBlockedAccount.mockResolvedValue({ stoppedIds: [] })
+ })
+
+ test.each([
+ "messenger",
+ "instagram",
+ "whatsapp",
+ "zalo",
+ ])("a %s broadcast send stops the page's broadcasts and still returns false", async (channel) => {
+ const reconciled = await run(blockedError(), {
+ channel,
+ inboxId: `i-${channel}`,
+ })
+
+ expect(reconciled).toBe(false)
+ expect(mocks.stopSendingForBlockedAccount).toHaveBeenCalledWith({
+ workspaceId: "ws-1",
+ inboxId: `i-${channel}`,
+ channel,
+ reason: ChannelErrorReason.ACCOUNT_POLICY_BLOCKED,
+ errorMessage: "page blocked",
+ })
+ })
+
+ test("inbox, flow and sequence sends do not stop broadcasts", async () => {
+ for (const metadata of [
+ undefined,
+ { type: "flowNode" },
+ { type: "sequenceSchedule" },
+ ]) {
+ await run(blockedError(), { metadata })
+ }
+ expect(mocks.stopSendingForBlockedAccount).not.toHaveBeenCalled()
+ })
+
+ test("a recipient-level or plain error does not stop broadcasts", async () => {
+ await run(new ChannelError("x", ChannelErrorCategory.USER_BLOCKED))
+ await run(new Error("boom"))
+ expect(mocks.stopSendingForBlockedAccount).not.toHaveBeenCalled()
+ })
+
+ test("a burst of 200 errors for one inbox calls the service once", async () => {
+ await Promise.all(
+ Array.from({ length: 200 }, () =>
+ run(blockedError(), { inboxId: "burst-inbox" }),
+ ),
+ )
+ expect(mocks.stopSendingForBlockedAccount).toHaveBeenCalledTimes(1)
+ })
+
+ test("another process already handled the burst: no stop here", async () => {
+ mocks.setIfAbsent.mockResolvedValue(false)
+ await run(blockedError())
+ expect(mocks.stopSendingForBlockedAccount).not.toHaveBeenCalled()
+ })
+
+ test("a Redis failure still stops (the stop is idempotent)", async () => {
+ mocks.setIfAbsent.mockRejectedValue(new Error("redis down"))
+ await run(blockedError())
+ expect(mocks.stopSendingForBlockedAccount).toHaveBeenCalledTimes(1)
+ })
+
+ test("a service failure is logged, never thrown, and the next error retries", async () => {
+ mocks.stopSendingForBlockedAccount.mockRejectedValueOnce(new Error("db"))
+ const first = await run(blockedError(), { inboxId: "retry-inbox" })
+ const second = await run(blockedError(), { inboxId: "retry-inbox" })
+
+ expect(first).toBe(false)
+ expect(second).toBe(false)
+ expect(mocks.loggerError).toHaveBeenCalledTimes(1)
+ expect(mocks.stopSendingForBlockedAccount).toHaveBeenCalledTimes(2)
+ // The shared guard is released too, or other processes would skip the retry.
+ expect(mocks.del).toHaveBeenCalledWith(
+ "broadcast:account-block-stop:retry-inbox",
+ )
+ })
+
+ test("failing to release the guard is only logged", async () => {
+ mocks.stopSendingForBlockedAccount.mockRejectedValueOnce(new Error("db"))
+ mocks.del.mockRejectedValueOnce(new Error("redis down"))
+
+ await expect(
+ run(blockedError(), { inboxId: "del-fail-inbox" }),
+ ).resolves.toBe(false)
+ expect(mocks.loggerWarn).toHaveBeenCalled()
+ })
+
+ test("a blocked Messenger page skips the thread-owner lookup", async () => {
+ const error = new ChannelError(
+ "restricted",
+ ChannelErrorCategory.PERMISSION_DENIED,
+ {
+ code: 10,
+ subCode: 1_893_063,
+ reason: ChannelErrorReason.ACCOUNT_SEND_RESTRICTED,
+ },
+ )
+ await run(error, { channel: "messenger" })
+ expect(mocks.syncThreadOwner).not.toHaveBeenCalled()
+ })
+
+ test("another Messenger permission error still looks up the thread owner", async () => {
+ mocks.syncThreadOwner.mockResolvedValue({ threadControlState: null })
+ const error = new ChannelError(
+ "denied",
+ ChannelErrorCategory.PERMISSION_DENIED,
+ { code: 10 },
+ )
+ await run(error, { channel: "messenger", metadata: undefined })
+ expect(mocks.syncThreadOwner).toHaveBeenCalledTimes(1)
+ })
+})
diff --git a/apps/worker/__tests__/contact-scan-engine.test.ts b/apps/worker/__tests__/contact-scan-engine.test.ts
index 096498d4c8..6875f74b38 100644
--- a/apps/worker/__tests__/contact-scan-engine.test.ts
+++ b/apps/worker/__tests__/contact-scan-engine.test.ts
@@ -7,13 +7,14 @@ const {
mockUpdateProgress,
mockYieldForContinuation,
mockReopenReleased,
- mockResetForRetry,
+ mockRetryOrFail,
mockBulkImportChannelContacts,
mockIncrementBy,
mockFindWorkspace,
mockLoadContext,
mockListPage,
mockClassifyError,
+ mockReadBackoff,
mockLogProviderError,
mockLowQueueAddBulk,
mockQueueAdd,
@@ -25,13 +26,14 @@ const {
mockUpdateProgress: vi.fn(),
mockYieldForContinuation: vi.fn(),
mockReopenReleased: vi.fn(),
- mockResetForRetry: vi.fn(),
+ mockRetryOrFail: vi.fn(),
mockBulkImportChannelContacts: vi.fn(),
mockIncrementBy: vi.fn(),
mockFindWorkspace: vi.fn(),
mockLoadContext: vi.fn(),
mockListPage: vi.fn(),
mockClassifyError: vi.fn(),
+ mockReadBackoff: vi.fn(),
mockLogProviderError: vi.fn(),
mockLowQueueAddBulk: vi.fn(),
mockQueueAdd: vi.fn(),
@@ -47,7 +49,7 @@ vi.mock("@chatbotx.io/business", () => ({
updateProgress: mockUpdateProgress,
yieldForContinuation: mockYieldForContinuation,
reopenReleased: mockReopenReleased,
- resetForRetry: mockResetForRetry,
+ retryOrFail: mockRetryOrFail,
},
quotaEnforcementService: {
incrementBy: mockIncrementBy,
@@ -86,11 +88,16 @@ vi.mock("@chatbotx.io/worker-config", () => ({
runId,
attempts,
pageNumber,
+ generation,
}: {
runId: string
attempts: number
pageNumber: number
- }) => `contact-scan-${runId}-${attempts}-page-${pageNumber}`,
+ generation?: number
+ }) =>
+ `contact-scan-${runId}-${attempts}-page-${pageNumber}${
+ generation === undefined ? "" : `-gen-${generation}`
+ }`,
integrationQueue: { add: mockQueueAdd },
lowQueue: { addBulk: mockLowQueueAddBulk },
}))
@@ -103,6 +110,7 @@ vi.mock("../src/integration/handlers/contact-scan/adapter", () => ({
loadContext: mockLoadContext,
listPage: mockListPage,
classifyError: mockClassifyError,
+ readBackoff: mockReadBackoff,
},
instagram: {
channel: "instagram",
@@ -110,10 +118,27 @@ vi.mock("../src/integration/handlers/contact-scan/adapter", () => ({
loadContext: mockLoadContext,
listPage: mockListPage,
classifyError: mockClassifyError,
+ readBackoff: mockReadBackoff,
},
},
}))
+// A tiny page gap keeps the multi-page tests fast; the real 1s value is pinned
+// in contact-scan-pacing.test.ts.
+vi.mock(
+ "../src/integration/handlers/contact-scan/pacing",
+ async (importOriginal) => {
+ const actual =
+ await importOriginal<
+ typeof import("../src/integration/handlers/contact-scan/pacing")
+ >()
+ return {
+ ...actual,
+ CONTACT_SCAN_PACING: { ...actual.CONTACT_SCAN_PACING, pageGapMs: 20 },
+ }
+ },
+)
+
vi.mock("../src/integration/handlers/profile-snapshot/queue", () => ({
enqueueProfileSnapshotJobs: mockEnqueueProfileSnapshots,
}))
@@ -122,6 +147,7 @@ const { runContactScan } = await import(
"../src/integration/handlers/contact-scan/engine"
)
+const SAME_PAGE_RETRY_JOB_ID = /^contact-scan-run-1-3-page-4-gen-\d+$/
const RUN_ID = "run-1"
const WORKSPACE_ID = "ws-1"
const INTEGRATION_ID = "int-1"
@@ -177,7 +203,8 @@ describe("runContactScan", () => {
mockUpdateProgress.mockResolvedValue(1)
mockYieldForContinuation.mockResolvedValue(1)
mockFinish.mockResolvedValue(1)
- mockResetForRetry.mockResolvedValue(1)
+ mockRetryOrFail.mockResolvedValue("retry")
+ mockReadBackoff.mockReturnValue(null)
mockReopenReleased.mockResolvedValue(1)
mockBulkImportChannelContacts.mockResolvedValue(emptyImportResult)
mockQueueAdd.mockResolvedValue(undefined)
@@ -250,31 +277,29 @@ describe("runContactScan", () => {
expect(mockListPage).not.toHaveBeenCalled()
})
- describe("setup throws (FIX 1 — resets for retry, never a stuck `running` row)", () => {
- it("adapter.loadContext throwing resets for retry with the providerRetryable sentinel, never finishes, and never starts the walk", async () => {
+ describe("setup throws (hands back via retryOrFail, never a stuck `running` row)", () => {
+ it("adapter.loadContext throwing hands the run back via retryOrFail, never finishes, and never starts the walk", async () => {
mockClaim.mockResolvedValue(baseRun())
mockLoadContext.mockRejectedValue(new Error("db down"))
await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
- expect(mockResetForRetry).toHaveBeenCalledWith({
+ expect(mockRetryOrFail).toHaveBeenCalledWith({
runId: RUN_ID,
- currentError: "providerRetryable",
expect: EXPECT_GUARD,
})
expect(mockFinish).not.toHaveBeenCalled()
expect(mockListPage).not.toHaveBeenCalled()
})
- it("workspaceService.find throwing resets for retry with the providerRetryable sentinel, never finishes, and never starts the walk", async () => {
+ it("workspaceService.find throwing hands the run back via retryOrFail, never finishes, and never starts the walk", async () => {
mockClaim.mockResolvedValue(baseRun())
mockFindWorkspace.mockRejectedValue(new Error("db down"))
await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
- expect(mockResetForRetry).toHaveBeenCalledWith({
+ expect(mockRetryOrFail).toHaveBeenCalledWith({
runId: RUN_ID,
- currentError: "providerRetryable",
expect: EXPECT_GUARD,
})
expect(mockFinish).not.toHaveBeenCalled()
@@ -390,9 +415,8 @@ describe("runContactScan", () => {
await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
expect(mockUpdateProgress).not.toHaveBeenCalled()
- expect(mockResetForRetry).toHaveBeenCalledWith({
+ expect(mockRetryOrFail).toHaveBeenCalledWith({
runId: RUN_ID,
- currentError: "providerRetryable",
expect: EXPECT_GUARD,
})
})
@@ -409,10 +433,10 @@ describe("runContactScan", () => {
await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
- expect(mockResetForRetry).toHaveBeenCalledWith({
+ expect(mockRetryOrFail).toHaveBeenCalledWith({
runId: RUN_ID,
- currentError: "pageImportFailed",
expect: EXPECT_GUARD,
+ retryError: "pageImportFailed",
})
// Nothing persists an advanced watermark — resumeCursor stays at
// "good-cursor" and currentPageNumber is untouched.
@@ -442,7 +466,7 @@ describe("runContactScan", () => {
await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
- expect(mockResetForRetry).not.toHaveBeenCalled()
+ expect(mockRetryOrFail).not.toHaveBeenCalled()
expect(mockIncrementProgress).toHaveBeenCalledWith(
expect.objectContaining({
increments: expect.objectContaining({ importedContactCount: 1 }),
@@ -469,7 +493,7 @@ describe("runContactScan", () => {
await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
expect(mockLowQueueAddBulk).not.toHaveBeenCalled()
- expect(mockResetForRetry).not.toHaveBeenCalled()
+ expect(mockRetryOrFail).not.toHaveBeenCalled()
expect(mockFinish).toHaveBeenCalledWith(
expect.objectContaining({ status: "succeeded" }),
)
@@ -575,6 +599,7 @@ describe("runContactScan", () => {
},
expect.objectContaining({
jobId: "contact-scan-run-1-4-page-2",
+ delay: 5000,
attempts: 1,
removeOnComplete: true,
}),
@@ -614,6 +639,227 @@ describe("runContactScan", () => {
})
})
+ describe("pacing", () => {
+ const emptyPage = (after: string | undefined) => ({
+ entries: [],
+ after,
+ })
+
+ it("ends a chunk after 5 pages and continues 5s later", async () => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage.mockImplementation(() => Promise.resolve(emptyPage("next")))
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockListPage).toHaveBeenCalledTimes(5)
+ expect(mockYieldForContinuation).toHaveBeenCalledTimes(1)
+ expect(mockQueueAdd).toHaveBeenCalledWith(
+ "contactScan",
+ expect.anything(),
+ expect.objectContaining({
+ delay: 5000,
+ jobId: "contact-scan-run-1-2-page-6",
+ }),
+ )
+ expect(mockFinish).not.toHaveBeenCalled()
+ })
+
+ it("pauses between two pages of the same chunk", async () => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage
+ .mockResolvedValueOnce(emptyPage("c2"))
+ .mockResolvedValueOnce(emptyPage("c3"))
+ .mockResolvedValueOnce(emptyPage(undefined))
+ const startedAt = Date.now()
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ // Two gaps of the (mocked) 20ms page gap sit between three pages.
+ expect(Date.now() - startedAt).toBeGreaterThanOrEqual(35)
+ expect(mockListPage).toHaveBeenCalledTimes(3)
+ })
+
+ it.each([
+ ["usage 85% waits 2 minutes", { usagePercent: 85 }, 120_000],
+ ["usage 95% waits 10 minutes", { usagePercent: 95 }, 600_000],
+ [
+ "Meta's wait wins",
+ { usagePercent: 99, retryAfterMs: 300_000 },
+ 300_000,
+ ],
+ [
+ "Meta's wait is capped at 30 minutes",
+ { retryAfterMs: 90 * 60_000 },
+ 1_800_000,
+ ],
+ ])("%s, as a delayed job and not a sleep", async (_name, signal, delay) => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage.mockResolvedValue({
+ entries: [],
+ after: "next",
+ usageSignal: signal,
+ })
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ // The page is persisted first, then the chunk ends: one page, one wait.
+ expect(mockListPage).toHaveBeenCalledTimes(1)
+ expect(mockIncrementProgress).toHaveBeenCalledTimes(1)
+ expect(mockQueueAdd).toHaveBeenCalledWith(
+ "contactScan",
+ expect.anything(),
+ expect.objectContaining({ delay }),
+ )
+ })
+
+ it("usage below 85% keeps walking", async () => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage
+ .mockResolvedValueOnce({
+ entries: [],
+ after: "c2",
+ usageSignal: { usagePercent: 84 },
+ })
+ .mockResolvedValueOnce(emptyPage(undefined))
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockListPage).toHaveBeenCalledTimes(2)
+ expect(mockQueueAdd).not.toHaveBeenCalled()
+ })
+
+ it("a finished page resets attempts to the running claim (1) and refreshes the heartbeat in the same write", async () => {
+ mockClaim.mockResolvedValue(baseRun({ attempts: 4 }))
+ mockListPage.mockResolvedValue(emptyPage(undefined))
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockIncrementProgress).toHaveBeenCalledWith(
+ expect.objectContaining({
+ fields: expect.objectContaining({
+ attempts: 1,
+ lastHeartbeatAt: expect.any(Date),
+ }),
+ }),
+ )
+ })
+ })
+
+ describe("rate limit", () => {
+ it("waits through the queue with the provider's backoff, retries the SAME page, and resets attempts so the sweeper cannot fail the released run", async () => {
+ mockClaim.mockResolvedValue(
+ baseRun({ attempts: 3, currentPageNumber: 2 }),
+ )
+ mockListPage.mockRejectedValue(new Error("(#80006) rate limited"))
+ mockClassifyError.mockReturnValue("rateLimited")
+ mockReadBackoff.mockReturnValue({ retryAfterMs: 180_000 })
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockYieldForContinuation).toHaveBeenCalledWith({
+ runId: RUN_ID,
+ expect: EXPECT_GUARD,
+ attempts: 1,
+ })
+ expect(mockQueueAdd).toHaveBeenCalledWith(
+ "contactScan",
+ expect.anything(),
+ expect.objectContaining({
+ delay: 180_000,
+ jobId: expect.stringMatching(SAME_PAGE_RETRY_JOB_ID),
+ }),
+ )
+ // Not a failure: no retry accounting, no terminal write, no cursor change.
+ expect(mockRetryOrFail).not.toHaveBeenCalled()
+ expect(mockFinish).not.toHaveBeenCalled()
+ expect(mockIncrementProgress).not.toHaveBeenCalled()
+ expect(mockUpdateProgress).not.toHaveBeenCalled()
+ })
+
+ it("with no usage header it backs off 10 minutes", async () => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage.mockRejectedValue(new Error("rate limited"))
+ mockClassifyError.mockReturnValue("rateLimited")
+ mockReadBackoff.mockReturnValue(null)
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockQueueAdd).toHaveBeenCalledWith(
+ "contactScan",
+ expect.anything(),
+ expect.objectContaining({ delay: 600_000 }),
+ )
+ })
+
+ it("a rate-limited first page does not clear a resume cursor", async () => {
+ mockClaim.mockResolvedValue(baseRun({ resumeCursor: "good-cursor" }))
+ mockListPage.mockRejectedValue(new Error("rate limited"))
+ mockClassifyError.mockReturnValue("rateLimited")
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockUpdateProgress).not.toHaveBeenCalled()
+ expect(mockListPage).toHaveBeenCalledTimes(1)
+ })
+
+ it("a repeatedly rate-limited page keeps waiting and never hot-loops", async () => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage.mockRejectedValue(new Error("rate limited"))
+ mockClassifyError.mockReturnValue("rateLimited")
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ // One provider call per job, and every job schedules a delayed next one.
+ expect(mockListPage).toHaveBeenCalledTimes(2)
+ const delays = mockQueueAdd.mock.calls.map(
+ (call) => (call[2] as { delay: number }).delay,
+ )
+ expect(delays).toEqual([600_000, 600_000])
+ })
+
+ it("a lost claim at the park step abandons without queueing a job", async () => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage.mockRejectedValue(new Error("rate limited"))
+ mockClassifyError.mockReturnValue("rateLimited")
+ mockYieldForContinuation.mockResolvedValue(0)
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockQueueAdd).not.toHaveBeenCalled()
+ })
+
+ it("a queue failure while parking reopens the run for the sweeper", async () => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage.mockRejectedValue(new Error("rate limited"))
+ mockClassifyError.mockReturnValue("rateLimited")
+ mockQueueAdd.mockRejectedValueOnce(new Error("redis down"))
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockReopenReleased).toHaveBeenCalledWith({ runId: RUN_ID })
+ })
+ })
+
+ describe("cancel", () => {
+ it("a cancel that lands during a page fences the next write: no further page, no continuation, no finish", async () => {
+ mockClaim.mockResolvedValue(baseRun())
+ mockListPage.mockResolvedValue({
+ entries: [entry("a", new Date("2026-02-01T00:00:00Z"))],
+ after: "next",
+ })
+ // The cancel cleared the claim, so the page's progress write matches 0 rows.
+ mockIncrementProgress.mockResolvedValue(0)
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockListPage).toHaveBeenCalledTimes(1)
+ expect(mockQueueAdd).not.toHaveBeenCalled()
+ expect(mockYieldForContinuation).not.toHaveBeenCalled()
+ expect(mockFinish).not.toHaveBeenCalled()
+ })
+ })
+
describe("CONTACT_SCAN_MAX_PAGES runaway guard (FIX 3)", () => {
it("stops with partial + scanLimitReached before fetching another page once currentPageNumber is at the cap", async () => {
mockClaim.mockResolvedValue(baseRun({ currentPageNumber: 5000 }))
@@ -660,7 +906,7 @@ describe("runContactScan", () => {
})
describe("error classification table", () => {
- it("retryable → resetForRetry with the providerRetryable sentinel", async () => {
+ it("retryable → retryOrFail (sweeper retry, or failed on the last attempt)", async () => {
mockClaim.mockResolvedValue(baseRun())
mockListPage.mockRejectedValue(new Error("rate limited"))
mockClassifyError.mockReturnValue("retryable")
@@ -673,9 +919,8 @@ describe("runContactScan", () => {
workspaceId: WORKSPACE_ID,
}),
)
- expect(mockResetForRetry).toHaveBeenCalledWith({
+ expect(mockRetryOrFail).toHaveBeenCalledWith({
runId: RUN_ID,
- currentError: "providerRetryable",
expect: EXPECT_GUARD,
})
expect(mockFinish).not.toHaveBeenCalled()
diff --git a/apps/worker/__tests__/contact-scan-graph-error.test.ts b/apps/worker/__tests__/contact-scan-graph-error.test.ts
index 9831a14831..d66d8380aa 100644
--- a/apps/worker/__tests__/contact-scan-graph-error.test.ts
+++ b/apps/worker/__tests__/contact-scan-graph-error.test.ts
@@ -1,137 +1,118 @@
-import { SdkException } from "@chatbotx.io/sdk"
+import {
+ ChannelError,
+ ChannelErrorCategory,
+ ChannelErrorReason,
+ SdkException,
+} from "@chatbotx.io/sdk"
import { describe, expect, it } from "vitest"
-import { classifyGraphSdkError } from "../src/integration/handlers/contact-scan/graph-error"
-
-describe("classifyGraphSdkError", () => {
- describe("flat SdkException fields (the real wrapped-exception shape)", () => {
- it("classifies a 429 httpStatusCode as retryable", () => {
- const error = new SdkException("graph error", "someCode", 429)
- expect(classifyGraphSdkError(error)).toBe("retryable")
- })
-
- it("classifies a 500 httpStatusCode as retryable", () => {
- const error = new SdkException("graph error", "someCode", 500)
- expect(classifyGraphSdkError(error)).toBe("retryable")
- })
-
- it("classifies Graph code 4 (app-level rate limit) as retryable without a 429/5xx status", () => {
- const error = new SdkException("graph error", 4, 400)
- expect(classifyGraphSdkError(error)).toBe("retryable")
- })
-
- it("classifies Graph code 613 (custom rate limit) as retryable", () => {
- const error = new SdkException("graph error", 613, 400)
- expect(classifyGraphSdkError(error)).toBe("retryable")
- })
-
- it("classifies OAuthException type as tokenInvalid", () => {
- const error = new SdkException(
- "graph error",
- "unrecognized",
- 401,
- null,
- "OAuthException",
- )
- expect(classifyGraphSdkError(error)).toBe("tokenInvalid")
- })
-
- it("classifies Graph code 190 (expired token) as tokenInvalid", () => {
- const error = new SdkException("graph error", 190, 401)
- expect(classifyGraphSdkError(error)).toBe("tokenInvalid")
- })
-
- it("classifies Graph code 10 (permission denied) as graphPermission", () => {
- const error = new SdkException("graph error", 10, 403)
- expect(classifyGraphSdkError(error)).toBe("graphPermission")
- })
-
- it("classifies a Graph code in the 200-series permission range as graphPermission", () => {
- const error = new SdkException("graph error", 200, 403)
- expect(classifyGraphSdkError(error)).toBe("graphPermission")
- })
+import { classifyChannelErrorForScan } from "../src/integration/handlers/contact-scan/graph-error"
+
+// The classifier owns no provider codes: it reads what the channel's mapper
+// decided. A stub mapper makes each decision observable on its own.
+const mapperReturning =
+ (
+ category: ChannelErrorCategory,
+ extra: { reason?: ChannelErrorReason; httpStatusCode?: number } = {},
+ ) =>
+ () =>
+ new ChannelError("mapped", category, extra)
+
+const classify = (
+ error: unknown,
+ category: ChannelErrorCategory,
+ extra: { reason?: ChannelErrorReason; httpStatusCode?: number } = {},
+) =>
+ classifyChannelErrorForScan({
+ error,
+ mapToChannelError: mapperReturning(category, extra),
+ })
- it("classifies an unrecognized code/status as unknown", () => {
- const error = new SdkException("graph error", 999, 400)
- expect(classifyGraphSdkError(error)).toBe("unknown")
- })
+describe("classifyChannelErrorForScan", () => {
+ it("a RATE_LIMITED category is rateLimited", () => {
+ expect(classify(new Error("x"), ChannelErrorCategory.RATE_LIMITED)).toBe(
+ "rateLimited",
+ )
})
- describe("duck-typed flat fields (not an SdkException instance)", () => {
- it("classifies a plain object with httpStatusCode 429 as retryable", () => {
- const error = { httpStatusCode: 429 }
- expect(classifyGraphSdkError(error)).toBe("retryable")
- })
+ it("the rate_limited reason alone (no category) is rateLimited", () => {
+ expect(
+ classify(new Error("x"), ChannelErrorCategory.UNKNOWN, {
+ reason: ChannelErrorReason.RATE_LIMITED,
+ }),
+ ).toBe("rateLimited")
+ })
- it("classifies a plain object with code 190 + OAuthException as tokenInvalid", () => {
- const error = { code: 190, type: "OAuthException" }
- expect(classifyGraphSdkError(error)).toBe("tokenInvalid")
- })
+ it("a bare HTTP 429 is rateLimited even when the mapper knows no code", () => {
+ expect(
+ classify(new Error("x"), ChannelErrorCategory.UNKNOWN, {
+ httpStatusCode: 429,
+ }),
+ ).toBe("rateLimited")
})
- describe("raw-origin fallback (a never-wrapped shape, or the raw error nested via getOriginError())", () => {
- it("classifies a raw ky-style { response: { status } } object with no flat fields as retryable", () => {
- const error = { response: { status: 503 } }
- expect(classifyGraphSdkError(error)).toBe("retryable")
- })
+ it("a network failure category is retryable", () => {
+ expect(classify(new Error("x"), ChannelErrorCategory.NETWORK_ERROR)).toBe(
+ "retryable",
+ )
+ })
- it("classifies via getOriginError() when the flat fields alone don't indicate retryable", () => {
- const error = Object.assign(new Error("wrapped"), {
- httpStatusCode: 400,
- code: 999,
- getOriginError: () => ({ response: { status: 503 } }),
- })
- expect(classifyGraphSdkError(error)).toBe("retryable")
- })
+ it("a 5xx SdkException is retryable even if the mapper says unknown", () => {
+ expect(
+ classify(
+ new SdkException("graph", "code", 503),
+ ChannelErrorCategory.UNKNOWN,
+ ),
+ ).toBe("retryable")
+ })
- it("does not let a non-retryable getOriginError() override an unrecognized flat shape", () => {
- const error = Object.assign(new Error("wrapped"), {
- httpStatusCode: 400,
- code: 999,
- getOriginError: () => ({ response: { status: 404 } }),
- })
- expect(classifyGraphSdkError(error)).toBe("unknown")
- })
+ it("AUTH_FAILED is tokenInvalid", () => {
+ expect(classify(new Error("x"), ChannelErrorCategory.AUTH_FAILED)).toBe(
+ "tokenInvalid",
+ )
})
- describe("non-object / unrecognized errors", () => {
- it("classifies a plain Error with no Graph fields as unknown", () => {
- expect(classifyGraphSdkError(new Error("boom"))).toBe("unknown")
- })
+ it("PERMISSION_DENIED is graphPermission", () => {
+ expect(
+ classify(new Error("x"), ChannelErrorCategory.PERMISSION_DENIED),
+ ).toBe("graphPermission")
+ })
- it("classifies null as unknown", () => {
- expect(classifyGraphSdkError(null)).toBe("unknown")
- })
+ it("anything else is unknown", () => {
+ expect(classify(new Error("x"), ChannelErrorCategory.UNKNOWN)).toBe(
+ "unknown",
+ )
+ expect(classify(null, ChannelErrorCategory.PAYLOAD_INVALID)).toBe("unknown")
+ })
- it("classifies undefined as unknown", () => {
- expect(classifyGraphSdkError(undefined)).toBe("unknown")
- })
+ it("a rate limit wins over a retryable status", () => {
+ expect(
+ classify(
+ new SdkException("graph", 4, 500),
+ ChannelErrorCategory.RATE_LIMITED,
+ ),
+ ).toBe("rateLimited")
})
describe("request timeouts (the shape that used to fail a whole scan run)", () => {
const timeoutError = (): Error =>
- Object.assign(
- new Error(
- "Request timed out: GET https://graph.facebook.com/v25.0/1/conversations",
- ),
- { name: "TimeoutError" },
- )
+ Object.assign(new Error("Request timed out: GET /conversations"), {
+ name: "TimeoutError",
+ })
- it("classifies a wrapped Graph timeout as retryable, not unknown", () => {
- // `rescue()` stamps FALLBACK_HTTP_STATUS (400) + the default
- // "messengerError" code on a timeout, which is indistinguishable from a
- // permanent failure by status alone — the run was terminalized as
- // `failed` on the first slow `/conversations` page.
+ it("a wrapped timeout (stamped 400 by the integration) is retryable, not unknown", () => {
const wrapped = new SdkException(
- "Request timed out: GET https://graph.facebook.com/v25.0/1/conversations",
+ "Request timed out",
"messengerError",
400,
)
wrapped.setOriginError(timeoutError())
- expect(classifyGraphSdkError(wrapped)).toBe("retryable")
+ expect(classify(wrapped, ChannelErrorCategory.UNKNOWN)).toBe("retryable")
})
- it("classifies a bare, never-wrapped timeout as retryable", () => {
- expect(classifyGraphSdkError(timeoutError())).toBe("retryable")
+ it("a bare, never-wrapped timeout is retryable", () => {
+ expect(classify(timeoutError(), ChannelErrorCategory.UNKNOWN)).toBe(
+ "retryable",
+ )
})
})
})
diff --git a/apps/worker/__tests__/contact-scan-instagram-adapter.test.ts b/apps/worker/__tests__/contact-scan-instagram-adapter.test.ts
index f711ecc9e3..1676120bb6 100644
--- a/apps/worker/__tests__/contact-scan-instagram-adapter.test.ts
+++ b/apps/worker/__tests__/contact-scan-instagram-adapter.test.ts
@@ -78,6 +78,23 @@ const participant = (
...extra,
})
+const nativeContext = {
+ providerType: "instagram" as const,
+ inbox: fakeInbox,
+ accessToken: "token",
+ version: "v20.0",
+ igId,
+}
+
+const facebookContext = {
+ providerType: "facebook" as const,
+ inbox: fakeInbox,
+ accessToken: "token",
+ version: "v20.0",
+ igId,
+ pageId,
+}
+
describe("instagramContactScanAdapter", () => {
beforeEach(() => {
vi.clearAllMocks()
@@ -172,23 +189,6 @@ describe("instagramContactScanAdapter", () => {
})
describe("listPage", () => {
- const nativeContext = {
- providerType: "instagram" as const,
- inbox: fakeInbox,
- accessToken: "token",
- version: "v20.0",
- igId,
- }
-
- const facebookContext = {
- providerType: "facebook" as const,
- inbox: fakeInbox,
- accessToken: "token",
- version: "v20.0",
- igId,
- pageId,
- }
-
it("dispatches to listInstagramConversations for a native context", async () => {
mockListInstagramConversations.mockResolvedValue({ data: [] })
@@ -297,7 +297,7 @@ describe("instagramContactScanAdapter", () => {
expect(page.entries).toEqual([])
})
- it("maps app-usage headers to the engine's usage signal shape", async () => {
+ it("maps app-usage headers to the neutral usage signal", async () => {
mockListInstagramConversations.mockResolvedValue({
data: [],
appUsage: { call_count: 5, total_cputime: 10, total_time: 15 },
@@ -307,12 +307,7 @@ describe("instagramContactScanAdapter", () => {
context: nativeContext,
})
- expect(page.usageSignal).toEqual({
- kind: "meta-app-usage",
- callCount: 5,
- totalCputime: 10,
- totalTime: 15,
- })
+ expect(page.usageSignal).toEqual({ usagePercent: 15 })
})
it("returns a null usage signal when no app-usage header was present", async () => {
@@ -325,62 +320,25 @@ describe("instagramContactScanAdapter", () => {
expect(page.usageSignal).toBeNull()
})
- // FIX 4 — this Graph call was previously unretried (unlike the Messenger
- // adapter's `listPage`), so a transient 429/5xx fell straight through as
- // a full page loss. Now wrapped in the shared `withInlineRetry`.
- it("retries a transient (429) failure inline instead of throwing immediately", async () => {
- const transient = { response: { status: 429 } }
- mockListInstagramConversations
- .mockRejectedValueOnce(transient)
- .mockResolvedValueOnce({ data: [] })
-
- // Spy on global.setTimeout so the inline retry's backoff delay doesn't
- // actually block the test — mirrors the pattern used for BUC-pause
- // assertions in `coexist-messenger-sync.test.ts`.
- const origSetTimeout = global.setTimeout
- vi.spyOn(global, "setTimeout").mockImplementation(
- (fn: TimerHandler, _delay?: number, ...args: unknown[]) => {
- if (typeof fn === "function") {
- fn(...(args as []))
- }
- return origSetTimeout(fn, 0, ...args)
- },
- )
-
- const page = await instagramContactScanAdapter.listPage({
- context: nativeContext,
- })
-
- vi.restoreAllMocks()
-
- expect(mockListInstagramConversations).toHaveBeenCalledTimes(2)
- expect(page.entries).toEqual([])
- })
-
- it("does not retry a non-retryable failure — it throws immediately", async () => {
- const permanent = { response: { status: 400 } }
- mockListInstagramConversations.mockRejectedValueOnce(permanent)
+ it("does not retry inline: a failure reaches the engine at once", async () => {
+ const failure = new Error("boom")
+ mockListInstagramConversations.mockRejectedValueOnce(failure)
await expect(
instagramContactScanAdapter.listPage({ context: nativeContext }),
- ).rejects.toBe(permanent)
+ ).rejects.toBe(failure)
expect(mockListInstagramConversations).toHaveBeenCalledTimes(1)
})
})
- describe("classifyError", () => {
- // Both `@chatbotx.io/integration-instagram` and
- // `@chatbotx.io/integration-instagram-facebook` wrap every Graph failure
- // into their own `InstagramAPIException` (extends `InstagramException`
- // extends `SdkException`) before it escapes
- // `listInstagramConversations`/`listInstagramFacebookConversations` — a
- // flat `httpStatusCode`/`code`/`type`, never a nested `response`/
- // `errorBody` shape.
- const apiException = (fields: {
+ describe("classifyError (through each provider's error mapper)", () => {
+ type ExceptionFields = {
httpStatusCode?: number
code?: string | number
type?: string
- }) =>
+ }
+ // Each provider throws its OWN exception class, which its own mapper reads.
+ const apiException = (fields: ExceptionFields) =>
new InstagramAPIException(
"graph error",
fields.httpStatusCode,
@@ -388,61 +346,119 @@ describe("instagramContactScanAdapter", () => {
undefined,
fields.type,
)
-
- it("classifies a 429 InstagramAPIException as retryable", () => {
- const error = apiException({ httpStatusCode: 429 })
- expect(instagramContactScanAdapter.classifyError(error)).toBe("retryable")
+ // The Facebook package exports no exception class, so its mapper is fed the
+ // raw `{ httpStatus, errorBody }` origin shape it also understands.
+ const facebookApiException = (fields: ExceptionFields) => ({
+ httpStatus: fields.httpStatusCode,
+ errorBody: { error: { code: fields.code, type: fields.type } },
})
+ const classify = (error: unknown, context = nativeContext) =>
+ instagramContactScanAdapter.classifyError({ error, context })
- it("classifies a 500 InstagramAPIException as retryable", () => {
- const error = apiException({ httpStatusCode: 500 })
- expect(instagramContactScanAdapter.classifyError(error)).toBe("retryable")
+ it("a 429 is rateLimited and a 500 is retryable", () => {
+ expect(classify(apiException({ httpStatusCode: 429 }))).toBe(
+ "rateLimited",
+ )
+ expect(classify(apiException({ httpStatusCode: 500 }))).toBe("retryable")
})
- it("classifies Graph code 190 (expired token) as tokenInvalid", () => {
- const error = apiException({
- httpStatusCode: 401,
- code: 190,
- type: "OAuthException",
- })
- expect(instagramContactScanAdapter.classifyError(error)).toBe(
- "tokenInvalid",
- )
+ it("Graph code 190 (expired token) is tokenInvalid", () => {
+ expect(
+ classify(
+ apiException({
+ httpStatusCode: 401,
+ code: 190,
+ type: "OAuthException",
+ }),
+ ),
+ ).toBe("tokenInvalid")
})
- it("classifies Graph code 10 (permission denied) as graphPermission", () => {
- const error = apiException({ httpStatusCode: 403, code: 10 })
- expect(instagramContactScanAdapter.classifyError(error)).toBe(
+ it.each([10, 200])("permission code %i is graphPermission", (code) => {
+ expect(classify(apiException({ httpStatusCode: 403, code }))).toBe(
"graphPermission",
)
})
- it("classifies a Graph code in the 200-series permission range as graphPermission", () => {
- const error = apiException({ httpStatusCode: 403, code: 200 })
- expect(instagramContactScanAdapter.classifyError(error)).toBe(
- "graphPermission",
+ it.each([
+ 4, 17, 613,
+ ])("Graph code %i is rateLimited on both providers", (code) => {
+ const fields = { httpStatusCode: 400, code }
+ expect(classify(apiException(fields), nativeContext)).toBe("rateLimited")
+ expect(classify(facebookApiException(fields), facebookContext)).toBe(
+ "rateLimited",
)
})
- it("classifies Graph code 4 (app-level rate limit) as retryable", () => {
- const error = apiException({ httpStatusCode: 400, code: 4 })
- expect(instagramContactScanAdapter.classifyError(error)).toBe("retryable")
+ it("code 80002 is rateLimited on both providers (reason only, so sends keep their category)", () => {
+ const fields = { httpStatusCode: 400, code: 80_002 }
+ expect(classify(apiException(fields), nativeContext)).toBe("rateLimited")
+ expect(classify(facebookApiException(fields), facebookContext)).toBe(
+ "rateLimited",
+ )
})
- it("classifies Graph code 613 (custom rate limit) as retryable", () => {
- const error = apiException({ httpStatusCode: 400, code: 613 })
- expect(instagramContactScanAdapter.classifyError(error)).toBe("retryable")
+ it.each([
+ 32, 80_001,
+ ])("code %i is rateLimited only for Instagram via Facebook", (code) => {
+ const fields = { httpStatusCode: 400, code }
+ expect(classify(facebookApiException(fields), facebookContext)).toBe(
+ "rateLimited",
+ )
+ expect(classify(apiException(fields), nativeContext)).not.toBe(
+ "rateLimited",
+ )
})
- it("classifies an unrecognized InstagramAPIException as unknown", () => {
- const error = apiException({ httpStatusCode: 400, code: 999 })
- expect(instagramContactScanAdapter.classifyError(error)).toBe("unknown")
+ it("an unrecognized code is unknown, and a plain error is unknown", () => {
+ expect(classify(apiException({ httpStatusCode: 400, code: 999 }))).toBe(
+ "unknown",
+ )
+ expect(classify(new Error("boom"))).toBe("unknown")
})
+ })
- it("classifies a plain non-API error as unknown", () => {
- expect(instagramContactScanAdapter.classifyError(new Error("boom"))).toBe(
- "unknown",
+ describe("readBackoff", () => {
+ it("reads Meta's wait (minutes) from the failed call's response headers", () => {
+ const exception = new InstagramAPIException(
+ "limit",
+ 429,
+ 4,
+ undefined,
+ undefined,
+ {
+ response: {
+ headers: new Headers({
+ "x-business-use-case-usage": JSON.stringify({
+ "1": [
+ {
+ call_count: 96,
+ total_cputime: 10,
+ total_time: 10,
+ estimated_time_to_regain_access: 4,
+ },
+ ],
+ }),
+ }),
+ },
+ },
)
+
+ expect(
+ instagramContactScanAdapter.readBackoff({
+ error: exception,
+ context: nativeContext,
+ }),
+ ).toEqual({ usagePercent: 96, retryAfterMs: 240_000 })
+ })
+
+ it("returns null without a usage header", () => {
+ expect(
+ instagramContactScanAdapter.readBackoff({
+ error: new Error("boom"),
+ context: nativeContext,
+ }),
+ ).toBeNull()
})
})
})
diff --git a/apps/worker/__tests__/contact-scan-messenger-adapter.test.ts b/apps/worker/__tests__/contact-scan-messenger-adapter.test.ts
index b1587df10e..022e4ab74d 100644
--- a/apps/worker/__tests__/contact-scan-messenger-adapter.test.ts
+++ b/apps/worker/__tests__/contact-scan-messenger-adapter.test.ts
@@ -193,28 +193,34 @@ describe("messengerContactScanAdapter", () => {
expect(page.entries).toEqual([])
})
- it("maps BUC usage headers to the engine's usage signal shape", async () => {
+ it("maps BUC usage to the neutral signal, converting Meta's minutes to ms", async () => {
mockListConversations.mockResolvedValue({
data: [],
bucUsage: {
callCount: 12,
totalCpuTime: 34,
totalTime: 56,
- estimatedTimeToRegainAccess: 0,
+ estimatedTimeToRegainAccess: 2,
},
})
const page = await messengerContactScanAdapter.listPage({ context })
expect(page.usageSignal).toEqual({
- kind: "meta-business-use-case-usage",
- callCount: 12,
- totalCputime: 34,
- totalTime: 56,
- estimatedTimeToRegainAccess: 0,
+ usagePercent: 56,
+ retryAfterMs: 120_000,
})
})
+ it("does not retry inline: a failure reaches the engine at once", async () => {
+ mockListConversations.mockRejectedValue(new Error("boom"))
+
+ await expect(
+ messengerContactScanAdapter.listPage({ context }),
+ ).rejects.toThrow("boom")
+ expect(mockListConversations).toHaveBeenCalledTimes(1)
+ })
+
it("returns a null usage signal when no BUC header was present", async () => {
mockListConversations.mockResolvedValue({ data: [] })
@@ -224,18 +230,13 @@ describe("messengerContactScanAdapter", () => {
})
})
- describe("classifyError", () => {
- // `rescue()` (`@chatbotx.io/integration-messenger/exception`) wraps every
- // Graph failure `listConversations` can throw into a `MessengerAPIException`
- // (`extends SdkException`) — a *flat* `httpStatusCode`/`code`/`type`, never
- // the raw, nested `{ response: { status } }` / `{ response: { error } }`
- // shape a ky `HTTPError` would carry. Before the fix, the classifier
- // re-parsed this flat exception as if it were still that raw shape (via
- // `parseOriginError`), which doesn't recognize it and silently falls back
- // to `{ httpStatusCode: 400 (fallback), code: undefined, type: undefined }`
- // — every case below except the last two would have returned "unknown"
- // against the pre-fix implementation, including the 429/500 cases that
- // should terminate as retryable rather than as a failed scan.
+ describe("classifyError (through the Messenger error mapper)", () => {
+ const context = {
+ inbox: fakeInbox,
+ accessToken: "token",
+ version: "v20.0",
+ pageId,
+ }
const apiException = (fields: {
httpStatusCode?: number
code?: string | number
@@ -248,56 +249,109 @@ describe("messengerContactScanAdapter", () => {
undefined,
fields.type,
)
-
- it("classifies a 429 MessengerAPIException as retryable", () => {
- const error = apiException({ httpStatusCode: 429 })
- expect(messengerContactScanAdapter.classifyError(error)).toBe("retryable")
+ const classify = (error: unknown) =>
+ messengerContactScanAdapter.classifyError({ error, context })
+
+ it.each([
+ 4, 17, 32, 613, 80_001, 80_006,
+ ])("Graph code %i is rateLimited", (code) => {
+ expect(classify(apiException({ httpStatusCode: 400, code }))).toBe(
+ "rateLimited",
+ )
})
- it("classifies a 500 MessengerAPIException as retryable", () => {
- const error = apiException({ httpStatusCode: 500 })
- expect(messengerContactScanAdapter.classifyError(error)).toBe("retryable")
+ it("a 429 is rateLimited", () => {
+ expect(classify(apiException({ httpStatusCode: 429 }))).toBe(
+ "rateLimited",
+ )
})
- it("classifies Graph code 4 (app-level rate limit) as retryable even without a 429/5xx status", () => {
- const error = apiException({ httpStatusCode: 400, code: 4 })
- expect(messengerContactScanAdapter.classifyError(error)).toBe("retryable")
+ it("a 500 is retryable", () => {
+ expect(classify(apiException({ httpStatusCode: 500 }))).toBe("retryable")
})
- it("classifies Graph code 190 (expired token) as tokenInvalid", () => {
- const error = apiException({
- httpStatusCode: 401,
- code: 190,
- type: "OAuthException",
- })
- expect(messengerContactScanAdapter.classifyError(error)).toBe(
- "tokenInvalid",
- )
+ it("Graph code 190 (expired token) is tokenInvalid", () => {
+ expect(
+ classify(
+ apiException({
+ httpStatusCode: 401,
+ code: 190,
+ type: "OAuthException",
+ }),
+ ),
+ ).toBe("tokenInvalid")
})
- it("classifies Graph code 10 (permission denied) as graphPermission", () => {
- const error = apiException({ httpStatusCode: 403, code: 10 })
- expect(messengerContactScanAdapter.classifyError(error)).toBe(
+ it.each([
+ 10, 200,
+ ])("Graph permission code %i is graphPermission", (code) => {
+ expect(classify(apiException({ httpStatusCode: 403, code }))).toBe(
"graphPermission",
)
})
- it("classifies a Graph code in the 200-series permission range as graphPermission", () => {
- const error = apiException({ httpStatusCode: 403, code: 200 })
- expect(messengerContactScanAdapter.classifyError(error)).toBe(
- "graphPermission",
+ it("an unrecognized code is unknown", () => {
+ expect(classify(apiException({ httpStatusCode: 400, code: 999 }))).toBe(
+ "unknown",
)
})
- it("classifies an unrecognized MessengerAPIException as unknown", () => {
- const error = apiException({ httpStatusCode: 400, code: 999 })
- expect(messengerContactScanAdapter.classifyError(error)).toBe("unknown")
+ it("a plain non-API error is unknown", () => {
+ expect(classify(new Error("boom"))).toBe("unknown")
})
+ })
- it("classifies a plain non-API error as unknown", () => {
- expect(messengerContactScanAdapter.classifyError(new Error("boom"))).toBe(
- "unknown",
+ describe("readBackoff", () => {
+ const context = {
+ inbox: fakeInbox,
+ accessToken: "token",
+ version: "v20.0",
+ pageId,
+ }
+
+ it("reads Meta's wait (minutes) from the failed call's response headers", () => {
+ const exception = new MessengerAPIException(
+ "limit",
+ 429,
+ 80_006,
+ undefined,
+ undefined,
+ {
+ response: {
+ headers: new Headers({
+ "x-business-use-case-usage": JSON.stringify({
+ "1": [
+ {
+ call_count: 100,
+ total_cputime: 20,
+ total_time: 20,
+ estimated_time_to_regain_access: 3,
+ },
+ ],
+ }),
+ }),
+ },
+ },
)
+
+ expect(
+ messengerContactScanAdapter.readBackoff({ error: exception, context }),
+ ).toEqual({ usagePercent: 100, retryAfterMs: 180_000 })
+ })
+
+ it("returns null when the error carries no usage header", () => {
+ expect(
+ messengerContactScanAdapter.readBackoff({
+ error: new MessengerAPIException("x", 500),
+ context,
+ }),
+ ).toBeNull()
+ expect(
+ messengerContactScanAdapter.readBackoff({
+ error: new Error("boom"),
+ context,
+ }),
+ ).toBeNull()
})
})
})
diff --git a/apps/worker/__tests__/contact-scan-pacing.test.ts b/apps/worker/__tests__/contact-scan-pacing.test.ts
new file mode 100644
index 0000000000..723ea3889b
--- /dev/null
+++ b/apps/worker/__tests__/contact-scan-pacing.test.ts
@@ -0,0 +1,70 @@
+import { CONTACT_SCAN_RELEASED_GRACE_MS } from "@chatbotx.io/business/contact-scan"
+import { describe, expect, it } from "vitest"
+import {
+ CONTACT_SCAN_PACING,
+ resolveScanPacing,
+} from "../src/integration/handlers/contact-scan/pacing"
+
+const MINUTE = 60_000
+
+describe("resolveScanPacing", () => {
+ it("does not wait without a signal", () => {
+ expect(resolveScanPacing({})).toBe(0)
+ expect(resolveScanPacing({ signal: null })).toBe(0)
+ expect(resolveScanPacing({ signal: { usagePercent: 40 } })).toBe(0)
+ })
+
+ it("waits 2 minutes from 85% usage and 10 minutes from 95%", () => {
+ expect(resolveScanPacing({ signal: { usagePercent: 84.9 } })).toBe(0)
+ expect(resolveScanPacing({ signal: { usagePercent: 85 } })).toBe(2 * MINUTE)
+ expect(resolveScanPacing({ signal: { usagePercent: 94 } })).toBe(2 * MINUTE)
+ expect(resolveScanPacing({ signal: { usagePercent: 95 } })).toBe(
+ 10 * MINUTE,
+ )
+ })
+
+ it("a rate limit waits 10 minutes even with no usage figure", () => {
+ expect(resolveScanPacing({ rateLimited: true })).toBe(10 * MINUTE)
+ expect(
+ resolveScanPacing({ rateLimited: true, signal: { usagePercent: 10 } }),
+ ).toBe(10 * MINUTE)
+ })
+
+ it("the provider's own wait wins over usage and a rate limit", () => {
+ expect(
+ resolveScanPacing({
+ rateLimited: true,
+ signal: { usagePercent: 99, retryAfterMs: 3 * MINUTE },
+ }),
+ ).toBe(3 * MINUTE)
+ })
+
+ it("the provider's wait is capped at 30 minutes", () => {
+ expect(resolveScanPacing({ signal: { retryAfterMs: 120 * MINUTE } })).toBe(
+ 30 * MINUTE,
+ )
+ })
+
+ it("a zero provider wait falls through to the usage rule", () => {
+ expect(
+ resolveScanPacing({ signal: { usagePercent: 90, retryAfterMs: 0 } }),
+ ).toBe(2 * MINUTE)
+ })
+})
+
+describe("CONTACT_SCAN_PACING", () => {
+ it("pins the scan rhythm", () => {
+ expect(CONTACT_SCAN_PACING).toMatchObject({
+ chunkMaxPages: 5,
+ chunkBudgetMs: 4 * MINUTE,
+ pageGapMs: 1000,
+ chunkGapMs: 5000,
+ })
+ })
+
+ it("a lost delayed job is recovered only after the longest possible wait", () => {
+ expect(CONTACT_SCAN_RELEASED_GRACE_MS).toBeGreaterThan(
+ CONTACT_SCAN_PACING.maxProviderWaitMs,
+ )
+ })
+})
diff --git a/apps/worker/__tests__/send-message-handler.test.ts b/apps/worker/__tests__/send-message-handler.test.ts
index 0247946dc6..3b5a9f9b0b 100644
--- a/apps/worker/__tests__/send-message-handler.test.ts
+++ b/apps/worker/__tests__/send-message-handler.test.ts
@@ -1819,4 +1819,176 @@ describe("chat send-message handlers", () => {
expect(mockSettleEvent).not.toHaveBeenCalled()
})
})
+ describe("inbox send result (composer queue signal)", () => {
+ const createdAt = new Date("2026-07-09T08:37:21.108Z")
+ const inboxMessage = (overrides: Record = {}) =>
+ ({
+ id: "msg-inbox",
+ workspaceId: "ws-1",
+ conversationId: "conv-1",
+ contactInboxId: "ci-1",
+ contentType: "text",
+ messageType: "outgoing",
+ senderType: "user",
+ senderId: "user-1",
+ text: "hello",
+ clientId: "client-1",
+ createdAt,
+ ...overrides,
+ }) as never
+
+ test("a first-attempt inbox send publishes messageFailed with error null, without touching the row", async () => {
+ await sendMessageToChannel({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ message: inboxMessage(),
+ sendFrom: "inbox",
+ })
+
+ expect(mockQueueWorkspaceRealtimeEvent).toHaveBeenCalledWith("ws-1", {
+ eventType: "messageFailed",
+ data: { messageId: "msg-inbox", clientId: "client-1", error: null },
+ route: { assignedTeamIds: [], assignedUserIds: [] },
+ })
+ expect(mockUpdateSendError).not.toHaveBeenCalled()
+ })
+
+ test("a send that is not from the inbox publishes nothing", async () => {
+ await sendMessageToChannel({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ message: inboxMessage(),
+ })
+
+ expect(mockQueueWorkspaceRealtimeEvent).not.toHaveBeenCalled()
+ })
+
+ test("a bulk broadcast send publishes nothing even with sendFrom set", async () => {
+ await sendMessageToChannel({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ isBulkBroadcast: true,
+ message: inboxMessage({
+ senderType: "bot",
+ contentAttributes: {
+ metadata: {
+ type: "broadcast",
+ broadcastId: "b-1",
+ contactInboxId: "ci-1",
+ },
+ },
+ }),
+ sendFrom: "inbox",
+ })
+
+ expect(mockQueueWorkspaceRealtimeEvent).not.toHaveBeenCalled()
+ })
+
+ test("the confirmation goes out even when later bookkeeping fails, which never marks the message failed or retries it", async () => {
+ mockRecordOutboundMessageSent.mockRejectedValueOnce(new Error("db down"))
+
+ await expect(
+ sendMessageToChannel({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ message: inboxMessage(),
+ sendFrom: "inbox",
+ }),
+ ).resolves.toEqual({ messageIds: ["mid-1"], sentCount: 1 })
+
+ expect(mockQueueWorkspaceRealtimeEvent).toHaveBeenCalledWith(
+ "ws-1",
+ expect.objectContaining({
+ eventType: "messageFailed",
+ data: expect.objectContaining({ error: null }),
+ }),
+ )
+ // Only the confirmation: no error was written or published.
+ expect(mockUpdateSendError).not.toHaveBeenCalled()
+ expect(mockEmit).not.toHaveBeenCalledWith(
+ "message:failed",
+ expect.anything(),
+ )
+ expect(logger.error).toHaveBeenCalledWith(
+ expect.objectContaining({ messageId: "msg-inbox" }),
+ expect.stringContaining("Post-send bookkeeping failed"),
+ )
+ })
+
+ test("a failure to publish the confirmation is only logged", async () => {
+ mockQueueWorkspaceRealtimeEvent.mockImplementationOnce(() => {
+ throw new Error("redis down")
+ })
+
+ await expect(
+ sendMessageToChannel({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ message: inboxMessage(),
+ sendFrom: "inbox",
+ }),
+ ).resolves.toEqual({ messageIds: ["mid-1"], sentCount: 1 })
+ })
+ })
+
+ describe("send error is recorded only once it is final", () => {
+ const failing = (willRetryOnThrow: boolean) => {
+ mockRunChannelHandler.mockRejectedValueOnce(
+ new ChannelError("rate limited", ChannelErrorCategory.RATE_LIMITED, {
+ code: "rate_limited",
+ }),
+ )
+ return sendMessageToChannel(
+ {
+ conversation: conversation as never,
+ contactInbox: { ...contactInbox, channel: "whatsapp" } as never,
+ message: {
+ id: "msg-1",
+ workspaceId: "ws-1",
+ conversationId: "conv-1",
+ contactInboxId: "ci-1",
+ contentType: "text",
+ messageType: "outgoing",
+ senderType: "user",
+ text: "hello",
+ clientId: "client-1",
+ createdAt: new Date("2026-07-09T08:37:21.108Z"),
+ } as never,
+ sendFrom: "inbox",
+ },
+ 0,
+ willRetryOnThrow,
+ )
+ }
+
+ test("while the job will still retry, nothing is persisted or shown", async () => {
+ await expect(failing(true)).rejects.toBeInstanceOf(ChannelError)
+
+ expect(mockUpdateSendError).not.toHaveBeenCalled()
+ expect(mockQueueWorkspaceRealtimeEvent).not.toHaveBeenCalled()
+ // The failure event still carries willRetry for analytics and logs.
+ expect(mockEmit).toHaveBeenCalledWith(
+ "message:failed",
+ expect.objectContaining({ willRetry: true }),
+ )
+ })
+
+ test("on the final failure the error is persisted and published", async () => {
+ await expect(failing(false)).rejects.toBeInstanceOf(ChannelError)
+
+ expect(mockUpdateSendError).toHaveBeenCalledWith(
+ "msg-1",
+ "sdk error",
+ "ws-1",
+ new Date("2026-07-09T08:37:21.108Z"),
+ )
+ expect(mockQueueWorkspaceRealtimeEvent).toHaveBeenCalledWith(
+ "ws-1",
+ expect.objectContaining({
+ eventType: "messageFailed",
+ data: expect.objectContaining({ error: "sdk error" }),
+ }),
+ )
+ })
+ })
})
diff --git a/apps/worker/src/chat/handlers/account-send-blocked.ts b/apps/worker/src/chat/handlers/account-send-blocked.ts
new file mode 100644
index 0000000000..6bd83013fb
--- /dev/null
+++ b/apps/worker/src/chat/handlers/account-send-blocked.ts
@@ -0,0 +1,91 @@
+import { broadcastService } from "@chatbotx.io/business"
+import { BROADCAST_PAYLOAD_TYPE } from "@chatbotx.io/flow-config"
+import { casStore } from "@chatbotx.io/redis"
+import { ChannelError, isAccountSendBlocked } from "@chatbotx.io/sdk"
+import { logger } from "../../lib/logger"
+import type { ChannelSendErrorContext } from "./channel-send-error-types"
+
+// A blocked page fails every queued recipient at once; one stop is enough, so
+// the burst after the first error is coalesced for this long. The stop itself
+// is idempotent, which is why losing Redis only costs duplicate (cheap) work.
+const BURST_WINDOW_MS = 2000
+const burstKey = (inboxId: string): string =>
+ `broadcast:account-block-stop:${inboxId}`
+
+// Bounded: entries older than the burst window are pruned on every insert.
+const recentStopByInbox = new Map()
+
+const isBroadcastSend = (context: ChannelSendErrorContext): boolean =>
+ context.metadata?.type === BROADCAST_PAYLOAD_TYPE
+
+/** True when this process or another one already handled the burst. */
+const isBurstHandled = async (inboxId: string): Promise => {
+ const now = Date.now()
+ const last = recentStopByInbox.get(inboxId)
+ if (last !== undefined && now - last < BURST_WINDOW_MS) {
+ return true
+ }
+ for (const [id, at] of recentStopByInbox) {
+ if (now - at >= BURST_WINDOW_MS) {
+ recentStopByInbox.delete(id)
+ }
+ }
+ recentStopByInbox.set(inboxId, now)
+ try {
+ return !(await casStore.setIfAbsent(burstKey(inboxId), 1, BURST_WINDOW_MS))
+ } catch (err) {
+ logger.warn({ err, inboxId }, "Burst guard unavailable; stopping anyway")
+ return false
+ }
+}
+
+/**
+ * A broadcast send was refused because the channel account itself is blocked
+ * from sending (`ChannelError.reason`, assigned by each channel's mapper):
+ * every recipient of every running broadcast of that page would fail the same
+ * way, so they are stopped (the customer resumes once the page is unblocked).
+ * Only broadcast sends trigger it; inbox, flow and sequence sends do not.
+ *
+ * Always returns `false`: the send error is still recorded and retried exactly
+ * as before, and a failure here is only logged.
+ */
+export async function reconcileAccountSendBlocked(
+ context: ChannelSendErrorContext,
+): Promise {
+ const { error, contactInbox, conversation } = context
+ if (
+ !(
+ error instanceof ChannelError &&
+ error.reason !== undefined &&
+ isAccountSendBlocked(error) &&
+ isBroadcastSend(context)
+ )
+ ) {
+ return false
+ }
+
+ const { inboxId } = contactInbox
+ try {
+ if (await isBurstHandled(inboxId)) {
+ return false
+ }
+ await broadcastService.stopSendingForBlockedAccount({
+ workspaceId: conversation.workspaceId,
+ inboxId,
+ channel: contactInbox.channel,
+ reason: error.reason,
+ errorMessage: error.message,
+ })
+ } catch (err) {
+ // Forget both marks so the next error of the burst can try again.
+ recentStopByInbox.delete(inboxId)
+ await casStore.del(burstKey(inboxId)).catch((delErr: unknown) => {
+ logger.warn({ err: delErr, inboxId }, "Unable to release the burst guard")
+ })
+ logger.error(
+ { err, inboxId },
+ "Unable to stop broadcasts for a blocked channel account",
+ )
+ }
+ return false
+}
diff --git a/apps/worker/src/chat/handlers/channel-send-error-reconcilers.ts b/apps/worker/src/chat/handlers/channel-send-error-reconcilers.ts
index a6d43c770c..aba40494f3 100644
--- a/apps/worker/src/chat/handlers/channel-send-error-reconcilers.ts
+++ b/apps/worker/src/chat/handlers/channel-send-error-reconcilers.ts
@@ -1,5 +1,6 @@
import { channelTypes } from "@chatbotx.io/database/partials"
import type { ContactInboxModel } from "@chatbotx.io/database/types"
+import { reconcileAccountSendBlocked } from "./account-send-blocked"
import type {
ChannelSendErrorContext,
ChannelSendErrorReconciler,
@@ -18,15 +19,24 @@ const channelSendErrorReconcilers: Partial<
[channelTypes.enum.messenger]: [reconcileMessengerThreadControlRejection],
}
+// Channel-agnostic: reads only the neutral `ChannelError.reason`, so a new
+// channel takes part by assigning a reason in its own error mapper.
+const sharedReconcilers: ChannelSendErrorReconciler[] = [
+ reconcileAccountSendBlocked,
+]
+
/**
- * Runs every reconciler registered for the channel (each one inspects the
- * error and ignores what is not its own); `true` when any of them reconciled.
+ * Runs the shared reconcilers, then every reconciler registered for the
+ * channel (each one inspects the error and ignores what is not its own);
+ * `true` when any of them reconciled.
*/
export async function reconcileChannelSendError(
context: ChannelSendErrorContext,
): Promise {
- const reconcilers =
- channelSendErrorReconcilers[context.contactInbox.channel] ?? []
+ const reconcilers = [
+ ...sharedReconcilers,
+ ...(channelSendErrorReconcilers[context.contactInbox.channel] ?? []),
+ ]
let isReconciled = false
for (const reconcile of reconcilers) {
isReconciled = (await reconcile(context)) || isReconciled
diff --git a/apps/worker/src/chat/handlers/channel-send-error-types.ts b/apps/worker/src/chat/handlers/channel-send-error-types.ts
index 10218584ca..72f69039e7 100644
--- a/apps/worker/src/chat/handlers/channel-send-error-types.ts
+++ b/apps/worker/src/chat/handlers/channel-send-error-types.ts
@@ -2,6 +2,7 @@ import type {
ContactInboxModel,
ConversationModel,
} from "@chatbotx.io/database/types"
+import type { MetadataPayload } from "@chatbotx.io/flow-config"
// Kept apart from the reconciler registry so each reconciler can import the
// contract without importing the registry that imports it (no module cycle).
@@ -14,6 +15,8 @@ export type ChannelSendErrorContext = {
>
contactInbox: ContactInboxModel
contentAttributes: unknown
+ /** The send job's payload tag (broadcast, sequence, flow node, ...). */
+ metadata?: MetadataPayload
}
/**
diff --git a/apps/worker/src/chat/handlers/messenger-thread-control-rejection.ts b/apps/worker/src/chat/handlers/messenger-thread-control-rejection.ts
index 51b978c02b..b920ca25a6 100644
--- a/apps/worker/src/chat/handlers/messenger-thread-control-rejection.ts
+++ b/apps/worker/src/chat/handlers/messenger-thread-control-rejection.ts
@@ -5,7 +5,11 @@ import {
import { syncThreadOwner } from "@chatbotx.io/channel-registry/thread-control"
import { toThreadControlTimestamp } from "@chatbotx.io/database/partials"
import { isThreadControlRejection } from "@chatbotx.io/integration-messenger"
-import { ChannelError, ChannelErrorCategory } from "@chatbotx.io/sdk"
+import {
+ ChannelError,
+ ChannelErrorCategory,
+ isAccountSendBlocked,
+} from "@chatbotx.io/sdk"
import { logger } from "../../lib/logger"
import type { ChannelSendErrorContext } from "./channel-send-error-types"
@@ -66,6 +70,11 @@ export async function reconcileMessengerThreadControlRejection(
) {
return false
}
+ // The page itself is blocked from sending, so no other app holds the thread:
+ // the owner lookup below cannot explain this refusal.
+ if (isAccountSendBlocked(error)) {
+ return false
+ }
if (isThreadControlRejection(error)) {
await recordServiceRejected(context, {
ownerRole: contactInbox.threadOwnerRole ?? null,
diff --git a/apps/worker/src/chat/handlers/send-message.ts b/apps/worker/src/chat/handlers/send-message.ts
index e15efc12b2..4f86d7ff2b 100644
--- a/apps/worker/src/chat/handlers/send-message.ts
+++ b/apps/worker/src/chat/handlers/send-message.ts
@@ -362,154 +362,173 @@ export async function sendMessageToChannel(
)
}
- if (isComment) {
- // When the outgoing message is a comment reply, store the Facebook comment
- // ID of the new reply so the page manager can edit/delete it later.
- const replyId = result.messageIds[0]
- if (message.parentId && replyId && message.id) {
- // The reply was already sent successfully — a failure past this
- // point must never rethrow, or BullMQ retries the whole job and
- // sendComment fires again, posting a second live duplicate reply.
- try {
- await messageService.updateSourceId({
- id: message.id,
- sourceId: replyId,
- workspaceId: conversation.workspaceId,
- createdAt: new Date(message.createdAt),
- })
+ // The channel accepted the message. Tell the composer right away (before
+ // any bookkeeping) so its send queue can move on.
+ await publishInboxSendConfirmation({
+ sendFrom,
+ silent: isBulkOutbound,
+ conversation,
+ message,
+ })
- // Notify the client so edit/delete buttons appear immediately without a refresh.
- await queueConversationScopedMessageEvent({
- workspaceId: conversation.workspaceId,
- conversationId: conversation.id,
- eventType: RealtimeEventType.messageIdAssigned,
- data: { messageId: message.id, commentId: replyId },
- })
+ // Everything below is bookkeeping for a message that is already delivered:
+ // a failure here must neither mark it failed nor rethrow into a retry, which
+ // would send it a second time.
+ try {
+ if (isComment) {
+ // When the outgoing message is a comment reply, store the Facebook comment
+ // ID of the new reply so the page manager can edit/delete it later.
+ const replyId = result.messageIds[0]
+ if (message.parentId && replyId && message.id) {
+ // The reply was already sent successfully — a failure past this
+ // point must never rethrow, or BullMQ retries the whole job and
+ // sendComment fires again, posting a second live duplicate reply.
+ try {
+ await messageService.updateSourceId({
+ id: message.id,
+ sourceId: replyId,
+ workspaceId: conversation.workspaceId,
+ createdAt: new Date(message.createdAt),
+ })
+
+ // Notify the client so edit/delete buttons appear immediately without a refresh.
+ await queueConversationScopedMessageEvent({
+ workspaceId: conversation.workspaceId,
+ conversationId: conversation.id,
+ eventType: RealtimeEventType.messageIdAssigned,
+ data: { messageId: message.id, commentId: replyId },
+ })
- if (attemptsMade > 0) {
- await clearMessageSendError(
- message.id,
- message.clientId,
- conversation.workspaceId,
- new Date(message.createdAt),
- { conversationId: conversation.id, silent: isBulkOutbound },
+ if (attemptsMade > 0) {
+ await clearMessageSendError(
+ message.id,
+ message.clientId,
+ conversation.workspaceId,
+ new Date(message.createdAt),
+ { conversationId: conversation.id, silent: isBulkOutbound },
+ )
+ }
+ } catch (err) {
+ logger.error(
+ err,
+ "Failed to persist comment reply sourceId after a successful send",
)
}
- } catch (err) {
- logger.error(
- err,
- "Failed to persist comment reply sourceId after a successful send",
- )
}
- }
- } else {
- // Persist the provider message id as this row's sourceId. The channel
- // echoes every page-sent message back via webhook (coexist); the echo
- // handler dedups through createOrUpdate → findBySourceId. Without a
- // sourceId here, bot/agent outgoing rows stay sourceId=null, the echo
- // lookup misses, and a duplicate row is inserted as senderType=user.
- await updateMessageSourceId(
- message.id,
- conversation.workspaceId,
- new Date(message.createdAt),
- result,
- )
-
- if (attemptsMade > 0) {
- await clearMessageSendError(
+ } else {
+ // Persist the provider message id as this row's sourceId. The channel
+ // echoes every page-sent message back via webhook (coexist); the echo
+ // handler dedups through createOrUpdate → findBySourceId. Without a
+ // sourceId here, bot/agent outgoing rows stay sourceId=null, the echo
+ // lookup misses, and a duplicate row is inserted as senderType=user.
+ await updateMessageSourceId(
message.id,
- message.clientId,
conversation.workspaceId,
new Date(message.createdAt),
- { conversationId: conversation.id, silent: isBulkOutbound },
+ result,
)
- }
- }
- await contactInboxService.recordOutboundMessageSent({
- contactInboxId: contactInbox.id,
- contactId: contactInbox.contactId,
- workspaceId: conversation.workspaceId,
- at: message.createdAt ?? new Date(),
- })
+ if (attemptsMade > 0) {
+ await clearMessageSendError(
+ message.id,
+ message.clientId,
+ conversation.workspaceId,
+ new Date(message.createdAt),
+ { conversationId: conversation.id, silent: isBulkOutbound },
+ )
+ }
+ }
- // A public comment reply reaches no one's inbox; a private reply does.
- if (!isComment || isPrivateReply) {
- await recordDeliveredWhenNoReceipts({
- contactInbox,
- sentCount: result.sentCount,
+ await contactInboxService.recordOutboundMessageSent({
+ contactInboxId: contactInbox.id,
+ contactId: contactInbox.contactId,
workspaceId: conversation.workspaceId,
+ at: message.createdAt ?? new Date(),
})
- }
-
- if (!isComment) {
- await recordServiceSent({
- conversation,
- contactInbox: routingContactInbox,
- isTemplateMessage: false,
- dispatchedAt,
- })
- }
- if (isDeliveredDirectMessage({ message, result })) {
- await markConversationReadAfterDelivery({
- workspaceId: conversation.workspaceId,
- conversationId: conversation.id,
- inboxId: contactInbox.inboxId,
- readAt: new Date(message.createdAt),
- silent: isBulkOutbound,
- })
- }
+ // A public comment reply reaches no one's inbox; a private reply does.
+ if (!isComment || isPrivateReply) {
+ await recordDeliveredWhenNoReceipts({
+ contactInbox,
+ sentCount: result.sentCount,
+ workspaceId: conversation.workspaceId,
+ })
+ }
- // The other half of the cross-queue anchor: the integration worker recorded
- // the attempt optimistically and only this handler knows the Graph API
- // accepted it. Meta sends no delivery receipt for a public comment reply,
- // so this is the automation's only delivery signal.
- await settleCommentAutomationDelivered({
- contentAttributes: message?.contentAttributes,
- })
+ if (!isComment) {
+ await recordServiceSent({
+ conversation,
+ contactInbox: routingContactInbox,
+ isTemplateMessage: false,
+ dispatchedAt,
+ })
+ }
- if (!isComment) {
- try {
- await contactService.unblockIfBlocked({
+ if (isDeliveredDirectMessage({ message, result })) {
+ await markConversationReadAfterDelivery({
workspaceId: conversation.workspaceId,
- id: conversation.contactId,
+ conversationId: conversation.id,
+ inboxId: contactInbox.inboxId,
+ readAt: new Date(message.createdAt),
+ silent: isBulkOutbound,
})
- } catch (error) {
- logger.warn(error, "Auto-unblock on successful send failed")
}
- }
- // Bot-message quota accounting: `chat/worker.ts`'s pre-send gate blocks this
- // job type when `senderType === "bot"` (`isBotMessageQuotaReached`), but
- // nothing previously counted it — the quota gate and the quota meter must
- // stay structurally paired or the gate is enforced against a counter that
- // never moves. Human-sent messages (senderType !== "bot") are unaffected.
- if (message.senderType === "bot") {
- await emitBotMessageSentEvents({
- workspaceId: conversation.workspaceId,
- contactInbox,
- result,
- trigger: {
- triggerHandler: "sendMessageToChannel",
- triggerType: "message_bot_sent_channel",
- },
- })
- } else if (message.senderType === "user" && message.senderId) {
- // A workspace member's message from the inbox composer. `api` and
- // `system` senders are not human agents and stay out of agent stats.
- await emitHumanMessageSentEvents({
- workspaceId: conversation.workspaceId,
- contactInbox,
- result,
- trigger: {
- triggerHandler: "sendMessageToChannel",
- triggerType: "message_human_sent_channel",
- },
- adminId: message.senderId,
- messageId: message.id,
- occurredAt: new Date(message.createdAt),
+ // The other half of the cross-queue anchor: the integration worker recorded
+ // the attempt optimistically and only this handler knows the Graph API
+ // accepted it. Meta sends no delivery receipt for a public comment reply,
+ // so this is the automation's only delivery signal.
+ await settleCommentAutomationDelivered({
+ contentAttributes: message?.contentAttributes,
})
+
+ if (!isComment) {
+ try {
+ await contactService.unblockIfBlocked({
+ workspaceId: conversation.workspaceId,
+ id: conversation.contactId,
+ })
+ } catch (error) {
+ logger.warn(error, "Auto-unblock on successful send failed")
+ }
+ }
+
+ // Bot-message quota accounting: `chat/worker.ts`'s pre-send gate blocks this
+ // job type when `senderType === "bot"` (`isBotMessageQuotaReached`), but
+ // nothing previously counted it — the quota gate and the quota meter must
+ // stay structurally paired or the gate is enforced against a counter that
+ // never moves. Human-sent messages (senderType !== "bot") are unaffected.
+ if (message.senderType === "bot") {
+ await emitBotMessageSentEvents({
+ workspaceId: conversation.workspaceId,
+ contactInbox,
+ result,
+ trigger: {
+ triggerHandler: "sendMessageToChannel",
+ triggerType: "message_bot_sent_channel",
+ },
+ })
+ } else if (message.senderType === "user" && message.senderId) {
+ // A workspace member's message from the inbox composer. `api` and
+ // `system` senders are not human agents and stay out of agent stats.
+ await emitHumanMessageSentEvents({
+ workspaceId: conversation.workspaceId,
+ contactInbox,
+ result,
+ trigger: {
+ triggerHandler: "sendMessageToChannel",
+ triggerType: "message_human_sent_channel",
+ },
+ adminId: message.senderId,
+ messageId: message.id,
+ occurredAt: new Date(message.createdAt),
+ })
+ }
+ } catch (err) {
+ logger.error(
+ { err, messageId: message.id, workspaceId: conversation.workspaceId },
+ "Post-send bookkeeping failed after the channel accepted the message",
+ )
}
return result
@@ -521,6 +540,7 @@ export async function sendMessageToChannel(
conversation,
contactInbox: routingContactInbox,
contentAttributes: message.contentAttributes,
+ metadata,
})
logger.error(error, "An error occurred while sending the message")
const errorData = await parseSdkError(error)
@@ -550,14 +570,19 @@ export async function sendMessageToChannel(
metadata,
willRetry,
})
- await recordMessageSendError(
- message?.id,
- message?.clientId,
- conversation.workspaceId,
- message?.createdAt ? new Date(message.createdAt) : undefined,
- errorData.message,
- { conversationId: conversation.id, silent: isBulkOutbound },
- )
+ // Only a FINAL failure is recorded and shown: while the job will still be
+ // retried the message may yet go out, and an error badge now would invite a
+ // Resend that duplicates it.
+ if (!willRetry) {
+ await recordMessageSendError(
+ message?.id,
+ message?.clientId,
+ conversation.workspaceId,
+ message?.createdAt ? new Date(message.createdAt) : undefined,
+ errorData.message,
+ { conversationId: conversation.id, silent: isBulkOutbound },
+ )
+ }
// Terminal failures only: an attempt that is about to be retried must not
// put a row in the automation's Error Logs for a reply that still lands.
if (!willRetry) {
@@ -889,6 +914,40 @@ const queueConversationScopedMessageEvent = async (input: {
}
}
+/**
+ * Success signal for a message typed in the inbox: the existing `messageFailed`
+ * event with `error: null`, which the builder already reads as "no error". It
+ * is the composer queue's only "this message was accepted" signal, so it is
+ * published for inbox sends only (broadcasts, flows and sequences stay silent).
+ */
+const publishInboxSendConfirmation = async (input: {
+ sendFrom: "inbox" | undefined
+ silent: boolean
+ conversation: Pick
+ message: Pick & { clientId?: string | undefined }
+}): Promise => {
+ if (input.sendFrom !== "inbox" || input.silent) {
+ return
+ }
+ try {
+ await queueConversationScopedMessageEvent({
+ workspaceId: input.conversation.workspaceId,
+ conversationId: input.conversation.id,
+ eventType: RealtimeEventType.messageFailed,
+ data: {
+ messageId: input.message.id,
+ clientId: input.message.clientId,
+ error: null,
+ },
+ })
+ } catch (err) {
+ logger.warn(
+ { err, messageId: input.message.id },
+ "Failed to publish the inbox send confirmation",
+ )
+ }
+}
+
const MAX_SEND_ERROR_LENGTH = 500
const persistMessageSendError = async (input: {
@@ -1220,6 +1279,7 @@ export async function sendFlowStepToChannel({
conversation,
contactInbox,
contentAttributes: undefined,
+ metadata,
})
throw error
}
diff --git a/apps/worker/src/integration/handlers/contact-scan/adapter.ts b/apps/worker/src/integration/handlers/contact-scan/adapter.ts
index fe944fc803..ec5c6b10b5 100644
--- a/apps/worker/src/integration/handlers/contact-scan/adapter.ts
+++ b/apps/worker/src/integration/handlers/contact-scan/adapter.ts
@@ -6,24 +6,16 @@ import { instagramContactScanAdapter } from "./adapters/instagram"
import { messengerContactScanAdapter } from "./adapters/messenger"
/**
- * Generic usage signal surfaced by a provider's list call, so the engine can
- * feed it into a shared throttle (`resolveUsageThrottle`/`sleepForUsageThrottle`,
- * `../coexist/usage-throttle.ts`) without knowing which provider produced it.
+ * Neutral usage signal a provider call yields. Each adapter converts its own
+ * headers and units into these two fields, so the engine and `pacing.ts` know no
+ * header names or units.
*/
-export type ContactScanUsageSignal =
- | {
- kind: "meta-app-usage"
- callCount?: number
- totalCputime?: number
- totalTime?: number
- }
- | {
- kind: "meta-business-use-case-usage"
- estimatedTimeToRegainAccess?: number
- callCount?: number
- totalCputime?: number
- totalTime?: number
- }
+export type ContactScanUsageSignal = {
+ /** Highest share (0-100) of the provider's quota in use. */
+ usagePercent?: number
+ /** How long the provider asks callers to wait, in milliseconds. */
+ retryAfterMs?: number
+}
export type ContactScanPage = {
entries: Array<{ contact: IncomingContact; updatedAt: Date | null }>
@@ -36,6 +28,7 @@ export type ContactScanPage = {
/** How a thrown provider error should be handled by the engine — a table
* lookup by the adapter, never a channel-specific if-chain in the engine. */
export type ContactScanErrorClassification =
+ | "rateLimited"
| "retryable"
| "tokenInvalid"
| "graphPermission"
@@ -64,8 +57,23 @@ export type ContactScanAdapter = {
}): Promise
/** Lists one page of conversations/contacts, newest → oldest. */
listPage(input: { context: Ctx; cursor?: string }): Promise
- /** Classifies a thrown provider error into the engine's retry/terminal table. */
- classifyError(error: unknown): ContactScanErrorClassification
+ /**
+ * Classifies a thrown provider error into the engine's table, through the
+ * channel's own error mapper. Takes the context because a channel may have
+ * several providers with different mappers (Instagram login vs Facebook).
+ */
+ classifyError(input: {
+ error: unknown
+ context: Ctx
+ }): ContactScanErrorClassification
+ /**
+ * Reads the quota headers of a FAILED call (they ride the error response) so
+ * a rate-limited scan can wait as long as the provider asks.
+ */
+ readBackoff(input: {
+ error: unknown
+ context: Ctx
+ }): ContactScanUsageSignal | null
/** `ErrorLog.action` value written by `logProviderError` on a thrown error. */
provider: ErrorLogProvider
}
diff --git a/apps/worker/src/integration/handlers/contact-scan/adapters/instagram.ts b/apps/worker/src/integration/handlers/contact-scan/adapters/instagram.ts
index ec919ad361..80f995f344 100644
--- a/apps/worker/src/integration/handlers/contact-scan/adapters/instagram.ts
+++ b/apps/worker/src/integration/handlers/contact-scan/adapters/instagram.ts
@@ -6,18 +6,19 @@ import type {
InboxModel,
IntegrationInstagramModel,
} from "@chatbotx.io/database/types"
+import { mapToChannelError as mapInstagramError } from "@chatbotx.io/integration-instagram"
import { listInstagramConversations } from "@chatbotx.io/integration-instagram/apis/sync"
+import { mapToChannelError as mapInstagramFacebookError } from "@chatbotx.io/integration-instagram-facebook"
import { listInstagramFacebookConversations } from "@chatbotx.io/integration-instagram-facebook/apis/sync"
import { z } from "zod"
import {
findCustomerParticipant,
parseInstagramApiDate,
- toAppUsageSignal,
toIncomingContact,
} from "../../coexist/instagram-normalize"
-import { withInlineRetry } from "../../coexist/messenger-helpers"
import type { ContactScanAdapter, ContactScanPage } from "../adapter"
-import { classifyGraphSdkError } from "../graph-error"
+import { classifyChannelErrorForScan } from "../graph-error"
+import { peakUsagePercent, readBackoffFromErrorResponse } from "../usage-signal"
type InstagramIntegrationType = IntegrationInstagramModel["type"]
@@ -132,6 +133,18 @@ const listConversationsByProviderType: Record<
},
}
+/**
+ * Each Instagram provider has its own error mapper (the two packages carry
+ * different rate-limit code tables), picked by the integration type.
+ */
+const mapErrorByProviderType: Record<
+ InstagramIntegrationType,
+ typeof mapInstagramError
+> = {
+ instagram: mapInstagramError,
+ facebook: mapInstagramFacebookError,
+}
+
export const instagramContactScanAdapter: ContactScanAdapter =
{
channel: "instagram",
@@ -172,21 +185,16 @@ export const instagramContactScanAdapter: ContactScanAdapter {
- // Wrapped in the same `withInlineRetry` the Messenger adapter uses
- // (`messenger.ts`'s `listPage`) — this Graph list call was previously
- // unretried, so a transient 429/5xx would fall straight through to the
- // engine's outer classifier as a full page loss instead of resolving
- // inline.
- const page = await withInlineRetry(() =>
- listConversationsByProviderType[context.providerType]({
- igId: context.igId,
- pageId:
- context.providerType === "facebook" ? context.pageId : undefined,
- accessToken: context.accessToken,
- version: context.version,
- cursor,
- }),
- )
+ // No inline retry: a transient failure or a rate limit is handed back to
+ // the engine, which waits through the queue instead of sleeping here.
+ const page = await listConversationsByProviderType[context.providerType]({
+ igId: context.igId,
+ pageId:
+ context.providerType === "facebook" ? context.pageId : undefined,
+ accessToken: context.accessToken,
+ version: context.version,
+ cursor,
+ })
const entries: ContactScanPage["entries"] = []
for (const conversation of page.data) {
@@ -207,9 +215,23 @@ export const instagramContactScanAdapter: ContactScanAdapter
+ classifyChannelErrorForScan({
+ error,
+ mapToChannelError: mapErrorByProviderType[context.providerType],
+ }),
+
+ readBackoff: ({ error }) => readBackoffFromErrorResponse(error),
}
diff --git a/apps/worker/src/integration/handlers/contact-scan/adapters/messenger.ts b/apps/worker/src/integration/handlers/contact-scan/adapters/messenger.ts
index b020adf1a0..a1d4a91435 100644
--- a/apps/worker/src/integration/handlers/contact-scan/adapters/messenger.ts
+++ b/apps/worker/src/integration/handlers/contact-scan/adapters/messenger.ts
@@ -3,15 +3,16 @@ import {
messengerIntegrationService,
} from "@chatbotx.io/business"
import type { InboxModel } from "@chatbotx.io/database/types"
+import { mapToChannelError } from "@chatbotx.io/integration-messenger"
import { listConversations } from "@chatbotx.io/integration-messenger/apis/sync"
import {
messengerAuthSchema,
participantSourceId,
splitName,
- withInlineRetry,
} from "../../coexist/messenger-helpers"
import type { ContactScanAdapter, ContactScanPage } from "../adapter"
-import { classifyGraphSdkError } from "../graph-error"
+import { classifyChannelErrorForScan } from "../graph-error"
+import { bucUsageToSignal, readBackoffFromErrorResponse } from "../usage-signal"
export type MessengerContactScanContext = {
inbox: InboxModel
@@ -56,14 +57,14 @@ export const messengerContactScanAdapter: ContactScanAdapter {
- const page = await withInlineRetry(() =>
- listConversations({
- pageId: context.pageId,
- accessToken: context.accessToken,
- version: context.version,
- after: cursor,
- }),
- )
+ // No inline retry: a transient failure or a rate limit is handed back to
+ // the engine, which waits through the queue instead of sleeping here.
+ const page = await listConversations({
+ pageId: context.pageId,
+ accessToken: context.accessToken,
+ version: context.version,
+ after: cursor,
+ })
const entries: ContactScanPage["entries"] = []
for (const conv of page.data) {
@@ -85,18 +86,12 @@ export const messengerContactScanAdapter: ContactScanAdapter
+ classifyChannelErrorForScan({ error, mapToChannelError }),
+
+ readBackoff: ({ error }) => readBackoffFromErrorResponse(error),
}
diff --git a/apps/worker/src/integration/handlers/contact-scan/engine.ts b/apps/worker/src/integration/handlers/contact-scan/engine.ts
index 1144660349..d7856e8836 100644
--- a/apps/worker/src/integration/handlers/contact-scan/engine.ts
+++ b/apps/worker/src/integration/handlers/contact-scan/engine.ts
@@ -12,6 +12,7 @@ import { logProviderError } from "@chatbotx.io/business/error-log"
import { sanitizePublicText } from "@chatbotx.io/business/errors"
import { supportsProfileSnapshot } from "@chatbotx.io/database/partials"
import type { CoexistRunWriteGuard } from "@chatbotx.io/database/repositories"
+import type { CoexistSyncRunModel } from "@chatbotx.io/database/types"
import { isContactScanChannel } from "@chatbotx.io/utils/channel"
import {
buildContactScanPageJobId,
@@ -21,65 +22,134 @@ import {
} from "@chatbotx.io/worker-config"
import { logger } from "../../../lib/logger"
import { filterConversationWindow } from "../coexist/conversation-window"
-import {
- resolveUsageThrottle,
- sleepForUsageThrottle,
-} from "../coexist/usage-throttle"
import { enqueueProfileSnapshotJobs } from "../profile-snapshot/queue"
import type { ContactScanErrorClassification } from "./adapter"
import { contactScanAdapters } from "./adapter"
+import { CONTACT_SCAN_PACING, resolveScanPacing } from "./pacing"
+
+const sleep = (ms: number): Promise =>
+ new Promise((resolve) => setTimeout(resolve, ms))
+
+type ContinuationInput = {
+ runId: string
+ workspaceId: string
+ /** `run.attempts` at claim: part of the job id, so a retry is a distinct job. */
+ attempts: number
+ pageNumber: number
+ expect: CoexistRunWriteGuard
+ delayMs: number
+ /** Set when the next chunk re-runs the SAME page: its job id must be unique. */
+ retriesSamePage: boolean
+ /** Writes `attempts = 1` with the release (a wait that is not a failure). */
+ resetAttempts?: boolean
+}
/**
- * Active wall-time budget per chunk — same value and rationale as coexist
- * (`coexist/messenger-sync.ts`'s `CHUNK_BUDGET_MS`): stay well inside the
- * BullMQ job lock, persist state, and hot-chain a continuation.
+ * Releases the claim (the run stays `running`) and queues the next chunk after
+ * `delayMs`. A wait is always a delayed job, never a sleep inside the worker, so
+ * a rate-limited scan holds no worker slot. If the job cannot be queued the run
+ * is reopened for the sweeper.
*/
-const CHUNK_BUDGET_MS = 4 * 60 * 1000
-
-/** Bounded in-process pause on a Meta usage-budget signal, same rationale as
- * `instagram-sync.ts`'s `MAX_USAGE_PAUSE_MS`. */
-const MAX_USAGE_PAUSE_MS = 45_000
+const scheduleContinuation = async (
+ input: ContinuationInput,
+): Promise => {
+ const { runId, workspaceId } = input
+ const yieldRows = await contactScanService.yieldForContinuation({
+ runId,
+ expect: input.expect,
+ attempts: input.resetAttempts ? 1 : undefined,
+ })
+ if (yieldRows === 0) {
+ logger.warn({ runId }, "[contact-scan] yield lost the claim — abandoning")
+ return
+ }
+ try {
+ await integrationQueue.add(
+ IntegrationJobAction.contactScan,
+ {
+ type: IntegrationJobAction.contactScan,
+ data: { runId, workspaceId },
+ },
+ {
+ jobId: buildContactScanPageJobId({
+ runId,
+ attempts: input.attempts,
+ pageNumber: input.pageNumber + 1,
+ generation: input.retriesSamePage ? Date.now() : undefined,
+ }),
+ delay: input.delayMs,
+ attempts: 1,
+ removeOnComplete: true,
+ },
+ )
+ logger.info(
+ { runId, pageNumber: input.pageNumber, delayMs: input.delayMs },
+ "[contact-scan] chunk done — continuation enqueued",
+ )
+ } catch (error) {
+ logger.error(
+ { err: error, runId },
+ "[contact-scan] continuation enqueue failed — reopening for the sweeper",
+ )
+ await contactScanService.reopenReleased({ runId })
+ }
+}
-/** Single sequential walk — no per-conversation fan-out — so the throttle's
- * concurrency value is unused; only its `pauseMs` matters here. */
-const SEQUENTIAL_CONCURRENCY = 1
+type ClassificationInput = {
+ run: CoexistSyncRunModel
+ workspaceId: string
+ pageNumber: number
+ expect: CoexistRunWriteGuard
+ /** Sanitized fallback text, used only by `unknown`. */
+ message: string
+ /** How long a rate-limited scan must wait, from the provider's headers. */
+ waitMs: number
+}
/**
* Terminal/retry handler per `adapter.classifyError` outcome — a table, never
* an if/else chain, so the compiler catches a missing arm if the union grows.
- * `message` is the sanitized fallback text used only by `unknown`.
*/
const CLASSIFICATION_HANDLERS: Record<
ContactScanErrorClassification,
- (input: {
- runId: string
- expect: CoexistRunWriteGuard
- message: string
- }) => Promise
+ (input: ClassificationInput) => Promise
> = {
- retryable: ({ runId, expect }) =>
- contactScanService.resetForRetry({
- runId,
- currentError: CONTACT_SCAN_ERRORS.providerRetryable,
+ // Wait through the queue and retry the SAME page (the failed page was never
+ // persisted, so the saved cursor still points at it). A rate limit is not a
+ // failure and the provider answered, so the count goes back to a single
+ // attempt: left high, the sweeper would terminalize the released run during
+ // a long wait (it is idle for more than 10 minutes).
+ rateLimited: ({ run, workspaceId, pageNumber, expect, waitMs }) =>
+ scheduleContinuation({
+ runId: run.id,
+ workspaceId,
+ attempts: run.attempts,
+ resetAttempts: true,
+ pageNumber,
expect,
+ delayMs: waitMs,
+ retriesSamePage: true,
}),
- tokenInvalid: ({ runId, expect }) =>
+ // Transient (network, 5xx): back to the sweeper, or failed on the last try.
+ retryable: ({ run, expect }) =>
+ contactScanService.retryOrFail({ runId: run.id, expect }),
+ tokenInvalid: ({ run, expect }) =>
contactScanService.finish({
- runId,
+ runId: run.id,
status: "failed",
currentError: CONTACT_SCAN_ERRORS.tokenInvalid,
expect,
}),
- graphPermission: ({ runId, expect }) =>
+ graphPermission: ({ run, expect }) =>
contactScanService.finish({
- runId,
+ runId: run.id,
status: "failed",
currentError: CONTACT_SCAN_ERRORS.graphPermission,
expect,
}),
- unknown: ({ runId, expect, message }) =>
+ unknown: ({ run, expect, message }) =>
contactScanService.finish({
- runId,
+ runId: run.id,
status: "failed",
currentError: sanitizePublicText(message),
expect,
@@ -152,11 +222,7 @@ export const runContactScan = async (
{ err: error, runId },
"[contact-scan] setup (loadContext/workspaceService.find) threw — retrying",
)
- await contactScanService.resetForRetry({
- runId,
- currentError: CONTACT_SCAN_ERRORS.providerRetryable,
- expect,
- })
+ await contactScanService.retryOrFail({ runId, expect })
return
}
@@ -184,25 +250,9 @@ export const runContactScan = async (
// later page failure goes straight to the outer error classification.
let firstPageCursorRecoveryAvailable = Boolean(cursor)
- let pauseUntil = 0
- const applyUsageThrottle = (
- signal: Parameters[0]["signal"],
- ): void => {
- const decision = resolveUsageThrottle({
- signal,
- defaultConcurrency: SEQUENTIAL_CONCURRENCY,
- maxPauseMs: MAX_USAGE_PAUSE_MS,
- })
- if (decision.pauseMs > 0) {
- pauseUntil = Math.max(pauseUntil, Date.now() + decision.pauseMs)
- }
- }
- const respectPause = async (): Promise => {
- const waitMs = pauseUntil - Date.now()
- if (waitMs > 0) {
- await sleepForUsageThrottle(waitMs)
- }
- }
+ // Pages walked in THIS chunk, and a wait the pacing asked for after a page.
+ let pagesInChunk = 0
+ let nextChunkDelayMs: number = CONTACT_SCAN_PACING.chunkGapMs
try {
while (true) {
@@ -226,21 +276,32 @@ export const runContactScan = async (
return
}
- if (Date.now() - jobStart >= CHUNK_BUDGET_MS) {
+ // A chunk is a few pages (not the whole budget), so a big inbox is walked
+ // as a steady trickle of short jobs rather than one long burst.
+ if (
+ pagesInChunk >= CONTACT_SCAN_PACING.chunkMaxPages ||
+ Date.now() - jobStart >= CONTACT_SCAN_PACING.chunkBudgetMs
+ ) {
continueLater = true
break
}
- await respectPause()
+ if (pagesInChunk > 0) {
+ await sleep(CONTACT_SCAN_PACING.pageGapMs)
+ }
pageNumber += 1
let page: Awaited>
try {
page = await adapter.listPage({ context, cursor })
} catch (error) {
+ // Only a cursor the provider REJECTS is cleared: a rate limit or a
+ // transient failure says nothing about the cursor.
+ const failure = adapter.classifyError({ error, context })
if (
firstPageCursorRecoveryAvailable &&
- adapter.classifyError(error) !== "retryable"
+ failure !== "retryable" &&
+ failure !== "rateLimited"
) {
firstPageCursorRecoveryAvailable = false
const clearedRows = await contactScanService.updateProgress({
@@ -263,7 +324,7 @@ export const runContactScan = async (
throw error
}
firstPageCursorRecoveryAvailable = false
- applyUsageThrottle(page.usageSignal)
+ pagesInChunk += 1
const filtered = filterConversationWindow({
items: page.entries,
@@ -277,9 +338,8 @@ export const runContactScan = async (
// this page was durably persisted as "processed" yet, so the ONLY safe
// move is to retry the SAME page from the last-good `resumeCursor` —
// never advance `cursor`/`page.after` past contacts we never actually
- // imported. `resetForRetry` hands the run back to the scheduler
- // (bounded by `CONTACT_SCAN_MAX_ATTEMPTS` → `markMaxAttemptsFailed`),
- // which re-fetches this exact page on the next attempt.
+ // imported. `retryOrFail` hands the run back to the scheduler (or fails
+ // it on the last attempt), which re-fetches this exact page next time.
let pageResult: Awaited<
ReturnType
> | null = null
@@ -298,12 +358,12 @@ export const runContactScan = async (
{ err: error, runId, pageNumber },
"[contact-scan] bulk import threw — retrying this page",
)
- const retryRows = await contactScanService.resetForRetry({
+ const outcome = await contactScanService.retryOrFail({
runId,
- currentError: CONTACT_SCAN_ERRORS.pageImportFailed,
expect,
+ retryError: CONTACT_SCAN_ERRORS.pageImportFailed,
})
- if (retryRows === 0) {
+ if (outcome === null) {
logger.warn(
{ runId },
"[contact-scan] retry reset lost the claim — abandoning",
@@ -364,6 +424,12 @@ export const runContactScan = async (
currentPageNumber: pageNumber,
currentStep: `page ${pageNumber} processed (${filtered.itemsToProcess.length} in window)`,
currentError: null,
+ // A finished page ends any run of failures. `attempts` counts the
+ // sweeper's picks, so a claim that is running counts as 1; reset to
+ // that (not 0) so the 5th consecutive failure fails the run, exactly
+ // like a fresh one.
+ attempts: 1,
+ lastHeartbeatAt: new Date(),
},
expect,
})
@@ -376,6 +442,15 @@ export const runContactScan = async (
if (!(cursor && !filtered.stopAll)) {
break
}
+
+ // High usage or a provider wait: stop here and continue after the wait,
+ // as a delayed job (never a sleep in the worker).
+ const pacingWaitMs = resolveScanPacing({ signal: page.usageSignal })
+ if (pacingWaitMs > 0) {
+ nextChunkDelayMs = pacingWaitMs
+ continueLater = true
+ break
+ }
}
if (abandoned) {
@@ -387,51 +462,21 @@ export const runContactScan = async (
}
if (continueLater) {
- const yieldRows = await contactScanService.yieldForContinuation({
+ await scheduleContinuation({
runId,
+ workspaceId,
+ attempts: run.attempts,
+ pageNumber,
expect,
+ delayMs: nextChunkDelayMs,
+ retriesSamePage: false,
})
- if (yieldRows === 0) {
- logger.warn(
- { runId },
- "[contact-scan] yield lost the claim — abandoning",
- )
- return
- }
- try {
- await integrationQueue.add(
- IntegrationJobAction.contactScan,
- {
- type: IntegrationJobAction.contactScan,
- data: { runId, workspaceId },
- },
- {
- jobId: buildContactScanPageJobId({
- runId,
- attempts: run.attempts,
- pageNumber: pageNumber + 1,
- }),
- attempts: 1,
- removeOnComplete: true,
- },
- )
- logger.info(
- { runId, pageNumber },
- "[contact-scan] chunk done — continuation enqueued",
- )
- } catch (error) {
- logger.error(
- { err: error, runId },
- "[contact-scan] continuation enqueue failed — reopening for the sweeper",
- )
- await contactScanService.reopenReleased({ runId })
- }
return
}
// Walk finished (no cursor left, or the ceiling was reached). A page
- // whose import throws now retries the SAME page via `resetForRetry`
- // (FIX 1) instead of counting a failure and moving on, so reaching this
+ // whose import throws now retries the SAME page via `retryOrFail`
+ // instead of counting a failure and moving on, so reaching this
// point always means every page in the walk imported — always
// `succeeded`. The only remaining `partial` outcome is the
// `CONTACT_SCAN_MAX_PAGES` page-budget cap above, which finishes
@@ -442,9 +487,19 @@ export const runContactScan = async (
logger.error({ err: error, runId }, "[contact-scan] fatal error")
await logProviderError({ provider: adapter.provider, workspaceId, error })
- const classification = adapter.classifyError(error)
+ const classification = adapter.classifyError({ error, context })
const message =
error instanceof Error ? error.message : "Unknown contact scan error"
- await CLASSIFICATION_HANDLERS[classification]({ runId, expect, message })
+ await CLASSIFICATION_HANDLERS[classification]({
+ run,
+ workspaceId,
+ pageNumber,
+ expect,
+ message,
+ waitMs: resolveScanPacing({
+ signal: adapter.readBackoff({ error, context }),
+ rateLimited: classification === "rateLimited",
+ }),
+ })
}
}
diff --git a/apps/worker/src/integration/handlers/contact-scan/graph-error.ts b/apps/worker/src/integration/handlers/contact-scan/graph-error.ts
index dfe1ffdf90..4d320cecb9 100644
--- a/apps/worker/src/integration/handlers/contact-scan/graph-error.ts
+++ b/apps/worker/src/integration/handlers/contact-scan/graph-error.ts
@@ -1,170 +1,53 @@
-import { SdkException } from "@chatbotx.io/sdk"
+import {
+ type ChannelError,
+ ChannelErrorCategory,
+ isRateLimited,
+} from "@chatbotx.io/sdk"
import { isRetryable, readOriginError } from "../shared/http-retry"
import type { ContactScanErrorClassification } from "./adapter"
-/**
- * Flat instance fields every Graph SDK exception carries —
- * `MessengerAPIException` (`@chatbotx.io/integration-messenger/exception`)
- * and `InstagramAPIException` (`@chatbotx.io/integration-instagram`'s and
- * `@chatbotx.io/integration-instagram-facebook`'s, both `extends
- * InstagramException`) all `extends SdkException`. Each package's own
- * `rescue()` already normalizes the raw Graph error body into these fields
- * at throw time — see `integrations/messenger/src/exception.ts`'s
- * `rescue`/`parseOriginError` — so `listConversations`/
- * `listInstagramConversations`/`listInstagramFacebookConversations` never
- * throw the raw, unwrapped shape (a ky `HTTPError`, `{ httpStatus,
- * errorBody }`, etc.); they throw this flat shape. A classifier that only
- * understands the raw shape (the bug this file fixes — see
- * `classifyMessengerError`'s prior implementation) silently falls through to
- * "unknown" for every real error.
- */
-type GraphSdkErrorFields = {
- httpStatusCode?: number
- code?: number | string
- type?: string
-}
-
-/**
- * Reads the flat fields off a thrown Graph SDK error. Prefers
- * `instanceof SdkException` (the real, common base class both channels'
- * exceptions share); falls back to duck-typing `{ httpStatusCode, code,
- * type }` for a same-shaped error that isn't literally an `SdkException`
- * instance (e.g. a test double, or a future wrapper class that hasn't
- * adopted the base class).
- */
-const readGraphSdkErrorFields = (error: unknown): GraphSdkErrorFields => {
- if (error instanceof SdkException) {
- return {
- httpStatusCode: error.httpStatusCode,
- code: error.code,
- type: error.type,
- }
- }
- if (error !== null && typeof error === "object") {
- const { httpStatusCode, code, type } = error as GraphSdkErrorFields
- return { httpStatusCode, code, type }
- }
- return {}
-}
-
-const toNumericCode = (
- code: number | string | undefined,
-): number | undefined => {
- if (typeof code === "number") {
- return code
- }
- if (code === undefined) {
- return
- }
- const parsed = Number(code)
- return Number.isNaN(parsed) ? undefined : parsed
-}
-
-/**
- * Meta Graph API codes shared by Messenger + Instagram (one Graph API, two
- * channels) that mean an application-level rate limit was hit — Meta doesn't
- * always signal this via a 429 HTTP status. Union of
- * `integrations/messenger/src/lib/error-mapper.ts`'s and
- * `integrations/instagram/src/lib/error-mapper.ts`'s (byte-identical to
- * `integrations/instagram-facebook/.../error-mapper.ts`) `RATE_LIMITED_CODES`.
- * The two packages' canonical sets differ by one code (613, Instagram-only);
- * unioned here since both channels ride the same Graph API and the retry
- * decision is identical either way.
- */
-const RATE_LIMITED_CODES = new Set([
- 4, // API-level rate limit reached
- 17, // User-level rate limit reached
- 613, // Custom rate limit (instagram/instagram-facebook error-mapper.ts only)
-])
+const HTTP_TOO_MANY_REQUESTS = 429
/**
- * Codes that mean the stored access token is invalid/expired/revoked. Union
- * of both packages' `AUTH_FAILED_CODES` — Messenger's canonical set is a
- * strict superset of Instagram's (`{190}` only).
- */
-const TOKEN_INVALID_CODES = new Set([
- 102, // Invalid API session
- 190, // Access token expired
- 458, // App not installed / user not authenticated
- 459, // User checkpoint required
- 460, // Password changed
- 463, // Access token expired
- 464, // Unconfirmed user
- 492, // Invalid session / user has no role on page
- 467, // Invalid access token
-])
-
-/**
- * Codes that mean the app/token lacks the permission the call needs. Union
- * of both packages' `PERMISSION_DENIED_CODES`.
- */
-const PERMISSION_DENIED_CODES = new Set([
- 3, // Missing capability or permissions (messenger only)
- 10, // Permission denied
- 24, // Permission error — IG Content Publishing (instagram only)
- 25, // IG account restricted/checkpointed (instagram only)
- 341, // Application limit reached (messenger only)
- 368, // Temporarily blocked for policy violations
-])
-
-/** Graph's dedicated "API Permission" status-code range. */
-const PERMISSION_RANGE_MIN = 200
-const PERMISSION_RANGE_MAX = 299
-
-const RETRYABLE_HTTP_STATUS_MIN = 500
-
-const isRetryableHttpStatus = (status: number | undefined): boolean =>
- typeof status === "number" &&
- (status === 429 || status >= RETRYABLE_HTTP_STATUS_MIN)
-
-/**
- * Channel-agnostic classifier for the errors thrown by the Messenger and
- * Instagram Automatic Customer Scan adapters' `listPage` calls. Both
- * channels ride the same underlying Meta Graph API and both packages' own
- * `rescue()` wrap every failure into an `SdkException` subclass carrying the
- * real `httpStatusCode`/`code`/`type` as flat instance fields (see
- * `GraphSdkErrorFields` above) — this reads those fields directly instead of
- * re-parsing the error as if it were still the raw, unwrapped shape.
+ * Maps a thrown provider error to the engine's classification through the
+ * channel's OWN error mapper (`mapToChannelError` of its integration package),
+ * so no provider error code lives here: the code tables stay in
+ * `integrations//src/lib/error-mapper.ts` and a new rate-limit code is
+ * one edit there.
*
* Decision order (first match wins):
- * 1. retryable — 429/5xx `httpStatusCode`, an application-level Graph
- * rate-limit code (`RATE_LIMITED_CODES`), or (safety
- * net for a raw, never-wrapped shape) `isRetryable`
- * against the error itself or its `getOriginError()`
- * 2. tokenInvalid — `type === "OAuthException"`, or a token-invalidation
- * code (`TOKEN_INVALID_CODES`)
- * 3. graphPermission — a permission-denied code (`PERMISSION_DENIED_CODES`),
- * or Graph's 200-299 "API Permission" status range
- * 4. unknown — anything else
+ * 1. rateLimited - the mapper says so (`isRateLimited`), or a bare HTTP 429
+ * 2. retryable - a network failure, a 5xx, or a timeout / dropped socket
+ * 3. tokenInvalid - `AUTH_FAILED`
+ * 4. graphPermission - `PERMISSION_DENIED`
+ * 5. unknown - anything else
*/
-export const classifyGraphSdkError = (
- error: unknown,
-): ContactScanErrorClassification => {
- const fields = readGraphSdkErrorFields(error)
- const code = toNumericCode(fields.code)
- const originError = readOriginError(error)
+export const classifyChannelErrorForScan = (input: {
+ error: unknown
+ mapToChannelError: (error: unknown) => ChannelError
+}): ContactScanErrorClassification => {
+ const mapped = input.mapToChannelError(input.error)
if (
- isRetryableHttpStatus(fields.httpStatusCode) ||
- (code !== undefined && RATE_LIMITED_CODES.has(code)) ||
- isRetryable(error) ||
- isRetryable(originError)
+ isRateLimited(mapped) ||
+ mapped.httpStatusCode === HTTP_TOO_MANY_REQUESTS
) {
- return "retryable"
+ return "rateLimited"
}
if (
- fields.type === "OAuthException" ||
- (code !== undefined && TOKEN_INVALID_CODES.has(code))
+ mapped.category === ChannelErrorCategory.NETWORK_ERROR ||
+ isRetryable(input.error) ||
+ isRetryable(readOriginError(input.error))
) {
+ return "retryable"
+ }
+
+ if (mapped.category === ChannelErrorCategory.AUTH_FAILED) {
return "tokenInvalid"
}
- if (
- code !== undefined &&
- (PERMISSION_DENIED_CODES.has(code) ||
- (code >= PERMISSION_RANGE_MIN && code <= PERMISSION_RANGE_MAX))
- ) {
+ if (mapped.category === ChannelErrorCategory.PERMISSION_DENIED) {
return "graphPermission"
}
diff --git a/apps/worker/src/integration/handlers/contact-scan/pacing.ts b/apps/worker/src/integration/handlers/contact-scan/pacing.ts
new file mode 100644
index 0000000000..515beceb27
--- /dev/null
+++ b/apps/worker/src/integration/handlers/contact-scan/pacing.ts
@@ -0,0 +1,55 @@
+import type { ContactScanUsageSignal } from "./adapter"
+
+const MS_PER_MINUTE = 60_000
+
+/**
+ * Scan rhythm. Thresholds follow v1 and Airbyte's Facebook connector
+ * (`source-facebook-marketing`: 85% waits 2 minutes, 95% waits 10 minutes).
+ * Plain constants: changing them is a code change and a deploy.
+ */
+export const CONTACT_SCAN_PACING = {
+ /** A chunk ends after this many pages... */
+ chunkMaxPages: 5,
+ /** ...or after this much wall time, whichever comes first. */
+ chunkBudgetMs: 4 * MS_PER_MINUTE,
+ /** Pause between two pages of the same chunk. */
+ pageGapMs: 1000,
+ /** Delay before the next chunk when nothing asks for a longer wait. */
+ chunkGapMs: 5000,
+ /** Longest wait a provider's own estimate may ask for. */
+ maxProviderWaitMs: 30 * MS_PER_MINUTE,
+ /** Wait once usage or a rate limit says "stop calling". */
+ exhaustedWaitMs: 10 * MS_PER_MINUTE,
+ /** Wait once usage is high but the provider has not refused anything. */
+ highUsageWaitMs: 2 * MS_PER_MINUTE,
+ exhaustedUsagePercent: 95,
+ highUsagePercent: 85,
+} as const
+
+/**
+ * How long the scan must wait before its next provider call, `0` to carry on.
+ * The provider's own estimate wins (capped); a refusal or a nearly exhausted
+ * quota means "stop calling" because calling on extends a lockout.
+ */
+export const resolveScanPacing = (input: {
+ signal?: ContactScanUsageSignal | null
+ rateLimited?: boolean
+}): number => {
+ const { signal, rateLimited = false } = input
+ const retryAfterMs = signal?.retryAfterMs ?? 0
+ if (retryAfterMs > 0) {
+ return Math.min(retryAfterMs, CONTACT_SCAN_PACING.maxProviderWaitMs)
+ }
+
+ const usagePercent = signal?.usagePercent ?? 0
+ if (
+ rateLimited ||
+ usagePercent >= CONTACT_SCAN_PACING.exhaustedUsagePercent
+ ) {
+ return CONTACT_SCAN_PACING.exhaustedWaitMs
+ }
+ if (usagePercent >= CONTACT_SCAN_PACING.highUsagePercent) {
+ return CONTACT_SCAN_PACING.highUsageWaitMs
+ }
+ return 0
+}
diff --git a/apps/worker/src/integration/handlers/contact-scan/usage-signal.ts b/apps/worker/src/integration/handlers/contact-scan/usage-signal.ts
new file mode 100644
index 0000000000..762a0923b4
--- /dev/null
+++ b/apps/worker/src/integration/handlers/contact-scan/usage-signal.ts
@@ -0,0 +1,69 @@
+import {
+ type BucUsage,
+ estimatedMinutesToMs,
+ parseBucHeader,
+} from "@chatbotx.io/integration-messenger/apis/usage"
+import { readOriginError } from "../shared/http-retry"
+import type { ContactScanUsageSignal } from "./adapter"
+
+const BUC_HEADER = "x-business-use-case-usage"
+
+/** The share of quota in use is the highest of the three figures Meta reports. */
+export const peakUsagePercent = (figures: {
+ callCount?: number
+ totalCputime?: number
+ totalTime?: number
+}): number =>
+ Math.max(
+ figures.callCount ?? 0,
+ figures.totalCputime ?? 0,
+ figures.totalTime ?? 0,
+ )
+
+/** Business Use Case usage -> neutral signal; Meta's wait estimate is in minutes. */
+export const bucUsageToSignal = (
+ usage: BucUsage | null | undefined,
+): ContactScanUsageSignal | null => {
+ if (!usage) {
+ return null
+ }
+ return {
+ usagePercent: peakUsagePercent({
+ callCount: usage.callCount,
+ totalCputime: usage.totalCpuTime,
+ totalTime: usage.totalTime,
+ }),
+ retryAfterMs: estimatedMinutesToMs(usage.estimatedTimeToRegainAccess),
+ }
+}
+
+type HeaderReader = { get: (name: string) => string | null }
+
+const isHeaderReader = (value: unknown): value is HeaderReader =>
+ typeof value === "object" &&
+ value !== null &&
+ "get" in value &&
+ typeof value.get === "function"
+
+/**
+ * The quota headers of a FAILED Graph call. They ride the error response, which
+ * the integrations keep as the origin error (`getOriginError()`); the error's
+ * own fields do not carry them.
+ */
+export const readBackoffFromErrorResponse = (
+ error: unknown,
+): ContactScanUsageSignal | null => {
+ const origin = readOriginError(error)
+ const response =
+ typeof origin === "object" && origin !== null && "response" in origin
+ ? origin.response
+ : undefined
+ const headers =
+ typeof response === "object" && response !== null && "headers" in response
+ ? response.headers
+ : undefined
+ if (!isHeaderReader(headers)) {
+ return null
+ }
+ return bucUsageToSignal(parseBucHeader(headers.get(BUC_HEADER)))
+}
diff --git a/docs/broadcasts.md b/docs/broadcasts.md
index 9e516f1241..90fb71d95a 100644
--- a/docs/broadcasts.md
+++ b/docs/broadcasts.md
@@ -43,3 +43,34 @@ preparation stops, and any recipients it already wrote are cleared in the
background. Until the preparation has stopped and the cleanup is done,
scheduling the draft again is refused with a message to try again shortly;
after that, scheduling goes through.
+
+## Automatic stop when the channel account is blocked
+
+When a **broadcast** message is refused because the channel account itself is
+blocked from sending (not one recipient), every `sending` broadcast of that
+page is stopped (`cancelled`) and the reason is recorded on the broadcast:
+`statusReason` (`accountPolicyBlocked` or `accountSendRestricted`),
+`statusErrorMessage` (the provider's text, at most 500 characters) and
+`statusInboxId` (the page). The public API returns the three fields; the
+builder shows a red line under the status.
+
+- **Which errors:** each channel's error mapper assigns a neutral
+ `ChannelError.reason` to the codes its provider documents for an
+ account-level send block (Messenger `2022` and `10/1893063`, Instagram
+ `100/2534029`, WhatsApp `368` and `131064`, Zalo ZNS `-1351`). The worker,
+ the service and the UI read only the reason, so another channel takes part by
+ assigning a reason in its own mapper. Codes with two meanings or no documented
+ meaning (WhatsApp `131031`, Zalo `-248`, Messenger `368`) are deliberately not
+ assigned.
+- **Scope:** only a broadcast send triggers it. Sequences, flows and inbox sends
+ are not stopped. One blocked page stops the whole broadcast, including a
+ multi-page or omnichannel one; a repeating series is paused with the same
+ reason (a run's series carries all three fields).
+- **Only synchronous errors:** the stop reads the error the channel returns to
+ the send call. A failure the provider reports later through a status webhook
+ (WhatsApp delivery receipts) does not reach this path and does not stop
+ broadcasts.
+- **Resume:** resuming or moving the broadcast back to draft clears the reason
+ fields. The resume dialog shows a warning (reason, page, provider error) with a
+ "continue anyway" button; the public `resume` does not block. If the page is
+ still blocked the first message fails and the broadcast stops again.
diff --git a/docs/contact-scan.md b/docs/contact-scan.md
index 5849fc5d32..15615bccb3 100644
--- a/docs/contact-scan.md
+++ b/docs/contact-scan.md
@@ -4,7 +4,7 @@ Creates ChatbotX contacts from a channel's existing conversation history — the
operator picks a connected inbox and a "scan from" time, and a background job
walks the channel's conversation list newest→oldest, stopping at that time, and
imports every participant who is not already a contact. Ported from v1's
-"Quét Khách Hàng Tự Động". Messenger only today (Instagram/Zalo are follow-ups).
+"Quét Khách Hàng Tự Động". Messenger and Instagram (native and via Facebook) today.
Entry point: **Contacts → Import ▸ Automatic Customer Scan**.
@@ -56,11 +56,22 @@ scanContactScans cron (1 min, distributedLock) ── pickDueRuns({ type:'conta
runContactScan engine ── claimContactScanRun (mints claimToken) ── walk /conversations DESC
│ stop at scanFromAt (ceiling); skip above lastSyncedAt (frontier); bulkImportChannelContacts per page
│ 4-min chunk budget → yieldForContinuation (release token, stay 'running') → enqueue next chunk → reclaim
- ├── done → succeeded | partial (some pages failed) | failed
- ├── transient err → resetForRetry (status='init'); sweeper re-drives; markMaxAttemptsFailed after 5 attempts
+ ├── done → succeeded | partial (page cap) | failed
+ ├── cancelled → partial + `cancelled` sentinel (operator Cancel, or channel disconnected)
+ ├── rate limit / high usage → park (running, no claim) + delayed job; attempts untouched
+ ├── transient err → retryOrFail: back to 'init' for the sweeper, or failed on the 5th in a row
└── auth/permission err → failed (currentError sentinel)
```
+- **Cancel**: `POST /v1/contact-scans/cancel` (`contactScans.cancel`) and the
+ "Cancel scan" button end a live scan as `partial` with the `cancelled`
+ sentinel, clear its claim and cursor, and keep the contacts already imported.
+ The worker's next write is fenced out, so at most the page in flight finishes.
+ It is shown as `cancelled` (one mapping, `resolveContactScanRunStatus`, used by
+ the status view and the history list; no new enum value). Nothing running is
+ `cancelled: false`, not an error. Disconnecting Messenger or Instagram cancels
+ the integration's scan in the same transaction. A cancelled scan still counts
+ toward the 24 h cooldown (measured from `createdAt`).
- **Cooldown**: 24 h from `createdAt` before the same inbox can scan again
(`resolveContactScanAvailability`). ETA shown to the user is `createdAt + 4 h`
(derived, not stored).
@@ -81,7 +92,54 @@ runContactScan engine ── claimContactScanRun (mints claimToken) ── walk
(`packages/business/src/contact-scan/channel-registry.ts`).
4. Add the adapter to `contactScanAdapters`
(`apps/worker/src/integration/handlers/contact-scan/adapter.ts`) implementing
- `loadContext` / `listPage` / `classifyError` for the channel's conversation API.
+ `loadContext` / `listPage` / `classifyError` / `readBackoff` for the channel's conversation API (`classifyError` goes through the channel's own `mapToChannelError`).
The `satisfies Record` on the registry and the adapter map
makes a missing channel a compile error — no other file needs a channel branch.
+
+## Pacing and rate limits
+
+`apps/worker/.../contact-scan/pacing.ts` owns the rhythm (named constants, no
+env switch: changing them is a code change and a deploy):
+
+| | Value |
+|---|---|
+| Chunk | 5 pages or 4 minutes, whichever comes first |
+| Between two pages | 1 second |
+| Next chunk | queued 5 seconds later |
+| Provider reports a wait | that wait, capped at 30 minutes |
+| Rate limited, or usage ≥ 95% | 10 minutes |
+| Usage ≥ 85% | 2 minutes |
+
+Every wait is a **delayed job** (`yieldForContinuation` + `integrationQueue.add`
+with `delay`), never a sleep in the worker, so a rate-limited scan holds no
+worker slot. The scan path no longer uses `withInlineRetry` or
+`sleepForUsageThrottle` (coexist keeps them).
+
+- **Units**: Meta's `estimated_time_to_regain_access` is in **minutes**
+ (Graph API "Rate Limits"). `estimatedMinutesToMs` in
+ `integrations/messenger/src/apis/usage.ts` is the one place that converts it.
+- **Neutral signal**: an adapter returns `{ usagePercent, retryAfterMs }` for a
+ page and for a failed call (`readBackoff`, read from the error response's
+ headers through `getOriginError`); the engine knows no header names or units.
+- **Classification** goes through each channel's own `mapToChannelError`: a rate
+ limit (`isRateLimited`: category `RATE_LIMITED` or reason `rate_limited`, or a
+ bare HTTP 429) waits and retries the same page; network/5xx/timeouts are
+ transient; `AUTH_FAILED` and `PERMISSION_DENIED` fail the scan. The code tables
+ live in the integrations (`RATE_LIMIT_CODES`); a code with only the reason
+ (Instagram `80002`; Instagram via Facebook `32`, `80001`, `80002`) makes the
+ scan back off without changing how messages are sent.
+- **Error accounting**: `attempts` is the sweeper's pick count, so a running
+ claim is 1 and the Nth consecutive failure sees N. A finished page resets it
+ to 1 (same write as the heartbeat); a rate limit leaves it alone; a
+ transient failure goes through `retryOrFailContactScanRun`, one atomic UPDATE
+ that returns the run to `init` or, on the 5th failure in a row, fails it at
+ once (it cannot wait for `markMaxAttemptsFailed`).
+- **Lost delayed job**: a parked run is `running` with no claim.
+ `pickDueRuns({ releasedGraceMs })` (passed only by the scan, 35 minutes, longer
+ than the 30-minute maximum wait) takes it back if its job is lost.
+- A job that retries the SAME page after a rate limit carries a unique
+ `generation` in its job id (`buildContactScanPageJobId`), because BullMQ drops
+ an add whose id still exists.
+- Separate work, not in this change: coexist's `usage-throttle.ts` and
+ `messenger-sync.ts` also read the unit as seconds.
diff --git a/integrations/instagram-facebook/__tests__/error-mapper-reason.test.ts b/integrations/instagram-facebook/__tests__/error-mapper-reason.test.ts
new file mode 100644
index 0000000000..da4a1060c7
--- /dev/null
+++ b/integrations/instagram-facebook/__tests__/error-mapper-reason.test.ts
@@ -0,0 +1,59 @@
+import {
+ ChannelErrorCategory,
+ ChannelErrorReason,
+ isAccountSendBlocked,
+ isRateLimited,
+} from "@chatbotx.io/sdk"
+import { describe, expect, test } from "vitest"
+import { InstagramException } from "../src/exception"
+import { mapToChannelError } from "../src/lib/error-mapper"
+
+describe("instagram-facebook error-mapper account send-block reason", () => {
+ test("code 100 + subcode 2534029 is account_policy_blocked", () => {
+ const mapped = mapToChannelError(
+ new InstagramException("blocked", 400, 100, 2_534_029),
+ )
+ expect(mapped.reason).toBe(ChannelErrorReason.ACCOUNT_POLICY_BLOCKED)
+ expect(isAccountSendBlocked(mapped)).toBe(true)
+ expect(mapped.category).toBe(ChannelErrorCategory.PAYLOAD_INVALID)
+ })
+
+ test("code 100 with another subcode has no reason", () => {
+ const mapped = mapToChannelError(
+ new InstagramException("bad param", 400, 100, 33),
+ )
+ expect(mapped.reason).toBeUndefined()
+ })
+
+ test("subcode 2534029 under another code has no reason", () => {
+ const mapped = mapToChannelError(
+ new InstagramException("other", 400, 200, 2_534_029),
+ )
+ expect(mapped.reason).toBeUndefined()
+ })
+})
+
+describe("instagram-facebook error-mapper rate-limit codes", () => {
+ test.each([
+ 4, 17, 613,
+ ])("code %i keeps the RATE_LIMITED category and carries the reason", (code) => {
+ const mapped = mapToChannelError(new InstagramException("limit", 429, code))
+ expect(mapped.category).toBe(ChannelErrorCategory.RATE_LIMITED)
+ expect(mapped.reason).toBe(ChannelErrorReason.RATE_LIMITED)
+ expect(isRateLimited(mapped)).toBe(true)
+ })
+
+ test.each([
+ 32, 80_001, 80_002,
+ ])("code %i is rate limited by reason only, so sends keep their category", (code) => {
+ const mapped = mapToChannelError(new InstagramException("limit", 400, code))
+ expect(isRateLimited(mapped)).toBe(true)
+ expect(mapped.reason).toBe(ChannelErrorReason.RATE_LIMITED)
+ expect(mapped.category).not.toBe(ChannelErrorCategory.RATE_LIMITED)
+ })
+
+ test("an unrelated code is not rate limited", () => {
+ const mapped = mapToChannelError(new InstagramException("bad", 400, 100))
+ expect(isRateLimited(mapped)).toBe(false)
+ })
+})
diff --git a/integrations/instagram-facebook/src/lib/error-mapper.ts b/integrations/instagram-facebook/src/lib/error-mapper.ts
index aa230b49df..3c96fd43b6 100644
--- a/integrations/instagram-facebook/src/lib/error-mapper.ts
+++ b/integrations/instagram-facebook/src/lib/error-mapper.ts
@@ -1,6 +1,7 @@
import {
ChannelError,
ChannelErrorCategory,
+ ChannelErrorReason,
UNKNOWN_ERROR,
} from "@chatbotx.io/sdk"
import {
@@ -38,10 +39,19 @@ const PERMISSION_DENIED_CODES = new Set([
368, // Temporarily blocked for policy violations
])
-const RATE_LIMITED_CODES = new Set([
- 4, // App-level rate limit (FB Graph + IG spam)
- 17, // User-level rate limit
- 613, // Custom rate (FB Graph)
+// developers.facebook.com/docs/graph-api/overview/rate-limiting: every code here
+// means "stop calling and wait". A `category` makes message sends auto-retry;
+// an entry without one only carries the `rate_limited` reason, so send behaviour
+// is unchanged and just the contact scan (which reads the reason) backs off.
+type RateLimitEntry = { category?: ChannelErrorCategory }
+
+const RATE_LIMIT_CODES: ReadonlyMap = new Map([
+ [4, { category: ChannelErrorCategory.RATE_LIMITED }], // App-level rate limit (FB Graph + IG spam)
+ [17, { category: ChannelErrorCategory.RATE_LIMITED }], // User-level rate limit
+ [613, { category: ChannelErrorCategory.RATE_LIMITED }], // Custom rate (FB Graph)
+ [32, {}], // Page-level rate limit (user token)
+ [80_001, {}], // Business Use Case limit: Pages
+ [80_002, {}], // Business Use Case limit: Instagram
])
const QUOTA_EXCEEDED_CODES = new Set([
@@ -105,8 +115,9 @@ function categorize(
return ChannelErrorCategory.AUTH_FAILED
}
- if (RATE_LIMITED_CODES.has(code)) {
- return ChannelErrorCategory.RATE_LIMITED
+ const rateLimitCategory = RATE_LIMIT_CODES.get(code)?.category
+ if (rateLimitCategory) {
+ return rateLimitCategory
}
if (QUOTA_EXCEEDED_CODES.has(code)) {
@@ -137,6 +148,28 @@ function categorize(
return ChannelErrorCategory.UNKNOWN
}
+// Account-level send blocks keyed by subcode (code 100). Source:
+// developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api
+const ACCOUNT_SEND_BLOCK_REASONS: ReadonlyMap =
+ new Map([
+ // The business was blocked from sending messages via the IG Messaging API
+ [2_534_029, ChannelErrorReason.ACCOUNT_POLICY_BLOCKED],
+ ])
+
+function resolveReason(
+ code: number | undefined,
+ subCode: number | undefined,
+): ChannelErrorReason | undefined {
+ if (code !== undefined && RATE_LIMIT_CODES.has(code)) {
+ return ChannelErrorReason.RATE_LIMITED
+ }
+ if (code !== 100 || subCode === undefined) {
+ return
+ }
+
+ return ACCOUNT_SEND_BLOCK_REASONS.get(subCode)
+}
+
function defaultHttpStatus(category: ChannelErrorCategory): number {
switch (category) {
case ChannelErrorCategory.RATE_LIMITED:
@@ -163,6 +196,7 @@ function mapApiFields(fields: ChannelErrorSource): ChannelError {
httpStatusCode: fields.httpStatusCode ?? defaultHttpStatus(category),
subCode: fields.subCode,
type: fields.type,
+ reason: resolveReason(numCode, numSubCode),
})
}
diff --git a/integrations/instagram/__tests__/error-mapper-reason.test.ts b/integrations/instagram/__tests__/error-mapper-reason.test.ts
new file mode 100644
index 0000000000..ca6212d69b
--- /dev/null
+++ b/integrations/instagram/__tests__/error-mapper-reason.test.ts
@@ -0,0 +1,59 @@
+import {
+ ChannelErrorCategory,
+ ChannelErrorReason,
+ isAccountSendBlocked,
+ isRateLimited,
+} from "@chatbotx.io/sdk"
+import { describe, expect, test } from "vitest"
+import { InstagramException } from "../src/exception"
+import { mapToChannelError } from "../src/lib/error-mapper"
+
+describe("instagram error-mapper account send-block reason", () => {
+ test("code 100 + subcode 2534029 is account_policy_blocked", () => {
+ const mapped = mapToChannelError(
+ new InstagramException("blocked", 400, 100, 2_534_029),
+ )
+ expect(mapped.reason).toBe(ChannelErrorReason.ACCOUNT_POLICY_BLOCKED)
+ expect(isAccountSendBlocked(mapped)).toBe(true)
+ expect(mapped.category).toBe(ChannelErrorCategory.PAYLOAD_INVALID)
+ })
+
+ test("code 100 with another subcode has no reason", () => {
+ const mapped = mapToChannelError(
+ new InstagramException("bad param", 400, 100, 33),
+ )
+ expect(mapped.reason).toBeUndefined()
+ })
+
+ test("subcode 2534029 under another code has no reason", () => {
+ const mapped = mapToChannelError(
+ new InstagramException("other", 400, 200, 2_534_029),
+ )
+ expect(mapped.reason).toBeUndefined()
+ })
+})
+
+describe("instagram error-mapper rate-limit codes", () => {
+ test.each([
+ 4, 17, 613,
+ ])("code %i keeps the RATE_LIMITED category and carries the reason", (code) => {
+ const mapped = mapToChannelError(new InstagramException("limit", 429, code))
+ expect(mapped.category).toBe(ChannelErrorCategory.RATE_LIMITED)
+ expect(mapped.reason).toBe(ChannelErrorReason.RATE_LIMITED)
+ expect(isRateLimited(mapped)).toBe(true)
+ })
+
+ test.each([
+ 80_002,
+ ])("code %i is rate limited by reason only, so sends keep their category", (code) => {
+ const mapped = mapToChannelError(new InstagramException("limit", 400, code))
+ expect(isRateLimited(mapped)).toBe(true)
+ expect(mapped.reason).toBe(ChannelErrorReason.RATE_LIMITED)
+ expect(mapped.category).not.toBe(ChannelErrorCategory.RATE_LIMITED)
+ })
+
+ test("an unrelated code is not rate limited", () => {
+ const mapped = mapToChannelError(new InstagramException("bad", 400, 100))
+ expect(isRateLimited(mapped)).toBe(false)
+ })
+})
diff --git a/integrations/instagram/src/lib/error-mapper.ts b/integrations/instagram/src/lib/error-mapper.ts
index 5138a75ef5..78b9c2e936 100644
--- a/integrations/instagram/src/lib/error-mapper.ts
+++ b/integrations/instagram/src/lib/error-mapper.ts
@@ -1,6 +1,7 @@
import {
ChannelError,
ChannelErrorCategory,
+ ChannelErrorReason,
UNKNOWN_ERROR,
} from "@chatbotx.io/sdk"
import {
@@ -38,10 +39,17 @@ const PERMISSION_DENIED_CODES = new Set([
368, // Temporarily blocked for policy violations
])
-const RATE_LIMITED_CODES = new Set([
- 4, // App-level rate limit (FB Graph + IG spam)
- 17, // User-level rate limit
- 613, // Custom rate (FB Graph)
+// developers.facebook.com/docs/graph-api/overview/rate-limiting: every code here
+// means "stop calling and wait". A `category` makes message sends auto-retry;
+// an entry without one only carries the `rate_limited` reason, so send behaviour
+// is unchanged and just the contact scan (which reads the reason) backs off.
+type RateLimitEntry = { category?: ChannelErrorCategory }
+
+const RATE_LIMIT_CODES: ReadonlyMap = new Map([
+ [4, { category: ChannelErrorCategory.RATE_LIMITED }], // App-level rate limit (FB Graph + IG spam)
+ [17, { category: ChannelErrorCategory.RATE_LIMITED }], // User-level rate limit
+ [613, { category: ChannelErrorCategory.RATE_LIMITED }], // Custom rate (FB Graph)
+ [80_002, {}], // Business Use Case limit: Instagram
])
const QUOTA_EXCEEDED_CODES = new Set([
@@ -105,8 +113,9 @@ function categorize(
return ChannelErrorCategory.AUTH_FAILED
}
- if (RATE_LIMITED_CODES.has(code)) {
- return ChannelErrorCategory.RATE_LIMITED
+ const rateLimitCategory = RATE_LIMIT_CODES.get(code)?.category
+ if (rateLimitCategory) {
+ return rateLimitCategory
}
if (QUOTA_EXCEEDED_CODES.has(code)) {
@@ -137,6 +146,28 @@ function categorize(
return ChannelErrorCategory.UNKNOWN
}
+// Account-level send blocks keyed by subcode (code 100). Source:
+// developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api
+const ACCOUNT_SEND_BLOCK_REASONS: ReadonlyMap =
+ new Map([
+ // The business was blocked from sending messages via the IG Messaging API
+ [2_534_029, ChannelErrorReason.ACCOUNT_POLICY_BLOCKED],
+ ])
+
+function resolveReason(
+ code: number | undefined,
+ subCode: number | undefined,
+): ChannelErrorReason | undefined {
+ if (code !== undefined && RATE_LIMIT_CODES.has(code)) {
+ return ChannelErrorReason.RATE_LIMITED
+ }
+ if (code !== 100 || subCode === undefined) {
+ return
+ }
+
+ return ACCOUNT_SEND_BLOCK_REASONS.get(subCode)
+}
+
function defaultHttpStatus(category: ChannelErrorCategory): number {
switch (category) {
case ChannelErrorCategory.RATE_LIMITED:
@@ -163,6 +194,7 @@ function mapApiFields(fields: ChannelErrorSource): ChannelError {
httpStatusCode: fields.httpStatusCode ?? defaultHttpStatus(category),
subCode: fields.subCode,
type: fields.type,
+ reason: resolveReason(numCode, numSubCode),
})
}
diff --git a/integrations/messenger/__tests__/error-mapper.test.ts b/integrations/messenger/__tests__/error-mapper.test.ts
index 12f21cf0e0..ba2843e6d7 100644
--- a/integrations/messenger/__tests__/error-mapper.test.ts
+++ b/integrations/messenger/__tests__/error-mapper.test.ts
@@ -1,4 +1,9 @@
-import { ChannelErrorCategory } from "@chatbotx.io/sdk"
+import {
+ ChannelErrorCategory,
+ ChannelErrorReason,
+ isAccountSendBlocked,
+ isRateLimited,
+} from "@chatbotx.io/sdk"
import { describe, expect, test } from "vitest"
import { MessengerException } from "../src/exception"
import {
@@ -180,3 +185,53 @@ describe("messenger error-mapper rate limits", () => {
expect(error.category).toBe(ChannelErrorCategory.RATE_LIMITED)
})
})
+
+describe("messenger error-mapper account send-block reasons", () => {
+ test("code 2022 is account_policy_blocked", () => {
+ const mapped = mapToChannelError(
+ new MessengerException("blocked", 400, 2022),
+ )
+ expect(mapped.reason).toBe(ChannelErrorReason.ACCOUNT_POLICY_BLOCKED)
+ expect(isAccountSendBlocked(mapped)).toBe(true)
+ })
+
+ test("code 10 + subcode 1893063 is account_send_restricted, category unchanged", () => {
+ const mapped = mapToChannelError(
+ new MessengerException("restricted", 403, 10, 1_893_063),
+ )
+ expect(mapped.reason).toBe(ChannelErrorReason.ACCOUNT_SEND_RESTRICTED)
+ expect(mapped.category).toBe(ChannelErrorCategory.PERMISSION_DENIED)
+ })
+
+ test("code 10 with another subcode has no reason", () => {
+ const mapped = mapToChannelError(
+ new MessengerException("denied", 403, 10, 2_018_300),
+ )
+ expect(mapped.reason).toBeUndefined()
+ })
+
+ test("code 368 deliberately has no reason", () => {
+ const mapped = mapToChannelError(new MessengerException("policy", 400, 368))
+ expect(mapped.reason).toBeUndefined()
+ expect(mapped.category).toBe(ChannelErrorCategory.PERMISSION_DENIED)
+ })
+})
+
+describe("messenger error-mapper rate-limit codes", () => {
+ test.each([
+ 4, 17, 32, 613, 80_001, 80_006,
+ ])("code %i keeps the RATE_LIMITED category and carries the reason", (code) => {
+ const mapped = mapToChannelError(new MessengerException("limit", 429, code))
+ expect(mapped.category).toBe(ChannelErrorCategory.RATE_LIMITED)
+ expect(mapped.reason).toBe(ChannelErrorReason.RATE_LIMITED)
+ expect(isRateLimited(mapped)).toBe(true)
+ })
+
+ test.each([
+ 80_000, 80_003, 80_004, 80_005, 80_008, 80_009, 80_014,
+ ])("Ads/LeadGen/Catalog code %i is not a Messenger rate limit", (code) => {
+ expect(
+ isRateLimited(mapToChannelError(new MessengerException("x", 400, code))),
+ ).toBe(false)
+ })
+})
diff --git a/integrations/messenger/__tests__/usage-minutes.test.ts b/integrations/messenger/__tests__/usage-minutes.test.ts
new file mode 100644
index 0000000000..c0183e9d5a
--- /dev/null
+++ b/integrations/messenger/__tests__/usage-minutes.test.ts
@@ -0,0 +1,37 @@
+import { describe, expect, test } from "vitest"
+import { estimatedMinutesToMs, parseBucHeader } from "../src/apis/usage"
+import { retryAfterForQuota } from "../src/handlers/bulk-thread-control"
+
+describe("estimated_time_to_regain_access unit", () => {
+ test("is converted from minutes to milliseconds", () => {
+ expect(estimatedMinutesToMs(0)).toBe(0)
+ expect(estimatedMinutesToMs(1)).toBe(60_000)
+ expect(estimatedMinutesToMs(30)).toBe(1_800_000)
+ })
+
+ test("retryAfterForQuota waits Meta's minutes, not seconds", () => {
+ const usage = parseBucHeader(
+ JSON.stringify({
+ "123": [
+ {
+ call_count: 40,
+ total_cputime: 10,
+ total_time: 10,
+ estimated_time_to_regain_access: 5,
+ },
+ ],
+ }),
+ )
+
+ expect(retryAfterForQuota(usage, false)).toBe(5 * 60_000)
+ })
+
+ test("parseBucHeader still returns the raw minutes figure unchanged", () => {
+ const usage = parseBucHeader(
+ JSON.stringify({
+ "1": [{ call_count: 1, estimated_time_to_regain_access: 7 }],
+ }),
+ )
+ expect(usage?.estimatedTimeToRegainAccess).toBe(7)
+ })
+})
diff --git a/integrations/messenger/src/apis/usage.ts b/integrations/messenger/src/apis/usage.ts
index 2d90c70cbe..cc27a7290c 100644
--- a/integrations/messenger/src/apis/usage.ts
+++ b/integrations/messenger/src/apis/usage.ts
@@ -23,6 +23,16 @@ type RawBucEntry = {
estimated_time_to_regain_access?: number
}
+const MS_PER_MINUTE = 60_000
+
+/**
+ * `estimated_time_to_regain_access` is in MINUTES (Meta: Graph API "Rate
+ * Limits"), not seconds. The one place that converts it, so no caller guesses
+ * the unit again.
+ */
+export const estimatedMinutesToMs = (minutes: number): number =>
+ minutes * MS_PER_MINUTE
+
/** Returns the first BUC entry in the header, or `null` if absent/malformed. */
export const parseBucHeader = (header: string | null): BucUsage | null => {
if (!header) {
diff --git a/integrations/messenger/src/handlers/bulk-thread-control.ts b/integrations/messenger/src/handlers/bulk-thread-control.ts
index c8cc8cfea1..eb316bf877 100644
--- a/integrations/messenger/src/handlers/bulk-thread-control.ts
+++ b/integrations/messenger/src/handlers/bulk-thread-control.ts
@@ -15,7 +15,7 @@ import {
type GraphBatchResult,
sendGraphBatch,
} from "../apis/batch"
-import type { BucUsage } from "../apis/usage"
+import { type BucUsage, estimatedMinutesToMs } from "../apis/usage"
import { mapToChannelError } from "../lib/error-mapper"
import {
readBusinessAiAppId,
@@ -48,7 +48,6 @@ const BULK_USAGE_CEILING_PERCENT = 50
const QUOTA_EXHAUSTED_PERCENT = 90
const SOFT_PAUSE_MS = 60_000
const EXHAUSTED_PAUSE_MS = 60 * 60_000
-const MS_PER_MINUTE = 60_000
/** Meta asks callers to spread their calls over time. */
const BATCH_GAP_MS = 1000
@@ -63,7 +62,7 @@ export const retryAfterForQuota = (
isRateLimited: boolean,
): number | null => {
if (usage && usage.estimatedTimeToRegainAccess > 0) {
- return usage.estimatedTimeToRegainAccess * MS_PER_MINUTE
+ return estimatedMinutesToMs(usage.estimatedTimeToRegainAccess)
}
const peak = usage
? Math.max(usage.callCount, usage.totalCpuTime, usage.totalTime)
diff --git a/integrations/messenger/src/lib/error-mapper.ts b/integrations/messenger/src/lib/error-mapper.ts
index b761404b22..df1e3e2560 100644
--- a/integrations/messenger/src/lib/error-mapper.ts
+++ b/integrations/messenger/src/lib/error-mapper.ts
@@ -1,6 +1,7 @@
import {
ChannelError,
ChannelErrorCategory,
+ ChannelErrorReason,
UNKNOWN_ERROR,
} from "@chatbotx.io/sdk"
import {
@@ -41,14 +42,18 @@ const PERMISSION_DENIED_CODES = new Set([
])
// developers.facebook.com/docs/graph-api/overview/rate-limiting: every code
-// below means "stop calling and wait", never "this request is invalid".
-const RATE_LIMITED_CODES = new Set([
- 4, // API rate limit reached
- 17, // User API rate limit reached
- 32, // Page-level rate limit reached
- 613, // Custom rate limit (incl. subcode 1996: inconsistent request pattern)
- 80_001, // Business Use Case limit: Pages
- 80_006, // Business Use Case limit: Messenger
+// below means "stop calling and wait", never "this request is invalid". Each
+// carries the `rate_limited` reason (read by the contact scan) and, being in
+// this table with a `category`, keeps message sends auto-retrying as before.
+type RateLimitEntry = { category?: ChannelErrorCategory }
+
+const RATE_LIMIT_CODES: ReadonlyMap = new Map([
+ [4, { category: ChannelErrorCategory.RATE_LIMITED }], // API rate limit reached
+ [17, { category: ChannelErrorCategory.RATE_LIMITED }], // User API rate limit reached
+ [32, { category: ChannelErrorCategory.RATE_LIMITED }], // Page-level rate limit reached
+ [613, { category: ChannelErrorCategory.RATE_LIMITED }], // Custom rate limit (incl. subcode 1996: inconsistent request pattern)
+ [80_001, { category: ChannelErrorCategory.RATE_LIMITED }], // Business Use Case limit: Pages
+ [80_006, { category: ChannelErrorCategory.RATE_LIMITED }], // Business Use Case limit: Messenger
])
const PAYLOAD_INVALID_CODES = new Set([
@@ -82,8 +87,9 @@ function categorize(
return ChannelErrorCategory.AUTH_FAILED
}
- if (RATE_LIMITED_CODES.has(code)) {
- return ChannelErrorCategory.RATE_LIMITED
+ const rateLimitCategory = RATE_LIMIT_CODES.get(code)?.category
+ if (rateLimitCategory) {
+ return rateLimitCategory
}
if (USER_BLOCKED_CODES.has(code)) {
@@ -118,6 +124,32 @@ function categorize(
return ChannelErrorCategory.UNKNOWN
}
+// Account-level send blocks, keyed `code` or `code:subCode`. Sources:
+// developers.facebook.com/docs/messenger-platform/error-codes. Meta's code 368
+// is deliberately absent: it also covers non-messaging policy blocks.
+const ACCOUNT_SEND_BLOCK_REASONS: ReadonlyMap =
+ new Map([
+ ["2022", ChannelErrorReason.ACCOUNT_POLICY_BLOCKED], // commerce messaging disabled
+ ["10:1893063", ChannelErrorReason.ACCOUNT_SEND_RESTRICTED], // Page temporarily restricted from sending
+ ])
+
+function resolveReason(
+ code: number | undefined,
+ subCode: number | string | undefined,
+): ChannelErrorReason | undefined {
+ if (code === undefined) {
+ return
+ }
+ if (RATE_LIMIT_CODES.has(code)) {
+ return ChannelErrorReason.RATE_LIMITED
+ }
+
+ return (
+ ACCOUNT_SEND_BLOCK_REASONS.get(`${code}:${subCode}`) ??
+ ACCOUNT_SEND_BLOCK_REASONS.get(String(code))
+ )
+}
+
function defaultHttpStatus(category: ChannelErrorCategory): number {
switch (category) {
case ChannelErrorCategory.RATE_LIMITED:
@@ -142,6 +174,7 @@ function mapApiFields(fields: ChannelErrorSource): ChannelError {
httpStatusCode: fields.httpStatusCode ?? defaultHttpStatus(category),
subCode: fields.subCode,
type: fields.type,
+ reason: resolveReason(numCode, fields.subCode ?? undefined),
})
}
diff --git a/integrations/whatsapp/__tests__/error-mapper-reason.test.ts b/integrations/whatsapp/__tests__/error-mapper-reason.test.ts
new file mode 100644
index 0000000000..17747cd2de
--- /dev/null
+++ b/integrations/whatsapp/__tests__/error-mapper-reason.test.ts
@@ -0,0 +1,38 @@
+import {
+ ChannelErrorCategory,
+ ChannelErrorReason,
+ isAccountSendBlocked,
+} from "@chatbotx.io/sdk"
+import { describe, expect, test } from "vitest"
+import { WhatsappException } from "../src/exception"
+import { mapToChannelError } from "../src/lib/error-mapper"
+
+describe("whatsapp error-mapper account send-block reason", () => {
+ test("code 368 is account_policy_blocked, category unchanged", () => {
+ const mapped = mapToChannelError(new WhatsappException("blocked", 400, 368))
+ expect(mapped.reason).toBe(ChannelErrorReason.ACCOUNT_POLICY_BLOCKED)
+ expect(isAccountSendBlocked(mapped)).toBe(true)
+ expect(mapped.category).toBe(ChannelErrorCategory.PERMISSION_DENIED)
+ })
+
+ test("code 131064 is account_send_restricted", () => {
+ const mapped = mapToChannelError(
+ new WhatsappException("limit", 400, 131_064),
+ )
+ expect(mapped.reason).toBe(ChannelErrorReason.ACCOUNT_SEND_RESTRICTED)
+ })
+
+ test("code 131031 deliberately has no reason", () => {
+ const mapped = mapToChannelError(
+ new WhatsappException("locked", 400, 131_031),
+ )
+ expect(mapped.reason).toBeUndefined()
+ })
+
+ test("recipient-level code 131049 has no reason", () => {
+ const mapped = mapToChannelError(
+ new WhatsappException("ecosystem", 400, 131_049),
+ )
+ expect(mapped.reason).toBeUndefined()
+ })
+})
diff --git a/integrations/whatsapp/src/lib/error-mapper.ts b/integrations/whatsapp/src/lib/error-mapper.ts
index 09c384adb6..90ce610e97 100644
--- a/integrations/whatsapp/src/lib/error-mapper.ts
+++ b/integrations/whatsapp/src/lib/error-mapper.ts
@@ -1,6 +1,7 @@
import {
ChannelError,
ChannelErrorCategory,
+ ChannelErrorReason,
UNKNOWN_ERROR,
} from "@chatbotx.io/sdk"
import { formatGraphErrorMessage } from "@chatbotx.io/utils/graph-error"
@@ -211,6 +212,15 @@ function defaultHttpStatus(category: ChannelErrorCategory): number {
}
}
+// Account-level send blocks. Source: developers.facebook.com/docs/whatsapp/
+// cloud-api/support/error-codes. 131031 is deliberately absent: it carries
+// two meanings (account locked, or request data mismatch such as a wrong PIN).
+const ACCOUNT_SEND_BLOCK_REASONS: ReadonlyMap =
+ new Map([
+ [368, ChannelErrorReason.ACCOUNT_POLICY_BLOCKED], // WABA restricted/disabled for policy violation
+ [131_064, ChannelErrorReason.ACCOUNT_SEND_RESTRICTED], // messaging limit after template classification violations
+ ])
+
function mapApiFields(fields: ChannelErrorSource): ChannelError {
const numCode = typeof fields.code === "number" ? fields.code : undefined
const category = categorize(numCode, fields.type)
@@ -228,6 +238,10 @@ function mapApiFields(fields: ChannelErrorSource): ChannelError {
httpStatusCode: fields.httpStatusCode ?? defaultHttpStatus(category),
subCode: fields.subCode,
type: fields.type,
+ reason:
+ numCode === undefined
+ ? undefined
+ : ACCOUNT_SEND_BLOCK_REASONS.get(numCode),
},
)
diff --git a/integrations/zalo/__tests__/error-mapper-reason.test.ts b/integrations/zalo/__tests__/error-mapper-reason.test.ts
new file mode 100644
index 0000000000..e5c301f523
--- /dev/null
+++ b/integrations/zalo/__tests__/error-mapper-reason.test.ts
@@ -0,0 +1,27 @@
+import {
+ ChannelErrorCategory,
+ ChannelErrorReason,
+ isAccountSendBlocked,
+} from "@chatbotx.io/sdk"
+import { describe, expect, test } from "vitest"
+import { mapToChannelError } from "../src/lib/error-mapper"
+import { ZaloException } from "../src/lib/exception"
+
+describe("zalo error-mapper account send-block reason", () => {
+ test("code -1351 is account_policy_blocked", () => {
+ const mapped = mapToChannelError(new ZaloException("blocked", 400, -1351))
+ expect(mapped.reason).toBe(ChannelErrorReason.ACCOUNT_POLICY_BLOCKED)
+ expect(isAccountSendBlocked(mapped)).toBe(true)
+ })
+
+ test("code -248 deliberately has no reason", () => {
+ const mapped = mapToChannelError(new ZaloException("content", 400, -248))
+ expect(mapped.reason).toBeUndefined()
+ })
+
+ test("a recipient-level code keeps its category and has no reason", () => {
+ const mapped = mapToChannelError(new ZaloException("blocked", 400, -216))
+ expect(mapped.category).toBe(ChannelErrorCategory.USER_BLOCKED)
+ expect(mapped.reason).toBeUndefined()
+ })
+})
diff --git a/integrations/zalo/src/lib/error-mapper.ts b/integrations/zalo/src/lib/error-mapper.ts
index 605d47cf27..9ccb864edd 100644
--- a/integrations/zalo/src/lib/error-mapper.ts
+++ b/integrations/zalo/src/lib/error-mapper.ts
@@ -1,6 +1,7 @@
import {
ChannelError,
ChannelErrorCategory,
+ ChannelErrorReason,
UNKNOWN_ERROR,
} from "@chatbotx.io/sdk"
import {
@@ -157,6 +158,13 @@ function defaultHttpStatus(category: ChannelErrorCategory): number {
}
}
+// Account-level send blocks. Source: Zalo ZNS error codes. -248 is deliberately
+// absent: the docs do not say whether the account or one message is blocked.
+const ACCOUNT_SEND_BLOCK_REASONS: ReadonlyMap =
+ new Map([
+ [-1351, ChannelErrorReason.ACCOUNT_POLICY_BLOCKED], // OA blocked for violation detection
+ ])
+
function mapZaloCode(fields: ChannelErrorSource): ChannelError {
const numCode = typeof fields.code === "number" ? fields.code : undefined
const category = categorize(numCode)
@@ -165,6 +173,10 @@ function mapZaloCode(fields: ChannelErrorSource): ChannelError {
httpStatusCode: fields.httpStatusCode ?? defaultHttpStatus(category),
subCode: fields.subCode,
type: fields.type,
+ reason:
+ numCode === undefined
+ ? undefined
+ : ACCOUNT_SEND_BLOCK_REASONS.get(numCode),
})
}
diff --git a/packages/business/__tests__/broadcast-service-transitions.test.ts b/packages/business/__tests__/broadcast-service-transitions.test.ts
index 9ce43ad22e..8407a39377 100644
--- a/packages/business/__tests__/broadcast-service-transitions.test.ts
+++ b/packages/business/__tests__/broadcast-service-transitions.test.ts
@@ -1058,6 +1058,9 @@ describe("repeating broadcasts (templates)", () => {
expect(result).toEqual({ id: "b-1", nextRunAt })
expect(updateReturning.mock.calls[0][0].values).toEqual({
status: "recurring",
+ statusReason: null,
+ statusErrorMessage: null,
+ statusInboxId: null,
})
expect(flatten(updateReturning.mock.calls[0][0].condition)).toEqual(
expect.arrayContaining([
diff --git a/packages/business/__tests__/contact-scan-run-status.test.ts b/packages/business/__tests__/contact-scan-run-status.test.ts
new file mode 100644
index 0000000000..20c33d46f8
--- /dev/null
+++ b/packages/business/__tests__/contact-scan-run-status.test.ts
@@ -0,0 +1,52 @@
+import { describe, expect, test } from "vitest"
+import { CONTACT_SCAN_ERRORS } from "../src/contact-scan/constants"
+import { resolveContactScanRunStatus } from "../src/contact-scan/run-status"
+
+describe("resolveContactScanRunStatus", () => {
+ test("a partial run with the cancel sentinel is cancelled", () => {
+ expect(
+ resolveContactScanRunStatus({
+ status: "partial",
+ currentError: CONTACT_SCAN_ERRORS.cancelled,
+ }),
+ ).toBe("cancelled")
+ })
+
+ test("a partial run for any other reason stays partial", () => {
+ expect(
+ resolveContactScanRunStatus({
+ status: "partial",
+ currentError: CONTACT_SCAN_ERRORS.scanLimitReached,
+ }),
+ ).toBe("partial")
+ expect(
+ resolveContactScanRunStatus({ status: "partial", currentError: null }),
+ ).toBe("partial")
+ })
+
+ test("the sentinel on a non-partial status does not make it cancelled", () => {
+ expect(
+ resolveContactScanRunStatus({
+ status: "failed",
+ currentError: CONTACT_SCAN_ERRORS.cancelled,
+ }),
+ ).toBe("failed")
+ })
+
+ test.each([
+ "init",
+ "running",
+ "succeeded",
+ "failed",
+ ] as const)("%s passes through", (status) => {
+ expect(resolveContactScanRunStatus({ status, currentError: null })).toBe(
+ status,
+ )
+ })
+
+ test("waiting (never set on a scan) is treated as running", () => {
+ expect(
+ resolveContactScanRunStatus({ status: "waiting", currentError: null }),
+ ).toBe("running")
+ })
+})
diff --git a/packages/business/__tests__/contact-scan.service.test.ts b/packages/business/__tests__/contact-scan.service.test.ts
index cd5ca6b636..44f33c73c2 100644
--- a/packages/business/__tests__/contact-scan.service.test.ts
+++ b/packages/business/__tests__/contact-scan.service.test.ts
@@ -16,6 +16,7 @@ const mocks = vi.hoisted(() => ({
markMaxAttemptsFailed: vi.fn(),
findRunById: vi.fn(),
listContactScanRuns: vi.fn(),
+ cancelActiveContactScanRuns: vi.fn(),
}))
vi.mock("@chatbotx.io/database/repositories", () => ({
@@ -34,6 +35,7 @@ vi.mock("@chatbotx.io/database/repositories", () => ({
markMaxAttemptsFailed: mocks.markMaxAttemptsFailed,
findRunById: mocks.findRunById,
listContactScanRuns: mocks.listContactScanRuns,
+ cancelActiveContactScanRuns: mocks.cancelActiveContactScanRuns,
},
}))
@@ -364,6 +366,8 @@ describe("contactScanService thin delegations", () => {
batchSize: 10,
maxAttempts: 5,
type: "contact_scan",
+ // A run parked on a delayed job is recovered after this grace if its job is lost.
+ releasedGraceMs: 35 * 60 * 1000,
})
})
@@ -523,26 +527,6 @@ describe("contactScanService thin delegations", () => {
expect: undefined,
})
})
-
- test("resetForRetry wraps updateProgress with status: init and no claimToken change", async () => {
- mocks.updateProgress.mockResolvedValue(1)
- await contactScanService.resetForRetry({
- runId: "run-1",
- currentError: "providerRetryable",
- })
-
- expect(mocks.updateProgress).toHaveBeenCalledWith(
- expect.objectContaining({
- runId: "run-1",
- fields: expect.objectContaining({
- status: "init",
- currentError: "providerRetryable",
- }),
- }),
- )
- const call = mocks.updateProgress.mock.calls.at(-1)?.[0]
- expect(call.fields).not.toHaveProperty("claimToken")
- })
})
const connectedInstagramInbox = {
@@ -591,3 +575,125 @@ describe("contactScanIntegrationRefs channel registry", () => {
).toBeNull()
})
})
+
+describe("contactScanService.cancel", () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ mocks.findWithIntegrations.mockResolvedValue(connectedMessengerInbox)
+ mocks.cancelActiveContactScanRuns.mockResolvedValue(1)
+ })
+
+ test("cancels the inbox's integration scan scoped to the workspace", async () => {
+ await expect(
+ contactScanService.cancel({
+ workspaceId: WORKSPACE_ID,
+ inboxId: INBOX_ID,
+ }),
+ ).resolves.toEqual({ cancelled: true })
+
+ expect(mocks.findWithIntegrations).toHaveBeenCalledWith({
+ where: { id: INBOX_ID, workspaceId: WORKSPACE_ID },
+ })
+ expect(mocks.cancelActiveContactScanRuns).toHaveBeenCalledWith({
+ channel: "messenger",
+ integrationId: INTEGRATION_ID,
+ workspaceId: WORKSPACE_ID,
+ currentError: "cancelled",
+ })
+ })
+
+ test("reports cancelled:false when no scan was running", async () => {
+ mocks.cancelActiveContactScanRuns.mockResolvedValue(0)
+
+ await expect(
+ contactScanService.cancel({
+ workspaceId: WORKSPACE_ID,
+ inboxId: INBOX_ID,
+ }),
+ ).resolves.toEqual({ cancelled: false })
+ })
+
+ test.each([
+ ["the inbox is missing or in another workspace", undefined],
+ [
+ "the channel has no scan",
+ { ...connectedMessengerInbox, channel: "zalo" },
+ ],
+ [
+ "the inbox has no integration",
+ { ...connectedMessengerInbox, integrationMessenger: null },
+ ],
+ ])("returns cancelled:false without touching runs when %s", async (_name, inbox) => {
+ mocks.findWithIntegrations.mockResolvedValue(inbox)
+
+ await expect(
+ contactScanService.cancel({
+ workspaceId: WORKSPACE_ID,
+ inboxId: INBOX_ID,
+ }),
+ ).resolves.toEqual({ cancelled: false })
+ expect(mocks.cancelActiveContactScanRuns).not.toHaveBeenCalled()
+ })
+})
+
+describe("contactScanService.cancelForIntegration", () => {
+ test("ends the integration's scan inside the caller's transaction, without a workspace filter", async () => {
+ vi.clearAllMocks()
+ const tx = {} as never
+
+ await contactScanService.cancelForIntegration({
+ channel: "instagram",
+ integrationId: INTEGRATION_ID,
+ tx,
+ })
+
+ expect(mocks.cancelActiveContactScanRuns).toHaveBeenCalledWith({
+ channel: "instagram",
+ integrationId: INTEGRATION_ID,
+ tx,
+ currentError: "cancelled",
+ })
+ })
+})
+
+describe("a cancelled scan is shown as cancelled", () => {
+ const cancelledRun = {
+ id: "run-1",
+ workspaceId: WORKSPACE_ID,
+ channel: "messenger",
+ status: "partial",
+ currentError: "cancelled",
+ scanFromAt: pastDate,
+ createdAt: new Date(),
+ startedAt: null,
+ finishedAt: new Date(),
+ importedContactCount: 3,
+ currentScan: 5,
+ requestedByUserId: null,
+ }
+
+ test("getStatus and listHistory agree, and it still counts toward the cooldown", async () => {
+ mocks.findWithIntegrations.mockResolvedValue(connectedMessengerInbox)
+ mocks.findLatestContactScanRun.mockResolvedValue(cancelledRun)
+ mocks.listContactScanRuns.mockResolvedValue({
+ data: [cancelledRun],
+ pageCount: 1,
+ })
+
+ const status = await contactScanService.getStatus({
+ workspaceId: WORKSPACE_ID,
+ inboxId: INBOX_ID,
+ })
+ const history = await contactScanService.listHistory({
+ workspaceId: WORKSPACE_ID,
+ })
+
+ expect(status.status).toBe("cancelled")
+ expect(status.latest?.status).toBe("cancelled")
+ expect(history.data[0]?.status).toBe("cancelled")
+ expect(status.availability).toMatchObject({
+ canScan: false,
+ blockedReason: "cooldown",
+ })
+ })
+})
diff --git a/packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts b/packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts
new file mode 100644
index 0000000000..bbfb8e3dcc
--- /dev/null
+++ b/packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts
@@ -0,0 +1,389 @@
+// @vitest-environment node
+
+import { db, eq } from "@chatbotx.io/database/client"
+import { broadcastRepository } from "@chatbotx.io/database/repositories"
+import {
+ broadcastModel,
+ broadcastRecurrenceModel,
+ broadcastTargetModel,
+ inboxModel,
+ integrationMessengerModel,
+ userModel,
+ workspaceModel,
+} from "@chatbotx.io/database/schema"
+import { ChannelErrorReason } from "@chatbotx.io/sdk"
+import { createId } from "@chatbotx.io/utils"
+import {
+ afterAll,
+ beforeAll,
+ beforeEach,
+ describe,
+ expect,
+ test,
+ vi,
+} from "vitest"
+
+const realDatabaseUrl = (): string | null => {
+ const url = process.env.DATABASE_URL
+ if (!url) {
+ return null
+ }
+ try {
+ return new URL(url).port === "1" ? null : url
+ } catch {
+ return null
+ }
+}
+
+const databaseUrl = realDatabaseUrl()
+
+vi.mock("../../src/broadcast/plan-policy.service", () => ({
+ broadcastPlanPolicyService: {
+ hasRestrictions: vi.fn(() => false),
+ resolveForWorkspace: vi
+ .fn()
+ .mockResolvedValue({ policy: { kind: "unrestricted" }, planName: null }),
+ restrictionFor: vi.fn(() => null),
+ },
+}))
+vi.mock("../../src/audit/dispatcher", () => ({ dispatchAuditRecord: vi.fn() }))
+
+const { broadcastService } = await import("../../src/broadcast/service")
+const { broadcastRecurrenceService } = await import(
+ "../../src/broadcast/recurrence.service"
+)
+
+const ownerId = createId()
+const workspaceId = createId()
+const blockedInboxId = createId()
+const otherInboxId = createId()
+const messengerIntegrationId = createId()
+
+const baseRow = {
+ workspaceId,
+ schedulesType: "now" as const,
+ schedulesAt: new Date(),
+ subaction: "flow",
+ contactCount: 5,
+}
+
+const insertBroadcast = async (
+ overrides: Partial,
+): Promise => {
+ const id = createId()
+ await db.insert(broadcastModel).values({
+ id,
+ name: `b-${id}`,
+ channel: "messenger",
+ status: "sending",
+ ...baseRow,
+ ...overrides,
+ })
+ return id
+}
+
+const readRow = async (id: string) => {
+ const [row] = await db
+ .select({
+ status: broadcastModel.status,
+ statusReason: broadcastModel.statusReason,
+ statusErrorMessage: broadcastModel.statusErrorMessage,
+ statusInboxId: broadcastModel.statusInboxId,
+ })
+ .from(broadcastModel)
+ .where(eq(broadcastModel.id, id))
+ return row
+}
+
+const stop = (channel = "messenger", inboxId = blockedInboxId) =>
+ broadcastService.stopSendingForBlockedAccount({
+ workspaceId,
+ inboxId,
+ channel,
+ reason: ChannelErrorReason.ACCOUNT_POLICY_BLOCKED,
+ errorMessage: "page blocked",
+ })
+
+describe.skipIf(!databaseUrl)("stopSendingForBlockedAccount", () => {
+ beforeAll(async () => {
+ await db.insert(userModel).values({
+ id: ownerId,
+ email: `stop-blocked-${ownerId}@example.test`,
+ name: "Stop blocked owner",
+ })
+ await db
+ .insert(workspaceModel)
+ .values({ id: workspaceId, name: "stop-blocked", ownerId })
+ await db.insert(inboxModel).values([
+ {
+ id: blockedInboxId,
+ name: "Blocked page",
+ channel: "messenger",
+ sourceId: `blocked-${blockedInboxId}`,
+ workspaceId,
+ },
+ {
+ id: otherInboxId,
+ name: "Other page",
+ channel: "messenger",
+ sourceId: `other-${otherInboxId}`,
+ workspaceId,
+ },
+ ])
+ })
+
+ beforeEach(async () => {
+ await db
+ .delete(broadcastModel)
+ .where(eq(broadcastModel.workspaceId, workspaceId))
+ })
+
+ afterAll(async () => {
+ await db.delete(workspaceModel).where(eq(workspaceModel.id, workspaceId))
+ await db.delete(userModel).where(eq(userModel.id, ownerId))
+ })
+
+ test("targets mode: stops only broadcasts that target the blocked inbox, and records why", async () => {
+ const targeted = await insertBroadcast({ targetMode: "targets" })
+ await db
+ .insert(broadcastTargetModel)
+ .values({ broadcastId: targeted, inboxId: blockedInboxId })
+ const elsewhere = await insertBroadcast({ targetMode: "targets" })
+ await db
+ .insert(broadcastTargetModel)
+ .values({ broadcastId: elsewhere, inboxId: otherInboxId })
+
+ const result = await stop()
+
+ expect(result.stoppedIds).toEqual([targeted])
+ expect(await readRow(targeted)).toEqual({
+ status: "cancelled",
+ statusReason: "accountPolicyBlocked",
+ statusErrorMessage: "page blocked",
+ statusInboxId: blockedInboxId,
+ })
+ expect((await readRow(elsewhere)).status).toBe("sending")
+ })
+
+ test("legacy whole-channel and omnichannel broadcasts stop; another channel's does not", async () => {
+ const wholeChannel = await insertBroadcast({})
+ const omnichannel = await insertBroadcast({ channel: "omnichannel" })
+ const otherChannel = await insertBroadcast({ channel: "telegram" })
+
+ await stop("messenger")
+
+ expect((await readRow(wholeChannel)).status).toBe("cancelled")
+ expect((await readRow(omnichannel)).status).toBe("cancelled")
+ expect((await readRow(otherChannel)).status).toBe("sending")
+ })
+
+ test("legacy by integration: only the broadcast pinned to the blocked page's integration stops", async () => {
+ await db.insert(integrationMessengerModel).values({
+ id: messengerIntegrationId,
+ name: "Blocked integration",
+ pageId: `page-${messengerIntegrationId}`,
+ auth: {},
+ // A drizzle `.default()` is not a database default: write these explicitly.
+ conversationStarters: [],
+ persistentMenus: [],
+ personas: [],
+ coexistEnabled: false,
+ coexistAiReadsSyncedHistory: false,
+ hasCapiScope: false,
+ workspaceId,
+ inboxId: blockedInboxId,
+ })
+ const pinned = await insertBroadcast({
+ integrationMessengerId: messengerIntegrationId,
+ })
+
+ await stop()
+
+ expect((await readRow(pinned)).status).toBe("cancelled")
+ await db
+ .delete(integrationMessengerModel)
+ .where(eq(integrationMessengerModel.id, messengerIntegrationId))
+ })
+
+ test("rows that are not sending are untouched, and a second call is a no-op", async () => {
+ const draft = await insertBroadcast({ status: "draft" })
+ const sent = await insertBroadcast({ status: "sent" })
+ const sending = await insertBroadcast({})
+
+ const first = await stop()
+ const second = await stop()
+
+ expect(first.stoppedIds).toEqual([sending])
+ expect(second.stoppedIds).toEqual([])
+ expect((await readRow(draft)).status).toBe("draft")
+ expect((await readRow(sent)).status).toBe("sent")
+ })
+
+ test("a soft-deleted broadcast is never stopped", async () => {
+ const deleted = await insertBroadcast({ deletedAt: new Date() })
+ await stop()
+ expect((await readRow(deleted)).status).toBe("sending")
+ })
+
+ test("a run's repeating series is paused with all three reason columns, once for two runs", async () => {
+ const series = await insertBroadcast({
+ status: "recurring",
+ schedulesType: "recurring",
+ })
+ await db.insert(broadcastRecurrenceModel).values({
+ workspaceId,
+ broadcastId: series,
+ rule: {
+ frequency: "daily",
+ interval: 1,
+ timeOfDay: "09:00",
+ timezone: "UTC",
+ startsOn: "2026-01-01",
+ end: { kind: "never" },
+ },
+ nextRunAt: new Date(Date.now() + 3_600_000),
+ })
+ const runA = await insertBroadcast({
+ parentBroadcastId: series,
+ occurrenceAt: new Date(Date.now() - 60_000),
+ })
+ const runB = await insertBroadcast({
+ parentBroadcastId: series,
+ occurrenceAt: new Date(Date.now() - 30_000),
+ })
+
+ await stop()
+
+ for (const id of [runA, runB]) {
+ expect((await readRow(id)).status).toBe("cancelled")
+ }
+ expect(await readRow(series)).toEqual({
+ status: "cancelled",
+ statusReason: "accountPolicyBlocked",
+ statusErrorMessage: "page blocked",
+ statusInboxId: blockedInboxId,
+ })
+ const [recurrence] = await db
+ .select({ pausedAt: broadcastRecurrenceModel.pausedAt })
+ .from(broadcastRecurrenceModel)
+ .where(eq(broadcastRecurrenceModel.broadcastId, series))
+ expect(recurrence.pausedAt).not.toBeNull()
+ })
+
+ test("a failure while pausing the series rolls the stop back too", async () => {
+ const series = await insertBroadcast({
+ status: "recurring",
+ schedulesType: "recurring",
+ })
+ await db.insert(broadcastRecurrenceModel).values({
+ workspaceId,
+ broadcastId: series,
+ rule: {
+ frequency: "daily",
+ interval: 1,
+ timeOfDay: "09:00",
+ timezone: "UTC",
+ startsOn: "2026-01-01",
+ end: { kind: "never" },
+ },
+ nextRunAt: new Date(Date.now() + 3_600_000),
+ })
+ const run = await insertBroadcast({
+ parentBroadcastId: series,
+ occurrenceAt: new Date(Date.now() - 60_000),
+ })
+ const disarm = vi
+ .spyOn(broadcastRecurrenceService, "disarm")
+ .mockRejectedValueOnce(new Error("disarm failed"))
+
+ await expect(stop()).rejects.toThrow("disarm failed")
+ disarm.mockRestore()
+
+ expect(await readRow(run)).toEqual({
+ status: "sending",
+ statusReason: null,
+ statusErrorMessage: null,
+ statusInboxId: null,
+ })
+ expect((await readRow(series)).status).toBe("recurring")
+ })
+
+ test("statusInbox returns the page name, and null once the page is deleted", async () => {
+ const pageId = createId()
+ await db.insert(inboxModel).values({
+ id: pageId,
+ name: "Short-lived page",
+ channel: "messenger",
+ sourceId: `short-${pageId}`,
+ workspaceId,
+ })
+ const id = await insertBroadcast({ targetMode: "targets" })
+ await db
+ .insert(broadcastTargetModel)
+ .values({ broadcastId: id, inboxId: pageId })
+ await stop("messenger", pageId)
+
+ const listed = async () =>
+ (await broadcastRepository.listWithRelations({ workspaceId })).find(
+ (row) => row.id === id,
+ )
+ expect((await listed())?.statusInbox).toEqual({
+ id: pageId,
+ name: "Short-lived page",
+ })
+ const found = await broadcastRepository.findByIdOrName({
+ workspaceId,
+ idOrName: id,
+ })
+ expect(found?.statusInbox?.name).toBe("Short-lived page")
+
+ await db.delete(inboxModel).where(eq(inboxModel.id, pageId))
+
+ expect((await listed())?.statusInbox).toBeNull()
+ })
+
+ test("two concurrent calls stop each broadcast once", async () => {
+ const id = await insertBroadcast({})
+ const [a, b] = await Promise.all([stop(), stop()])
+ expect([...a.stoppedIds, ...b.stoppedIds]).toEqual([id])
+ })
+
+ test("resume and move-to-draft clear the reason columns", async () => {
+ const resumed = await insertBroadcast({})
+ await stop()
+ await broadcastService.resumeSending({ workspaceId, broadcastId: resumed })
+ expect(await readRow(resumed)).toEqual({
+ status: "sending",
+ statusReason: null,
+ statusErrorMessage: null,
+ statusInboxId: null,
+ })
+ })
+
+ test("a rate-limit reason stops nothing", async () => {
+ const id = await insertBroadcast({})
+ const result = await broadcastService.stopSendingForBlockedAccount({
+ workspaceId,
+ inboxId: blockedInboxId,
+ channel: "messenger",
+ reason: ChannelErrorReason.RATE_LIMITED,
+ errorMessage: "slow down",
+ })
+ expect(result.stoppedIds).toEqual([])
+ expect((await readRow(id)).status).toBe("sending")
+ })
+
+ test("the error message is truncated to 500 characters", async () => {
+ const id = await insertBroadcast({})
+ await broadcastService.stopSendingForBlockedAccount({
+ workspaceId,
+ inboxId: blockedInboxId,
+ channel: "messenger",
+ reason: ChannelErrorReason.ACCOUNT_SEND_RESTRICTED,
+ errorMessage: "x".repeat(900),
+ })
+ const row = await readRow(id)
+ expect(row.statusErrorMessage).toHaveLength(500)
+ expect(row.statusReason).toBe("accountSendRestricted")
+ })
+})
diff --git a/packages/business/__tests__/message-create-outgoing.test.ts b/packages/business/__tests__/message-create-outgoing.test.ts
index 7e15d059f1..7474bbb10b 100644
--- a/packages/business/__tests__/message-create-outgoing.test.ts
+++ b/packages/business/__tests__/message-create-outgoing.test.ts
@@ -14,6 +14,8 @@ const mockPrepareProductMessage = vi.fn()
const mockFindMediaFilesByIds = vi.fn()
const mockCopyObject = vi.fn()
const mockQueueMessageCreatedEvent = vi.fn()
+const mockQueueWorkspaceRealtimeEvent = vi.fn()
+const mockUpdateSendError = vi.fn()
vi.mock("@chatbotx.io/database/repositories", () => ({
createMessageRepository: mockCreateMessageRepository,
@@ -33,7 +35,10 @@ vi.mock("@chatbotx.io/filesystem", () => ({
}))
vi.mock("@chatbotx.io/realtime-protocol", () => ({
- RealtimeEventType: { messageCreated: "messageCreated" },
+ RealtimeEventType: {
+ messageCreated: "messageCreated",
+ messageFailed: "messageFailed",
+ },
routeForConversation: vi.fn(() => ({
assignedTeamIds: [],
assignedUserIds: [],
@@ -91,6 +96,7 @@ vi.mock("../src/platform/settings", () => ({
vi.mock("../src/platform/realtime-broadcast", () => ({
queueMessageCreatedEvent: mockQueueMessageCreatedEvent,
+ queueWorkspaceRealtimeEvent: mockQueueWorkspaceRealtimeEvent,
}))
vi.mock("../src/utils", () => ({
@@ -130,9 +136,12 @@ describe("messageService.createOutgoing", () => {
mockCreateMessageRepository.mockResolvedValue({
create: mockRepositoryCreate,
createWithAttachments: vi.fn(),
+ updateSendError: mockUpdateSendError,
})
+ mockUpdateSendError.mockResolvedValue({ id: "msg-1" })
mockChatQueueAdd.mockResolvedValue(undefined)
mockQueueMessageCreatedEvent.mockResolvedValue(undefined)
+ mockQueueWorkspaceRealtimeEvent.mockResolvedValue(undefined)
})
test("uses one shared timestamp for the message and conversation agent-replied fields", async () => {
@@ -292,6 +301,127 @@ describe("messageService.createOutgoing", () => {
})
})
+describe("messageService.createOutgoing enqueue failure", () => {
+ const input = { text: "hello", clientId: "client-1" }
+
+ test("a failed channel enqueue leaves a sendError on the row and tells every tab, then still throws", async () => {
+ const failure = new Error("redis down")
+ mockChatQueueAdd.mockRejectedValueOnce(failure)
+
+ await expect(
+ createOutgoing({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ input,
+ user: { id: "user-1" } as never,
+ }),
+ ).rejects.toBe(failure)
+
+ expect(mockUpdateSendError).toHaveBeenCalledWith(
+ "msg-1",
+ "Could not queue the message for delivery",
+ "ws-1",
+ expect.any(Date),
+ )
+ expect(mockQueueWorkspaceRealtimeEvent).toHaveBeenCalledWith("ws-1", {
+ eventType: "messageFailed",
+ data: {
+ messageId: "msg-1",
+ clientId: "client-1",
+ error: "Could not queue the message for delivery",
+ },
+ route: { assignedTeamIds: [], assignedUserIds: [] },
+ })
+ })
+
+ test("bookkeeping that fails never replaces the enqueue error", async () => {
+ const failure = new Error("redis down")
+ mockChatQueueAdd.mockRejectedValueOnce(failure)
+ mockUpdateSendError.mockRejectedValueOnce(new Error("db down"))
+
+ await expect(
+ createOutgoing({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ input,
+ user: { id: "user-1" } as never,
+ }),
+ ).rejects.toBe(failure)
+ })
+
+ test("a successful enqueue records nothing", async () => {
+ await createOutgoing({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ input,
+ user: { id: "user-1" } as never,
+ })
+
+ expect(mockUpdateSendError).not.toHaveBeenCalled()
+ expect(mockQueueWorkspaceRealtimeEvent).not.toHaveBeenCalled()
+ })
+
+ test("a failure of only the automation job does not mark the message failed", async () => {
+ mockChatQueueAdd
+ .mockResolvedValueOnce(undefined)
+ .mockRejectedValueOnce(new Error("automation queue down"))
+
+ await createOutgoing({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ input,
+ user: { id: "user-1" } as never,
+ })
+
+ expect(mockUpdateSendError).not.toHaveBeenCalled()
+ })
+})
+
+describe("messageService.createOutgoing private reply target", () => {
+ test("keeps the replied-to comment's createdAt on the row so the reply can be resent", async () => {
+ mockFindOrCreate.mockResolvedValue({ id: "dm-conv", workspaceId: "ws-1" })
+ const commentCreatedAt = new Date("2026-07-01T10:00:00.000Z")
+
+ await createOutgoing({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ input: {
+ text: "hi",
+ replyToMessageId: "comment-1",
+ replyToMessageCreatedAt: commentCreatedAt,
+ isPrivateReply: true,
+ },
+ user: { id: "user-1" } as never,
+ })
+
+ const created = mockRepositoryCreate.mock.calls[0]?.[0] as {
+ contentAttributes: Record
+ }
+ expect(created.contentAttributes).toEqual({
+ isPrivateReply: true,
+ replyToMessageCreatedAt: "2026-07-01T10:00:00.000Z",
+ })
+ })
+
+ test("a public comment reply stores no reply target", async () => {
+ await createOutgoing({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ input: {
+ text: "hi",
+ replyToMessageId: "comment-1",
+ replyToMessageCreatedAt: new Date("2026-07-01T10:00:00.000Z"),
+ },
+ user: { id: "user-1" } as never,
+ })
+
+ const created = mockRepositoryCreate.mock.calls[0]?.[0] as {
+ contentAttributes: Record | null
+ }
+ expect(created.contentAttributes).toBeNull()
+ })
+})
+
describe("messageService.createOutgoing with a flow", () => {
beforeEach(() => {
vi.clearAllMocks()
diff --git a/packages/business/__tests__/message-resend-outgoing.test.ts b/packages/business/__tests__/message-resend-outgoing.test.ts
new file mode 100644
index 0000000000..814e3e168b
--- /dev/null
+++ b/packages/business/__tests__/message-resend-outgoing.test.ts
@@ -0,0 +1,281 @@
+// @vitest-environment node
+import { beforeEach, describe, expect, test, vi } from "vitest"
+
+const mocks = vi.hoisted(() => ({
+ findById: vi.fn(),
+ claimForResend: vi.fn(),
+ updateSendError: vi.fn(),
+ findConversation: vi.fn(),
+ findContactInbox: vi.fn(),
+ chatQueueAdd: vi.fn(),
+ resolveTenantSettings: vi.fn(),
+}))
+
+vi.mock("@chatbotx.io/database/repositories", () => ({
+ createMessageRepository: vi.fn(() =>
+ Promise.resolve({
+ findById: mocks.findById,
+ claimForResend: mocks.claimForResend,
+ updateSendError: mocks.updateSendError,
+ }),
+ ),
+}))
+
+vi.mock("@chatbotx.io/worker-config", () => ({
+ ChatJobAction: { sendChannelMessage: "sendChannelMessage" },
+ chatQueue: { add: mocks.chatQueueAdd },
+}))
+
+vi.mock("../src/conversation/service", () => ({
+ conversationService: { findByOrFail: mocks.findConversation },
+}))
+
+vi.mock("../src/contact-inbox/service", () => ({
+ contactInboxService: { findByIdForWorkspace: mocks.findContactInbox },
+}))
+
+vi.mock("../src/platform/settings", () => ({
+ resolveTenantSettings: mocks.resolveTenantSettings,
+}))
+
+vi.mock("../src/utils", () => ({
+ getPublicFileUrl: (path: string, base: string) => `${base}/${path}`,
+}))
+
+vi.mock("../src/logger", () => ({ logger: { error: vi.fn() } }))
+
+const { resendOutgoing } = await import("../src/message/resend-outgoing")
+
+const CREATED_AT = new Date("2026-07-09T08:37:21.108Z")
+const PARENT_CREATED_AT = "2026-07-01T10:00:00.000Z"
+const conversation = { id: "conv-1", workspaceId: "ws-1", contactId: "c-1" }
+const contactInbox = { id: "ci-1", channel: "messenger", contactId: "c-1" }
+
+const failedMessage = (overrides: Record = {}) => ({
+ id: "msg-1",
+ workspaceId: "ws-1",
+ conversationId: "conv-1",
+ contactInboxId: "ci-1",
+ messageType: "outgoing",
+ senderType: "user",
+ type: "message",
+ contentAttributes: null,
+ sendError: "(#10) permission denied",
+ sourceId: null,
+ parentId: null,
+ createdAt: CREATED_AT,
+ attachments: [],
+ ...overrides,
+})
+
+const resend = () =>
+ resendOutgoing({
+ workspaceId: "ws-1",
+ conversationId: "conv-1",
+ messageId: "msg-1",
+ createdAt: CREATED_AT,
+ })
+
+describe("messageService.resendOutgoing", () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ mocks.findById.mockResolvedValue(failedMessage())
+ mocks.claimForResend.mockResolvedValue({ id: "msg-1" })
+ mocks.updateSendError.mockResolvedValue({ id: "msg-1" })
+ mocks.findConversation.mockResolvedValue(conversation)
+ mocks.findContactInbox.mockResolvedValue(contactInbox)
+ mocks.chatQueueAdd.mockResolvedValue(undefined)
+ mocks.resolveTenantSettings.mockResolvedValue({
+ storageUrl: "https://storage.example.com",
+ })
+ })
+
+ test("claims the failed message, then queues it for the inbox send path", async () => {
+ await expect(resend()).resolves.toEqual({ id: "msg-1", queued: true })
+
+ expect(mocks.findById).toHaveBeenCalledWith({
+ id: "msg-1",
+ createdAt: CREATED_AT,
+ workspaceId: "ws-1",
+ conversationId: "conv-1",
+ })
+ expect(mocks.claimForResend).toHaveBeenCalledWith({
+ id: "msg-1",
+ workspaceId: "ws-1",
+ createdAt: CREATED_AT,
+ })
+ expect(mocks.chatQueueAdd).toHaveBeenCalledWith(
+ "sendChannelMessage",
+ expect.objectContaining({
+ type: "sendChannelMessage",
+ data: expect.objectContaining({
+ conversation,
+ contactInbox,
+ sendFrom: "inbox",
+ message: expect.objectContaining({
+ id: "msg-1",
+ parentCreatedAt: null,
+ }),
+ }),
+ }),
+ )
+ })
+
+ test("a message with files is resent whole, with resolved attachment urls", async () => {
+ mocks.findById.mockResolvedValue(
+ failedMessage({
+ attachments: [{ id: "att-1", originPath: "public/a.png" }],
+ }),
+ )
+
+ await resend()
+
+ const payload = mocks.chatQueueAdd.mock.calls[0]?.[1] as {
+ data: { message: { attachments: { url: string }[] } }
+ }
+ expect(payload.data.message.attachments).toEqual([
+ expect.objectContaining({
+ id: "att-1",
+ url: "https://storage.example.com/public/a.png",
+ }),
+ ])
+ })
+
+ test("a message that does not exist in this workspace/conversation is a 404 and nothing happens", async () => {
+ mocks.findById.mockResolvedValue(null)
+
+ await expect(resend()).rejects.toMatchObject({ httpStatusCode: 404 })
+
+ expect(mocks.claimForResend).not.toHaveBeenCalled()
+ expect(mocks.chatQueueAdd).not.toHaveBeenCalled()
+ })
+
+ test.each([
+ ["a bot message", { senderType: "bot" }],
+ ["a system message", { senderType: "system" }],
+ ["a message that did not fail", { sendError: null }],
+ ["a message the channel already accepted", { sourceId: "mid-1" }],
+ ["an incoming message", { messageType: "incoming" }],
+ ["a public comment reply", { type: "comment", contentAttributes: null }],
+ ])("%s cannot be resent: 409, nothing claimed or queued", async (_name, overrides) => {
+ mocks.findById.mockResolvedValue(failedMessage(overrides))
+
+ await expect(resend()).rejects.toMatchObject({
+ code: "messageNotResendable",
+ httpStatusCode: 409,
+ })
+
+ expect(mocks.claimForResend).not.toHaveBeenCalled()
+ expect(mocks.chatQueueAdd).not.toHaveBeenCalled()
+ })
+
+ test("a message sent through the API can be resent", async () => {
+ mocks.findById.mockResolvedValue(failedMessage({ senderType: "api" }))
+ await expect(resend()).resolves.toEqual({ id: "msg-1", queued: true })
+ })
+
+ describe("private reply (stored as a comment, delivered as a DM)", () => {
+ const privateReply = (extra: Record = {}) =>
+ failedMessage({
+ type: "comment",
+ parentId: "comment-1",
+ contentAttributes: {
+ isPrivateReply: true,
+ replyToMessageCreatedAt: PARENT_CREATED_AT,
+ },
+ ...extra,
+ })
+
+ test("is resent with the replied-to comment's createdAt", async () => {
+ mocks.findById.mockResolvedValue(privateReply())
+
+ await resend()
+
+ const payload = mocks.chatQueueAdd.mock.calls[0]?.[1] as {
+ data: { message: { parentCreatedAt: Date | null } }
+ }
+ expect(payload.data.message.parentCreatedAt).toEqual(
+ new Date(PARENT_CREATED_AT),
+ )
+ })
+
+ test("without the kept createdAt it is refused, and nothing is claimed", async () => {
+ mocks.findById.mockResolvedValue(
+ privateReply({ contentAttributes: { isPrivateReply: true } }),
+ )
+
+ await expect(resend()).rejects.toMatchObject({
+ code: "messageNotResendable",
+ httpStatusCode: 409,
+ })
+
+ expect(mocks.claimForResend).not.toHaveBeenCalled()
+ expect(mocks.chatQueueAdd).not.toHaveBeenCalled()
+ })
+
+ test("a garbled kept createdAt is refused too", async () => {
+ mocks.findById.mockResolvedValue(
+ privateReply({
+ contentAttributes: {
+ isPrivateReply: true,
+ replyToMessageCreatedAt: "not-a-date",
+ },
+ }),
+ )
+
+ await expect(resend()).rejects.toMatchObject({ httpStatusCode: 409 })
+ expect(mocks.claimForResend).not.toHaveBeenCalled()
+ })
+ })
+
+ test("two concurrent resends queue once: the loser gets a conflict and queues nothing", async () => {
+ mocks.claimForResend
+ .mockResolvedValueOnce({ id: "msg-1" })
+ .mockResolvedValueOnce(null)
+
+ const results = await Promise.allSettled([resend(), resend()])
+
+ expect(results.map((result) => result.status).sort()).toEqual([
+ "fulfilled",
+ "rejected",
+ ])
+ expect(mocks.chatQueueAdd).toHaveBeenCalledTimes(1)
+ })
+
+ test("a queue failure puts the failed state back and rethrows, so it can be tried again", async () => {
+ const failure = new Error("redis down")
+ mocks.chatQueueAdd.mockRejectedValueOnce(failure)
+
+ await expect(resend()).rejects.toBe(failure)
+
+ expect(mocks.updateSendError).toHaveBeenCalledWith(
+ "msg-1",
+ "(#10) permission denied",
+ "ws-1",
+ CREATED_AT,
+ )
+ })
+
+ test("a failure while restoring the failed state never replaces the queue error", async () => {
+ const failure = new Error("redis down")
+ mocks.chatQueueAdd.mockRejectedValueOnce(failure)
+ mocks.updateSendError.mockRejectedValueOnce(new Error("db down"))
+
+ await expect(resend()).rejects.toBe(failure)
+ })
+
+ test("a missing contact inbox is a 404 before anything is claimed", async () => {
+ mocks.findContactInbox.mockResolvedValue(null)
+
+ await expect(resend()).rejects.toMatchObject({ httpStatusCode: 404 })
+ expect(mocks.claimForResend).not.toHaveBeenCalled()
+ })
+
+ test("a failure while preparing the payload happens before the claim, so the message is never left claimed with no job", async () => {
+ mocks.resolveTenantSettings.mockRejectedValue(new Error("cache down"))
+
+ await expect(resend()).rejects.toThrow("cache down")
+ expect(mocks.claimForResend).not.toHaveBeenCalled()
+ expect(mocks.chatQueueAdd).not.toHaveBeenCalled()
+ })
+})
diff --git a/packages/business/src/broadcast/service.ts b/packages/business/src/broadcast/service.ts
index 75d67e5acc..09e8106c83 100644
--- a/packages/business/src/broadcast/service.ts
+++ b/packages/business/src/broadcast/service.ts
@@ -24,6 +24,7 @@ import {
type BroadcastScheduleType,
type BroadcastSendLimit,
type BroadcastStatus,
+ type BroadcastStatusReason,
type BroadcastSubaction,
type BroadcastTerminalStatus,
broadcastScheduleTypes,
@@ -107,6 +108,7 @@ import {
waTemplateParamsSchema,
} from "@chatbotx.io/flow-config"
import { casStore } from "@chatbotx.io/redis"
+import type { ChannelErrorReason } from "@chatbotx.io/sdk"
import { createId } from "@chatbotx.io/utils"
import type { RecurrenceRule } from "@chatbotx.io/utils/recurrence"
import {
@@ -147,6 +149,11 @@ import type {
BroadcastAudiencePreviewRow,
BroadcastTemplateDetail,
} from "./schema"
+import {
+ CLEARED_STATUS_REASON,
+ resolveBroadcastStatusReason,
+ truncateStatusErrorMessage,
+} from "./status-reason"
const DEFAULT_BROADCAST_NAME = "Broadcast"
/** Next runs shown on a repeating broadcast's detail. */
@@ -1312,6 +1319,7 @@ class BroadcastService extends BaseService {
contactCount: null,
handoffCompletedAt: null,
resumeCount: sql`${broadcastModel.resumeCount} + 1`,
+ ...CLEARED_STATUS_REASON,
})
.where(
and(
@@ -1449,6 +1457,7 @@ class BroadcastService extends BaseService {
set: {
status: broadcastStatuses.enum.draft,
resumeCount: sql`${broadcastModel.resumeCount} + 1`,
+ ...CLEARED_STATUS_REASON,
},
failure: "Broadcast is no longer scheduled",
})
@@ -1511,6 +1520,134 @@ class BroadcastService extends BaseService {
return { id: row.id }
}
+ /**
+ * Stops every `sending` broadcast that sends through `inboxId` because its
+ * channel account is blocked from sending, recording why on each row (and on
+ * the series of a run, which is paused so no new run starts). One
+ * transaction: the stop and the series pause land together or not at all.
+ * Idempotent: a second call finds nothing `sending`.
+ */
+ async stopSendingForBlockedAccount(input: {
+ workspaceId: string
+ inboxId: string
+ channel: string
+ reason: ChannelErrorReason
+ errorMessage: string
+ }): Promise<{ stoppedIds: string[] }> {
+ const statusReason = resolveBroadcastStatusReason(input.reason)
+ if (statusReason === null) {
+ return { stoppedIds: [] }
+ }
+ const reasonColumns = {
+ statusReason,
+ statusErrorMessage: truncateStatusErrorMessage(input.errorMessage),
+ statusInboxId: input.inboxId,
+ }
+
+ const stoppedIds = await db.transaction(async (tx) => {
+ const sending = await broadcastRepository.listSendingIdsForInbox(
+ input,
+ tx,
+ )
+ if (sending.length === 0) {
+ return []
+ }
+ const ids = sending.map((row) => row.id)
+ // Series rows are locked before broadcast rows, as everywhere else.
+ const parentIds = [
+ ...new Set(
+ sending.flatMap((row) =>
+ row.parentBroadcastId === null ? [] : [row.parentBroadcastId],
+ ),
+ ),
+ ]
+ const series = await broadcastRecurrenceRepository.lockForWrite(tx, {
+ workspaceId: input.workspaceId,
+ broadcastIds: parentIds,
+ })
+
+ const stopped = await tx
+ .update(broadcastModel)
+ .set({ status: broadcastStatuses.enum.cancelled, ...reasonColumns })
+ .where(
+ and(
+ eq(broadcastModel.workspaceId, input.workspaceId),
+ inArray(broadcastModel.id, ids),
+ eq(broadcastModel.status, broadcastStatuses.enum.sending),
+ isNull(broadcastModel.deletedAt),
+ ),
+ )
+ .returning({ id: broadcastModel.id })
+
+ await this.pauseSeriesForBlockedAccount(tx, {
+ workspaceId: input.workspaceId,
+ series,
+ reasonColumns,
+ })
+ return stopped.map((row) => row.id)
+ })
+
+ if (stoppedIds.length > 0) {
+ await this.audit(
+ "broadcast_stopped",
+ `stopped ${stoppedIds.length} broadcast(s) because the channel account is blocked from sending`,
+ )
+ }
+ return { stoppedIds }
+ }
+
+ /** Pauses (`recurring` -> `cancelled`) the locked series whose template is still running; others are left alone. */
+ private async pauseSeriesForBlockedAccount(
+ tx: DatabaseClient,
+ input: {
+ workspaceId: string
+ series: BroadcastRecurrenceModel[]
+ reasonColumns: {
+ statusReason: BroadcastStatusReason
+ statusErrorMessage: string
+ statusInboxId: string
+ }
+ },
+ ): Promise {
+ if (input.series.length === 0) {
+ return
+ }
+ const paused = await tx
+ .update(broadcastModel)
+ .set({
+ status: broadcastStatuses.enum.cancelled,
+ ...input.reasonColumns,
+ })
+ .where(
+ and(
+ eq(broadcastModel.workspaceId, input.workspaceId),
+ inArray(
+ broadcastModel.id,
+ input.series.map((recurrence) => recurrence.broadcastId),
+ ),
+ eq(broadcastModel.status, broadcastStatuses.enum.recurring),
+ eq(
+ broadcastModel.schedulesType,
+ broadcastScheduleTypes.enum.recurring,
+ ),
+ isNull(broadcastModel.occurrenceAt),
+ isNull(broadcastModel.deletedAt),
+ ),
+ )
+ .returning({ id: broadcastModel.id })
+ const pausedIds = new Set(paused.map((row) => row.id))
+ const now = await broadcastRecurrenceRepository.selectDbNow(tx)
+ for (const recurrence of input.series) {
+ if (pausedIds.has(recurrence.broadcastId)) {
+ await broadcastRecurrenceService.disarm(tx, {
+ recurrence,
+ reason: "paused",
+ now,
+ })
+ }
+ }
+ }
+
/**
* `cancelled` -> `sending`, in a single pinned UPDATE. Clearing
* `handoffCompletedAt` here (rather than a separate statement) closes both
@@ -1552,6 +1689,7 @@ class BroadcastService extends BaseService {
status: broadcastStatuses.enum.sending,
handoffCompletedAt: null,
resumeCount: sql`${broadcastModel.resumeCount} + 1`,
+ ...CLEARED_STATUS_REASON,
...override,
})
.where(scope)
@@ -1639,7 +1777,10 @@ class BroadcastService extends BaseService {
workspaceId: input.workspaceId,
broadcastId: input.broadcastId,
from: [broadcastStatuses.enum.cancelled],
- set: { status: broadcastStatuses.enum.recurring },
+ set: {
+ status: broadcastStatuses.enum.recurring,
+ ...CLEARED_STATUS_REASON,
+ },
failure: "Broadcast is not stopped",
})
const row = await this.activateRecurringTemplate(tx, {
diff --git a/packages/business/src/broadcast/status-reason.ts b/packages/business/src/broadcast/status-reason.ts
new file mode 100644
index 0000000000..5dd6156318
--- /dev/null
+++ b/packages/business/src/broadcast/status-reason.ts
@@ -0,0 +1,32 @@
+import type { BroadcastStatusReason } from "@chatbotx.io/database/partials"
+import { BROADCAST_STATUS_ERROR_MESSAGE_MAX_LENGTH } from "@chatbotx.io/database/partials"
+import { ChannelErrorReason } from "@chatbotx.io/sdk"
+
+/**
+ * SDK error reason -> persisted broadcast status reason. Exhaustive on purpose:
+ * a new `ChannelErrorReason` fails to compile until it is classified here.
+ * `null` = the reason does not stop a broadcast.
+ */
+const BROADCAST_STATUS_REASON_BY_CHANNEL_REASON: Record<
+ ChannelErrorReason,
+ BroadcastStatusReason | null
+> = {
+ [ChannelErrorReason.ACCOUNT_POLICY_BLOCKED]: "accountPolicyBlocked",
+ [ChannelErrorReason.ACCOUNT_SEND_RESTRICTED]: "accountSendRestricted",
+ [ChannelErrorReason.RATE_LIMITED]: null,
+}
+
+export const resolveBroadcastStatusReason = (
+ reason: ChannelErrorReason,
+): BroadcastStatusReason | null =>
+ BROADCAST_STATUS_REASON_BY_CHANNEL_REASON[reason]
+
+export const truncateStatusErrorMessage = (message: string): string =>
+ message.slice(0, BROADCAST_STATUS_ERROR_MESSAGE_MAX_LENGTH)
+
+/** Spread into a status-changing UPDATE the customer drives (resume, move to draft). */
+export const CLEARED_STATUS_REASON = {
+ statusReason: null,
+ statusErrorMessage: null,
+ statusInboxId: null,
+} as const
diff --git a/packages/business/src/contact-scan/constants.ts b/packages/business/src/contact-scan/constants.ts
index a05460bb8a..530f4101ba 100644
--- a/packages/business/src/contact-scan/constants.ts
+++ b/packages/business/src/contact-scan/constants.ts
@@ -19,6 +19,14 @@ export const CONTACT_SCAN_ETA_MS = 4 * 60 * 60 * 1000
*/
export const CONTACT_SCAN_MAX_ATTEMPTS = 5
+/**
+ * A scan parked on a delayed job (rate limit / high usage) holds no claim. If the
+ * job is lost the sweeper takes it back after this long. It must exceed the
+ * longest wait a scan can ask for (`maxProviderWaitMs`, 30 minutes, in the
+ * worker's `contact-scan/pacing.ts`, which has a test pinning the relation).
+ */
+export const CONTACT_SCAN_RELEASED_GRACE_MS = 35 * 60 * 1000
+
/** `CoexistSyncRun.triggerSource` value written by `ContactScanService.schedule`. */
export const CONTACT_SCAN_TRIGGER_SOURCE = "contact-scan-manual"
@@ -56,7 +64,7 @@ export const CONTACT_SCAN_ERRORS = {
* `bulkImportChannelContacts` threw for the current page. Distinct from
* `pageFailed` (which used to mean "the walk continued past a lost page"):
* this sentinel means the walk STOPPED and handed the run back to the
- * scheduler via `resetForRetry` so the SAME page is retried from the last
+ * scheduler (`retryOrFail`) so the SAME page is retried from the last
* persisted `resumeCursor` — no cursor advance, no contacts skipped.
*/
pageImportFailed: "pageImportFailed",
@@ -64,6 +72,11 @@ export const CONTACT_SCAN_ERRORS = {
channelUnsupported: "channelUnsupported",
/** The walk hit `CONTACT_SCAN_MAX_PAGES` and stopped early as a runaway guard. */
scanLimitReached: "scanLimitReached",
+ /**
+ * The operator cancelled the scan, or its channel was disconnected. Stored as
+ * `partial` + this sentinel; shown as `cancelled` (`resolveContactScanRunStatus`).
+ */
+ cancelled: "cancelled",
} as const
export type ContactScanErrorSentinel =
diff --git a/packages/business/src/contact-scan/index.ts b/packages/business/src/contact-scan/index.ts
index 34750cb6ba..6f17071304 100644
--- a/packages/business/src/contact-scan/index.ts
+++ b/packages/business/src/contact-scan/index.ts
@@ -1,4 +1,5 @@
export * from "./availability"
export * from "./channel-registry"
export * from "./constants"
+export * from "./run-status"
export * from "./service"
diff --git a/packages/business/src/contact-scan/run-status.ts b/packages/business/src/contact-scan/run-status.ts
new file mode 100644
index 0000000000..a835b9c9a0
--- /dev/null
+++ b/packages/business/src/contact-scan/run-status.ts
@@ -0,0 +1,26 @@
+import type { ContactScanRunStatus } from "@chatbotx.io/database/partials"
+import type { CoexistSyncRunModel } from "@chatbotx.io/database/types"
+import { CONTACT_SCAN_ERRORS } from "./constants"
+
+type RunForStatus = Pick
+
+/**
+ * The status a scan run is shown as, in one place for the latest-status view
+ * and the history list so they cannot disagree. A cancelled scan is stored as
+ * `partial` + the cancel sentinel; `waiting` (WhatsApp coexist only) can never
+ * occur on a scan and is treated as still running, like the availability rules.
+ */
+export const resolveContactScanRunStatus = (
+ run: RunForStatus,
+): ContactScanRunStatus => {
+ if (
+ run.status === "partial" &&
+ run.currentError === CONTACT_SCAN_ERRORS.cancelled
+ ) {
+ return "cancelled"
+ }
+ if (run.status === "waiting") {
+ return "running"
+ }
+ return run.status
+}
diff --git a/packages/business/src/contact-scan/service.ts b/packages/business/src/contact-scan/service.ts
index f7b5264fbd..1a7cd6a547 100644
--- a/packages/business/src/contact-scan/service.ts
+++ b/packages/business/src/contact-scan/service.ts
@@ -1,13 +1,18 @@
+import type { DatabaseClient } from "@chatbotx.io/database/client"
+import type { ContactScanRunStatus } from "@chatbotx.io/database/partials"
import {
type CoexistRunProgressInput,
- type CoexistRunStatus,
type CoexistRunWriteGuard,
+ type ContactScanRetryOutcome,
coexistSyncRunRepository,
type IncrementProgressCounters,
type PickedCoexistRun,
} from "@chatbotx.io/database/repositories"
import type { CoexistSyncRunModel } from "@chatbotx.io/database/types"
-import { isContactScanChannel } from "@chatbotx.io/utils/channel"
+import {
+ type ContactScanChannel,
+ isContactScanChannel,
+} from "@chatbotx.io/utils/channel"
import { BaseService } from "../base.service"
import { ChatbotXException } from "../errors"
import { inboxService } from "../inbox/service"
@@ -18,7 +23,13 @@ import {
resolveContactScanAvailability,
} from "./availability"
import { contactScanIntegrationRefs } from "./channel-registry"
-import { CONTACT_SCAN_TRIGGER_SOURCE } from "./constants"
+import {
+ CONTACT_SCAN_ERRORS,
+ CONTACT_SCAN_MAX_ATTEMPTS,
+ CONTACT_SCAN_RELEASED_GRACE_MS,
+ CONTACT_SCAN_TRIGGER_SOURCE,
+} from "./constants"
+import { resolveContactScanRunStatus } from "./run-status"
export type ContactScanScheduleInput = {
workspaceId: string
@@ -30,7 +41,6 @@ export type ContactScanScheduleInput = {
export type ContactScanRunView = Pick<
CoexistSyncRunModel,
| "id"
- | "status"
| "scanFromAt"
| "createdAt"
| "startedAt"
@@ -38,10 +48,10 @@ export type ContactScanRunView = Pick<
| "importedContactCount"
| "currentScan"
| "currentError"
->
+> & { status: ContactScanRunStatus }
export type ContactScanStatusView = {
- status: CoexistRunStatus | "idle"
+ status: ContactScanRunStatus | "idle"
latest: ContactScanRunView | null
availability: ContactScanAvailability
}
@@ -57,7 +67,6 @@ export type ContactScanHistoryItem = Pick<
| "id"
| "workspaceId"
| "channel"
- | "status"
| "scanFromAt"
| "importedContactCount"
| "currentScan"
@@ -66,7 +75,7 @@ export type ContactScanHistoryItem = Pick<
| "createdAt"
| "requestedByUserId"
| "currentError"
->
+> & { status: ContactScanRunStatus }
export type ContactScanHistoryView = {
data: ContactScanHistoryItem[]
@@ -131,7 +140,7 @@ const finishHandlers = {
const toRunView = (run: CoexistSyncRunModel): ContactScanRunView => ({
id: run.id,
- status: run.status,
+ status: resolveContactScanRunStatus(run),
scanFromAt: run.scanFromAt,
createdAt: run.createdAt,
startedAt: run.startedAt,
@@ -145,7 +154,7 @@ const toHistoryItem = (run: CoexistSyncRunModel): ContactScanHistoryItem => ({
id: run.id,
workspaceId: run.workspaceId,
channel: run.channel,
- status: run.status,
+ status: resolveContactScanRunStatus(run),
scanFromAt: run.scanFromAt,
importedContactCount: run.importedContactCount,
currentScan: run.currentScan,
@@ -275,12 +284,62 @@ class ContactScanService extends BaseService {
})
return {
- status: latest?.status ?? "idle",
+ status: latest ? resolveContactScanRunStatus(latest) : "idle",
latest: latest ? toRunView(latest) : null,
availability: resolveContactScanAvailability({ latest, now: new Date() }),
}
}
+ /**
+ * Cancels the inbox's live scan (`init`/`running`) so it stops at its next
+ * write; contacts already imported are kept. Same inbox → integration
+ * resolution as `getStatus`, workspace-scoped. Nothing running (or no such
+ * inbox) is not an error: it returns `cancelled: false`, so the call is safe
+ * to repeat. The cancelled scan still counts toward the 24h cooldown, which
+ * is measured from `createdAt`.
+ */
+ async cancel(input: {
+ workspaceId: string
+ inboxId: string
+ }): Promise<{ cancelled: boolean }> {
+ const { workspaceId, inboxId } = input
+
+ const inbox = await inboxService.findWithIntegrations({
+ where: { id: inboxId, workspaceId },
+ })
+ if (!(inbox && isContactScanChannel(inbox.channel))) {
+ return { cancelled: false }
+ }
+ const integrationRef = contactScanIntegrationRefs[inbox.channel](inbox)
+ if (!integrationRef) {
+ return { cancelled: false }
+ }
+
+ const cancelledRuns =
+ await coexistSyncRunRepository.cancelActiveContactScanRuns({
+ channel: inbox.channel,
+ integrationId: integrationRef.integrationId,
+ workspaceId,
+ currentError: CONTACT_SCAN_ERRORS.cancelled,
+ })
+ return { cancelled: cancelledRuns > 0 }
+ }
+
+ /**
+ * Ends the live scan of an integration that is being disconnected, inside the
+ * caller's transaction, so no scan is left walking a channel that is gone.
+ */
+ async cancelForIntegration(input: {
+ channel: ContactScanChannel
+ integrationId: string
+ tx: DatabaseClient
+ }): Promise {
+ await coexistSyncRunRepository.cancelActiveContactScanRuns({
+ ...input,
+ currentError: CONTACT_SCAN_ERRORS.cancelled,
+ })
+ }
+
/** Scheduler pick — always `type: "contact_scan"`, never passed by the caller. */
pickDue(input: {
batchSize: number
@@ -289,6 +348,7 @@ class ContactScanService extends BaseService {
return coexistSyncRunRepository.pickDueRuns({
...input,
type: "contact_scan",
+ releasedGraceMs: CONTACT_SCAN_RELEASED_GRACE_MS,
})
}
@@ -308,6 +368,7 @@ class ContactScanService extends BaseService {
yieldForContinuation(input: {
runId: string
expect: CoexistRunWriteGuard
+ attempts?: number
}): Promise {
return coexistSyncRunRepository.yieldForContinuation(input)
}
@@ -362,24 +423,22 @@ class ContactScanService extends BaseService {
}
/**
- * Hands a run back to the scheduler after a TRANSIENT failure: `init` with
- * a fresh heartbeat, `currentError` set to the classified sentinel.
- * `claimToken` is deliberately untouched — see `coexist/service.ts`'s
- * `resetForRetry` for why nulling it here would be unnecessary (a fresh
- * claim mints its own token regardless of the stale one).
+ * Hands a run back after a TRANSIENT failure (network, 5xx): `init` for the
+ * sweeper while attempts remain, `failed` immediately on the last one.
+ *
+ * @returns `null` when the `expect` guard did not hold.
*/
- resetForRetry(input: {
+ retryOrFail(input: {
runId: string
- currentError: string
- expect?: CoexistRunWriteGuard
- }): Promise {
- return coexistSyncRunRepository.updateProgress({
+ expect: CoexistRunWriteGuard
+ /** The sentinel shown while it waits for the retry; defaults to a provider failure. */
+ retryError?: string
+ }): Promise {
+ return coexistSyncRunRepository.retryOrFailContactScanRun({
runId: input.runId,
- fields: {
- status: "init",
- currentError: input.currentError,
- lastHeartbeatAt: new Date(),
- },
+ maxAttempts: CONTACT_SCAN_MAX_ATTEMPTS,
+ retryError: input.retryError ?? CONTACT_SCAN_ERRORS.providerRetryable,
+ exhaustedError: CONTACT_SCAN_ERRORS.maxAttempts,
expect: input.expect,
})
}
diff --git a/packages/business/src/message/create-outgoing.ts b/packages/business/src/message/create-outgoing.ts
index 78600db97c..9816ffc921 100644
--- a/packages/business/src/message/create-outgoing.ts
+++ b/packages/business/src/message/create-outgoing.ts
@@ -1,3 +1,4 @@
+import { REPLY_TARGET_CREATED_AT_KEY } from "@chatbotx.io/database/partials"
import {
createMessageRepository,
flowRepository,
@@ -6,6 +7,7 @@ import {
import type {
ContactInboxModel,
ConversationModel,
+ MessageModel,
UserModel,
} from "@chatbotx.io/database/types"
import {
@@ -16,6 +18,10 @@ import {
uploadMultipleFiles,
} from "@chatbotx.io/filesystem"
import type { SendProductsContent } from "@chatbotx.io/flow-config"
+import {
+ RealtimeEventType,
+ routeForConversation,
+} from "@chatbotx.io/realtime-protocol"
import type { MessageButtonTemplate } from "@chatbotx.io/sdk"
import { createId } from "@chatbotx.io/utils"
import { channelTypes } from "@chatbotx.io/utils/channel"
@@ -40,7 +46,10 @@ import {
validationException,
} from "../errors"
import { logger } from "../logger"
-import { queueMessageCreatedEvent } from "../platform/realtime-broadcast"
+import {
+ queueMessageCreatedEvent,
+ queueWorkspaceRealtimeEvent,
+} from "../platform/realtime-broadcast"
import { resolveTenantSettings } from "../platform/settings"
import { productMessageService } from "../product-message/service"
import { getPublicFileUrl } from "../utils"
@@ -227,6 +236,62 @@ const withBypassThreadControlLock = (
}
}
+const ENQUEUE_FAILED_SEND_ERROR = "Could not queue the message for delivery"
+
+/**
+ * The row exists and `messageCreated` has already gone to every open tab, so a
+ * failed enqueue must leave the failed state on the row and tell those tabs,
+ * or they would show a message that is neither sent nor marked failed (and that
+ * cannot be resent). Bookkeeping only: it never replaces the enqueue error.
+ */
+const recordEnqueueFailure = async (input: {
+ repository: Awaited>
+ message: Pick
+ conversation: ConversationModel
+ clientId: string | undefined
+}): Promise => {
+ const { repository, message, conversation, clientId } = input
+ try {
+ await repository.updateSendError(
+ message.id,
+ ENQUEUE_FAILED_SEND_ERROR,
+ message.workspaceId,
+ message.createdAt,
+ )
+ await queueWorkspaceRealtimeEvent(message.workspaceId, {
+ eventType: RealtimeEventType.messageFailed,
+ data: {
+ messageId: message.id,
+ clientId,
+ error: ENQUEUE_FAILED_SEND_ERROR,
+ },
+ route: routeForConversation(conversation),
+ })
+ } catch (err) {
+ logger.error(
+ { err, messageId: message.id, workspaceId: message.workspaceId },
+ "Failed to record an enqueue failure on the outgoing message",
+ )
+ }
+}
+
+/**
+ * A private reply answers a comment stored in the commenter's own conversation,
+ * and the row keeps only that comment's id. Its createdAt (the shard key needed
+ * to find it again) is kept here so a failed private reply can be resent.
+ */
+const withReplyTargetCreatedAt = (
+ contentAttributes: Record | null,
+ isPrivateReply: boolean | undefined,
+ replyToMessageCreatedAt: Date | undefined,
+): Record | null =>
+ isPrivateReply && replyToMessageCreatedAt
+ ? {
+ ...contentAttributes,
+ [REPLY_TARGET_CREATED_AT_KEY]: replyToMessageCreatedAt.toISOString(),
+ }
+ : contentAttributes
+
export const createOutgoing = async (props: {
conversation: ConversationModel
contactInbox: ContactInboxModel
@@ -374,11 +439,15 @@ export const createOutgoing = async (props: {
? ("comment" as const)
: ("message" as const),
parentId,
- contentAttributes: withBypassThreadControlLock(
- productMessage?.contentAttributes ??
- parsedInput.contentAttributes ??
- (parsedInput.isPrivateReply ? { isPrivateReply: true } : null),
- parsedInput.bypassThreadControlLock,
+ contentAttributes: withReplyTargetCreatedAt(
+ withBypassThreadControlLock(
+ productMessage?.contentAttributes ??
+ parsedInput.contentAttributes ??
+ (parsedInput.isPrivateReply ? { isPrivateReply: true } : null),
+ parsedInput.bypassThreadControlLock,
+ ),
+ parsedInput.isPrivateReply,
+ parsedInput.replyToMessageCreatedAt,
),
}
@@ -497,6 +566,12 @@ export const createOutgoing = async (props: {
// actually delivers it to the channel failed, the caller must see an
// error instead of a false "sent" success — the row stays for retry.
if (sendChannelMessageError !== undefined) {
+ await recordEnqueueFailure({
+ repository,
+ message,
+ conversation: targetConversation,
+ clientId: parsedInput.clientId,
+ })
throw sendChannelMessageError
}
diff --git a/packages/business/src/message/resend-outgoing.ts b/packages/business/src/message/resend-outgoing.ts
new file mode 100644
index 0000000000..7a20ae5dfc
--- /dev/null
+++ b/packages/business/src/message/resend-outgoing.ts
@@ -0,0 +1,136 @@
+import {
+ isResendableMessage,
+ REPLY_TARGET_CREATED_AT_KEY,
+} from "@chatbotx.io/database/partials"
+import { createMessageRepository } from "@chatbotx.io/database/repositories"
+import type { MessageModel } from "@chatbotx.io/database/types"
+import { ChatJobAction, chatQueue } from "@chatbotx.io/worker-config"
+import { contactInboxService } from "../contact-inbox/service"
+import { conversationService } from "../conversation/service"
+import { conflictException, notFoundException } from "../errors"
+import { logger } from "../logger"
+import { resolveTenantSettings } from "../platform/settings"
+import { getPublicFileUrl } from "../utils"
+
+const NOT_RESENDABLE_CODE = "messageNotResendable"
+
+const readReplyTargetCreatedAt = (
+ contentAttributes: MessageModel["contentAttributes"],
+): Date | null => {
+ const value = contentAttributes?.[REPLY_TARGET_CREATED_AT_KEY]
+ if (typeof value !== "string") {
+ return null
+ }
+ const date = new Date(value)
+ return Number.isNaN(date.getTime()) ? null : date
+}
+
+/**
+ * Re-queues a failed outgoing message for delivery, whole (no record is kept of
+ * which part reached the customer). Safe against a double click: the failed
+ * state is claimed by one conditional UPDATE, so only the winner enqueues.
+ */
+export const resendOutgoing = async (props: {
+ workspaceId: string
+ conversationId: string
+ messageId: string
+ createdAt: Date
+}): Promise<{ id: string; queued: true }> => {
+ const { workspaceId, conversationId, messageId, createdAt } = props
+ const repository = await createMessageRepository()
+
+ const message = await repository.findById({
+ id: messageId,
+ createdAt,
+ workspaceId,
+ conversationId,
+ })
+ if (!message) {
+ throw notFoundException("Message not found")
+ }
+ if (!isResendableMessage(message)) {
+ throw conflictException(
+ "This message cannot be resent",
+ NOT_RESENDABLE_CODE,
+ )
+ }
+
+ const conversation = await conversationService.findByOrFail({
+ where: { id: conversationId, workspaceId },
+ })
+ const contactInbox = message.contactInboxId
+ ? await contactInboxService.findByIdForWorkspace({
+ id: message.contactInboxId,
+ workspaceId,
+ })
+ : null
+ if (!contactInbox) {
+ throw notFoundException("Contact inbox not found")
+ }
+
+ // Everything that can throw is done before the claim, so a failure here
+ // never leaves the message claimed (no error, no job) with no way back.
+ // The worker finds the comment a private reply answers by its id and
+ // createdAt; `createOutgoing` kept the createdAt on the row.
+ let parentCreatedAt: Date | null = null
+ if (message.parentId) {
+ parentCreatedAt = readReplyTargetCreatedAt(message.contentAttributes)
+ if (!parentCreatedAt) {
+ throw conflictException(
+ "The comment this message replies to is no longer available",
+ NOT_RESENDABLE_CODE,
+ )
+ }
+ }
+
+ const { storageUrl } = await resolveTenantSettings({ workspaceId })
+ const messageWithAttachments = {
+ ...message,
+ attachments: message.attachments.map((attachment) => ({
+ ...attachment,
+ url: getPublicFileUrl(attachment.originPath, storageUrl),
+ })),
+ }
+
+ const claimed = await repository.claimForResend({
+ id: message.id,
+ workspaceId,
+ createdAt: message.createdAt,
+ })
+ if (!claimed) {
+ throw conflictException(
+ "This message is already being resent",
+ NOT_RESENDABLE_CODE,
+ )
+ }
+
+ try {
+ await chatQueue.add(ChatJobAction.sendChannelMessage, {
+ type: ChatJobAction.sendChannelMessage,
+ data: {
+ conversation,
+ contactInbox,
+ message: { ...messageWithAttachments, parentCreatedAt },
+ sendFrom: "inbox",
+ },
+ })
+ } catch (error) {
+ // Put the failed state back so the message can be tried again.
+ await repository
+ .updateSendError(
+ message.id,
+ message.sendError,
+ workspaceId,
+ message.createdAt,
+ )
+ .catch((restoreError: unknown) => {
+ logger.error(
+ { err: restoreError, messageId: message.id, workspaceId },
+ "Failed to restore sendError after a resend enqueue failure",
+ )
+ })
+ throw error
+ }
+
+ return { id: message.id, queued: true }
+}
diff --git a/packages/business/src/message/service.ts b/packages/business/src/message/service.ts
index 330f3e3a8a..79d0a119b7 100644
--- a/packages/business/src/message/service.ts
+++ b/packages/business/src/message/service.ts
@@ -19,6 +19,7 @@ import {
listForConversation,
withResolvedAttachmentUrls,
} from "./list-for-conversation"
+import { resendOutgoing } from "./resend-outgoing"
type FindByProps = {
conversationId: string
@@ -28,6 +29,7 @@ type FindByProps = {
class MessageService extends BaseService {
createOutgoing = createOutgoing
+ resendOutgoing = resendOutgoing
listForConversation = listForConversation
findForContact = findForContact
findByIdWithUrls = findByIdWithUrls
diff --git a/packages/connections/__tests__/messenger-teardown.test.ts b/packages/connections/__tests__/messenger-teardown.test.ts
index f8dfc67adf..3817754fa6 100644
--- a/packages/connections/__tests__/messenger-teardown.test.ts
+++ b/packages/connections/__tests__/messenger-teardown.test.ts
@@ -10,12 +10,14 @@ const mocks = vi.hoisted(() => ({
serviceDisconnect: vi.fn(),
subscribePageToAppWebhook: vi.fn(),
tearDownForIntegration: vi.fn(),
+ cancelScanForIntegration: vi.fn(),
transaction: vi.fn(),
tx: { marker: "tx" },
}))
vi.mock("@chatbotx.io/business", () => ({
coexistService: { tearDownForIntegration: mocks.tearDownForIntegration },
+ contactScanService: { cancelForIntegration: mocks.cancelScanForIntegration },
instagramIntegrationService: { existsForPage: mocks.existsForPage },
messengerIntegrationService: {
disconnect: mocks.serviceDisconnect,
@@ -75,6 +77,7 @@ describe("disconnectMessengerConnection", () => {
mocks.isDisconnectSafeError.mockReturnValue(false)
mocks.remoteDisconnect.mockResolvedValue(undefined)
mocks.tearDownForIntegration.mockResolvedValue(undefined)
+ mocks.cancelScanForIntegration.mockResolvedValue(undefined)
mocks.deleteByIntegration.mockResolvedValue(undefined)
mocks.serviceDisconnect.mockResolvedValue(undefined)
mocks.disconnectInbox.mockResolvedValue(undefined)
@@ -96,6 +99,11 @@ describe("disconnectMessengerConnection", () => {
currentError: "Integration disconnected",
tx: mocks.tx,
})
+ expect(mocks.cancelScanForIntegration).toHaveBeenCalledWith({
+ channel: "messenger",
+ integrationId: BASE_INPUT.integrationId,
+ tx: mocks.tx,
+ })
expect(mocks.deleteByIntegration).toHaveBeenCalledWith(
{
workspaceId: BASE_INPUT.workspaceId,
diff --git a/packages/connections/src/messenger-teardown.ts b/packages/connections/src/messenger-teardown.ts
index 48168cdd87..07d169a170 100644
--- a/packages/connections/src/messenger-teardown.ts
+++ b/packages/connections/src/messenger-teardown.ts
@@ -1,5 +1,6 @@
import {
coexistService,
+ contactScanService,
instagramIntegrationService,
messengerIntegrationService,
} from "@chatbotx.io/business"
@@ -139,6 +140,11 @@ const tearDownMessengerConnection = async (input: {
currentError: "Integration disconnected",
tx,
})
+ await contactScanService.cancelForIntegration({
+ channel: "messenger",
+ integrationId,
+ tx,
+ })
await metaCapiEventRepository.deleteByIntegration(
{ workspaceId, channel: "messenger", integrationId },
diff --git a/packages/database/__tests__/coexist-sync-run-type-scoping.test.ts b/packages/database/__tests__/coexist-sync-run-type-scoping.test.ts
index 2c6e0cda6c..0f3077d286 100644
--- a/packages/database/__tests__/coexist-sync-run-type-scoping.test.ts
+++ b/packages/database/__tests__/coexist-sync-run-type-scoping.test.ts
@@ -244,6 +244,38 @@ describe("CoexistSyncRun type-discriminator scoping", () => {
expect(bound).toContain("coexist")
})
+ test("pickDueRuns has no released-claim clause unless a grace is passed (coexist unchanged)", async () => {
+ const execute = vi.fn().mockResolvedValue({ rows: [] })
+ const repository = new CoexistSyncRunRepository()
+
+ await repository.pickDueRuns({
+ type: "coexist",
+ batchSize: 10,
+ maxAttempts: 5,
+ tx: { execute } as never,
+ })
+
+ const query = execute.mock.calls[0]?.[0] as { text: string }
+ expect(JSON.stringify(query)).not.toContain("claimToken")
+ })
+
+ test("pickDueRuns binds a released-claim grace as seconds, never inline", async () => {
+ const execute = vi.fn().mockResolvedValue({ rows: [] })
+ const repository = new CoexistSyncRunRepository()
+
+ await repository.pickDueRuns({
+ type: "contact_scan",
+ batchSize: 10,
+ maxAttempts: 5,
+ releasedGraceMs: 35 * 60 * 1000,
+ tx: { execute } as never,
+ })
+
+ const serialized = JSON.stringify(execute.mock.calls[0]?.[0])
+ expect(serialized).toContain("claimToken")
+ expect(serialized).toContain("2100")
+ })
+
// --- WhatsApp "belt" recovery selectors: raw SQL, type scoped -----------
// All three emit `r.type = 'coexist'` as an inline SQL literal (unlike
// `pickDueRuns`'s `type`, which is a bound parameter), so the filter is
diff --git a/packages/database/__tests__/integration/contact-scan-cancel.test.ts b/packages/database/__tests__/integration/contact-scan-cancel.test.ts
new file mode 100644
index 0000000000..68c9240c97
--- /dev/null
+++ b/packages/database/__tests__/integration/contact-scan-cancel.test.ts
@@ -0,0 +1,196 @@
+// @vitest-environment node
+
+/**
+ * `cancelActiveContactScanRuns` against a real Postgres: a live scan on the
+ * integration is ended as `partial` + the caller's sentinel, while settled
+ * scans, other integrations, other workspaces and `coexist` rows are untouched.
+ * Skipped unless `DATABASE_URL` is reachable; run with
+ * `pnpm --filter @chatbotx.io/database test:db`.
+ */
+
+import { createId } from "@chatbotx.io/utils"
+import { eq } from "drizzle-orm"
+import { afterAll, describe, expect, test } from "vitest"
+import { realDatabaseUrl } from "./database-url"
+
+const databaseUrl = realDatabaseUrl()
+
+describe.skipIf(!databaseUrl)("cancelActiveContactScanRuns", async () => {
+ const { db } = await import("../../src/client")
+ const { coexistSyncRunRepository } = await import(
+ "../../src/repositories/coexist-sync-run/repository"
+ )
+ const { coexistSyncRunModel } = await import("../../src/schema")
+
+ const workspaceId = createId()
+ const otherWorkspaceId = createId()
+ const SENTINEL = "cancelled"
+
+ const readRun = async (id: string) => {
+ const [row] = await db
+ .select({
+ status: coexistSyncRunModel.status,
+ currentError: coexistSyncRunModel.currentError,
+ claimToken: coexistSyncRunModel.claimToken,
+ resumeCursor: coexistSyncRunModel.resumeCursor,
+ finishedAt: coexistSyncRunModel.finishedAt,
+ })
+ .from(coexistSyncRunModel)
+ .where(eq(coexistSyncRunModel.id, id))
+ return row
+ }
+
+ const createScan = async (input: { integrationId: string }) => {
+ const run = await coexistSyncRunRepository.createContactScanRun({
+ workspaceId,
+ integrationId: input.integrationId,
+ channel: "messenger",
+ requestedByUserId: null,
+ scanFromAt: new Date(Date.now() - 3_600_000),
+ triggerSource: "test",
+ })
+ if (!run) {
+ throw new Error("scan not created")
+ }
+ return run.id
+ }
+
+ const cancel = (integrationId: string, scopeWorkspace = true) =>
+ coexistSyncRunRepository.cancelActiveContactScanRuns({
+ channel: "messenger",
+ integrationId,
+ workspaceId: scopeWorkspace ? workspaceId : undefined,
+ currentError: SENTINEL,
+ })
+
+ afterAll(async () => {
+ for (const id of [workspaceId, otherWorkspaceId]) {
+ await db
+ .delete(coexistSyncRunModel)
+ .where(eq(coexistSyncRunModel.workspaceId, id))
+ }
+ })
+
+ test("an init scan is ended as partial with the sentinel", async () => {
+ const integrationId = createId()
+ const runId = await createScan({ integrationId })
+
+ expect(await cancel(integrationId)).toBe(1)
+
+ const row = await readRun(runId)
+ expect(row.status).toBe("partial")
+ expect(row.currentError).toBe(SENTINEL)
+ expect(row.finishedAt).not.toBeNull()
+ })
+
+ test("a running scan loses its claim and cursor so the worker's next write is fenced out", async () => {
+ const integrationId = createId()
+ const runId = await createScan({ integrationId })
+ const claimed = await coexistSyncRunRepository.claimContactScanRun({
+ runId,
+ })
+ await coexistSyncRunRepository.updateProgress({
+ runId,
+ fields: { resumeCursor: "cursor-1" },
+ expect: { status: "running", claimToken: claimed?.claimToken },
+ })
+
+ expect(await cancel(integrationId)).toBe(1)
+
+ const row = await readRun(runId)
+ expect(row.status).toBe("partial")
+ expect(row.claimToken).toBeNull()
+ expect(row.resumeCursor).toBeNull()
+ // The worker still holding the old token writes zero rows.
+ const stale = await coexistSyncRunRepository.updateProgress({
+ runId,
+ fields: { currentStep: "late write" },
+ expect: { status: "running", claimToken: claimed?.claimToken },
+ })
+ expect(stale).toBe(0)
+ })
+
+ test("a released (running, no token) scan between chunks is cancelled too", async () => {
+ const integrationId = createId()
+ const runId = await createScan({ integrationId })
+ const claimed = await coexistSyncRunRepository.claimContactScanRun({
+ runId,
+ })
+ await coexistSyncRunRepository.yieldForContinuation({
+ runId,
+ expect: { status: "running", claimToken: claimed?.claimToken },
+ })
+
+ expect(await cancel(integrationId)).toBe(1)
+ expect((await readRun(runId)).status).toBe("partial")
+ // A continuation job can no longer claim it.
+ expect(
+ await coexistSyncRunRepository.claimContactScanRun({ runId }),
+ ).toBeNull()
+ })
+
+ test("nothing running returns 0, and a settled scan is left alone", async () => {
+ const integrationId = createId()
+ const runId = await createScan({ integrationId })
+ await coexistSyncRunRepository.markSucceeded({ runId })
+
+ expect(await cancel(integrationId)).toBe(0)
+ const row = await readRun(runId)
+ expect(row.status).toBe("succeeded")
+ expect(row.currentError).toBeNull()
+ })
+
+ test("a second cancel is a no-op", async () => {
+ const integrationId = createId()
+ await createScan({ integrationId })
+ expect(await cancel(integrationId)).toBe(1)
+ expect(await cancel(integrationId)).toBe(0)
+ })
+
+ test("another integration and a coexist row are untouched", async () => {
+ const integrationId = createId()
+ const otherIntegrationId = createId()
+ const coexistIntegrationId = createId()
+ const target = await createScan({ integrationId })
+ const otherIntegration = await createScan({
+ integrationId: otherIntegrationId,
+ })
+ const coexist = await coexistSyncRunRepository.createRun({
+ workspaceId,
+ integrationId: coexistIntegrationId,
+ channel: "messenger",
+ triggerSource: "manual",
+ })
+
+ expect(await cancel(integrationId)).toBe(1)
+ expect(await cancel(coexistIntegrationId)).toBe(0)
+
+ expect((await readRun(target)).status).toBe("partial")
+ expect((await readRun(otherIntegration)).status).toBe("init")
+ expect((await readRun(coexist.id)).status).toBe("init")
+ })
+
+ test("another workspace cannot cancel the scan", async () => {
+ const integrationId = createId()
+ const runId = await createScan({ integrationId })
+
+ const cancelled =
+ await coexistSyncRunRepository.cancelActiveContactScanRuns({
+ channel: "messenger",
+ integrationId,
+ workspaceId: otherWorkspaceId,
+ currentError: SENTINEL,
+ })
+
+ expect(cancelled).toBe(0)
+ expect((await readRun(runId)).status).toBe("init")
+ })
+
+ test("without a workspace (disconnect teardown) it still ends the integration's scan", async () => {
+ const integrationId = createId()
+ const runId = await createScan({ integrationId })
+
+ expect(await cancel(integrationId, false)).toBe(1)
+ expect((await readRun(runId)).status).toBe("partial")
+ })
+})
diff --git a/packages/database/__tests__/integration/contact-scan-retry-or-fail.test.ts b/packages/database/__tests__/integration/contact-scan-retry-or-fail.test.ts
new file mode 100644
index 0000000000..fa0216cd85
--- /dev/null
+++ b/packages/database/__tests__/integration/contact-scan-retry-or-fail.test.ts
@@ -0,0 +1,180 @@
+// @vitest-environment node
+
+/**
+ * `retryOrFailContactScanRun` against a real Postgres: one atomic UPDATE that
+ * hands a scan back to the sweeper (`init`) while it has attempts left and fails
+ * it on the spot on the last one. Skipped unless `DATABASE_URL` is reachable.
+ */
+
+import { createId } from "@chatbotx.io/utils"
+import { eq } from "drizzle-orm"
+import { afterAll, describe, expect, test } from "vitest"
+import { realDatabaseUrl } from "./database-url"
+
+const databaseUrl = realDatabaseUrl()
+
+describe.skipIf(!databaseUrl)("retryOrFailContactScanRun", async () => {
+ const { db } = await import("../../src/client")
+ const { coexistSyncRunRepository } = await import(
+ "../../src/repositories/coexist-sync-run/repository"
+ )
+ const { coexistSyncRunModel } = await import("../../src/schema")
+
+ const workspaceId = createId()
+ const MAX_ATTEMPTS = 5
+
+ const claimedScan = async (attempts: number) => {
+ const run = await coexistSyncRunRepository.createContactScanRun({
+ workspaceId,
+ integrationId: createId(),
+ channel: "messenger",
+ requestedByUserId: null,
+ scanFromAt: new Date(Date.now() - 3_600_000),
+ triggerSource: "test",
+ })
+ if (!run) {
+ throw new Error("scan not created")
+ }
+ const claimed = await coexistSyncRunRepository.claimContactScanRun({
+ runId: run.id,
+ })
+ await coexistSyncRunRepository.updateProgress({
+ runId: run.id,
+ fields: { attempts, resumeCursor: "cursor-1" },
+ expect: { status: "running", claimToken: claimed?.claimToken },
+ })
+ return { runId: run.id, claimToken: claimed?.claimToken ?? null }
+ }
+
+ const retryOrFail = (runId: string, claimToken: string | null) =>
+ coexistSyncRunRepository.retryOrFailContactScanRun({
+ runId,
+ maxAttempts: MAX_ATTEMPTS,
+ retryError: "providerRetryable",
+ exhaustedError: "maxAttempts",
+ expect: { status: "running", claimToken },
+ })
+
+ const readRun = async (id: string) => {
+ const [row] = await db
+ .select({
+ status: coexistSyncRunModel.status,
+ currentError: coexistSyncRunModel.currentError,
+ resumeCursor: coexistSyncRunModel.resumeCursor,
+ finishedAt: coexistSyncRunModel.finishedAt,
+ attempts: coexistSyncRunModel.attempts,
+ claimToken: coexistSyncRunModel.claimToken,
+ })
+ .from(coexistSyncRunModel)
+ .where(eq(coexistSyncRunModel.id, id))
+ return row
+ }
+
+ afterAll(async () => {
+ await db
+ .delete(coexistSyncRunModel)
+ .where(eq(coexistSyncRunModel.workspaceId, workspaceId))
+ })
+
+ test("releasing for a wait can reset attempts, so the sweeper cannot fail the idle run", async () => {
+ const { runId, claimToken } = await claimedScan(MAX_ATTEMPTS)
+
+ await coexistSyncRunRepository.yieldForContinuation({
+ runId,
+ expect: { status: "running", claimToken },
+ attempts: 1,
+ })
+
+ const row = await readRun(runId)
+ expect(row.attempts).toBe(1)
+ expect(row.claimToken).toBeNull()
+ expect(row.status).toBe("running")
+ })
+
+ test("releasing without an attempts value leaves the count alone", async () => {
+ const { runId, claimToken } = await claimedScan(3)
+
+ await coexistSyncRunRepository.yieldForContinuation({
+ runId,
+ expect: { status: "running", claimToken },
+ })
+
+ expect((await readRun(runId)).attempts).toBe(3)
+ })
+
+ test("with attempts left it goes back to init and keeps its resume cursor", async () => {
+ const { runId, claimToken } = await claimedScan(MAX_ATTEMPTS - 1)
+
+ expect(await retryOrFail(runId, claimToken)).toBe("retry")
+
+ const row = await readRun(runId)
+ expect(row.status).toBe("init")
+ expect(row.currentError).toBe("providerRetryable")
+ expect(row.resumeCursor).toBe("cursor-1")
+ expect(row.finishedAt).toBeNull()
+ })
+
+ test("on the last attempt it fails immediately and clears the cursor", async () => {
+ const { runId, claimToken } = await claimedScan(MAX_ATTEMPTS)
+
+ expect(await retryOrFail(runId, claimToken)).toBe("failed")
+
+ const row = await readRun(runId)
+ expect(row.status).toBe("failed")
+ expect(row.currentError).toBe("maxAttempts")
+ expect(row.resumeCursor).toBeNull()
+ expect(row.finishedAt).not.toBeNull()
+ })
+
+ // The sweeper's pick (`pickDueRuns`) does `attempts + 1` and sets `init`; it is
+ // replayed here because the real query sweeps every scan in the database.
+ const sweeperPick = async (runId: string) => {
+ const [row] = await db
+ .select({ attempts: coexistSyncRunModel.attempts })
+ .from(coexistSyncRunModel)
+ .where(eq(coexistSyncRunModel.id, runId))
+ await coexistSyncRunRepository.updateProgress({
+ runId,
+ fields: { status: "init", attempts: row.attempts + 1 },
+ })
+ const claimed = await coexistSyncRunRepository.claimContactScanRun({
+ runId,
+ })
+ return claimed?.claimToken ?? null
+ }
+
+ test.each([
+ ["a fresh run", false],
+ ["a run that already finished a page", true],
+ ])("%s fails on exactly the 5th consecutive failure", async (_name, afterFinishedPage) => {
+ // Fresh: the first sweeper pick leaves the claim at attempts = 1.
+ let { runId, claimToken } = await claimedScan(1)
+ if (afterFinishedPage) {
+ // What the engine's progress write does after a completed page.
+ await coexistSyncRunRepository.updateProgress({
+ runId,
+ fields: { attempts: 1 },
+ expect: { status: "running", claimToken },
+ })
+ }
+
+ const outcomes: string[] = []
+ for (let failure = 1; failure <= MAX_ATTEMPTS; failure++) {
+ const outcome = await retryOrFail(runId, claimToken)
+ outcomes.push(String(outcome))
+ if (outcome === "retry") {
+ claimToken = await sweeperPick(runId)
+ }
+ }
+
+ expect(outcomes).toEqual(["retry", "retry", "retry", "retry", "failed"])
+ expect((await readRun(runId)).status).toBe("failed")
+ })
+
+ test("a lost claim (cancelled or taken over) writes nothing", async () => {
+ const { runId } = await claimedScan(1)
+
+ expect(await retryOrFail(runId, "someone-elses-token")).toBeNull()
+ expect((await readRun(runId)).status).toBe("running")
+ })
+})
diff --git a/packages/database/__tests__/message-resendable-partial.test.ts b/packages/database/__tests__/message-resendable-partial.test.ts
new file mode 100644
index 0000000000..10a2609cb5
--- /dev/null
+++ b/packages/database/__tests__/message-resendable-partial.test.ts
@@ -0,0 +1,69 @@
+import { describe, expect, test } from "vitest"
+import {
+ isResendableMessage,
+ type ResendableMessageFields,
+} from "../src/partials/message"
+
+const failed: ResendableMessageFields = {
+ messageType: "outgoing",
+ senderType: "user",
+ type: "message",
+ contentAttributes: null,
+ sendError: "(#10) permission denied",
+ sourceId: null,
+ contactInboxId: "ci-1",
+}
+
+describe("isResendableMessage", () => {
+ test("a failed outgoing message from a person is resendable", () => {
+ expect(isResendableMessage(failed)).toBe(true)
+ })
+
+ test("a row only the browser knows (no contact inbox) is not: nothing exists to resend", () => {
+ expect(isResendableMessage({ ...failed, contactInboxId: "" })).toBe(false)
+ expect(isResendableMessage({ ...failed, contactInboxId: null })).toBe(false)
+ })
+
+ test.each([
+ ["no error", { sendError: null }],
+ ["already delivered", { sourceId: "wamid.1" }],
+ ["sent by a bot", { senderType: "bot" }],
+ ["incoming", { messageType: "incoming" }],
+ ["a public comment reply", { type: "comment" }],
+ ])("%s is not resendable", (_name, override) => {
+ expect(isResendableMessage({ ...failed, ...override })).toBe(false)
+ })
+
+ test("a private reply (a comment delivered as a DM) is resendable", () => {
+ expect(
+ isResendableMessage({
+ ...failed,
+ type: "comment",
+ contentAttributes: { isPrivateReply: true },
+ }),
+ ).toBe(true)
+ })
+
+ test("a reply to a comment is resendable only when the comment's createdAt was kept", () => {
+ const reply = {
+ ...failed,
+ type: "comment",
+ parentId: "comment-1",
+ }
+ expect(
+ isResendableMessage({
+ ...reply,
+ contentAttributes: { isPrivateReply: true },
+ }),
+ ).toBe(false)
+ expect(
+ isResendableMessage({
+ ...reply,
+ contentAttributes: {
+ isPrivateReply: true,
+ replyToMessageCreatedAt: "2026-11-01T00:00:00.000Z",
+ },
+ }),
+ ).toBe(true)
+ })
+})
diff --git a/packages/database/__tests__/sharded-message-repository.test.ts b/packages/database/__tests__/sharded-message-repository.test.ts
index ef65f415d4..32ab2e2092 100644
--- a/packages/database/__tests__/sharded-message-repository.test.ts
+++ b/packages/database/__tests__/sharded-message-repository.test.ts
@@ -1108,6 +1108,87 @@ describe("ShardedMessageRepository.updateSourceId", () => {
})
})
+describe("ShardedMessageRepository.claimForResend", () => {
+ const createdAt = new Date("2026-01-01T00:00:00Z")
+ const rangeShard = makeShardInfo("tr:range", "range")
+
+ function makeClient(rows: unknown[]) {
+ const chain = {
+ set: vi.fn().mockReturnThis(),
+ where: vi.fn().mockReturnThis(),
+ returning: vi.fn().mockResolvedValue(rows),
+ }
+ return { update: vi.fn().mockReturnValue(chain), chain }
+ }
+
+ const repoWith = (client: ReturnType) =>
+ new ShardedMessageRepository({
+ getShardsForTimeRange: vi.fn().mockResolvedValue([rangeShard]),
+ getWriteShardInfo: vi.fn().mockResolvedValue(null),
+ getShardClient: vi.fn(() => Promise.resolve(client)),
+ } as never)
+
+ test("clears sendError only while the row is a failed send the channel never accepted", async () => {
+ const client = makeClient([{ id: "msg-1" }])
+
+ const result = await repoWith(client).claimForResend({
+ id: "msg-1",
+ workspaceId: "ws-1",
+ createdAt,
+ })
+
+ expect(client.chain.set).toHaveBeenCalledWith({ sendError: null })
+ const { sql } = new PgDialect().sqlToQuery(
+ client.chain.where.mock.calls[0][0],
+ )
+ expect(sql).toContain('"sendError" IS NOT NULL')
+ expect(sql).toContain('"sourceId" IS NULL')
+ expect(result).toEqual({ id: "msg-1" })
+ })
+
+ test("is scoped to the workspace and the message's createdAt shard key", async () => {
+ const client = makeClient([{ id: "msg-1" }])
+
+ await repoWith(client).claimForResend({
+ id: "msg-1",
+ workspaceId: "ws-1",
+ createdAt,
+ })
+
+ const { sql, params } = new PgDialect().sqlToQuery(
+ client.chain.where.mock.calls[0][0],
+ )
+ expect(sql).toContain('"workspaceId" = $')
+ expect(sql).toContain('"createdAt" >= $')
+ expect(params).toContain("ws-1")
+ expect(params).toContain("msg-1")
+ })
+
+ test("returns null when no row matched (already claimed, sent, or not failed)", async () => {
+ await expect(
+ repoWith(makeClient([])).claimForResend({
+ id: "msg-1",
+ workspaceId: "ws-1",
+ createdAt,
+ }),
+ ).resolves.toBeNull()
+ })
+
+ test("a shard-level failure is swallowed as not claimed", async () => {
+ const repo = new ShardedMessageRepository({
+ getShardsForTimeRange: vi.fn().mockResolvedValue([rangeShard]),
+ getWriteShardInfo: vi.fn().mockResolvedValue(null),
+ getShardClient: vi
+ .fn()
+ .mockRejectedValue(new Error("connection refused")),
+ } as never)
+
+ await expect(
+ repo.claimForResend({ id: "msg-1", workspaceId: "ws-1", createdAt }),
+ ).resolves.toBeNull()
+ })
+})
+
describe("ShardedMessageRepository.mergeContentAttributesBySourceId", () => {
const rangeShard = makeShardInfo("tr:range", "range")
const writeShard = makeShardInfo("tr:write", "write")
diff --git a/packages/database/drizzle/20261113171821_broadcast_status_reason/migration.sql b/packages/database/drizzle/20261113171821_broadcast_status_reason/migration.sql
new file mode 100644
index 0000000000..54af96b5f2
--- /dev/null
+++ b/packages/database/drizzle/20261113171821_broadcast_status_reason/migration.sql
@@ -0,0 +1,4 @@
+CREATE TYPE "broadcastStatusReason" AS ENUM('accountPolicyBlocked', 'accountSendRestricted');--> statement-breakpoint
+ALTER TABLE "Broadcast" ADD COLUMN "statusReason" "broadcastStatusReason";--> statement-breakpoint
+ALTER TABLE "Broadcast" ADD COLUMN "statusErrorMessage" text;--> statement-breakpoint
+ALTER TABLE "Broadcast" ADD COLUMN "statusInboxId" bigint;
\ No newline at end of file
diff --git a/packages/database/drizzle/20261113171821_broadcast_status_reason/snapshot.json b/packages/database/drizzle/20261113171821_broadcast_status_reason/snapshot.json
new file mode 100644
index 0000000000..f4358be0e2
--- /dev/null
+++ b/packages/database/drizzle/20261113171821_broadcast_status_reason/snapshot.json
@@ -0,0 +1,77911 @@
+{
+ "version": "8",
+ "dialect": "postgres",
+ "id": "81823a40-52ac-4c4f-a12d-516c5582a1cb",
+ "prevIds": [
+ "92eba09c-e001-4035-99bf-7445ad765ab8",
+ "b73177b2-2f4d-40ef-b2ab-184d0bf661bc"
+ ],
+ "ddl": [
+ {
+ "values": [
+ "pending",
+ "sent",
+ "failed",
+ "skipped_no_scope",
+ "skipped_region"
+ ],
+ "name": "adsConversionCapiStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "automatic",
+ "rule",
+ "trigger"
+ ],
+ "name": "adsConversionEventSource",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "whatsapp",
+ "facebook",
+ "messenger",
+ "instagram"
+ ],
+ "name": "adsConversionChannel",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "lead",
+ "purchase"
+ ],
+ "name": "adsConversionEventType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "success",
+ "error",
+ "processing"
+ ],
+ "name": "aiConversationEmbeddingStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "processing",
+ "success",
+ "error"
+ ],
+ "name": "aiConversationSourceStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "document",
+ "image",
+ "url",
+ "web_search"
+ ],
+ "name": "aiConversationSourceType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "success",
+ "error",
+ "processing"
+ ],
+ "name": "aiEmbeddingStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "enable",
+ "disable"
+ ],
+ "name": "aiHandoverBulkAction",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "running",
+ "cancelling",
+ "completed",
+ "failed",
+ "cancelled"
+ ],
+ "name": "aiHandoverBulkStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "automated_response",
+ "ai_agent",
+ "flow",
+ "none"
+ ],
+ "name": "analyticsBotResponseType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "success",
+ "fallback"
+ ],
+ "name": "analyticsBotResult",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "flow",
+ "agent",
+ "fallback"
+ ],
+ "name": "analyticsBotRouteType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "contact_created",
+ "contact_deleted",
+ "contact_blocked"
+ ],
+ "name": "analyticsContactEventType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "bot",
+ "human"
+ ],
+ "name": "analyticsContactSenderType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "conversation_created",
+ "conversation_assigned",
+ "conversation_unassigned",
+ "conversation_transferred_to_human",
+ "conversation_transferred_to_bot",
+ "conversation_followed",
+ "conversation_unfollowed",
+ "conversation_archived",
+ "conversation_unarchived"
+ ],
+ "name": "analyticsConversationEventType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "message_human_sent",
+ "message_bot_sent"
+ ],
+ "name": "analyticsMessageEventType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "processing",
+ "ingested",
+ "failed"
+ ],
+ "name": "analyticsStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "synced",
+ "failed"
+ ],
+ "name": "appointmentExternalSyncStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "inPerson",
+ "phoneCall",
+ "onlineMeeting"
+ ],
+ "name": "appointmentLocationTypeSnapshot",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "scheduled",
+ "cancelled"
+ ],
+ "name": "appointmentStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "inPerson",
+ "phoneCall",
+ "onlineMeeting"
+ ],
+ "name": "appointmentLocationType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "rollingDays",
+ "dateRange",
+ "specificDay",
+ "anyFutureDate"
+ ],
+ "name": "appointmentScheduleWindowType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "minutes",
+ "hours",
+ "days"
+ ],
+ "name": "appointmentReminderTimingUnit",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "sent",
+ "cancelled",
+ "failed"
+ ],
+ "name": "appointmentReminderDispatchStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "image",
+ "video",
+ "audio",
+ "gif",
+ "file"
+ ],
+ "name": "fileType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "inbound",
+ "outbound"
+ ],
+ "name": "automatedResponseType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "defaultReply"
+ ],
+ "name": "automationThrottleType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "now",
+ "future",
+ "recurring"
+ ],
+ "name": "broadcastScheduleType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "scheduled",
+ "sent",
+ "sending",
+ "cancelled",
+ "draft",
+ "failed",
+ "recurring"
+ ],
+ "name": "broadcastStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "accountPolicyBlocked",
+ "accountSendRestricted"
+ ],
+ "name": "broadcastStatusReason",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "created",
+ "skipped",
+ "missed"
+ ],
+ "name": "broadcastOccurrenceOutcome",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "catchUpSuperseded",
+ "paused",
+ "draft",
+ "blockedOwner",
+ "planLimit",
+ "noTargets",
+ "undeliverable",
+ "excludedDate"
+ ],
+ "name": "broadcastOccurrenceReason",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "whatsapp",
+ "messenger",
+ "instagram"
+ ],
+ "name": "coexistChannel",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "contacts",
+ "messages"
+ ],
+ "name": "coexistMessengerSyncPhase",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "init",
+ "running",
+ "succeeded",
+ "failed",
+ "partial",
+ "waiting"
+ ],
+ "name": "coexistRunStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "coexist",
+ "contact_scan"
+ ],
+ "name": "coexistRunType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "messenger",
+ "instagram",
+ "instagramFacebook",
+ "threads",
+ "tiktok"
+ ],
+ "name": "commentAutomationType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "equal",
+ "contain"
+ ],
+ "name": "commentExcludeKeywordsType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "sent",
+ "failed"
+ ],
+ "name": "commentAutomationEventStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "public",
+ "private"
+ ],
+ "name": "commentAutomationReplyChannel",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "AIAgent",
+ "text",
+ "flow",
+ "none"
+ ],
+ "name": "commentAutomationReplyType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "outsideSchedule",
+ "postNotMatched",
+ "commentIsReply",
+ "keywordsNotMatched",
+ "mentionCountNotMatched",
+ "noImageAttachment",
+ "contactNotNew",
+ "alreadyRepliedOnPost",
+ "engagedOnOtherPost",
+ "moderated"
+ ],
+ "name": "commentAutomationMissReason",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "hide",
+ "delete"
+ ],
+ "name": "commentModerationAction",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "all",
+ "phoneNumber",
+ "link",
+ "keyword",
+ "image",
+ "video",
+ "gif",
+ "emoji"
+ ],
+ "name": "commentModerationRule",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "rule",
+ "ai"
+ ],
+ "name": "commentModerationSource",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "done",
+ "failed"
+ ],
+ "name": "commentModerationStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "male",
+ "female",
+ "unknown"
+ ],
+ "name": "gender",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "flow",
+ "flowNode",
+ "automatedResponse",
+ "whatsappFlow",
+ "emailTopic",
+ "ad"
+ ],
+ "name": "contactActivityReferenceType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "flowExecuted",
+ "flowNodeExecuted",
+ "automatedResponseMatched",
+ "formCompleted",
+ "messageSent",
+ "messageDelivered",
+ "messageOpened",
+ "messageClicked",
+ "adClicked"
+ ],
+ "name": "contactActivityType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "captured",
+ "unavailable",
+ "failed"
+ ],
+ "name": "contactInboxProfileSnapshotState",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "text",
+ "location",
+ "refLink",
+ "image",
+ "video",
+ "audio",
+ "gif",
+ "file",
+ "storyMention",
+ "reel"
+ ],
+ "name": "lastUserInputType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "inboundReceived",
+ "standbyReceived",
+ "controlPassed",
+ "controlTaken",
+ "taken",
+ "released",
+ "passed",
+ "serviceSent",
+ "serviceRejected"
+ ],
+ "name": "threadControlEvent",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "owned",
+ "standby",
+ "idle"
+ ],
+ "name": "threadControlState",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "scheduled",
+ "completed",
+ "failed",
+ "canceled"
+ ],
+ "name": "ContactOnSmartDelayStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "waitNode",
+ "followUp",
+ "quickReplyFollowUp",
+ "stepInputTimeout"
+ ],
+ "name": "ContactOnSmartDelayType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "active",
+ "archived"
+ ],
+ "name": "couponTopicStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "shortText",
+ "email",
+ "phoneNumber",
+ "number",
+ "date",
+ "datetime",
+ "boolean",
+ "longText"
+ ],
+ "name": "customFieldType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "enabled",
+ "disabled"
+ ],
+ "name": "DecisionConnectionStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "passed",
+ "failed"
+ ],
+ "name": "DecisionConnectionTestStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "typesafe",
+ "systemOneCompatible",
+ "openrouterDecision"
+ ],
+ "name": "DecisionProviderKind",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "enabled",
+ "disabled"
+ ],
+ "name": "DecisionProfileStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "entireOrder",
+ "category",
+ "products"
+ ],
+ "name": "discountAppliesTo",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "everyone",
+ "specificCustomers"
+ ],
+ "name": "discountEligibility",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "none",
+ "amount",
+ "quantity"
+ ],
+ "name": "discountMinimumType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "percentage",
+ "fixedAmount",
+ "freeShipping"
+ ],
+ "name": "discountType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "stripe",
+ "paypal"
+ ],
+ "name": "onlinePaymentProvider",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "open",
+ "paid",
+ "expired",
+ "refunded"
+ ],
+ "name": "orderPaymentStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "default",
+ "externalLink",
+ "flow",
+ "productPage"
+ ],
+ "name": "checkoutMode",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "left",
+ "leftSpace",
+ "right",
+ "rightSpace"
+ ],
+ "name": "currencyPosition",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "default",
+ "flow",
+ "none"
+ ],
+ "name": "orderConfirmationMode",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "bigSquare",
+ "mediumRectangle"
+ ],
+ "name": "productImageSize",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "none",
+ "delivery",
+ "pickup",
+ "deliveryAndPickup"
+ ],
+ "name": "shippingMode",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "list",
+ "listWithoutImage",
+ "card",
+ "cardSquare",
+ "image",
+ "imageSquare"
+ ],
+ "name": "webshopProductView",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "set",
+ "cleared"
+ ],
+ "name": "tenantDefaultTemplateAction",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "import",
+ "generic",
+ "export"
+ ],
+ "name": "fileContextType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "uploaded",
+ "failed"
+ ],
+ "name": "fileStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "tag",
+ "flow",
+ "customField",
+ "automatedResponse",
+ "trigger",
+ "webhook",
+ "sequence",
+ "emailTopic",
+ "fbComment",
+ "igComment",
+ "igStory",
+ "outboundAutomatedResponse"
+ ],
+ "name": "folderType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "gclid",
+ "gbraid"
+ ],
+ "name": "googleAdsClickIdType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "flowStep",
+ "triggerAction"
+ ],
+ "name": "googleAdsEventSource",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "sending",
+ "sent",
+ "processed",
+ "failed",
+ "skipped_no_account",
+ "skipped_expired"
+ ],
+ "name": "googleAdsEventStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "delivery",
+ "processing",
+ "timeout"
+ ],
+ "name": "googleAdsFailureStage",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "processing",
+ "success",
+ "partial_success",
+ "failed",
+ "unknown",
+ "timed_out"
+ ],
+ "name": "googleAdsProcessingStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "storyReply",
+ "storyMention"
+ ],
+ "name": "igStoryAutomationTrigger",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "instagram",
+ "instagramFacebook"
+ ],
+ "name": "igStoryAutomationType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "csv",
+ "xlsx",
+ "xls",
+ "json"
+ ],
+ "name": "importFormat",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "processing",
+ "completed",
+ "failed"
+ ],
+ "name": "importStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "contacts",
+ "coupons",
+ "products",
+ "flow"
+ ],
+ "name": "importType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "received",
+ "processing",
+ "processed",
+ "completedWithErrors",
+ "skipped",
+ "failed"
+ ],
+ "name": "inboundWebhookRequestStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "oauth",
+ "fbe"
+ ],
+ "name": "metaCatalogAuthMode",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "active",
+ "invalid"
+ ],
+ "name": "metaCatalogConnectionStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "idle",
+ "queued",
+ "running",
+ "succeeded",
+ "partial",
+ "failed"
+ ],
+ "name": "metaCatalogImportStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "token",
+ "clientCredentials"
+ ],
+ "name": "shopifyAuthKind",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "metaNative",
+ "browserWhisper"
+ ],
+ "name": "whatsappCallRecordingMode",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "metaNative",
+ "browserWhisper"
+ ],
+ "name": "whatsappCallTranscriptionMode",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending_verification",
+ "registered",
+ "failed"
+ ],
+ "name": "whatsappRegistrationStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "messenger",
+ "instagram",
+ "whatsapp",
+ "zalo",
+ "telegram",
+ "tiktok",
+ "threads",
+ "email",
+ "gamification"
+ ],
+ "name": "leaderboardPlatform",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "draft",
+ "active",
+ "paused",
+ "finished"
+ ],
+ "name": "leaderboardStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "adjust",
+ "resetOne",
+ "resetAll",
+ "ban",
+ "unban"
+ ],
+ "name": "leaderboardAuditAction",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "rule",
+ "flow",
+ "referral",
+ "manual",
+ "reset"
+ ],
+ "name": "leaderboardScoreSource",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "text",
+ "location",
+ "refLink"
+ ],
+ "name": "contentType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "message",
+ "comment"
+ ],
+ "name": "messageKind",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "incoming",
+ "outgoing",
+ "activity"
+ ],
+ "name": "messageType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "bot",
+ "contact",
+ "system",
+ "user",
+ "api"
+ ],
+ "name": "senderType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "processing",
+ "completed",
+ "failed"
+ ],
+ "name": "MessageCleanupStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "whatsapp",
+ "messenger",
+ "instagram"
+ ],
+ "name": "messagingAdChannel",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "campaignCreated",
+ "adSetCreated",
+ "creativeCreated",
+ "adCreated",
+ "failed"
+ ],
+ "name": "messagingAdCreateState",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "draft",
+ "publishing",
+ "published",
+ "pausing",
+ "paused",
+ "deleting",
+ "deleted",
+ "publishFailed"
+ ],
+ "name": "messagingAdPublishState",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "push",
+ "import"
+ ],
+ "name": "metaCatalogItemDirection",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "all",
+ "category",
+ "selected"
+ ],
+ "name": "metaCatalogSyncScope",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "queued",
+ "running",
+ "succeeded",
+ "partial",
+ "failed"
+ ],
+ "name": "metaCatalogSyncStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "web"
+ ],
+ "name": "miniAppSubmissionSource",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "submitted"
+ ],
+ "name": "miniAppUploadStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "luckyWheel",
+ "jackpot",
+ "gashapon",
+ "drawLots",
+ "scratchOff"
+ ],
+ "name": "minigameType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "unfulfilled",
+ "partial",
+ "fulfilled"
+ ],
+ "name": "fulfillmentStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "user",
+ "apiToken",
+ "system",
+ "contact"
+ ],
+ "name": "orderActorType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "webshop",
+ "api",
+ "manual",
+ "shopify",
+ "woocommerce"
+ ],
+ "name": "orderSource",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "accepted",
+ "shipped",
+ "concluded",
+ "cancelled"
+ ],
+ "name": "orderStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "cod",
+ "stripe",
+ "paypal"
+ ],
+ "name": "paymentMethod",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "unpaid",
+ "paid",
+ "refunded"
+ ],
+ "name": "paymentStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "delivery",
+ "pickup"
+ ],
+ "name": "shippingType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "created",
+ "stageChanged",
+ "statusChanged",
+ "valueChanged",
+ "priorityChanged",
+ "dueDateChanged",
+ "titleChanged",
+ "descriptionChanged",
+ "fieldValuesChanged",
+ "assigneesChanged",
+ "attachmentAdded",
+ "attachmentRemoved",
+ "commentAdded",
+ "commentDeleted",
+ "transferred",
+ "deleted"
+ ],
+ "name": "pipelineActivityKind",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "user",
+ "workspaceToken",
+ "flow",
+ "trigger",
+ "system"
+ ],
+ "name": "pipelineActorKind",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "low",
+ "medium",
+ "high"
+ ],
+ "name": "pipelineItemPriority",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "open",
+ "won",
+ "lost"
+ ],
+ "name": "pipelineItemStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "opportunity",
+ "ticket",
+ "custom"
+ ],
+ "name": "pipelineType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "dont_track",
+ "track"
+ ],
+ "name": "inventoryPolicy",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "active",
+ "draft",
+ "unlisted"
+ ],
+ "name": "productStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "text",
+ "number",
+ "email",
+ "phone",
+ "multipleChoice",
+ "date",
+ "datetime",
+ "image",
+ "file",
+ "location",
+ "websiteLink"
+ ],
+ "name": "questionnaireQuestionType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "inProgress",
+ "completed",
+ "cancelled",
+ "failed",
+ "timeout"
+ ],
+ "name": "questionnaireSubmissionStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "refLink",
+ "qrCode"
+ ],
+ "name": "ReflinkType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "workspace",
+ "channel",
+ "user"
+ ],
+ "name": "resourceDeletionResourceType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "completed",
+ "canceled"
+ ],
+ "name": "resourceDeletionStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "webCheckout",
+ "inApp"
+ ],
+ "name": "externalCheckoutMethod",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "active",
+ "invalid"
+ ],
+ "name": "externalStoreConnectionStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "idle",
+ "queued",
+ "running",
+ "succeeded",
+ "failed"
+ ],
+ "name": "externalStoreSyncStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "chatbotx",
+ "shopify",
+ "woocommerce"
+ ],
+ "name": "storeSource",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "me"
+ ],
+ "name": "SystemFieldType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "creator",
+ "administrator",
+ "member",
+ "restricted",
+ "left",
+ "kicked"
+ ],
+ "name": "telegramBotChatStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "private",
+ "group",
+ "supergroup",
+ "channel"
+ ],
+ "name": "telegramChatType",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "manual",
+ "tenantDefault"
+ ],
+ "name": "templateInstallSource",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "installing",
+ "completed",
+ "partial",
+ "failed",
+ "uninstalled"
+ ],
+ "name": "templateInstallationStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "none",
+ "pending",
+ "running",
+ "done",
+ "partial",
+ "failed",
+ "skipped"
+ ],
+ "name": "templateUninstallState",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "pending",
+ "running",
+ "completed",
+ "partial",
+ "failed",
+ "skipped",
+ "cancelled"
+ ],
+ "name": "templateSyncStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "autoUpdate",
+ "manual",
+ "reinstall"
+ ],
+ "name": "templateSyncTrigger",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "flows",
+ "products",
+ "aiFunctions",
+ "aiAgents",
+ "calendars",
+ "webchats",
+ "keywords",
+ "entryPointLinks",
+ "triggers",
+ "fbCommentAutomations",
+ "settings",
+ "sequences",
+ "aiMcpServers",
+ "aiFiles",
+ "questionnaires",
+ "couponTopics",
+ "pipelines",
+ "customFields",
+ "tags",
+ "productCategories"
+ ],
+ "name": "templateResourceCategory",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "none",
+ "pending",
+ "running",
+ "done",
+ "partial",
+ "failed",
+ "skipped"
+ ],
+ "name": "templateUninstallOperationState",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "ios",
+ "android"
+ ],
+ "name": "devicePlatform",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "userInitiated",
+ "businessInitiated"
+ ],
+ "name": "whatsappCallDirection",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "completed",
+ "failed",
+ "rejected",
+ "canceled"
+ ],
+ "name": "whatsappCallOutcome",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "ringing",
+ "accepted",
+ "rejected",
+ "completed",
+ "failed"
+ ],
+ "name": "whatsappCallStatus",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "accept",
+ "reject"
+ ],
+ "name": "whatsappCallPermissionResponse",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "allTime",
+ "oncePerHour",
+ "oncePerDay"
+ ],
+ "name": "defaultReplyFrequency",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "full",
+ "read_only"
+ ],
+ "name": "WorkspaceApiTokenPermission",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "values": [
+ "owner",
+ "agent"
+ ],
+ "name": "workspaceMemberRole",
+ "entityType": "enums",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MessageShard",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ShardTimeRange",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AdsConversionEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AdsConversionRule",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIAgent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIConversationEmbedding",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIConversationSource",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIEmbedding",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIFile",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIFunction",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIHandoverBulkRun",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIHandoverSettings",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AIMCPServer",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AnalyticsAgentResponseEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AnalyticsBotMessageEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AnalyticsContactEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AnalyticsConversationEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AnalyticsMessageEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AnalyticsEmailTopic",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AnalyticsManifestStatus",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Appointment",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AppointmentCalendar",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AppointmentCalendarAvailability",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AppointmentCalendarReminder",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AppointmentReminderDispatch",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Attachment",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Account",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Invitation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Jwk",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Session",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "User",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Verification",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AutomatedResponse",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AutomationThrottle",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "BotField",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Broadcast",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "BroadcastRecurrence",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "BroadcastRecurrenceOccurrence",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "BroadcastTarget",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Cart",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ChannelPost",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CoexistSyncRun",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CommentAutomation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CommentAutomationEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CommentAutomationMiss",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CommentAutomationReply",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CommentModerationLog",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ConnectSession",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Connection",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Contact",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactActiveHourly",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactActiveMonthly",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactActivity",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactCustomField",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactInbox",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactInboxPost",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactKeywordMessage",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactNote",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactOnBroadcast",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactOnSequence",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactOnSmartDelay",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactReferralEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactState",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactToTag",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ContactToTagChannel",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Conversation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ConversationParticipant",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Coupon",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CouponTopic",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CustomField",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "DecisionConnection",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "DecisionProfile",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "DiscountCode",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "DynamicImage",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "EcommerceOpenHours",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "EcommercePaymentProvider",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OrderPayment",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "EcommerceOrderCounter",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "EcommerceSettings",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "EmailTopic",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "AuditLog",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "CustomDomain",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "License",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PlatformAdmin",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Tenant",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TenantDefaultTemplate",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TenantDefaultTemplateEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TenantHelpItem",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "UserQuota",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkspaceUsage",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ErrorLog",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ExternalWebhook",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FacebookLeadAdsAutomation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FacebookLeadAdsLead",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FacebookMarketingMessage",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FacebookMarketingMessageAudience",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FacebookMarketingMessageRecipient",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FacebookMarketingMessagesAuth",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "File",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Flow",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FlowAnalyticsSession",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FlowNodeStat",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FlowRun",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "FlowVersion",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Folder",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "GoogleAdsConversionEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "GoogleAdsSettings",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IgStoryAutomation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Import",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "InboundWebhook",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "InboundWebhookRequest",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Inbox",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "InboxContactStat",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "InboxTeam",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "InboxTeamMember",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationActiveCampaign",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationApi",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Integration",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationClaude",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationDeepseek",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationDrip",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationFacebookAds",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationGemini",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationGetResponse",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationGoogleAds",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationGoogleCalendar",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationGoogleSheet",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationInstagram",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationKlaviyo",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationMailchimp",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationMailerLite",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationMessenger",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationMetaCatalog",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationMoosend",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationMuse",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationOpenai",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationOpenaiCompatible",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationOpenrouter",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationOutlookCalendar",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationSendGrid",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationShopify",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationSmtp",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationTelegram",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationThreads",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationTiktok",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationWebchat",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationWhatsapp",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationWoocommerce",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "IntegrationZalo",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Leaderboard",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "LeaderboardAuditLog",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "LeaderboardParticipant",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "LeaderboardScoreEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MagicLink",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MagicLinkStat",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MediaLibraryFile",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MediaLibraryFolder",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Message",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MessageCleanup",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MessagingAdOperation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MessagingAdsConnection",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MessengerMessageTemplate",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MessengerWelcomeMessageFlow",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MetaCapiEvent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MetaCatalogItem",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MetaCatalogSyncRun",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MiniApp",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MiniAppPublication",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MiniAppSubmission",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MiniAppUpload",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Minigame",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MinigameContact",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MinigamePlay",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "MobileRefreshToken",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OAuthAccessToken",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OAuthClient",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OAuthClientAssertion",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OAuthClientResource",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OAuthConsent",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OAuthRefreshToken",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OAuthResource",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "DiscountCodeRedemption",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OrderItem",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Order",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "OrderStatusHistory",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineField",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineItemActivity",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineItemAssignee",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineItemAttachment",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineItemComment",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineItemCounter",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineItem",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineMember",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Pipeline",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PipelineStage",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PlaceCategory",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PlaceLocation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PlatformCredential",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PollCandidate",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Poll",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "PollVote",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Product",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ProductAddon",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ProductCategory",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ProductVariant",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ProductVariantOption",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "QuestionnaireAnswer",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Questionnaire",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "QuestionnaireQuestion",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "QuestionnaireSubmission",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "RefLinkStat",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Reflink",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ResourceDeletionLog",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "ResponseSlaPolicy",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "SavedReply",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "SavedReplyImage",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Sequence",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "SequenceDispatch",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "SequenceStep",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Spreadsheet",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "SystemField",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Tag",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TagChannel",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TelegramChat",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Template",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateInstallation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateInstallationSync",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateInstalledResource",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateResourceBackup",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateStoreCategory",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateStoreListingCategory",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateStoreListing",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateUninstallOperation",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TemplateVersion",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Trigger",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Condition",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TriggerContactHistory",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TriggerExecution",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "TriggerStat",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "UserDeviceToken",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "UserPersistentMenu",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Vendor",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Webhook",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WebhookExecution",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WhatsappBusinessAccount",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WhatsappCall",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WhatsappCallPermission",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WhatsappCoexistStaging",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WhatsappFlow",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WhatsappMessageTemplate",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WhatsappSignupSession",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkingHours",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkingHoursDateOverride",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkingHoursInterval",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkingHoursMember",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "Workspace",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkspaceApiToken",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkspaceBotMessageUsage",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkspaceDeletionRecord",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkspaceMac",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "WorkspaceMember",
+ "entityType": "tables",
+ "schema": "public"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "host",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": "5432",
+ "generated": null,
+ "identity": null,
+ "name": "port",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "database",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "credentialRef",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": "'disable'",
+ "generated": null,
+ "identity": null,
+ "name": "sslMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isActive",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isMain",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shardKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "readHost",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "readPort",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shardId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "adsConversionChannel",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'whatsapp'",
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationWhatsappId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMessengerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationInstagramId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "wabaId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "adsConversionEventSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "adsConversionEventType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ctwaClid",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referralEventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "numeric",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "orderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contents",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceEventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "adsConversionCapiStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "capiStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiSentAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "adsConversionChannel",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationWhatsappId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationFacebookAdsId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMessengerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationInstagramId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adAccountId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "adsConversionEventType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "trigger",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "markAs",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prompt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actionPrompt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "ARRAY[]",
+ "generated": null,
+ "identity": null,
+ "name": "actionRules",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "messages",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isDefault",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isRichResponse",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "tools",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "webSearchAuthorizedDomains",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "models",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "temperature",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxOutputTokens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "chunkIndex",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "content",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "vector(1536)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "embedding",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "aiConversationEmbeddingStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "messageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "attachmentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "aiConversationSourceType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "aiConversationSourceStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contentHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mimeType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "summary",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "content",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "vector(1536)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "embedding",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "aiEmbeddingStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "chunkIndex",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aiFileId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "path",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "size",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mimeType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "chunking",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "chunkingConfig",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processingRun",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "purpose",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dataCollect",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "outputMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "triggerFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "revision",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "aiHandoverBulkAction",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "action",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "aiHandoverBulkStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "message",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedByUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "finishedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastHeartbeatAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pausedUntil",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "attempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "chunkSeq",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "totalCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "skippedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "failedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cursorContactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inFlightFromId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inFlightToId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currentError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "scheduleEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "timeRanges",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "gotoFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "returnMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "pauseBotWaitingForStaff",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "applyToAllCustomers",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "applyToAllRevision",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "applyToAllMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "applyToAllRequestedByUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "availableTools",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "selectedTools",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adminId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "awaitingSince",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "measuredFrom",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "responseSeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workingResponseSeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "isFirstResponse",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workingHoursId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slaTargetSeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slaMet",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "insertedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "messageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "hasResponse",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "analyticsBotResponseType",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "responseType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "analyticsBotRouteType",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "routeType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "analyticsBotResult",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "result",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aiProvider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "insertedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "analyticsContactEventType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "language",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "country",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "analyticsContactSenderType",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "senderType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adminId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "insertedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "analyticsConversationEventType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromAssignee",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "toAssignee",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "insertedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "analyticsMessageEventType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "analyticsContactSenderType",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "senderType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adminId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "insertedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "topicId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "topicReferenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "email",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deliveredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "failedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "firstSeenAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastSeenAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "seenCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "firstClickedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastClickedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "clickCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "objectKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsManifestStatus"
+ },
+ {
+ "type": "analyticsStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsManifestStatus"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsManifestStatus"
+ },
+ {
+ "type": "timestamp",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ingestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsManifestStatus"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AnalyticsManifestStatus"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "calendarId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inviteeTimezone",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "appointmentStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'scheduled'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "appointmentLocationTypeSnapshot",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "locationType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "locationDetail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalEventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalEventIntegrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalEventProviderCalendarId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "appointmentExternalSyncStatus",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalSyncStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cancelledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "active",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "timezone",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "30",
+ "generated": null,
+ "identity": null,
+ "name": "durationMinutes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bufferAfterMinutes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "appointmentLocationType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "locationType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "locationDetail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "appointmentScheduleWindowType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'rollingDays'",
+ "generated": null,
+ "identity": null,
+ "name": "scheduleWindowType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "scheduleWindowConfig",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxAppointmentsPerUser",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "dailyLimitEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxPerDay",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "allowGroupMeeting",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxPerSlot",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "confirmationMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "confirmationFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cancellationFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalConnectionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalEventTitleTemplate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalEventDescriptionTemplate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalEventAttendeesTemplate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "publicLinkSlug",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "calendarId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "weekday",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startMinute",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endMinute",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "calendarId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "timingValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "type": "appointmentReminderTimingUnit",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "timingUnit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "appointmentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reminderConfigId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sendAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "appointmentReminderDispatchStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "jobId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sentAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cancelledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "failedReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "messageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "messageCreatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "fileType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fileType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mimeType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "width",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "height",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "size",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "thumbnailPath",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "originPath",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "keepOriginal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accountId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "providerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accessToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accessTokenExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refreshToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refreshTokenExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scope",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "idToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "password",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "code",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "permissions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "invitedBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Jwk"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Jwk"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Jwk"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "publicKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Jwk"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "privateKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Jwk"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "alg",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Jwk"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "crv",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Jwk"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Jwk"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ipAddress",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userAgent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "email",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "emailVerified",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "image",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isAnonymous",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "mustChangePassword",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletionRequestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scheduledDeletionAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Verification"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Verification"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Verification"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "identifier",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Verification"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Verification"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Verification"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "keywords",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conditions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "text",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "automatedResponseType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'inbound'",
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "type": "automationThrottleType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "throttleType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subjectId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "lastTriggeredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "customFieldType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationWhatsappId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMessengerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateData",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'channel'",
+ "generated": null,
+ "identity": null,
+ "name": "targetMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "broadcastStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "broadcastStatusReason",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusErrorMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "broadcastScheduleType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "schedulesType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "schedulesAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactFilter",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subaction",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "handoffCompletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "resumeCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "audienceRangeStart",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "audienceRangeEnd",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sendRatePerMinute",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "parentBroadcastId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurrenceAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "broadcastId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rule",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextRunAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accountedThroughAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "occurrenceCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastOccurrenceAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pausedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "recurrenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "localSlot",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurrenceAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "broadcastOccurrenceOutcome",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "outcome",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "broadcastOccurrenceReason",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "childBroadcastId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "materializedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "supersededCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "broadcastId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateData",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "items",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "discountCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "lastActivityAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "abandonedNotifiedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceAccountId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalPostId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "caption",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mediaType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "thumbnail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "permalink",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "publishedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadataFetchedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadataAttemptedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "coexistChannel",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "coexistRunType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'coexist'",
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "coexistRunStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'init'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "triggerSource",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "finishedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastHeartbeatAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "totalScan",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "currentScan",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currentStep",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastSyncedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "currentPageNumber",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "importedContactCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "importedMessageCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "skippedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "failedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currentError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastPhase",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastChunkOrder",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "syncProgress",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "coexistMessengerSyncPhase",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'contacts'",
+ "generated": null,
+ "identity": null,
+ "name": "messengerSyncPhase",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pendingPatches",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scanFromAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedByUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resumeCursor",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "commentAutomationType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'messenger'",
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isActive",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "repliesCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sentCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "deliveredCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "seenCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "clickedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "failedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "missedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "moderatedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"type\":\"all\",\"value\":[]}'",
+ "generated": null,
+ "identity": null,
+ "name": "post",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"type\":\"text\",\"value\":\"\"}'",
+ "generated": null,
+ "identity": null,
+ "name": "privateReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"type\":\"none\",\"value\":null}'",
+ "generated": null,
+ "identity": null,
+ "name": "publicReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"type\":\"all\",\"value\":[]}'",
+ "generated": null,
+ "identity": null,
+ "name": "includeKeywords",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "ARRAY[]",
+ "generated": null,
+ "identity": null,
+ "name": "excludeKeywords",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "commentExcludeKeywordsType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'contain'",
+ "generated": null,
+ "identity": null,
+ "name": "excludeKeywordsType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"replyToNewContactsOnly\":false,\"replyOncePerUserPerPost\":false,\"likeUserComment\":false,\"replyToUsersWhoCommentedOnOtherPosts\":true,\"ignoreCommentReplies\":true,\"trackUserTags\":false}'",
+ "generated": null,
+ "identity": null,
+ "name": "options",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"all\":false,\"hasPhoneNumber\":false,\"hasImage\":false,\"hasVideo\":false,\"hasLink\":false,\"hasKeywords\":false,\"hasGif\":false,\"hasEmoji\":false,\"keywords\":[],\"showCommentsAfter\":\"none\"}'",
+ "generated": null,
+ "identity": null,
+ "name": "hideComments",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"type\":\"immediately\",\"value\":0}'",
+ "generated": null,
+ "identity": null,
+ "name": "replyAfter",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "automationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "postId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "commentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "commentText",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "commentAutomationReplyChannel",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "replyChannel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "commentAutomationReplyType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "replyType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "replyText",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "commentAutomationEventStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deliveredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "seenAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clickedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "failedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorDetail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "httpCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "automationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "postId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "commentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "commentText",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "commentAutomationMissReason",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "automationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "postId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "automationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "postId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "commentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "commentText",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "commentModerationSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "commentModerationRule",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rule",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "matchedKeyword",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "categories",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "commentModerationAction",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "action",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "commentModerationStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorDetail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "modelId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "purpose",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "targetConnectionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorTokenId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "platformOwnerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "originHost",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "returnUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "stateNonceHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'authorize'",
+ "generated": null,
+ "identity": null,
+ "name": "step",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextAction",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "encryptedAuth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "targets",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "targetClaims",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "ARRAY[]",
+ "generated": null,
+ "identity": null,
+ "name": "resultConnectionIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "results",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "consumedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "displayName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'connected'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "authExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "connectedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "disconnectedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "providerEventAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "providerEventKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "avatar",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "phoneNumber",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "email",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "emailVerified",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "emailOptIn",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "firstName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": {
+ "as": "CASE\n WHEN \"firstName\" IS NULL AND \"lastName\" IS NULL THEN NULL\n WHEN \"firstName\" IS NULL THEN \"lastName\"\n WHEN \"lastName\" IS NULL THEN \"firstName\"\n ELSE \"firstName\" || ' ' || \"lastName\"\n END",
+ "type": "stored"
+ },
+ "identity": null,
+ "name": "fullName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "gender",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "gender",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastReadAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ref",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "country",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "state",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "city",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "location",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "locale",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "timezone",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subscribedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "broadcastSubscribedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "blockedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "totalTagged",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "totalNewTagged",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveHourly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveHourly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveHourly"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "hourBucket",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveHourly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveHourly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveMonthly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveMonthly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveMonthly"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "periodStart",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveMonthly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveMonthly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceMacId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActiveMonthly"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "type": "contactActivityType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "activityType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "type": "contactActivityReferenceType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referenceType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "parentReferenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "firstOccurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customFieldId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "originalContactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "followsBusiness",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "businessFollowsContact",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accountVerified",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "followerCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "contactInboxProfileSnapshotState",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "profileSnapshotState",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "profileSnapshotAttempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "profileSnapshotNextAttemptAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "language",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "personaId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactLastReadAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "firstInteractionAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastMessageAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastIncomingMessageAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastOutboundMessageAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referral",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastCommentMessageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastCommentMessageAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastStoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "consecutiveFailedReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastInputFailure",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastErrorLog",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastBtnTitle",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastUserInput",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "lastUserInputType",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastUserInputType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "webchatParentUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceParentUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceUsername",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceIdentityHistory",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "threadControlState",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadControlState",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadOwnerRole",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadControlUpdatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "threadControlEvent",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadControlLastEvent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadOwnerAppId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadOwnerExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadPreviousOwnerAppId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInboxPost"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInboxPost"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "postId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInboxPost"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "commentedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactInboxPost"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "messageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "automatedResponseId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "text",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "normalizedText",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "text",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdById",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "broadcastId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "sent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "seenAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deliveredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clickedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "failedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorContent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": {
+ "as": "case when \"seenAt\" is null then false when \"deliveredAt\" is null then false else \"seenAt\" >= \"deliveredAt\" end",
+ "type": "stored"
+ },
+ "identity": null,
+ "name": "isRead",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "enrolledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "completedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "currentStep",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextRunAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastStepId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextStepId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lockedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lockOwner",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sequenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowVersionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "appointmentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nodeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "stepId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "ContactOnSmartDelayType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "triggerAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "ContactOnSmartDelayStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "campaignId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adGroupId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clickIdType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clickId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ref",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dedupKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactState"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactState"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastDeliveredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactState"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactToTag"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tagId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactToTag"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tagId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tagChannelId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "botEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "botResumeAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "archivedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "additionalAttributes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactLastReadAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "agentLastReadAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aiContextLastMessageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastActivityAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "followed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "assignedUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "assignedInboxTeamId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastStep",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currentStep",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adminRepliedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactRepliedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "awaitingHumanReplySince",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "awaitingHumanReplyClosedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "assignedUserAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "responseDueAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "responseSlaBreachingAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "responseSlaTargetSeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "topicId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "code",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "issuedContactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "issuedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "usedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "couponTopicStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "hasEverHadCoupon",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdById",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "customFieldType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "showInInbox",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "DecisionProviderKind",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "providerKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endpoint",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "credential",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "modelCatalog",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "defaultModel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "DecisionConnectionStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'enabled'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "DecisionConnectionTestStatus",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastTestStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastTestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "DecisionProfileStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'enabled'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "connectionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "model",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contract",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "thresholdConfig",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "globalRouterEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "globalRouterConfig",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "code",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoApply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "discountType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "discountType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'0'",
+ "generated": null,
+ "identity": null,
+ "name": "discountValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "discountAppliesTo",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'entireOrder'",
+ "generated": null,
+ "identity": null,
+ "name": "appliesTo",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "categoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "discountMinimumType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'none'",
+ "generated": null,
+ "identity": null,
+ "name": "minimumType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'0'",
+ "generated": null,
+ "identity": null,
+ "name": "minimumValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "usageLimit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "usedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "oncePerCustomer",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "discountEligibility",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'everyone'",
+ "generated": null,
+ "identity": null,
+ "name": "eligibility",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customerFilter",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "startsAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endsAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isActive",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "storeSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'chatbotx'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customFieldId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "data",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "backgroundUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceOpenHours"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceOpenHours"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceOpenHours"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceOpenHours"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceOpenHours"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ranges",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceOpenHours"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "onlinePaymentProvider",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "livemode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accountLabel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalAccountId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "platformCredentialId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "secret",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "webhookEndpointId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "orderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "onlinePaymentProvider",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "providerReference",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "transactionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refundId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "amount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "orderPaymentStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'open'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "livemode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "checkoutUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "paidAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refundedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceOrderCounter"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "lastNumber",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceOrderCounter"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "storeSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'chatbotx'",
+ "generated": null,
+ "identity": null,
+ "name": "storeSource",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "orderingAvailable",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "webshopProductView",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "webshopProductView",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "openHoursId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "searchProducts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "facebookPixelId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "abandonedCartDelayMinutes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "abandonedCartFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productButtons",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "productImageSize",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productImageSize",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "allowRateOrders",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notifyOnCartStatusChange",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "paymentMethods",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "currencyPosition",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currencyPosition",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currencySymbol",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "serviceFeePercent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "shippingMode",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shippingType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "storeAddress",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shippingCountries",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "defaultShippingCountry",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deliveryCost",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "checkoutMode",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "checkoutMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "checkoutLink",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "checkoutFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "minimumOrderValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "orderConfirmationMode",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'default'",
+ "generated": null,
+ "identity": null,
+ "name": "orderConfirmationMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "orderConfirmationFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requireName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requireEmail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requirePhone",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requireState",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requireZip",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "externalCheckoutMethod",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'webCheckout'",
+ "generated": null,
+ "identity": null,
+ "name": "externalCheckoutMethod",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "externalAutoApplyDiscounts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sendsTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "deliveredsTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "seensTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "clicksTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "action",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "detail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ipAddress",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userAgent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "domain",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "verifiedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cfHostnameId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cfOwnershipValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cfAcmeValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "License"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "License"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "License"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "licenseId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "License"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "License"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "License"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformAdmin"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformAdmin"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformAdmin"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformAdmin"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'super-admin'",
+ "generated": null,
+ "identity": null,
+ "name": "role",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformAdmin"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ownerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "disabledReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "brandName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "logoLightPath",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "logoDarkPath",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "faviconPath",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customCss",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customJs",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "theme",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "storageUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "policyUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "termsOfServiceUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "signupEmailTemplate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "forgotPasswordEmailTemplate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "magicLinkEmailTemplate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accountCredentialsEmailTemplate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "hiddenChannels",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "keyHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "encryptedKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "type": "tenantDefaultTemplateAction",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "action",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "icon",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "position",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactsLimit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "contactsUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspacesLimit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "workspacesUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channelsLimit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "channelsUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "teamMembersLimit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "teamMembersUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "macLimit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "macUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "botMessagesLimit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "botMessagesUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "monthlyBotMessagesLimit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "monthlyBotMessagesUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "monthlyBotMessagesPeriodStart",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "botMessagesTopUpGranted",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "whiteLabel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "ssoSaml",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "saasMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "customAppCredentials",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "planName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "planStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "selectedTrialPlanId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "periodStart",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "periodEnd",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channelsTornDownAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "syncedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "contactsUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "channelsUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "teamMembersUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "botMessagesUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "macUsed",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "syncedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "action",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "detail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "httpCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "stackTrace",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'make'",
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "event",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pageName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "formId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "formName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "fieldMapping",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "leadsHandledCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "automationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "leadgenId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "formId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "formName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adgroupId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adsetId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adsetName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "campaignId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "campaignName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adAccountId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currencyOffset",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "budgetType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "budgetMinorUnits",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "content",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'optIn'",
+ "generated": null,
+ "identity": null,
+ "name": "targetType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "audienceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "campaignId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "facebookUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'scheduled'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusErrorCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusErrorMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startsAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "firstSentAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "completedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextDayAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metaEndsAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "timezoneName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adSetId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dayTarget",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "daySent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "resumeCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customAudienceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adAccountId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rowsUploaded",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "readyAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "facebookUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "campaignRowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subscriptionToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "psid",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mid",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "trackingId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextAttemptAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextEligibleAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sentAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deliveredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "failedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorSource",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "facebookUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "fileContextType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contextType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "path",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fileName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mimeType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fileSize",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "fileStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "meta",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uploadedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "active",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enableInInbox",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currentVersionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "draftVersionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowAnalyticsSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowAnalyticsSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowAnalyticsSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowAnalyticsSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowAnalyticsSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowAnalyticsSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "analyticsId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nodeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "buttonId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorContent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "seenAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowVersionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nodes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "edges",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "isDraft",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isLatest",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startNodeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "folderType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "parentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isTrash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "paths",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationGoogleAdsId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referralEventId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "loginCustomerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversionCustomerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversionActionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversionActionName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversionActionCategory",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lookbackWindowDays",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "googleAdsEventSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scopeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "googleAdsClickIdType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clickIdType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clickId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "googleClickReceivedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "numeric",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "transactionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "options",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uploadMethod",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "googleAdsEventStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "attempt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sentAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "error",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "googleAdsFailureStage",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "failureStage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "googleAdsProcessingStatus",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processingStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processingCheckedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processingAttempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextProcessingCheckAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processingDetail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsSettings"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsSettings"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsSettings"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "settings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "GoogleAdsSettings"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "igStoryAutomationType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "igStoryAutomationTrigger",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'storyReply'",
+ "generated": null,
+ "identity": null,
+ "name": "trigger",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isActive",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "repliesCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"type\":\"all\",\"value\":[]}'",
+ "generated": null,
+ "identity": null,
+ "name": "story",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"type\":\"none\",\"value\":null}'",
+ "generated": null,
+ "identity": null,
+ "name": "reply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{\"type\":\"all\",\"value\":[]}'",
+ "generated": null,
+ "identity": null,
+ "name": "includeKeywords",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fileId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "importType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "importFormat",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "format",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "importStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "meta",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "totalCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "processedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "successCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "failedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "errorSample",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "completedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "active",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxResolution",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "identifiers",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fieldMappings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sampleJson",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "requestCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboundWebhookId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "idempotencyKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clientIp",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userAgent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "inboundWebhookRequestStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'received'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "skipReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "payload",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fieldErrors",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actionResults",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'connected'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "markReadOnOutbound",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "disconnectedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "disconnectReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadControlSeenAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxContactStat"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "totalContacts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxContactStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxContactStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeam"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeam"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeam"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeam"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeam"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeamMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeamMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeamMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxTeamId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeamMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "InboxTeamMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenPrefix",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "callbackUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Integration"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Integration"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Integration"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Integration"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Integration"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxOutputTokens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "model",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prompt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "temperature",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxOutputTokens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "model",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prompt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "temperature",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxOutputTokens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "model",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prompt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "temperature",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "loginCustomerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "descriptiveName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currencyCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversionCustomerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "acceptedCustomerDataTerms",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversionActions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversionActionsSyncedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "setupError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "setupErrorAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'primary'",
+ "generated": null,
+ "identity": null,
+ "name": "providerCalendarId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "email",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userInfo",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "igId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "username",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "coexistEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "coexistAiReadsSyncedHistory",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "hasCapiScope",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiScopeCheckedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "datasetId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiAccessToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiDisconnectedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiTestEventCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "conversationStarters",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "persistentMenus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "welcomeFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'instagram'",
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenRefreshError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userInfo",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "conversationStarters",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "persistentMenus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "personas",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "personaId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "coexistEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "coexistAiReadsSyncedHistory",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "hasCapiScope",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiScopeCheckedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "datasetId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiAccessToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiDisconnectedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiTestEventCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "welcomeFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "syncTagEnabledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenRefreshError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "handoverResumeFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "catalogId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "catalogName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "businessId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "encryptedAuth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "metaCatalogAuthMode",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'oauth'",
+ "generated": null,
+ "identity": null,
+ "name": "authMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "metaCatalogConnectionStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "metaCatalogImportStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'idle'",
+ "generated": null,
+ "identity": null,
+ "name": "importStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "importTotalCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "importedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "importFailedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "importError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastImportedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'VND'",
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "storeUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxOutputTokens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "model",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prompt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "temperature",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "autoReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoReplyVoice",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "voice",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prompt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "model",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "temperature",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxOutputTokens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aiAgentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "baseURL",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "defaultModel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "preset",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "maxOutputTokens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "model",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prompt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "temperature",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'primary'",
+ "generated": null,
+ "identity": null,
+ "name": "providerCalendarId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "email",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shopDomain",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shopName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "shopifyAuthKind",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "authKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "encryptedAuth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "webhookSubscriptionIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "externalStoreConnectionStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "externalStoreSyncStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'idle'",
+ "generated": null,
+ "identity": null,
+ "name": "syncStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "syncError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastSyncedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "productCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "orderCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromAddress",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "botId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "threadsUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "username",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenRefreshError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "openId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenRefreshError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enable",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "authorizedDomains",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "conversationStarters",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "persistentMenus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "brandColor",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "hideHeader",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "showLogo",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "hideMessageInput",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customCss",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "welcomeFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "phoneNumberId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "wabaId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "businessId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "displayPhoneNumber",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "coexistEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "callingEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "inboundCallsEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "callHours",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "callRecordingEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "90",
+ "generated": null,
+ "identity": null,
+ "name": "callRecordingRetentionDays",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "callTranscriptionEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "whatsappCallRecordingMode",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'metaNative'",
+ "generated": null,
+ "identity": null,
+ "name": "callRecordingMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "whatsappCallTranscriptionMode",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'metaNative'",
+ "generated": null,
+ "identity": null,
+ "name": "callTranscriptionMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "callAnnouncementLanguage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "callRecordingPurpose",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "pixRedirectEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "coexistAiReadsSyncedHistory",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isCoexist",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "platformType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "historyDeclined",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "hasCapiScope",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiScopeCheckedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "datasetId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiAccessToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiDisconnectedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiTestEventCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "whatsappRegistrationStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending_verification'",
+ "generated": null,
+ "identity": null,
+ "name": "registrationStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "registrationError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "verificationCodeRequestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenRefreshError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "handoverResumeFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "routingRoles",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "siteUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "storeName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "encryptedAuth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "webhookIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "externalStoreConnectionStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "externalStoreSyncStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'idle'",
+ "generated": null,
+ "identity": null,
+ "name": "syncStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "syncError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastSyncedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "productCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "orderCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "oaId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fallbackFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "syncTagEnabledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenRefreshError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "coverImageUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startsAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endsAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "leaderboardStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'draft'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "leaderboardPlatform",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "platform",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "minigameId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scope",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rules",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "followersOnly",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tagIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'22:00'",
+ "generated": null,
+ "identity": null,
+ "name": "resetTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "cooldownSeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referralWelcomeFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rewardSettings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rewardsTriggeredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rewardRecipients",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "finishedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "leaderboardId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "leaderboardAuditAction",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "action",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "delta",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "reason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "leaderboardId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "score",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isBanned",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referrerContactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "scoredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dailyBucket",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dailyCounts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "breakdown",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "lastActivityAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "leaderboardId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "delta",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "leaderboardScoreSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rule",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceRef",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "linkId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "path",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mimeType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "size",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isFavourite",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastAccessedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFolder"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFolder"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFolder"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFolder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MediaLibraryFolder"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "text",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contentAttributes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "messageType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "messageType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "contentType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contentType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "senderType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "senderType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "senderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "messageKind",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'message'",
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "parentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "attributes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sendError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sinceTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "MessageCleanupStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "messagingAdChannel",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationWhatsappId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMessengerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationInstagramId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "adAccountId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "messagingAdCreateState",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "createState",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "messagingAdPublishState",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'draft'",
+ "generated": null,
+ "identity": null,
+ "name": "publishState",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metaCampaignId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metaAdSetId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metaAdCreativeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metaAdId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "input",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cleanupError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "messagingAdChannel",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationWhatsappId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMessengerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationInstagramId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auth",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMessengerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "language",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'POSITIONAL'",
+ "generated": null,
+ "identity": null,
+ "name": "parameterFormat",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "components",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMessengerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metaFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowVersionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'current'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "eventName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contentCategory",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contentName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "numeric",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'business_messaging'",
+ "generated": null,
+ "identity": null,
+ "name": "actionSource",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contentType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contentIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "capiStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiSentAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "capiError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMetaCatalogId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "catalogId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "metaCatalogItemDirection",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'push'",
+ "generated": null,
+ "identity": null,
+ "name": "direction",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "retailerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastSyncedFingerprint",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastSyncedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationMetaCatalogId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "metaCatalogSyncStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'queued'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "metaCatalogItemDirection",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'push'",
+ "generated": null,
+ "identity": null,
+ "name": "direction",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "catalogId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "metaCatalogSyncScope",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'all'",
+ "generated": null,
+ "identity": null,
+ "name": "scope",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "categoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "selectedProductIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "handles",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "submissionLeaseId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "totalCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "succeededCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "failedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "skippedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "itemErrors",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "skippedItems",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "pollAttempt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "error",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "finishedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "definition",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowJson",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "submissionsCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "miniAppId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationWhatsappId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "whatsappFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "validationErrors",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "publishedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "miniAppId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "type": "miniAppSubmissionSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "answers",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "miniAppId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "submissionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inputName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uploadToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "path",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fileName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mimeType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "size",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "miniAppUploadStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "minigameType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "generalSettings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "appearance",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "playerSettings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prizeSettings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "winningMessageSettings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nonWinningMessageSettings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "playsCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "participantsCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "winnersCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sharesCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "minigameId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "openedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "played",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "remaining",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sharesCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referrerContactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "minigameId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "isWinning",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prizeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "prizeName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deviceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "familyId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rotatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "revoked",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clientId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sessionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "authorizationCodeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resources",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedUserInfoClaims",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refreshId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "revoked",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "confirmation",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scopes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clientId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clientSecret",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clientDiscoveryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "disabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "skipConsent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "enableEndSession",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subjectType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scopes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "clientCredentialsScopes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uri",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "icon",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contacts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tos",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "policy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "softwareId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "softwareVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "softwareStatement",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "redirectUris",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "postLogoutRedirectUris",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "backchannelLogoutUri",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "backchannelLogoutSessionRequired",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenEndpointAuthMethod",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "applicationType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "jwks",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "jwksUri",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "grantTypes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "responseTypes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requirePKCE",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "dpopBoundAccessTokens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClientAssertion"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClientAssertion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clientId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clientId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resources",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedUserInfoClaims",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scopes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clientId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sessionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "authorizationCodeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resources",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedUserInfoClaims",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "revoked",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rotatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rotationReplayResponse",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rotationReplayExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "authTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "confirmation",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scopes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "identifier",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accessTokenTtl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refreshTokenTtl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "signingAlgorithm",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "signingKeyId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "allowedScopes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customClaims",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "dpopBoundAccessTokensRequired",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "disabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "policyVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "discountCodeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "orderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "amount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "orderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "variantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "vendorId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "categoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "variantLabel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "combination",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sku",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "retailerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "imageUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "vendorName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "unitPrice",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "quantity",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "stockTaken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "discountPercent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "taxPercent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "discountTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "taxTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lineTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "number",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channel",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "orderSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "orderStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "paymentMethod",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'cod'",
+ "generated": null,
+ "identity": null,
+ "name": "paymentMethod",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "paymentStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'unpaid'",
+ "generated": null,
+ "identity": null,
+ "name": "paymentStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "paymentExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "paidAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subtotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "discountTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shippingTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "serviceFeeTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "taxTotal",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'0'",
+ "generated": null,
+ "identity": null,
+ "name": "couponDiscount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "total",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "discountCodeId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "discountCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customerName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customerEmail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customerPhone",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "shippingType",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shippingType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shippingAddress",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "note",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rating",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ratingComment",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "acceptedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shippedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "concludedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cancelledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cancelReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "fulfillmentStatus",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fulfillmentStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "trackingCompany",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "trackingNumber",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "trackingUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "orderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "orderStatus",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "orderStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "toStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "orderActorType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "note",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pipelineId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referenceName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "customFieldType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "required",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "position",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pipelineId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "itemId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "itemNumber",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "itemTitle",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "pipelineActivityKind",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "pipelineActorKind",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "actorSourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromStageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "toStageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "pipelineItemStatus",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "pipelineItemStatus",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "toStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "toValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "pipelineItemPriority",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromPriority",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "pipelineItemPriority",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "toPriority",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromDueDate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "toDueDate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromTitle",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "toTitle",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromPipelineId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "version",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "itemId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceMemberId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxTeamId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "itemId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mediaLibraryFileId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "itemId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "text",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdById",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "idempotencyKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemCounter"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "lastNumber",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItemCounter"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pipelineId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "stageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "number",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "pipelineItemStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "pipelineItemPriority",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "priority",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dueDate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fieldValues",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdById",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "closedById",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "stageEnteredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "statusChangedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "closedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastCommentAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "idempotencyKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pipelineId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceMemberId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "canManageSettings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "canView",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "canEdit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "canDelete",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "pipelineType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "referenceName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "settings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdById",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pipelineId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "textColor",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "backgroundColor",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "position",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bulkJobId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "10",
+ "generated": null,
+ "identity": null,
+ "name": "rank",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "latitude",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "longitude",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "categoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "publicConfig",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "livemode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "usePlatformCredential",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isVerified",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "verifiedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastUsedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pollId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "position",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "imageUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "imageUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startsAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endsAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "afterVoteFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pollId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "candidateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shortDescription",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "longDescription",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "price",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "taxes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "discount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'USD'",
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sku",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "inventoryPolicy",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'dont_track'",
+ "generated": null,
+ "identity": null,
+ "name": "inventoryPolicy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "inventoryQuantity",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "allowOutOfStockPurchase",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "images",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "tags",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "vendorId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "10",
+ "generated": null,
+ "identity": null,
+ "name": "rank",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "categoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subcategoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "productStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isSearchable",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "allowSpecialRequest",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isAddonOnly",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "storeSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'chatbotx'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalHandle",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalVariantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "maxSelections",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "addonProductIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "parentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "imageUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isVisible",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "10",
+ "generated": null,
+ "identity": null,
+ "name": "rank",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "storeSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'chatbotx'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "combination",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "price",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sku",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inventoryQuantity",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalInventoryItemId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "productId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "values",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "10",
+ "generated": null,
+ "identity": null,
+ "name": "position",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "submissionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "questionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "questionIdSnapshot",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "questionTitleSnapshot",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "questionTypeSnapshot",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "labelSnapshot",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pointsEarned",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "attemptCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "answeredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "enableScore",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "enableRetryMessages",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enableCustomFieldMapping",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "triggerFlowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "questionnaireId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "questionnaireQuestionType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "active",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "image",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "orderNo",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "point",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "retryMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customFieldId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "systemFieldKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "config",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "questionnaireId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "questionnaireSubmissionStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'inProgress'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "totalPoints",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currentQuestionId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currentQuestionSentAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastAnsweredMessageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "startedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "completedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cancelledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "linkId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "occurredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "ReflinkType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'refLink'",
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "customFieldId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "qrStyles",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "ARRAY[]",
+ "generated": null,
+ "identity": null,
+ "name": "widgetAuthorizedDomains",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "ARRAY[]",
+ "generated": null,
+ "identity": null,
+ "name": "widgetHiddenInboxIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "widgetLogoFileId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "widgetBrandName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "widgetBrandUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "widgetLogoBackgroundColor",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "resourceDeletionResourceType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceSubtype",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "resourceDeletionStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedByUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestSource",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ipAddress",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userAgent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "completedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "canceledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResourceDeletionLog"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "firstResponseTargetSeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nextResponseTargetSeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "25",
+ "generated": null,
+ "identity": null,
+ "name": "breachingThresholdPercent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReply"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReply"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReply"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shortcut",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReply"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "text",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReply"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReply"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "savedReplyId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "mediaLibraryFileId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "position",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "active",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "subscribers",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "messages",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "runAtMs",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "bucket",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "idempotencyKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attempt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lockedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lockOwner",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "completedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deliveredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "seenAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "clickedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "failedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorContent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sequenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "stepId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "enrollmentId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": {
+ "as": "case when \"seenAt\" is null then false when \"deliveredAt\" is null then false else \"seenAt\" >= \"deliveredAt\" end",
+ "type": "stored"
+ },
+ "identity": null,
+ "name": "isRead",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "order",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "delayDays",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "delayMinutes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "delayUnit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "specificDateTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isActive",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "anytime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sendTimeStart",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sendTimeEnd",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": "'[\"monday\",\"tuesday\",\"wednesday\",\"thursday\",\"friday\",\"saturday\",\"sunday\"]'",
+ "generated": null,
+ "identity": null,
+ "name": "sendDays",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "flowId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sequenceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "spreadsheetId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SystemField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SystemField"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SystemField"
+ },
+ {
+ "type": "SystemFieldType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SystemField"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "payload",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "SystemField"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tagId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "channelType",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "externalLabelId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "chatId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "telegramChatType",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "telegramBotChatStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "botStatus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "imageUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "publisherName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "youtubeVideoId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "testLink",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "selection",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "payload",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "categoryCounts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "formatVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shareToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "shareEnabled",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shareExpiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "defaultPermissions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "createInstallFolder",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "defaultAutoUpdate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "installCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "version",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "payloadHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceWorkspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "formatVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "templateInstallationStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "permissions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "warnings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "warningCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorMessage",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "resourceCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "installFolderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "autoUpdate",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceUpdatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "installedBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'apiToken'",
+ "generated": null,
+ "identity": null,
+ "name": "installedByKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "templateInstallSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'manual'",
+ "generated": null,
+ "identity": null,
+ "name": "installSource",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "completedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "stagingGeneration",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "-1",
+ "generated": null,
+ "identity": null,
+ "name": "stagedCleanedGeneration",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "stagedCleanupClaimedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pendingPublishEffects",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceTemplateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "successfulInstallEvents",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceDeletedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxBindings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "publisherRef",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "smallint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "publisherUninstallGrant",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstalledAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstalledByKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallCounts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "templateUninstallState",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'none'",
+ "generated": null,
+ "identity": null,
+ "name": "uninstallState",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallRequestedByKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallRequestedBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallRequestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "uninstallAttempt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallClaimToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallClaimedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallErrorCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallOperationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "sourceVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastSyncedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "installationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "templateSyncStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "templateSyncTrigger",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "trigger",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "idempotencyKey",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestFingerprint",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'apiToken'",
+ "generated": null,
+ "identity": null,
+ "name": "requestedByKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "claimedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "errorCode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "fromVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "appliedVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "appliedHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "counts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "warnings",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "warningSummary",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "finishedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "installationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "templateResourceCategory",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceResourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "wasExisting",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "allowEdit",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "allowDelete",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "detachedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "syncedHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "syncedVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallOutcome",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallEffects",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "uninstallEffectsAttempts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallFrozenFrom",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "uninstallDrainStartedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "installationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "syncId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "installedResourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "resourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "formatVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "content",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "byteSize",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "rank",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "listingId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreListingCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "categoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreListingCategory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "createdBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "publisherRef",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedByKind",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requestedBy",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "templateUninstallOperationState",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "state",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "counts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "auditLogId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "noticeDeliveredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "finishedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "templateId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "version",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "payload",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "payloadHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "formatVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "changes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "active",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "actions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "triggerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "webhookId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "varchar(255)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "operator",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "triggerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "firstEnteredAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "executedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "triggerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "triggerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "totalContacts",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "successCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "failureCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "totalExecutions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "type": "devicePlatform",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "platform",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "lastSeenAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserPersistentMenu"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserPersistentMenu"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserPersistentMenu"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserPersistentMenu"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "",
+ "generated": null,
+ "identity": null,
+ "name": "menus",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserPersistentMenu"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "UserPersistentMenu"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shortDescription",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "phone",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "storeAddress",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "imageUrl",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isActive",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'0'",
+ "generated": null,
+ "identity": null,
+ "name": "discountPercent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "numeric(19,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'0'",
+ "generated": null,
+ "identity": null,
+ "name": "minimumOrderValue",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "openHoursId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "categoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subcategoryId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "10",
+ "generated": null,
+ "identity": null,
+ "name": "rank",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "storeSource",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'chatbotx'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "active",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "folderId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "executedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "webhookId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "wabaId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "businessId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "credential",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "grantedScopes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scopeCheckedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provisionedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "creditLineId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "revision",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "wacid",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "attemptId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "whatsappCallDirection",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "direction",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "whatsappCallStatus",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'ringing'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "whatsappCallOutcome",
+ "typeSchema": "public",
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "outcome",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "durationSeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "messageId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lastError",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "answeredByUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "initiatedByUserId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "recordingRequested",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "recordingFailureReason",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "recordingPath",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "recordedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "transcript",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "transcribedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "transcriptSegments",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aiSummary",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aiSummarizedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aiSummaryProvider",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "inboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "conversationId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "whatsappCallPermissionResponse",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "response",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isPermanent",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "respondedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contactInboxId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "phoneNumberId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "payload",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "payloadHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "processedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "parseFailedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationWhatsappId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "categories",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "validationErrors",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "completedCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "screens",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "integrationWhatsappId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sourceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "language",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "components",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ownerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "wabaId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "businessId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "encryptedAccessToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "apiVersion",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "candidatePhoneNumberIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "claimedPhoneNumberIds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expiresAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "consumedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHours"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHours"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHours"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHours"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHours"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workingHoursId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ranges",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workingHoursId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "weekday",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startMinute",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endMinute",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workingHoursId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "defaultReply",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "defaultReplyFrequency",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'allTime'",
+ "generated": null,
+ "identity": null,
+ "name": "defaultReplyFrequency",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "targetCountry",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'en'",
+ "generated": null,
+ "identity": null,
+ "name": "language",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'UTC'",
+ "generated": null,
+ "identity": null,
+ "name": "timezone",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'#016DFF'",
+ "generated": null,
+ "identity": null,
+ "name": "brandColor",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "developmentMode",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "smartResponseDelaySeconds",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "isActive",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "startTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "endTime",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "logo",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scheduledDeletionAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletionRequestedById",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletionRequestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "purgeStartedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "supportAccessUntil",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "capiLimitedDataUse",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ownerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "WorkspaceApiTokenPermission",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "permission",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenHash",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tokenPrefix",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "isDefault",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "encryptedToken",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scopes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ownerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "periodStart",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "periodEnd",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "count",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceName",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ownerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ownerEmail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletionRequestedById",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletionRequestedByEmail",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deletionRequestedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scheduledDeletionAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "purgedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "usageSnapshot",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "details",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ownerId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "tenantId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "periodStart",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "periodEnd",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "macCount",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "createdAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updatedAt",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "workspaceId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "userId",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "workspaceMemberRole",
+ "typeSchema": "public",
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "role",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "notificationChannels",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "notificationTypes",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "permissions",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "type": "timestamp(6) with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "onlineSince",
+ "entityType": "columns",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "isActive",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessageShard_isActive_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "shardKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessageShard_shardKey_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessageShard"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "startTime",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "endTime",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ShardTimeRange_time_lookup_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "shardId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ShardTimeRange_shardId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationWhatsappId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceEventId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_workspace_integration_source_sourceEventId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationWhatsappId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceEventId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"channel\" = 'whatsapp'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_ws_whatsapp_source_sourceEventId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationMessengerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceEventId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"channel\" = 'messenger'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_ws_messenger_source_sourceEventId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationInstagramId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceEventId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"channel\" = 'instagram'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_ws_instagram_source_sourceEventId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "eventType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_workspaceId_eventType_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "referralEventId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"referralEventId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_referralEventId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_workspaceId_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "adId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionEvent_workspaceId_adId_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "enabled",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AdsConversionRule_workspaceId_channel_enabled_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIAgent_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIConversationEmbedding_sourceId_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "chunkIndex",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIConversationEmbedding_sourceId_chunkIndex_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "embedding",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": {
+ "name": "vector_cosine_ops",
+ "default": false
+ }
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "hnsw",
+ "concurrently": false,
+ "name": "AIConversationEmbedding_embedding_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIConversationEmbedding_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIConversationEmbedding_lookup_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIConversationSource_lookup_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIConversationSource_workspaceId_sourceType_sourceKey_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "messageId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIConversationSource_messageId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIConversationSource_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIEmbedding_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "aiFileId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "chunkIndex",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIEmbedding_aiFileId_chunkIndex_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIFile_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "(\"processingRun\"->>'queuedAt')",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"processingRun\"->>'status' = 'queued'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIFile_queuedAt_queued_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "status IN ('pending', 'running', 'cancelling')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverBulkRun_inbox_live_uq",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "revision",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverBulkRun_inbox_revision_uq",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverBulkRun_workspace_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"createdAt\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverBulkRun_inbox_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lastHeartbeatAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "status IN ('pending', 'running', 'cancelling')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverBulkRun_live_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "requestedByUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverBulkRun_requestedByUserId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverSettings_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverSettings_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "applyToAllRequestedByUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverSettings_applyToAllRequestedByUserId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "gotoFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AIHandoverSettings_gotoFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsAgentResponseEvent_workspaceId_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsBotMessageEvent_workspaceId_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "aiProvider",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsBotMessageEvent_workspaceId_aiProvider_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "hasResponse",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "result",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsBotMessageEvent_workspaceId_hasResponse_result_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "eventType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsContactEvent_workspaceId_occurredAt_eventType_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "eventType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsContactEvent_workspaceId_eventType_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "adminId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsContactEvent_workspaceId_adminId_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "eventType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsConversationEvent_workspaceId_occurredAt_eventType_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "toAssignee",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsConversationEvent_workspaceId_toAssignee_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "eventType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsMessageEvent_workspaceId_occurredAt_eventType_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "eventType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsMessageEvent_workspaceId_eventType_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "adminId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsMessageEvent_workspaceId_adminId_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "senderType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsMessageEvent_workspaceId_senderType_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "token",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsEmailTopic_token_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "topicId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsEmailTopic_topicId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "topicId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsEmailTopic_workspaceId_topicId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"contactId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsEmailTopic_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"conversationId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsEmailTopic_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"contactInboxId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsEmailTopic_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "objectKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AnalyticsManifestStatus_objectKey_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AnalyticsManifestStatus"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Appointment_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "startAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Appointment_workspaceId_startAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "calendarId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "startAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Appointment_calendarId_status_startAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "calendarId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Appointment_contactId_calendarId_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentCalendar_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "(\"deletedAt\" is null)",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentCalendar_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "publicLinkSlug",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentCalendar_publicLinkSlug_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "calendarId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentCalendarAvailability_calendarId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "calendarId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "timingValue",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "timingUnit",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentCalendarReminder_dedupe_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "jobId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentReminderDispatch_jobId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sendAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentReminderDispatch_status_sendAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "appointmentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentReminderDispatch_appointmentId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AppointmentReminderDispatch_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "messageId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "messageCreatedAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Attachment_message_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Attachment_workspaceId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Attachment_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "providerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "accountId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Account_providerId_accountId_tenantId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Account_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "code",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Invitation_code_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "token",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Session_token_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Session_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "email",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "User_email_tenant_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "User_tenantId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "scheduledDeletionAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"scheduledDeletionAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "User_scheduledDeletionAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Verification_identifier_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Verification"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AutomatedResponse_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "lastTriggeredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AutomationThrottle_lastTriggeredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AutomationThrottle_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BotField_workspaceId_type_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Broadcast_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" IN ('scheduled', 'sending') AND \"deletedAt\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Broadcast_workspaceId_active_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Broadcast_flowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Broadcast_channel_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "schedulesAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Broadcast_schedulesAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Broadcast_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "deletedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"deletedAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Broadcast_deletedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "parentBroadcastId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurrenceAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Broadcast_parentBroadcastId_occurrenceAt_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "broadcastId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastRecurrence_broadcastId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastRecurrence_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "nextRunAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"nextRunAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastRecurrence_due_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "recurrenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "localSlot",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurrenceAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastRecurrenceOccurrence_recurrenceId_localSlot_occurrenceAt_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "recurrenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurrenceAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastRecurrenceOccurrence_recurrenceId_occurrenceAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastRecurrenceOccurrence_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "childBroadcastId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastRecurrenceOccurrence_childBroadcastId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastTarget_inboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "BroadcastTarget_flowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Cart_workspaceId_contactId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Cart_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Cart_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "lastActivityAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"abandonedNotifiedAt\" IS NULL AND jsonb_array_length(\"items\") > 0",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Cart_abandoned_due_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "externalPostId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ChannelPost_workspaceId_channel_externalPostId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "COALESCE(\"publishedAt\", \"createdAt\") DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ChannelPost_workspaceId_sortAt_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ChannelPost_inboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CoexistSyncRun_workspace_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CoexistSyncRun_integration_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lastHeartbeatAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "status IN ('init', 'running')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CoexistSyncRun_active_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"startedAt\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "status IN ('succeeded', 'partial')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CoexistSyncRun_integration_resume_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "status = 'init' AND type = 'coexist'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CoexistSyncRun_integration_init_uq",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "type = 'contact_scan' AND status IN ('init', 'running')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CoexistSyncRun_contact_scan_active_uq",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "type = 'contact_scan'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CoexistSyncRun_contact_scan_due_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomation_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "folderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomation_folderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomation_inboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "automationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "commentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "replyChannel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationEvent_dedup_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "automationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationEvent_automation_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationEvent_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationEvent_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"replyChannel\" = 'private' AND \"deliveredAt\" IS NOT NULL AND \"seenAt\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationEvent_private_unseen_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'failed'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationEvent_failed_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "automationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "commentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationMiss_dedup_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "automationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationMiss_automation_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationMiss_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationMiss_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "automationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "postId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationReply_dedup_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationReply_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentAutomationReply_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "automationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "commentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentModerationLog_dedup_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "automationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentModerationLog_workspace_automation_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"contactId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentModerationLog_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"contactInboxId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CommentModerationLog_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ConnectSession_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "expiresAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ConnectSession_expiresAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "consumedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"consumedAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ConnectSession_consumedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "stateNonceHash",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ConnectSession_stateNonceHash_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Connection_workspaceId_provider_sourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Connection_provider_sourceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Connection_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Connection_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "broadcastSubscribedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "idx_contact_broadcast_subscribed_at",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "idx_contact_workspace_created_at",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "email",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "idx_contact_workspace_email",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "phoneNumber",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "idx_contact_workspace_phone_number",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "md5(btrim(regexp_replace(\"fullName\", '[ \\t\\n\\v\\f\\r]+', ' ', 'g')))",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "idx_contact_workspace_full_name_md5",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "firstName",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": {
+ "name": "gin_trgm_ops",
+ "default": false
+ }
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "Contact_firstName_trgm_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "lastName",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": {
+ "name": "gin_trgm_ops",
+ "default": false
+ }
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "Contact_lastName_trgm_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "email",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": {
+ "name": "gin_trgm_ops",
+ "default": false
+ }
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "Contact_email_trgm_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "phoneNumber",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": {
+ "name": "gin_trgm_ops",
+ "default": false
+ }
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "Contact_phoneNumber_trgm_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "activityType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "referenceType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "parentReferenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "referenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactActivity_reference_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "customFieldId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactCustomField_contactId_customFieldId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "customFieldId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactCustomField_customFieldId_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_inboxId_sourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"sourceUserId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_inboxId_sourceUserId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceParentUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"sourceParentUserId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_inboxId_sourceParentUserId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "profileSnapshotNextAttemptAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"profileSnapshotState\" = 'pending'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_profileSnapshot_pending_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_inboxId_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"threadControlState\" = 'standby' AND \"threadOwnerRole\" = 'ai_agent'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_inboxId_id_ai_held_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lastIncomingMessageAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_contactId_lastIncomingMessageAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lastOutboundMessageAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_contactId_lastOutboundMessageAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "(\"referral\"->>'ctwaClid')",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"referral\"->>'ctwaClid' IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_referral_ctwaClid_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "(\"referral\"->>'adId')",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"referral\"->>'adId' IS NOT NULL AND \"referral\"->>'source' = 'ADS'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInbox_referral_adId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "postId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactInboxPost_workspaceId_postId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactInboxPost"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "normalizedText",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": {
+ "name": "gin_trgm_ops",
+ "default": false
+ }
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "ContactKeywordMessage_text_trgm_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "normalizedText",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": {
+ "name": "text_pattern_ops",
+ "default": false
+ }
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactKeywordMessage_text_prefix_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactNote_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdById",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"createdById\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactNote_createdById_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "idx_contact_on_broadcast_contact_id",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnBroadcast_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnBroadcast_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "isRead",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "idx_contact_on_broadcast_is_read",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "broadcastId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"sent\" = false AND \"failedAt\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnBroadcast_unsent_order_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sequenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactsOnSequence_sequenceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactsOnSequence_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactsOnSequence_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "nextRunAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactsOnSequence_status_nextRunAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "nextRunAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactsOnSequence_workspaceId_status_nextRunAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sequenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactsOnSequence_contactId_sequenceId_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "stepId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnSmartDelay_workspaceId_flowId_contactInboxId_stepId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "triggerAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnSmartDelay_status_triggerAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnSmartDelay_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "appointmentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnSmartDelay_appointmentId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "stepId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"status\" NOT IN ('completed', 'failed', 'canceled') AND \"type\" = 'followUp'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnSmartDelay_followUp_active_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "nodeId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"status\" NOT IN ('completed', 'failed', 'canceled') AND \"type\" = 'quickReplyFollowUp'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnSmartDelay_quickReplyFollowUp_active_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"status\" NOT IN ('completed', 'failed', 'canceled') AND \"type\" = 'stepInputTimeout'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactOnSmartDelay_stepInputTimeout_active_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "dedupKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactReferralEvent_workspaceId_contactInboxId_dedupKey_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactReferralEvent_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactReferralEvent_workspaceId_contactId_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"adId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactReferralEvent_workspaceId_type_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lastDeliveredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"lastDeliveredAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactState_lastDeliveredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactState"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tagId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactToTag_tagId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactToTag"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactToTagChannel_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tagId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ContactToTagChannel_tagId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"sourceId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_contactId_sourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"sourceId\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_contactId_dm_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "assignedUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"assignedUserId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_assignedUserId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "responseDueAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"responseDueAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_workspaceId_responseDueAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "aiContextLastMessageId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_aiContextLastMessageId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lastActivityAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_workspaceId_lastActivityAt_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "assignedUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lastActivityAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"assignedUserId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_workspaceId_assignedUserId_lastActivityAt_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "assignedInboxTeamId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lastActivityAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"assignedInboxTeamId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Conversation_ws_team_lastActivity_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ConversationParticipant_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ConversationParticipant_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ConversationParticipant_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ConversationParticipant_conversationId_userId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "code",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_workspaceId_code_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "topicId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "issuedContactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"issuedContactId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_workspaceId_topicId_issuedContactId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "topicId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_workspaceId_topicId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "topicId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "issuedContactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_workspaceId_topicId_issuedContactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "issuedContactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_issuedContactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "issuedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_issuedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "usedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_usedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "code",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_workspaceId_code_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "topicId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "issuedContactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "usedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Coupon_workspaceId_topicId_issuedContactId_usedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "deletedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CouponTopic_workspaceId_status_deletedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "expiresAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CouponTopic_workspaceId_expiresAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lower(\"name\")",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"deletedAt\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CouponTopic_workspaceId_name_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CustomField_workspaceId_type_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DecisionConnection_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DecisionConnection_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DecisionProfile_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "connectionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DecisionProfile_connectionId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DecisionProfile_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"globalRouterEnabled\" = true",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DecisionProfile_workspaceId_globalRouter_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lower(\"code\")",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DiscountCode_workspaceId_code_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "externalId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"externalId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DiscountCode_workspaceId_source_externalId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "categoryId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DiscountCode_categoryId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DynamicImage_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommerceOpenHours_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommerceOpenHours"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommercePaymentProvider_workspaceId_provider_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "platformCredentialId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "externalAccountId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"externalAccountId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommercePaymentProvider_platformCredentialId_account_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "externalAccountId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommercePaymentProvider_externalAccountId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "providerReference",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderPayment_provider_providerReference_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "orderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderPayment_orderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderPayment_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "expiresAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'open'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderPayment_open_expiresAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommerceSettings_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "openHoursId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommerceSettings_openHoursId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "abandonedCartFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommerceSettings_abandonedCartFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "checkoutFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommerceSettings_checkoutFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "orderConfirmationFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EcommerceSettings_orderConfirmationFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EmailTopic_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "folderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "EmailTopic_folderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AuditLog_workspaceId_createdAt_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"userId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AuditLog_workspaceId_userId_createdAt_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"userId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AuditLog_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "AuditLog_createdAt_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CustomDomain_tenantId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "domain",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CustomDomain_domain_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "CustomDomain_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "licenseId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "License_licenseId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "License"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlatformAdmin_userId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlatformAdmin"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "ownerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Tenant_ownerId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "templateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TenantDefaultTemplate_templateId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TenantDefaultTemplateEvent_tenantId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "actorUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TenantDefaultTemplateEvent_actorUserId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "position",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TenantHelpItem_tenantId_position_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "channelsTornDownAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "UserQuota_channelsTornDownAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"channelsTornDownAt\" IS NULL AND \"planStatus\" = 'trial'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "UserQuota_due_expired_trial_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ErrorLog_workspaceId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ErrorLog_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ErrorLog_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "event",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ExternalWebhook_workspaceId_event_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "event",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "url",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ExternalWebhook_workspaceId_event_url_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "pageId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "formId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookLeadAdsAutomation_workspaceId_pageId_formId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "automationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "leadgenId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookLeadAdsLead_automationId_leadgenId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "leadgenId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookLeadAdsLead_leadgenId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"contactId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookLeadAdsLead_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookLeadAdsLead_contactId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessage_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "audienceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessage_audienceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "startsAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessage_status_startsAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "campaignId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessage_campaignId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessageAudience_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "customAudienceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessageAudience_customAudienceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "campaignRowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "subscriptionToken",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessageRecipient_campaign_token_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "trackingId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessageRecipient_trackingId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "campaignRowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "nextAttemptAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'pending'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessageRecipient_due_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FacebookMarketingMessagesAuth_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "path",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "File_path_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contextType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "File_workspaceId_contextType_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "subType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "File_workspaceId_subType_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"contextType\" = 'export'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "File_export_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"userId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "File_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Flow_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"deletedAt\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowAnalyticsSession_workspaceId_flowId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowAnalyticsSession"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowAnalyticsSession_flowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowAnalyticsSession"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "analyticsId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "nodeId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "eventType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "buttonId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowNodeStat_filter_1_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "analyticsId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "nodeId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"eventType\" = 'seen' AND \"seenAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowNodeStat_filter_2_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowRun_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowRun_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowRun_flowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowVersionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowRun_flowVersionId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowVersion_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "FlowVersion_flowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Folder_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "parentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Folder_parentId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "transactionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "GoogleAdsConversionEvent_workspaceId_transactionId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "GoogleAdsConversionEvent_workspaceId_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "GoogleAdsConversionEvent_workspaceId_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "GoogleAdsConversionEvent_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "referralEventId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"referralEventId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "GoogleAdsConversionEvent_referralEventId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "nextProcessingCheckAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "GoogleAdsConversionEvent_status_nextProcessingCheckAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "claimedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "GoogleAdsConversionEvent_status_claimedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "GoogleAdsSettings_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "GoogleAdsSettings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IgStoryAutomation_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "folderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IgStoryAutomation_folderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IgStoryAutomation_inboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Import_workspaceId_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Import_workspaceId_type_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Import_inboxId_type_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "fileId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Import_fileId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"type\" = 'products' AND \"status\" IN ('pending', 'processing')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Import_products_active_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"userId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Import_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhook_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "token",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhook_token_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboundWebhookId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "idempotencyKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"idempotencyKey\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhookRequest_inboundWebhookId_idempotencyKey_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboundWebhookId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhookRequest_inboundWebhookId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhookRequest_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhookRequest_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhookRequest_inboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'received'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhookRequest_createdAt_received_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "claimedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'processing'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhookRequest_claimedAt_processing_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboundWebhookRequest_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Inbox_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Inbox_workspaceId_channel_sourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboxTeam_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboxTeam"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "inboxTeamId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "InboxTeamMember_userId_inboxTeamId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "InboxTeamMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationActiveCampaign_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationActiveCampaign_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationApi_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationApi_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tokenHash",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationApi_tokenHash_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Integration_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Integration"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Integration_workspaceId_integrationType_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Integration"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationClaude_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationClaude_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationDeepseek_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationDeepseek_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationDrip_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationDrip_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationFacebookAds_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationFacebookAds_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationGemini_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationGemini_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationGetResponse_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationGetResponse_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationGoogleAds_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationGoogleAds_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationGoogleCalendar_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationGoogleSheet_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationInstagram_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "welcomeFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationInstagram_welcomeFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationInstagram_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "igId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationInstagram_igId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationKlaviyo_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationKlaviyo_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMailchimp_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMailchimp_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMailerLite_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMailerLite_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMessenger_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "welcomeFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMessenger_welcomeFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "handoverResumeFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMessenger_handoverResumeFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMessenger_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pageId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMessenger_pageId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMetaCatalog_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMetaCatalog_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "deletedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMetaCatalog_deletedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMoosend_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMoosend_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMuse_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationMuse_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationOpenAI_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationOpenAI_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationOpenaiCompatible_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationOpenaiCompatible_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "preset",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"preset\" <> 'custom'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationOpenaiCompatible_workspaceId_preset_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationOpenrouter_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationOpenrouter_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationOutlookCalendar_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationSendGrid_integrationId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationSendGrid_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationShopify_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationSmtp_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationSmtp_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationTelegram_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationTelegram_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "botId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationTelegram_botId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationThreads_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationThreads_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "threadsUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationThreads_threadsUserId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationTiktok_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationTiktok_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "openId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationTiktok_openId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWebchat_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWebchat_inboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWebchat_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "welcomeFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWebchat_welcomeFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWhatsapp_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWhatsapp_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "wabaId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWhatsapp_wabaId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "handoverResumeFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWhatsapp_handoverResumeFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "phoneNumberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWhatsapp_phoneNumberId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationWoocommerce_workspaceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationZalo_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "fallbackFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationZalo_fallbackFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "oaId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationZalo_oaId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "IntegrationZalo_inboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Leaderboard_workspaceId_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Leaderboard_inboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "minigameId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Leaderboard_minigameId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "leaderboardId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardAuditLog_leaderboardId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardAuditLog_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "leaderboardId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "score",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "scoredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "NOT \"isBanned\"",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardParticipant_ranking_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "leaderboardId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "referrerContactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardParticipant_leaderboardId_referrerContactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardParticipant_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardParticipant_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "referrerContactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"referrerContactId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardParticipant_referrerContactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "leaderboardId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardScoreEvent_leaderboardId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "leaderboardId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardScoreEvent_leaderboardId_contactId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "LeaderboardScoreEvent_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MagicLink_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MagicLink_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "linkId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MagicLinkStat_workspaceId_linkId_occurredAt_contactInboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MediaLibraryFile_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "folderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MediaLibraryFile_folderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MediaLibraryFolder_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MediaLibraryFolder"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Message_conversation_history_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Message_workspace_created_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Message_contactInboxId_sourceId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Message_conversationId_type_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "parentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"parentId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Message_parentId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessageCleanup_inboxId_sourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessageCleanup_status_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessageCleanup_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessageCleanup"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessagingAdOperation_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationWhatsappId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessagingAdOperation_integrationWhatsappId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationMessengerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessagingAdOperation_integrationMessengerId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationInstagramId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessagingAdOperation_integrationInstagramId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessagingAdsConnection_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationWhatsappId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessagingAdsConnection_integrationWhatsappId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationMessengerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessagingAdsConnection_integrationMessengerId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationInstagramId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessagingAdsConnection_integrationInstagramId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationMessengerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessengerMessageTemplate_integrationMessengerId_sourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessengerWelcomeMessageFlow_workspaceId_flowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationMessengerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessengerWelcomeMessageFlow_integrationMessengerId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationMessengerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"status\" = 'current'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MessengerWelcomeMessageFlow_current_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MetaCapiEvent_workspaceId_channel_sourceKey_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MetaCapiEvent_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "channel",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MetaCapiEvent_channel_integrationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationMetaCatalogId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "catalogId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "retailerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MetaCatalogItem_integration_retailer_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationMetaCatalogId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "catalogId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "productId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MetaCatalogItem_integration_product_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "productId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MetaCatalogItem_productId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"status\" IN ('queued', 'running')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MetaCatalogSyncRun_active_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniApp_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniApp_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "miniAppId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationWhatsappId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniAppPublication_miniAppId_integrationWhatsappId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "miniAppId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniAppSubmission_miniAppId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniAppSubmission_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "uploadToken",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniAppUpload_uploadToken_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "path",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniAppUpload_path_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "miniAppId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "inputName",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniAppUpload_miniAppId_inputName_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "submissionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniAppUpload_submissionId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"contactId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MiniAppUpload_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Minigame_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Minigame_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "minigameId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MinigameContact_minigameId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MinigameContact_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "minigameId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MinigameContact_minigameId_contactId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "referrerContactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"referrerContactId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MinigameContact_referrerContactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"contactInboxId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MinigameContact_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "minigameId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MinigamePlay_minigameId_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MinigamePlay_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tokenHash",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MobileRefreshToken_tokenHash_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MobileRefreshToken_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "familyId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "rotatedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MobileRefreshToken_familyId_rotatedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "expiresAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "MobileRefreshToken_expiresAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "token",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthAccessToken_token_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "clientId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthAccessToken_clientId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sessionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthAccessToken_sessionId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthAccessToken_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "authorizationCodeId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthAccessToken_authorizationCodeId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "refreshId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthAccessToken_refreshId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "clientId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthClient_clientId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthClient_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "expiresAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthClientAssertion_expiresAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthClientAssertion"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "clientId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthClientResource_clientId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "resourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthClientResource_resourceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "clientId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "resourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthClientResource_clientId_resourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "clientId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthConsent_clientId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthConsent_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workspaceId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthConsent_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "token",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthRefreshToken_token_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "clientId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthRefreshToken_clientId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sessionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthRefreshToken_sessionId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthRefreshToken_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "authorizationCodeId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthRefreshToken_authorizationCodeId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthResource_identifier_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "disabled",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OAuthResource_disabled_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OAuthResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "orderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DiscountCodeRedemption_orderId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "discountCodeId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DiscountCodeRedemption_discountCodeId_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "DiscountCodeRedemption_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "orderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderItem_orderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "productId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderItem_workspaceId_productId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "vendorId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderItem_workspaceId_vendorId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "variantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderItem_variantId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "categoryId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderItem_categoryId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "externalId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"externalId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_workspaceId_externalId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_workspaceId_source_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "number",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_workspaceId_number_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_workspaceId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_workspaceId_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_inboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "discountCodeId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_discountCodeId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "paymentExpiresAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'pending' AND \"paymentStatus\" = 'unpaid' AND \"paymentExpiresAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Order_paymentExpiresAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "orderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderStatusHistory_orderId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderStatusHistory_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "actorUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "OrderStatusHistory_actorUserId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "referenceName",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineField_pipelineId_referenceName_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineField_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemActivity_pipeline_kind_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "itemId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"occurredAt\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemActivity_item_occurredAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemActivity_contact_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemActivity_pipelineId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "actorUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"actorUserId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemActivity_actorUserId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "itemId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "workspaceMemberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAssignee_item_member_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "itemId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "inboxTeamId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAssignee_item_team_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "workspaceMemberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAssignee_member_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "inboxTeamId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAssignee_team_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceMemberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workspaceMemberId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAssignee_workspaceMemberId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxTeamId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"inboxTeamId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAssignee_inboxTeamId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "itemId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "mediaLibraryFileId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAttachment_item_file_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "mediaLibraryFileId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAttachment_mediaLibraryFileId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemAttachment_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "itemId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"createdAt\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemComment_item_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdById",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"createdById\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemComment_createdById_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "itemId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "idempotencyKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"idempotencyKey\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItemComment_item_idempotencyKey_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "number",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_workspaceId_number_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "idempotencyKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"idempotencyKey\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_pipeline_idempotencyKey_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"createdAt\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_contact_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "stageId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"createdAt\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"id\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_stage_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"createdAt\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "\"id\" DESC",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_pipeline_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_pipeline_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "stageId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_stageId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdById",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"createdById\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_createdById_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "closedById",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"closedById\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineItem_closedById_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "workspaceMemberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineMember_pipeline_member_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "workspaceMemberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineMember_member_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceMemberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineMember_workspaceMemberId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "referenceName",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Pipeline_workspaceId_referenceName_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Pipeline_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdById",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"createdById\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Pipeline_createdById_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pipelineId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "position",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineStage_pipelineId_position_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PipelineStage_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlaceCategory_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lower(\"name\")",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlaceCategory_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlaceLocation_workspaceId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "categoryId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlaceLocation_categoryId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "livemode",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"userId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlatformCredential_user_type_livemode_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "livemode",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"userId\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlatformCredential_platform_type_livemode_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"userId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlatformCredential_user_type_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"userId\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlatformCredential_platform_type_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PlatformCredential_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pollId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "position",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PollCandidate_pollId_position_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PollCandidate_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Poll_workspaceId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "afterVoteFlowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Poll_afterVoteFlowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "pollId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PollVote_pollId_contactId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PollVote_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "candidateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PollVote_candidateId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PollVote_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "PollVote_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Product_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "categoryId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Product_categoryId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "subcategoryId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Product_subcategoryId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "vendorId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Product_vendorId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "externalId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"externalId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Product_workspaceId_source_externalId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "productId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ProductAddon_productId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ProductCategory_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "parentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ProductCategory_parentId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "productId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ProductVariant_productId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "externalInventoryItemId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"externalInventoryItemId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ProductVariant_externalInventoryItemId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "productId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "ProductVariantOption_productId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "submissionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "questionIdSnapshot",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireAnswer_submissionId_questionIdSnapshot_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "questionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireAnswer_questionId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Questionnaire_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "(\"deletedAt\" is null)",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Questionnaire_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "questionnaireId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "orderNo",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireQuestion_questionnaireId_orderNo_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "customFieldId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireQuestion_customFieldId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireSubmission_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "questionnaireId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireSubmission_questionnaireId_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "questionnaireId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireSubmission_questionnaireId_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireSubmission_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"conversationId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireSubmission_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "currentQuestionId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"currentQuestionId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireSubmission_currentQuestionId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "completedAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireSubmission_workspaceId_contactId_completedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"status\" = 'inProgress'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "QuestionnaireSubmission_workspaceId_contactId_active_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "RefLinkStat_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "linkId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "occurredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "RefLinkStat_workspaceId_linkId_occurredAt_contactInboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Reflink_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SavedReply_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SavedReply"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "savedReplyId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SavedReplyImage_savedReplyId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "mediaLibraryFileId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SavedReplyImage_mediaLibraryFileId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SavedReplyImage_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "savedReplyId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "mediaLibraryFileId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SavedReplyImage_savedReplyId_mediaLibraryFileId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "folderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Sequence_folderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Sequence_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "idempotencyKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_idempotencyKey_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "runAtMs",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'pending'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_pending_runAtMs_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "bucket",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "runAtMs",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'pending'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_pending_bucket_runAtMs_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "runAtMs",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_status_runAtMs_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "runAtMs",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_workspaceId_status_runAtMs_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "enrollmentId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_enrollmentId_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sequenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "stepId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_workspace_sequence_step_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "bucket",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "runAtMs",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_bucket_status_runAtMs_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "updatedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" in ('completed', 'failed', 'canceled')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_terminal_updatedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sequenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_sequenceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "stepId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceDispatch_stepId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sequenceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceStep_sequenceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "flowId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "SequenceStep_flowId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Spreadsheet_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "spreadsheetId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Spreadsheet_workspaceId_spreadsheetId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "spreadsheetId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Spreadsheet_spreadsheetId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "(\"deletedAt\" is null)",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Tag_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "folderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Tag_folderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tagId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channelType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TagChannel_tag_integration_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "channelType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "externalLabelId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TagChannel_external_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "channelType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TagChannel_workspace_channel_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "channelType",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "integrationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TagChannel_integration_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "chatId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TelegramChat_inboxId_chatId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TelegramChat_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Template_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Template_tenantId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "shareToken",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Template_shareToken_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "templateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_templateId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_workspaceId_status_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceTemplateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"status\" IN ('pending', 'installing')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_workspaceId_sourceTemplateId_active_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sourceTemplateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_sourceTemplateId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sourceTemplateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceVersion",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"autoUpdate\" = true AND \"status\" IN ('completed', 'partial') AND \"sourceDeletedAt\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_autoUpdate_sourceTemplateId_sourceVersion_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "templateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "publisherRef",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_templateId_publisherRef_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "uninstallRequestedBy",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_uninstallRequestedBy_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "uninstallOperationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_uninstallOperationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "uninstallState",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "uninstallClaimedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"uninstallState\" IN ('pending', 'running')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_uninstallState_claimedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "updatedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"pendingPublishEffects\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_pendingPublishEffects_updatedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "updatedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "((\"status\" = 'failed' AND \"stagedCleanedGeneration\" < \"stagingGeneration\") OR (\"status\" <> 'failed' AND \"stagedCleanedGeneration\" < \"stagingGeneration\" - 1))",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_stagedCleanupOwed_updatedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "claimedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallation_status_claimedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallationSync_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "requestedBy",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallationSync_requestedBy_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "installationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallationSync_installationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "installationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "requestedVersion",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"trigger\" = 'autoUpdate' AND \"status\" IN ('pending', 'running')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallationSync_auto_active_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "installationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "idempotencyKey",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"idempotencyKey\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallationSync_idempotency_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "claimedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstallationSync_status_claimedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "resourceKind",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "resourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"wasExisting\" = false AND \"detachedAt\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstalledResource_active_lookup_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "installationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "resourceKind",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceResourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"detachedAt\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstalledResource_active_source_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "uninstallEffectsAttempts",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"uninstallEffects\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstalledResource_pending_effects_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "installationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstalledResource_installationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "resourceKind",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "resourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateInstalledResource_workspaceId_resourceKind_resourceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateResourceBackup_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "installationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateResourceBackup_installationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "syncId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateResourceBackup_syncId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "installedResourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateResourceBackup_installedResourceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lower(\"name\")",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateStoreCategory_tenantId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "rank",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateStoreCategory_tenantId_rank_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdBy",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"createdBy\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateStoreCategory_createdBy_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "categoryId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateStoreListingCategory_categoryId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateStoreListingCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "templateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateStoreListing_tenantId_templateId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "templateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateStoreListing_templateId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdBy",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"createdBy\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateStoreListing_createdBy_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateUninstallOperation_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "templateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateUninstallOperation_templateId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "requestedBy",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateUninstallOperation_requestedBy_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "state",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "noticeDeliveredAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateUninstallOperation_notice_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "templateId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "version",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateVersion_templateId_version_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TemplateVersion_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Trigger_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Trigger_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "folderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Trigger_folderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "active",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Trigger_workspaceId_active_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Condition_type_source_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "triggerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Condition_triggerId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "webhookId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Condition_webhookId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "triggerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Condition_type_sourceId_triggerId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "type",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "webhookId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Condition_type_sourceId_webhookId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "triggerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerContactHistory_triggerId_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerContactHistory_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerContactHistory_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "triggerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerExecution_triggerId_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerExecution_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerExecution_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "triggerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerStat_triggerId_date_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "triggerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerStat_triggerId_date_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "TriggerStat_workspaceId_date_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "UserDeviceToken_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "UserPersistentMenu_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "UserPersistentMenu"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Vendor_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "openHoursId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Vendor_openHoursId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "categoryId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Vendor_categoryId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "subcategoryId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Vendor_subcategoryId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "lower(\"name\")",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Vendor_workspaceId_name_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Webhook_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "folderId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Webhook_folderId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "active",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Webhook_workspaceId_active_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "webhookId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WebhookExecution_webhookId_contactId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WebhookExecution_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WebhookExecution_contactId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "wabaId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappBusinessAccount_workspaceId_wabaId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "wacid",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"wacid\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_wacid_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "attemptId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"attemptId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_attemptId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "conversationId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_conversationId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_contactInboxId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_workspaceId_createdAt_id_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_contactInboxId_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'ringing'",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_ringing_createdAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "createdAt",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"status\" = 'ringing' AND \"wacid\" IS NOT NULL AND \"answeredByUserId\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_resumableRinging_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "recordedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"recordingPath\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_recording_inboxId_recordedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "inboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"direction\" = 'businessInitiated' AND \"status\" IN ('ringing', 'accepted')",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_pendingOutbound_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "answeredByUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"answeredByUserId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_answeredByUserId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "initiatedByUserId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"initiatedByUserId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCall_initiatedByUserId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "contactInboxId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCallPermission_contactInboxId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCallPermission_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "phoneNumberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCoexistStaging_phoneNumberId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "phoneNumberId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "payloadHash",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCoexistStaging_phone_hash_uq",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "processedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"processedAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCoexistStaging_processedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "parseFailedAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "\"parseFailedAt\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappCoexistStaging_parseFailedAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationWhatsappId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappFlow_integrationWhatsappId_sourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "integrationWhatsappId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "sourceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappMessageTemplate_integrationWhatsappId_sourceId_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappSignupSession_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "expiresAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WhatsappSignupSession_expiresAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkingHours_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkingHours"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workingHoursId\" IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkingHoursDateOverride_workspace_date_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workingHoursId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workingHoursId\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkingHoursDateOverride_schedule_date_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkingHoursDateOverride_workspaceId_date_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workingHoursId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkingHoursInterval_workingHoursId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workingHoursId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkingHoursMember_workingHoursId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "ownerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Workspace_ownerId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Workspace_tenantId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "scheduledDeletionAt",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Workspace_scheduledDeletionAt_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "supportAccessUntil",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "Workspace_supportAccessUntil_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceApiToken_workspaceId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"isDefault\"",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceApiToken_workspaceId_default_key",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "ownerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "periodStart",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceBotMessageUsage_ownerId_periodStart_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "periodStart",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceBotMessageUsage_tenantId_periodStart_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "ownerEmail",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceDeletionRecord_ownerEmail_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "ownerId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "periodStart",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceMac_ownerId_periodStart_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tenantId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "periodStart",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceMac_tenantId_periodStart_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "workspaceId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceMember_workspaceId_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "userId",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "WorkspaceMember_userId_idx",
+ "entityType": "indexes",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "shardId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MessageShard",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ShardTimeRange_shardId_MessageShard_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ShardTimeRange"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationWhatsappId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationWhatsapp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionEvent_IENNsXLBb1k1_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMessengerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMessenger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionEvent_yeTDEtvJMs4H_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationInstagramId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationInstagram",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionEvent_1X1qUqZpm24x_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AdsConversionEvent_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "referralEventId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactReferralEvent",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AdsConversionEvent_referralEventId_ContactReferralEvent_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionRule_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationWhatsappId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationWhatsapp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionRule_k99JXbMObQIn_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationFacebookAdsId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationFacebookAds",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionRule_fBmu8W26Mw5R_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMessengerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMessenger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionRule_3zzAptVRRuZD_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationInstagramId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationInstagram",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AdsConversionRule_HUibBtSUZbML_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AdsConversionRule"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIAgent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIAgent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "sourceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "AIConversationSource",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIConversationEmbedding_sourceId_AIConversationSource_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIConversationEmbedding_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIConversationEmbedding_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIConversationEmbedding"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIConversationSource_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIConversationSource_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIConversationSource"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIEmbedding_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "aiFileId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "AIFile",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIEmbedding_aiFileId_AIFile_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIEmbedding"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIFile_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIFile"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "triggerFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AIFunction_triggerFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIFunction_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIFunction"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIHandoverBulkRun_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIHandoverBulkRun_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "requestedByUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AIHandoverBulkRun_requestedByUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIHandoverBulkRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIHandoverSettings_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIHandoverSettings_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "gotoFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AIHandoverSettings_gotoFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "applyToAllRequestedByUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AIHandoverSettings_applyToAllRequestedByUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIHandoverSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AIMCPServer_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AIMCPServer"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "AnalyticsAgentResponseEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "AnalyticsBotMessageEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "AnalyticsContactEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "AnalyticsConversationEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "AnalyticsMessageEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "topicId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "EmailTopic",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AnalyticsEmailTopic_topicId_EmailTopic_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AnalyticsEmailTopic_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AnalyticsEmailTopic_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AnalyticsEmailTopic_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AnalyticsEmailTopic_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Appointment_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "calendarId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "AppointmentCalendar",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "Appointment_calendarId_AppointmentCalendar_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Appointment_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Appointment_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Appointment_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Appointment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AppointmentCalendar_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "confirmationFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AppointmentCalendar_confirmationFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "cancellationFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AppointmentCalendar_cancellationFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "externalConnectionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AppointmentCalendar_externalConnectionId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentCalendar"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "calendarId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "AppointmentCalendar",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AppointmentCalendarAvailability_QfahoIQAX592_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "calendarId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "AppointmentCalendar",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AppointmentCalendarReminder_5O4INfYC3dY3_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AppointmentCalendarReminder_flowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AppointmentReminderDispatch_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "appointmentId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Appointment",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AppointmentReminderDispatch_appointmentId_Appointment_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "reminderConfigId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "AppointmentCalendarReminder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AppointmentReminderDispatch_a526jJM55OD7_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AppointmentReminderDispatch_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Account_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "Account_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Account"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Invitation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "invitedBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Invitation_invitedBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Invitation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Session_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Session"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "User_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "User"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AutomatedResponse_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AutomatedResponse_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AutomatedResponse_flowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AutomatedResponse"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AutomationThrottle_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AutomationThrottle_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "BotField_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "BotField_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BotField"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Broadcast_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Broadcast_flowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationWhatsappId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationWhatsapp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Broadcast_integrationWhatsappId_IntegrationWhatsapp_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMessengerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMessenger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Broadcast_integrationMessengerId_IntegrationMessenger_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "parentBroadcastId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Broadcast",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Broadcast_parentBroadcastId_Broadcast_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "BroadcastRecurrence_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "broadcastId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Broadcast",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "BroadcastRecurrence_broadcastId_Broadcast_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BroadcastRecurrence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "BroadcastRecurrenceOccurrence_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "recurrenceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "BroadcastRecurrence",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "BroadcastRecurrenceOccurrence_x0yNXfzZ2cZs_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "childBroadcastId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Broadcast",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "BroadcastRecurrenceOccurrence_Md67cxyTrOQZ_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "broadcastId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Broadcast",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "BroadcastTarget_broadcastId_Broadcast_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "BroadcastTarget_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "BroadcastTarget_flowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Cart_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Cart_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Cart_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Cart"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ChannelPost_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ChannelPost_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ChannelPost"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "requestedByUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CoexistSyncRun_requestedByUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CoexistSyncRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CommentAutomation_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomation_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomationEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "automationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CommentAutomation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomationEvent_automationId_CommentAutomation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CommentAutomationEvent_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CommentAutomationEvent_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomationMiss_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "automationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CommentAutomation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomationMiss_automationId_CommentAutomation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CommentAutomationMiss_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CommentAutomationMiss_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationMiss"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "automationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CommentAutomation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomationReply_automationId_CommentAutomation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomationReply_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "CommentAutomationReply_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentAutomationReply"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CommentModerationLog_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "automationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CommentAutomation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CommentModerationLog_automationId_CommentAutomation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CommentModerationLog_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CommentModerationLog_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CommentModerationLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ConnectSession_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "targetConnectionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Connection",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ConnectSession_targetConnectionId_Connection_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "actorUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "ConnectSession_actorUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "actorTokenId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "WorkspaceApiToken",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "ConnectSession_actorTokenId_WorkspaceApiToken_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Connection_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Connection_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Connection_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Connection_createdBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Contact_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Contact"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactCustomField_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "customFieldId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CustomField",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactCustomField_customFieldId_CustomField_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactCustomField"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactInbox_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactInbox_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactInbox"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactNote_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdById"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "ContactNote_createdById_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactNote"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "broadcastId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Broadcast",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnBroadcast_broadcastId_Broadcast_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnBroadcast_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnBroadcast_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnBroadcast_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnSequence_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "sequenceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Sequence",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnSequence_sequenceId_Sequence_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnSequence_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnSmartDelay_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "appointmentId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Appointment",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "ContactOnSmartDelay_appointmentId_Appointment_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactOnSmartDelay_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactOnSmartDelay"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactReferralEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactReferralEvent_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactToTag_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactToTag"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tagId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tag",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactToTag_tagId_Tag_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactToTag"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tagId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tag",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactToTagChannel_tagId_Tag_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tagChannelId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TagChannel",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactToTagChannel_tagChannelId_TagChannel_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ContactToTagChannel_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "assignedUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Conversation_assignedUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "assignedInboxTeamId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "InboxTeam",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Conversation_assignedInboxTeamId_InboxTeam_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Conversation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Conversation_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Conversation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ConversationParticipant_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ConversationParticipant_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ConversationParticipant_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ConversationParticipant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Coupon_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "topicId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CouponTopic",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Coupon_topicId_CouponTopic_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "issuedContactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Coupon_issuedContactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Coupon"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CouponTopic_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdById"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CouponTopic_createdById_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CouponTopic"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "CustomField_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CustomField_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CustomField"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "DecisionConnection_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DecisionConnection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "DecisionProfile_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "connectionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "DecisionConnection",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "DecisionProfile_connectionId_DecisionConnection_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DecisionProfile"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "DiscountCode_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "categoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "DiscountCode_categoryId_ProductCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "DynamicImage_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "customFieldId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CustomField",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "DynamicImage_customFieldId_CustomField_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DynamicImage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "EcommerceOpenHours_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommerceOpenHours"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "EcommercePaymentProvider_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "platformCredentialId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "PlatformCredential",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "EcommercePaymentProvider_eOJU9fhqr8NU_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommercePaymentProvider"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "orderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Order",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OrderPayment_orderId_Order_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OrderPayment_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderPayment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "EcommerceOrderCounter_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommerceOrderCounter"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "EcommerceSettings_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "openHoursId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "EcommerceOpenHours",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "EcommerceSettings_openHoursId_EcommerceOpenHours_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "abandonedCartFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "EcommerceSettings_abandonedCartFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "checkoutFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "EcommerceSettings_checkoutFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "orderConfirmationFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "EcommerceSettings_orderConfirmationFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "EmailTopic_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "EmailTopic_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "EmailTopic"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "AuditLog_workspaceId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "AuditLog_userId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "AuditLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "CustomDomain_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "CustomDomain"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "PlatformAdmin_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PlatformAdmin"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "ownerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "Tenant_ownerId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Tenant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TenantDefaultTemplate_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "templateId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Template",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TenantDefaultTemplate_templateId_Template_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TenantDefaultTemplate"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TenantDefaultTemplateEvent_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "actorUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TenantDefaultTemplateEvent_actorUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TenantHelpItem_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TenantHelpItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "UserQuota_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "UserQuota"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "WorkspaceUsage_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkspaceUsage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ErrorLog_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "ErrorLog_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ErrorLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ExternalWebhook_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ExternalWebhook"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FacebookLeadAdsAutomation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "automationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "FacebookLeadAdsAutomation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FacebookLeadAdsLead_n8swD949nr3L_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "FacebookLeadAdsLead_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FacebookMarketingMessage_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "audienceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "FacebookMarketingMessageAudience",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "FacebookMarketingMessage_3m4P7t9wgiEX_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookMarketingMessage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FacebookMarketingMessageAudience_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FacebookMarketingMessageRecipient_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "campaignRowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "FacebookMarketingMessage",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FacebookMarketingMessageRecipient_JpRpjGJ419Rs_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FacebookMarketingMessagesAuth_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "File_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "File_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "File"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Flow_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Flow_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Flow"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FlowNodeStat_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FlowNodeStat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FlowRun_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FlowRun_flowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowVersionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "FlowVersion",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FlowRun_flowVersionId_FlowVersion_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FlowRun_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FlowRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FlowVersion_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "FlowVersion_flowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "FlowVersion"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Folder_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Folder"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "GoogleAdsConversionEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationGoogleAdsId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationGoogleAds",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "GoogleAdsConversionEvent_Ju5oh0fVmaLy_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "GoogleAdsConversionEvent_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "referralEventId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactReferralEvent",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "GoogleAdsConversionEvent_0EWR38dBZsuA_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "GoogleAdsSettings_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "GoogleAdsSettings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IgStoryAutomation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "IgStoryAutomation_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IgStoryAutomation_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IgStoryAutomation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Import_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Import_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Import_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "fileId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "File",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "Import_fileId_File_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Import"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "InboundWebhook_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboundWebhook"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "InboundWebhookRequest_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboundWebhookId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "InboundWebhook",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "InboundWebhookRequest_inboundWebhookId_InboundWebhook_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "InboundWebhookRequest_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "InboundWebhookRequest_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboundWebhookRequest"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Inbox_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Inbox"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "InboxContactStat_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboxContactStat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "InboxTeam_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboxTeam"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxTeamId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "InboxTeam",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "InboxTeamMember_inboxTeamId_InboxTeam_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboxTeamMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "InboxTeamMember_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "InboxTeamMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationActiveCampaign_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationActiveCampaign_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationApi_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationApi_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationApi"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Integration_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Integration"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationClaude_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationClaude_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationClaude"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationDeepseek_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationDeepseek_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationDeepseek"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationDrip_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationDrip_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationDrip"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationFacebookAds_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationFacebookAds_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationFacebookAds"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGemini_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGemini_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGemini"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGetResponse_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGetResponse_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGetResponse"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGoogleAds_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGoogleAds_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGoogleAds"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGoogleCalendar_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGoogleCalendar_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGoogleSheet_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationGoogleSheet_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationInstagram_workspaceId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationInstagram_inboxId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "welcomeFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "IntegrationInstagram_welcomeFlowId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationInstagram"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationKlaviyo_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationKlaviyo_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationKlaviyo"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMailchimp_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMailchimp_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMailchimp"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMailerLite_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMailerLite_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMailerLite"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMessenger_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMessenger_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "welcomeFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "IntegrationMessenger_welcomeFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "handoverResumeFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "IntegrationMessenger_handoverResumeFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMessenger"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMetaCatalog_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMetaCatalog_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMoosend_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMoosend_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMoosend"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMuse_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationMuse_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationMuse"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationOpenai_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationOpenai_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "aiAgentId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "AIAgent",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "IntegrationOpenai_aiAgentId_AIAgent_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOpenai"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationOpenaiCompatible_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationOpenaiCompatible_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationOpenrouter_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationOpenrouter_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOpenrouter"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationOutlookCalendar_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationOutlookCalendar_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationSendGrid_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Integration",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationSendGrid_integrationId_Integration_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationSendGrid"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationShopify_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationShopify"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationSmtp_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationSmtp_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationSmtp"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationTelegram_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationTelegram_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationTelegram"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationThreads_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationThreads_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationThreads"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationTiktok_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationTiktok_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationTiktok"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationWebchat_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationWebchat_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "welcomeFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "IntegrationWebchat_welcomeFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationWebchat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "handoverResumeFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "IntegrationWhatsapp_handoverResumeFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationWhatsapp_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationWhatsapp_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationWoocommerce_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationWoocommerce"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationZalo_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "IntegrationZalo_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "fallbackFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "IntegrationZalo_fallbackFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "IntegrationZalo"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Leaderboard_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Leaderboard_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "minigameId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Minigame",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Leaderboard_minigameId_Minigame_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "referralWelcomeFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Leaderboard_referralWelcomeFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Leaderboard"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "leaderboardId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Leaderboard",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "LeaderboardAuditLog_leaderboardId_Leaderboard_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "LeaderboardAuditLog_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "LeaderboardAuditLog_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "actorUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "LeaderboardAuditLog_actorUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "LeaderboardAuditLog"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "leaderboardId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Leaderboard",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "LeaderboardParticipant_leaderboardId_Leaderboard_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "LeaderboardParticipant_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "LeaderboardParticipant_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "referrerContactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "LeaderboardParticipant_referrerContactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MagicLink_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MagicLink"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MagicLinkStat_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "linkId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MagicLink",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MagicLinkStat_linkId_MagicLink_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MagicLinkStat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MediaLibraryFile_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MediaLibraryFolder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "MediaLibraryFile_folderId_MediaLibraryFolder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MediaLibraryFile"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MediaLibraryFolder_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MediaLibraryFolder"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessagingAdOperation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationWhatsappId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationWhatsapp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessagingAdOperation_D2X0VlACjh0B_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMessengerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMessenger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessagingAdOperation_DlCmuyYqclNt_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationInstagramId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationInstagram",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessagingAdOperation_LwL2ykeZegup_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "MessagingAdOperation_createdBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessagingAdsConnection_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationWhatsappId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationWhatsapp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessagingAdsConnection_Q2FrBLiP3QqD_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMessengerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMessenger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessagingAdsConnection_tLZC78O5pMBb_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationInstagramId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationInstagram",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessagingAdsConnection_4ubezEjd9jQX_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMessengerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMessenger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessengerMessageTemplate_x0Vv1d8cvLYN_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessengerMessageTemplate"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessengerWelcomeMessageFlow_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMessengerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMessenger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MessengerWelcomeMessageFlow_OSpsF41G77zr_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MetaCapiEvent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MetaCapiEvent_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMetaCatalogId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMetaCatalog",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MetaCatalogItem_wJXyKUssR08y_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "productId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Product",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MetaCatalogItem_productId_Product_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MetaCatalogItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MetaCatalogSyncRun_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationMetaCatalogId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationMetaCatalog",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MetaCatalogSyncRun_8PnmCJ0uISUd_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "categoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "MetaCatalogSyncRun_categoryId_ProductCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MiniApp_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniApp"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "miniAppId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MiniApp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MiniAppPublication_miniAppId_MiniApp_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationWhatsappId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationWhatsapp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MiniAppPublication_oBb1VPqI8uvn_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "whatsappFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "WhatsappFlow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "MiniAppPublication_whatsappFlowId_WhatsappFlow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppPublication"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MiniAppSubmission_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "miniAppId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MiniApp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MiniAppSubmission_miniAppId_MiniApp_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "MiniAppSubmission_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppSubmission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MiniAppUpload_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "miniAppId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MiniApp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MiniAppUpload_miniAppId_MiniApp_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MiniAppUpload_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "submissionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MiniAppSubmission",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "MiniAppUpload_submissionId_MiniAppSubmission_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MiniAppUpload"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Minigame_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Minigame"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "minigameId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Minigame",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MinigameContact_minigameId_Minigame_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MinigameContact_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "referrerContactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "MinigameContact_referrerContactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "MinigameContact_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MinigameContact"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "minigameId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Minigame",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MinigamePlay_minigameId_Minigame_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MinigamePlay_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MinigamePlay"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "MobileRefreshToken_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "MobileRefreshToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "clientId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "OAuthClient",
+ "columnsTo": [
+ "clientId"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthAccessToken_clientId_OAuthClient_clientId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "sessionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Session",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "OAuthAccessToken_sessionId_Session_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthAccessToken_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "refreshId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "OAuthRefreshToken",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "OAuthAccessToken_refreshId_OAuthRefreshToken_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthAccessToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthClient_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthClient"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "clientId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "OAuthClient",
+ "columnsTo": [
+ "clientId"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthClientResource_clientId_OAuthClient_clientId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "resourceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "OAuthResource",
+ "columnsTo": [
+ "identifier"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthClientResource_resourceId_OAuthResource_identifier_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthClientResource"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "clientId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "OAuthClient",
+ "columnsTo": [
+ "clientId"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthConsent_clientId_OAuthClient_clientId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthConsent_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthConsent_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthConsent"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "clientId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "OAuthClient",
+ "columnsTo": [
+ "clientId"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthRefreshToken_clientId_OAuthClient_clientId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "sessionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Session",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "OAuthRefreshToken_sessionId_Session_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OAuthRefreshToken_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OAuthRefreshToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "DiscountCodeRedemption_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "discountCodeId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "DiscountCode",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "DiscountCodeRedemption_discountCodeId_DiscountCode_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "orderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Order",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "DiscountCodeRedemption_orderId_Order_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "DiscountCodeRedemption_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "DiscountCodeRedemption"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "orderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Order",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OrderItem_orderId_Order_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OrderItem_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "productId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Product",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "OrderItem_productId_Product_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "variantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductVariant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "OrderItem_variantId_ProductVariant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "vendorId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Vendor",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "OrderItem_vendorId_Vendor_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "categoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "OrderItem_categoryId_ProductCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Order_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Order_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Order_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Order_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Order_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "discountCodeId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "DiscountCode",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Order_discountCodeId_DiscountCode_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Order"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "orderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Order",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OrderStatusHistory_orderId_Order_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "OrderStatusHistory_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "actorUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "OrderStatusHistory_actorUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "OrderStatusHistory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineField_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pipelineId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Pipeline",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineField_pipelineId_Pipeline_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineField"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemActivity_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pipelineId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Pipeline",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemActivity_pipelineId_Pipeline_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "actorUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "PipelineItemActivity_actorUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemAssignee_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "itemId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "PipelineItem",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemAssignee_itemId_PipelineItem_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceMemberId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "WorkspaceMember",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemAssignee_workspaceMemberId_WorkspaceMember_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxTeamId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "InboxTeam",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemAssignee_inboxTeamId_InboxTeam_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemAttachment_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "itemId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "PipelineItem",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemAttachment_itemId_PipelineItem_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "mediaLibraryFileId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MediaLibraryFile",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemAttachment_BBiTPytjYFfD_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemAttachment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemComment_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "itemId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "PipelineItem",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemComment_itemId_PipelineItem_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdById"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "PipelineItemComment_createdById_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemComment"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItemCounter_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItemCounter"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItem_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pipelineId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Pipeline",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItem_pipelineId_Pipeline_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "stageId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "PipelineStage",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItem_stageId_PipelineStage_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineItem_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdById"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "PipelineItem_createdById_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "closedById"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "PipelineItem_closedById_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineItem"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineMember_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pipelineId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Pipeline",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineMember_pipelineId_Pipeline_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceMemberId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "WorkspaceMember",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineMember_workspaceMemberId_WorkspaceMember_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Pipeline_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdById"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Pipeline_createdById_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Pipeline"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineStage_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pipelineId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Pipeline",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PipelineStage_pipelineId_Pipeline_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PipelineStage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PlaceCategory_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PlaceCategory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PlaceLocation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "categoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "PlaceCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "PlaceLocation_categoryId_PlaceCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Credential_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PlatformCredential"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PollCandidate_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pollId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Poll",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PollCandidate_pollId_Poll_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PollCandidate"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Poll_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "afterVoteFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Poll_afterVoteFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Poll"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PollVote_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pollId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Poll",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PollVote_pollId_Poll_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "candidateId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "PollCandidate",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PollVote_candidateId_PollCandidate_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "PollVote_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "PollVote_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "PollVote"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "vendorId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Vendor",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Product_vendorId_Vendor_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "categoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Product_categoryId_ProductCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "subcategoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Product_subcategoryId_ProductCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Product_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Product"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "productId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Product",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ProductAddon_productId_Product_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ProductAddon"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ProductCategory_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "parentId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ProductCategory_parentId_ProductCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "productId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Product",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ProductVariant_productId_Product_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ProductVariant"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "productId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Product",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ProductVariantOption_productId_Product_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ProductVariantOption"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "submissionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "QuestionnaireSubmission",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "QuestionnaireAnswer_l8clOEM7NsPl_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "questionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "QuestionnaireQuestion",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "QuestionnaireAnswer_questionId_QuestionnaireQuestion_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireAnswer"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "triggerFlowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Questionnaire_triggerFlowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Questionnaire_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Questionnaire"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "questionnaireId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Questionnaire",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "QuestionnaireQuestion_questionnaireId_Questionnaire_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "customFieldId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CustomField",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "QuestionnaireQuestion_customFieldId_CustomField_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "QuestionnaireSubmission_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "questionnaireId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Questionnaire",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "QuestionnaireSubmission_questionnaireId_Questionnaire_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "QuestionnaireSubmission_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "QuestionnaireSubmission_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "currentQuestionId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "QuestionnaireQuestion",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "QuestionnaireSubmission_mha0bYFxcV7A_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "QuestionnaireSubmission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "RefLinkStat_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "linkId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Reflink",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "RefLinkStat_linkId_Reflink_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "RefLinkStat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Reflink_flowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Reflink_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "customFieldId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "CustomField",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Reflink_customFieldId_CustomField_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "widgetLogoFileId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MediaLibraryFile",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Reflink_widgetLogoFileId_MediaLibraryFile_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Reflink"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "ResponseSlaPolicy_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SavedReply_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SavedReply"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "savedReplyId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "SavedReply",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SavedReplyImage_savedReplyId_SavedReply_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "mediaLibraryFileId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "MediaLibraryFile",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SavedReplyImage_mediaLibraryFileId_MediaLibraryFile_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SavedReplyImage_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SavedReplyImage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Sequence_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Sequence_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Sequence"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SequenceDispatch_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "sequenceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Sequence",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SequenceDispatch_sequenceId_Sequence_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SequenceDispatch_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SequenceDispatch_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "stepId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "SequenceStep",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SequenceDispatch_stepId_SequenceStep_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "enrollmentId",
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactOnSequence",
+ "columnsTo": [
+ "id",
+ "workspaceId"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SequenceDispatch_enrollment_workspace_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "flowId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Flow",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "SequenceStep_flowId_Flow_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "sequenceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Sequence",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "SequenceStep_sequenceId_Sequence_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "SequenceStep"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Spreadsheet_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Spreadsheet"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Tag_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Tag_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Tag"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TagChannel_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tagId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tag",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TagChannel_tagId_Tag_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TagChannel"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TelegramChat_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TelegramChat_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TelegramChat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Template_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "Template_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Template_createdBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Template"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateInstallation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "templateId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Template",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateInstallation_templateId_Template_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "installFolderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateInstallation_installFolderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "installedBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateInstallation_installedBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "uninstallRequestedBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateInstallation_uninstallRequestedBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "uninstallOperationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TemplateUninstallOperation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateInstallation_jgQpmfUEHTMJ_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateInstallationSync_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "installationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TemplateInstallation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateInstallationSync_FDCAZLsj6sha_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "requestedBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateInstallationSync_requestedBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstallationSync"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "installationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TemplateInstallation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateInstalledResource_a0BqwWeO96EB_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateInstalledResource_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateInstalledResource"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateResourceBackup_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "installationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TemplateInstallation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateResourceBackup_mhH3iOmsXeXF_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "syncId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TemplateInstallationSync",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateResourceBackup_syncId_TemplateInstallationSync_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "installedResourceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TemplateInstalledResource",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateResourceBackup_6ze53IE5Y2X5_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateResourceBackup"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateStoreCategory_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateStoreCategory_createdBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateStoreCategory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "listingId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TemplateStoreListing",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateStoreListingCategory_6NRhid3zrtxN_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateStoreListingCategory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "categoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "TemplateStoreCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateStoreListingCategory_8ENSsaBUskGb_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateStoreListingCategory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateStoreListing_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "templateId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Template",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateStoreListing_templateId_Template_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "createdBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateStoreListing_createdBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateStoreListing"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateUninstallOperation_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "templateId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Template",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateUninstallOperation_templateId_Template_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "requestedBy"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "TemplateUninstallOperation_requestedBy_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateUninstallOperation"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "templateId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Template",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateVersion_templateId_Template_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TemplateVersion_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TemplateVersion"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Trigger_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Trigger_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Trigger"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "triggerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Trigger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Condition_triggerId_Trigger_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "webhookId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Webhook",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Condition_webhookId_Webhook_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Condition"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "triggerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Trigger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TriggerContactHistory_triggerId_Trigger_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TriggerContactHistory_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TriggerContactHistory_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "triggerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Trigger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TriggerExecution_triggerId_Trigger_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TriggerExecution_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TriggerExecution_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TriggerExecution"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "triggerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Trigger",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TriggerStat_triggerId_Trigger_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "TriggerStat_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "TriggerStat"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "UserDeviceToken_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "UserDeviceToken_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "UserPersistentMenu_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "UserPersistentMenu"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Vendor_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "openHoursId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "EcommerceOpenHours",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Vendor_openHoursId_EcommerceOpenHours_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "categoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Vendor_categoryId_ProductCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "subcategoryId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ProductCategory",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Vendor_subcategoryId_ProductCategory_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "folderId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Folder",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "Webhook_folderId_Folder_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "Webhook_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Webhook"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "webhookId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Webhook",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WebhookExecution_webhookId_Webhook_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Contact",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WebhookExecution_contactId_Contact_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WebhookExecution_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WebhookExecution"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappBusinessAccount_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "answeredByUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "WhatsappCall_answeredByUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "initiatedByUserId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "SET NULL",
+ "name": "WhatsappCall_initiatedByUserId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappCall_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "inboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Inbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappCall_inboxId_Inbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappCall_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "conversationId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Conversation",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappCall_conversationId_Conversation_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappCall"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappCallPermission_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "contactInboxId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "ContactInbox",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappCallPermission_contactInboxId_ContactInbox_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappCallPermission"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationWhatsappId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationWhatsapp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappFlow_integrationWhatsappId_IntegrationWhatsapp_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappFlow"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "integrationWhatsappId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "IntegrationWhatsapp",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappMessageTemplate_p6pSomUTTJCm_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappSignupSession_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "ownerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappSignupSession_ownerId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WhatsappSignupSession_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkingHours_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkingHours"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkingHoursDateOverride_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workingHoursId",
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "WorkingHours",
+ "columnsTo": [
+ "id",
+ "workspaceId"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkingHoursDateOverride_workingHoursId_workspaceId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workingHoursId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "WorkingHours",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkingHoursInterval_workingHoursId_WorkingHours_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkingHoursMember_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkingHoursMember_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workingHoursId",
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "WorkingHours",
+ "columnsTo": [
+ "id",
+ "workspaceId"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkingHoursMember_workingHoursId_workspaceId_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "ownerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "Workspace_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "tenantId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Tenant",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "RESTRICT",
+ "name": "Workspace_tenantId_Tenant_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "Workspace"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkspaceApiToken_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "ownerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkspaceBotMessageUsage_ownerId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "ownerId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkspaceMac_ownerId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "Workspace",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkspaceMember_workspaceId_Workspace_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "schemaTo": "public",
+ "tableTo": "User",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "CASCADE",
+ "onDelete": "CASCADE",
+ "name": "WorkspaceMember_userId_User_id_fkey",
+ "entityType": "fks",
+ "schema": "public",
+ "table": "WorkspaceMember"
+ },
+ {
+ "columns": [
+ "occurredAt",
+ "eventId"
+ ],
+ "nameExplicit": false,
+ "name": "AnalyticsAgentResponseEvent_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "AnalyticsAgentResponseEvent"
+ },
+ {
+ "columns": [
+ "occurredAt",
+ "eventId"
+ ],
+ "nameExplicit": false,
+ "name": "AnalyticsBotMessageEvent_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "AnalyticsBotMessageEvent"
+ },
+ {
+ "columns": [
+ "occurredAt",
+ "eventId"
+ ],
+ "nameExplicit": false,
+ "name": "AnalyticsContactEvent_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "AnalyticsContactEvent"
+ },
+ {
+ "columns": [
+ "occurredAt",
+ "eventId"
+ ],
+ "nameExplicit": false,
+ "name": "AnalyticsConversationEvent_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "AnalyticsConversationEvent"
+ },
+ {
+ "columns": [
+ "occurredAt",
+ "eventId"
+ ],
+ "nameExplicit": false,
+ "name": "AnalyticsMessageEvent_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "AnalyticsMessageEvent"
+ },
+ {
+ "columns": [
+ "id",
+ "createdAt"
+ ],
+ "nameExplicit": false,
+ "name": "Attachment_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "Attachment"
+ },
+ {
+ "columns": [
+ "workspaceId",
+ "contactInboxId",
+ "throttleType",
+ "subjectId"
+ ],
+ "nameExplicit": true,
+ "name": "AutomationThrottle_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "AutomationThrottle"
+ },
+ {
+ "columns": [
+ "broadcastId",
+ "inboxId"
+ ],
+ "nameExplicit": true,
+ "name": "BroadcastTarget_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "BroadcastTarget"
+ },
+ {
+ "columns": [
+ "workspaceId",
+ "hourBucket",
+ "contactInboxId"
+ ],
+ "nameExplicit": false,
+ "name": "ContactActiveHourly_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactActiveHourly"
+ },
+ {
+ "columns": [
+ "workspaceId",
+ "periodStart",
+ "contactInboxId"
+ ],
+ "nameExplicit": false,
+ "name": "ContactActiveMonthly_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactActiveMonthly"
+ },
+ {
+ "columns": [
+ "workspaceId",
+ "contactId",
+ "activityType",
+ "referenceType",
+ "parentReferenceId",
+ "referenceId"
+ ],
+ "nameExplicit": true,
+ "name": "ContactActivity_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "columns": [
+ "workspaceId",
+ "contactInboxId",
+ "postId"
+ ],
+ "nameExplicit": true,
+ "name": "ContactInboxPost_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactInboxPost"
+ },
+ {
+ "columns": [
+ "workspaceId",
+ "contactId",
+ "messageId"
+ ],
+ "nameExplicit": true,
+ "name": "ContactKeywordMessage_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactKeywordMessage"
+ },
+ {
+ "columns": [
+ "broadcastId",
+ "contactId"
+ ],
+ "nameExplicit": true,
+ "name": "ContactsOnBroadcast_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactOnBroadcast"
+ },
+ {
+ "columns": [
+ "id",
+ "workspaceId"
+ ],
+ "nameExplicit": true,
+ "name": "ContactOnSequence_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactOnSequence"
+ },
+ {
+ "columns": [
+ "workspaceId",
+ "contactId"
+ ],
+ "nameExplicit": true,
+ "name": "ContactState_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactState"
+ },
+ {
+ "columns": [
+ "contactId",
+ "tagId"
+ ],
+ "nameExplicit": false,
+ "name": "ContactToTag_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactToTag"
+ },
+ {
+ "columns": [
+ "tagChannelId",
+ "contactInboxId"
+ ],
+ "nameExplicit": false,
+ "name": "ContactToTagChannel_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "ContactToTagChannel"
+ },
+ {
+ "columns": [
+ "leaderboardId",
+ "contactId"
+ ],
+ "nameExplicit": false,
+ "name": "LeaderboardParticipant_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "LeaderboardParticipant"
+ },
+ {
+ "columns": [
+ "createdAt",
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "LeaderboardScoreEvent_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "LeaderboardScoreEvent"
+ },
+ {
+ "columns": [
+ "id",
+ "createdAt"
+ ],
+ "nameExplicit": false,
+ "name": "Message_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "columns": [
+ "id",
+ "workspaceId"
+ ],
+ "nameExplicit": true,
+ "name": "PipelineItemActivity_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "PipelineItemActivity"
+ },
+ {
+ "columns": [
+ "id",
+ "workspaceId"
+ ],
+ "nameExplicit": true,
+ "name": "SequenceDispatch_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "SequenceDispatch"
+ },
+ {
+ "columns": [
+ "listingId",
+ "categoryId"
+ ],
+ "nameExplicit": true,
+ "name": "TemplateStoreListingCategory_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "TemplateStoreListingCategory"
+ },
+ {
+ "columns": [
+ "id",
+ "contactId"
+ ],
+ "nameExplicit": true,
+ "name": "TriggerContactHistory_pkey",
+ "entityType": "pks",
+ "schema": "public",
+ "table": "TriggerContactHistory"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MessageShard_pkey",
+ "schema": "public",
+ "table": "MessageShard",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ShardTimeRange_pkey",
+ "schema": "public",
+ "table": "ShardTimeRange",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AdsConversionEvent_pkey",
+ "schema": "public",
+ "table": "AdsConversionEvent",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AdsConversionRule_pkey",
+ "schema": "public",
+ "table": "AdsConversionRule",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIAgent_pkey",
+ "schema": "public",
+ "table": "AIAgent",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIConversationEmbedding_pkey",
+ "schema": "public",
+ "table": "AIConversationEmbedding",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIConversationSource_pkey",
+ "schema": "public",
+ "table": "AIConversationSource",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIEmbedding_pkey",
+ "schema": "public",
+ "table": "AIEmbedding",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIFile_pkey",
+ "schema": "public",
+ "table": "AIFile",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIFunction_pkey",
+ "schema": "public",
+ "table": "AIFunction",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIHandoverBulkRun_pkey",
+ "schema": "public",
+ "table": "AIHandoverBulkRun",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIHandoverSettings_pkey",
+ "schema": "public",
+ "table": "AIHandoverSettings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AIMCPServer_pkey",
+ "schema": "public",
+ "table": "AIMCPServer",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AnalyticsEmailTopic_pkey",
+ "schema": "public",
+ "table": "AnalyticsEmailTopic",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Appointment_pkey",
+ "schema": "public",
+ "table": "Appointment",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AppointmentCalendar_pkey",
+ "schema": "public",
+ "table": "AppointmentCalendar",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AppointmentCalendarAvailability_pkey",
+ "schema": "public",
+ "table": "AppointmentCalendarAvailability",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AppointmentCalendarReminder_pkey",
+ "schema": "public",
+ "table": "AppointmentCalendarReminder",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AppointmentReminderDispatch_pkey",
+ "schema": "public",
+ "table": "AppointmentReminderDispatch",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Account_pkey",
+ "schema": "public",
+ "table": "Account",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Invitation_pkey",
+ "schema": "public",
+ "table": "Invitation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Jwk_pkey",
+ "schema": "public",
+ "table": "Jwk",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Session_pkey",
+ "schema": "public",
+ "table": "Session",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "User_pkey",
+ "schema": "public",
+ "table": "User",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Verification_pkey",
+ "schema": "public",
+ "table": "Verification",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AutomatedResponse_pkey",
+ "schema": "public",
+ "table": "AutomatedResponse",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "BotField_pkey",
+ "schema": "public",
+ "table": "BotField",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Broadcast_pkey",
+ "schema": "public",
+ "table": "Broadcast",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "BroadcastRecurrence_pkey",
+ "schema": "public",
+ "table": "BroadcastRecurrence",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "BroadcastRecurrenceOccurrence_pkey",
+ "schema": "public",
+ "table": "BroadcastRecurrenceOccurrence",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Cart_pkey",
+ "schema": "public",
+ "table": "Cart",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ChannelPost_pkey",
+ "schema": "public",
+ "table": "ChannelPost",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CoexistSyncRun_pkey",
+ "schema": "public",
+ "table": "CoexistSyncRun",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CommentAutomation_pkey",
+ "schema": "public",
+ "table": "CommentAutomation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CommentAutomationEvent_pkey",
+ "schema": "public",
+ "table": "CommentAutomationEvent",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CommentAutomationMiss_pkey",
+ "schema": "public",
+ "table": "CommentAutomationMiss",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CommentAutomationReply_pkey",
+ "schema": "public",
+ "table": "CommentAutomationReply",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CommentModerationLog_pkey",
+ "schema": "public",
+ "table": "CommentModerationLog",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ConnectSession_pkey",
+ "schema": "public",
+ "table": "ConnectSession",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Connection_pkey",
+ "schema": "public",
+ "table": "Connection",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Contact_pkey",
+ "schema": "public",
+ "table": "Contact",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ContactCustomField_pkey",
+ "schema": "public",
+ "table": "ContactCustomField",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ContactInbox_pkey",
+ "schema": "public",
+ "table": "ContactInbox",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ContactNote_pkey",
+ "schema": "public",
+ "table": "ContactNote",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ContactOnSmartDelay_pkey",
+ "schema": "public",
+ "table": "ContactOnSmartDelay",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ContactReferralEvent_pkey",
+ "schema": "public",
+ "table": "ContactReferralEvent",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Conversation_pkey",
+ "schema": "public",
+ "table": "Conversation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ConversationParticipant_pkey",
+ "schema": "public",
+ "table": "ConversationParticipant",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Coupon_pkey",
+ "schema": "public",
+ "table": "Coupon",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CouponTopic_pkey",
+ "schema": "public",
+ "table": "CouponTopic",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CustomField_pkey",
+ "schema": "public",
+ "table": "CustomField",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "DecisionConnection_pkey",
+ "schema": "public",
+ "table": "DecisionConnection",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "DecisionProfile_pkey",
+ "schema": "public",
+ "table": "DecisionProfile",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "DiscountCode_pkey",
+ "schema": "public",
+ "table": "DiscountCode",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "DynamicImage_pkey",
+ "schema": "public",
+ "table": "DynamicImage",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "EcommerceOpenHours_pkey",
+ "schema": "public",
+ "table": "EcommerceOpenHours",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "EcommercePaymentProvider_pkey",
+ "schema": "public",
+ "table": "EcommercePaymentProvider",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OrderPayment_pkey",
+ "schema": "public",
+ "table": "OrderPayment",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "workspaceId"
+ ],
+ "nameExplicit": false,
+ "name": "EcommerceOrderCounter_pkey",
+ "schema": "public",
+ "table": "EcommerceOrderCounter",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "EcommerceSettings_pkey",
+ "schema": "public",
+ "table": "EcommerceSettings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "EmailTopic_pkey",
+ "schema": "public",
+ "table": "EmailTopic",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "AuditLog_pkey",
+ "schema": "public",
+ "table": "AuditLog",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "CustomDomain_pkey",
+ "schema": "public",
+ "table": "CustomDomain",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "License_pkey",
+ "schema": "public",
+ "table": "License",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PlatformAdmin_pkey",
+ "schema": "public",
+ "table": "PlatformAdmin",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Tenant_pkey",
+ "schema": "public",
+ "table": "Tenant",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "tenantId"
+ ],
+ "nameExplicit": false,
+ "name": "TenantDefaultTemplate_pkey",
+ "schema": "public",
+ "table": "TenantDefaultTemplate",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TenantDefaultTemplateEvent_pkey",
+ "schema": "public",
+ "table": "TenantDefaultTemplateEvent",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TenantHelpItem_pkey",
+ "schema": "public",
+ "table": "TenantHelpItem",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "UserQuota_pkey",
+ "schema": "public",
+ "table": "UserQuota",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkspaceUsage_pkey",
+ "schema": "public",
+ "table": "WorkspaceUsage",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ErrorLog_pkey",
+ "schema": "public",
+ "table": "ErrorLog",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ExternalWebhook_pkey",
+ "schema": "public",
+ "table": "ExternalWebhook",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FacebookLeadAdsAutomation_pkey",
+ "schema": "public",
+ "table": "FacebookLeadAdsAutomation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FacebookLeadAdsLead_pkey",
+ "schema": "public",
+ "table": "FacebookLeadAdsLead",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FacebookMarketingMessage_pkey",
+ "schema": "public",
+ "table": "FacebookMarketingMessage",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FacebookMarketingMessageAudience_pkey",
+ "schema": "public",
+ "table": "FacebookMarketingMessageAudience",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FacebookMarketingMessageRecipient_pkey",
+ "schema": "public",
+ "table": "FacebookMarketingMessageRecipient",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FacebookMarketingMessagesAuth_pkey",
+ "schema": "public",
+ "table": "FacebookMarketingMessagesAuth",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "File_pkey",
+ "schema": "public",
+ "table": "File",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Flow_pkey",
+ "schema": "public",
+ "table": "Flow",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FlowAnalyticsSession_pkey",
+ "schema": "public",
+ "table": "FlowAnalyticsSession",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FlowNodeStat_pkey",
+ "schema": "public",
+ "table": "FlowNodeStat",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FlowRun_pkey",
+ "schema": "public",
+ "table": "FlowRun",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "FlowVersion_pkey",
+ "schema": "public",
+ "table": "FlowVersion",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Folder_pkey",
+ "schema": "public",
+ "table": "Folder",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "GoogleAdsConversionEvent_pkey",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "GoogleAdsSettings_pkey",
+ "schema": "public",
+ "table": "GoogleAdsSettings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IgStoryAutomation_pkey",
+ "schema": "public",
+ "table": "IgStoryAutomation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Import_pkey",
+ "schema": "public",
+ "table": "Import",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "InboundWebhook_pkey",
+ "schema": "public",
+ "table": "InboundWebhook",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "InboundWebhookRequest_pkey",
+ "schema": "public",
+ "table": "InboundWebhookRequest",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Inbox_pkey",
+ "schema": "public",
+ "table": "Inbox",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "inboxId"
+ ],
+ "nameExplicit": false,
+ "name": "InboxContactStat_pkey",
+ "schema": "public",
+ "table": "InboxContactStat",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "InboxTeam_pkey",
+ "schema": "public",
+ "table": "InboxTeam",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "InboxTeamMember_pkey",
+ "schema": "public",
+ "table": "InboxTeamMember",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationActiveCampaign_pkey",
+ "schema": "public",
+ "table": "IntegrationActiveCampaign",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationApi_pkey",
+ "schema": "public",
+ "table": "IntegrationApi",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Integration_pkey",
+ "schema": "public",
+ "table": "Integration",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationClaude_pkey",
+ "schema": "public",
+ "table": "IntegrationClaude",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationDeepseek_pkey",
+ "schema": "public",
+ "table": "IntegrationDeepseek",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationDrip_pkey",
+ "schema": "public",
+ "table": "IntegrationDrip",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationFacebookAds_pkey",
+ "schema": "public",
+ "table": "IntegrationFacebookAds",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationGemini_pkey",
+ "schema": "public",
+ "table": "IntegrationGemini",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationGetResponse_pkey",
+ "schema": "public",
+ "table": "IntegrationGetResponse",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationGoogleAds_pkey",
+ "schema": "public",
+ "table": "IntegrationGoogleAds",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationGoogleCalendar_pkey",
+ "schema": "public",
+ "table": "IntegrationGoogleCalendar",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationGoogleSheet_pkey",
+ "schema": "public",
+ "table": "IntegrationGoogleSheet",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationInstagram_pkey",
+ "schema": "public",
+ "table": "IntegrationInstagram",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationKlaviyo_pkey",
+ "schema": "public",
+ "table": "IntegrationKlaviyo",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationMailchimp_pkey",
+ "schema": "public",
+ "table": "IntegrationMailchimp",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationMailerLite_pkey",
+ "schema": "public",
+ "table": "IntegrationMailerLite",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationMessenger_pkey",
+ "schema": "public",
+ "table": "IntegrationMessenger",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationMetaCatalog_pkey",
+ "schema": "public",
+ "table": "IntegrationMetaCatalog",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationMoosend_pkey",
+ "schema": "public",
+ "table": "IntegrationMoosend",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationMuse_pkey",
+ "schema": "public",
+ "table": "IntegrationMuse",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationOpenai_pkey",
+ "schema": "public",
+ "table": "IntegrationOpenai",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationOpenaiCompatible_pkey",
+ "schema": "public",
+ "table": "IntegrationOpenaiCompatible",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationOpenrouter_pkey",
+ "schema": "public",
+ "table": "IntegrationOpenrouter",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationOutlookCalendar_pkey",
+ "schema": "public",
+ "table": "IntegrationOutlookCalendar",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationSendGrid_pkey",
+ "schema": "public",
+ "table": "IntegrationSendGrid",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationShopify_pkey",
+ "schema": "public",
+ "table": "IntegrationShopify",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationSmtp_pkey",
+ "schema": "public",
+ "table": "IntegrationSmtp",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationTelegram_pkey",
+ "schema": "public",
+ "table": "IntegrationTelegram",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationThreads_pkey",
+ "schema": "public",
+ "table": "IntegrationThreads",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationTiktok_pkey",
+ "schema": "public",
+ "table": "IntegrationTiktok",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationWebchat_pkey",
+ "schema": "public",
+ "table": "IntegrationWebchat",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationWhatsapp_pkey",
+ "schema": "public",
+ "table": "IntegrationWhatsapp",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationWoocommerce_pkey",
+ "schema": "public",
+ "table": "IntegrationWoocommerce",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "IntegrationZalo_pkey",
+ "schema": "public",
+ "table": "IntegrationZalo",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Leaderboard_pkey",
+ "schema": "public",
+ "table": "Leaderboard",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "LeaderboardAuditLog_pkey",
+ "schema": "public",
+ "table": "LeaderboardAuditLog",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MagicLink_pkey",
+ "schema": "public",
+ "table": "MagicLink",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MediaLibraryFile_pkey",
+ "schema": "public",
+ "table": "MediaLibraryFile",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MediaLibraryFolder_pkey",
+ "schema": "public",
+ "table": "MediaLibraryFolder",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MessageCleanup_pkey",
+ "schema": "public",
+ "table": "MessageCleanup",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MessagingAdOperation_pkey",
+ "schema": "public",
+ "table": "MessagingAdOperation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MessagingAdsConnection_pkey",
+ "schema": "public",
+ "table": "MessagingAdsConnection",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MessengerMessageTemplate_pkey",
+ "schema": "public",
+ "table": "MessengerMessageTemplate",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MessengerWelcomeMessageFlow_pkey",
+ "schema": "public",
+ "table": "MessengerWelcomeMessageFlow",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MetaCapiEvent_pkey",
+ "schema": "public",
+ "table": "MetaCapiEvent",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MetaCatalogItem_pkey",
+ "schema": "public",
+ "table": "MetaCatalogItem",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MetaCatalogSyncRun_pkey",
+ "schema": "public",
+ "table": "MetaCatalogSyncRun",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MiniApp_pkey",
+ "schema": "public",
+ "table": "MiniApp",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MiniAppPublication_pkey",
+ "schema": "public",
+ "table": "MiniAppPublication",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MiniAppSubmission_pkey",
+ "schema": "public",
+ "table": "MiniAppSubmission",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MiniAppUpload_pkey",
+ "schema": "public",
+ "table": "MiniAppUpload",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Minigame_pkey",
+ "schema": "public",
+ "table": "Minigame",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MinigameContact_pkey",
+ "schema": "public",
+ "table": "MinigameContact",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MinigamePlay_pkey",
+ "schema": "public",
+ "table": "MinigamePlay",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "MobileRefreshToken_pkey",
+ "schema": "public",
+ "table": "MobileRefreshToken",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OAuthAccessToken_pkey",
+ "schema": "public",
+ "table": "OAuthAccessToken",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OAuthClient_pkey",
+ "schema": "public",
+ "table": "OAuthClient",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OAuthClientAssertion_pkey",
+ "schema": "public",
+ "table": "OAuthClientAssertion",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OAuthClientResource_pkey",
+ "schema": "public",
+ "table": "OAuthClientResource",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OAuthConsent_pkey",
+ "schema": "public",
+ "table": "OAuthConsent",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OAuthRefreshToken_pkey",
+ "schema": "public",
+ "table": "OAuthRefreshToken",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OAuthResource_pkey",
+ "schema": "public",
+ "table": "OAuthResource",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "DiscountCodeRedemption_pkey",
+ "schema": "public",
+ "table": "DiscountCodeRedemption",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OrderItem_pkey",
+ "schema": "public",
+ "table": "OrderItem",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Order_pkey",
+ "schema": "public",
+ "table": "Order",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "OrderStatusHistory_pkey",
+ "schema": "public",
+ "table": "OrderStatusHistory",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PipelineField_pkey",
+ "schema": "public",
+ "table": "PipelineField",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PipelineItemAssignee_pkey",
+ "schema": "public",
+ "table": "PipelineItemAssignee",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PipelineItemAttachment_pkey",
+ "schema": "public",
+ "table": "PipelineItemAttachment",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PipelineItemComment_pkey",
+ "schema": "public",
+ "table": "PipelineItemComment",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "workspaceId"
+ ],
+ "nameExplicit": false,
+ "name": "PipelineItemCounter_pkey",
+ "schema": "public",
+ "table": "PipelineItemCounter",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PipelineItem_pkey",
+ "schema": "public",
+ "table": "PipelineItem",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PipelineMember_pkey",
+ "schema": "public",
+ "table": "PipelineMember",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Pipeline_pkey",
+ "schema": "public",
+ "table": "Pipeline",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PipelineStage_pkey",
+ "schema": "public",
+ "table": "PipelineStage",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PlaceCategory_pkey",
+ "schema": "public",
+ "table": "PlaceCategory",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PlaceLocation_pkey",
+ "schema": "public",
+ "table": "PlaceLocation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Credential_pkey",
+ "schema": "public",
+ "table": "PlatformCredential",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PollCandidate_pkey",
+ "schema": "public",
+ "table": "PollCandidate",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Poll_pkey",
+ "schema": "public",
+ "table": "Poll",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "PollVote_pkey",
+ "schema": "public",
+ "table": "PollVote",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Product_pkey",
+ "schema": "public",
+ "table": "Product",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ProductAddon_pkey",
+ "schema": "public",
+ "table": "ProductAddon",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ProductCategory_pkey",
+ "schema": "public",
+ "table": "ProductCategory",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ProductVariant_pkey",
+ "schema": "public",
+ "table": "ProductVariant",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ProductVariantOption_pkey",
+ "schema": "public",
+ "table": "ProductVariantOption",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "QuestionnaireAnswer_pkey",
+ "schema": "public",
+ "table": "QuestionnaireAnswer",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Questionnaire_pkey",
+ "schema": "public",
+ "table": "Questionnaire",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "QuestionnaireQuestion_pkey",
+ "schema": "public",
+ "table": "QuestionnaireQuestion",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "QuestionnaireSubmission_pkey",
+ "schema": "public",
+ "table": "QuestionnaireSubmission",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Reflink_pkey",
+ "schema": "public",
+ "table": "Reflink",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ResourceDeletionLog_pkey",
+ "schema": "public",
+ "table": "ResourceDeletionLog",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "ResponseSlaPolicy_pkey",
+ "schema": "public",
+ "table": "ResponseSlaPolicy",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "SavedReply_pkey",
+ "schema": "public",
+ "table": "SavedReply",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "SavedReplyImage_pkey",
+ "schema": "public",
+ "table": "SavedReplyImage",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Sequence_pkey",
+ "schema": "public",
+ "table": "Sequence",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "SequenceStep_pkey",
+ "schema": "public",
+ "table": "SequenceStep",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Spreadsheet_pkey",
+ "schema": "public",
+ "table": "Spreadsheet",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "SystemField_pkey",
+ "schema": "public",
+ "table": "SystemField",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Tag_pkey",
+ "schema": "public",
+ "table": "Tag",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TagChannel_pkey",
+ "schema": "public",
+ "table": "TagChannel",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TelegramChat_pkey",
+ "schema": "public",
+ "table": "TelegramChat",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Template_pkey",
+ "schema": "public",
+ "table": "Template",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TemplateInstallation_pkey",
+ "schema": "public",
+ "table": "TemplateInstallation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TemplateInstallationSync_pkey",
+ "schema": "public",
+ "table": "TemplateInstallationSync",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TemplateInstalledResource_pkey",
+ "schema": "public",
+ "table": "TemplateInstalledResource",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TemplateResourceBackup_pkey",
+ "schema": "public",
+ "table": "TemplateResourceBackup",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TemplateStoreCategory_pkey",
+ "schema": "public",
+ "table": "TemplateStoreCategory",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TemplateStoreListing_pkey",
+ "schema": "public",
+ "table": "TemplateStoreListing",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TemplateUninstallOperation_pkey",
+ "schema": "public",
+ "table": "TemplateUninstallOperation",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TemplateVersion_pkey",
+ "schema": "public",
+ "table": "TemplateVersion",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Trigger_pkey",
+ "schema": "public",
+ "table": "Trigger",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Condition_pkey",
+ "schema": "public",
+ "table": "Condition",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TriggerExecution_pkey",
+ "schema": "public",
+ "table": "TriggerExecution",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "TriggerStat_pkey",
+ "schema": "public",
+ "table": "TriggerStat",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "UserDeviceToken_pkey",
+ "schema": "public",
+ "table": "UserDeviceToken",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "UserPersistentMenu_pkey",
+ "schema": "public",
+ "table": "UserPersistentMenu",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Vendor_pkey",
+ "schema": "public",
+ "table": "Vendor",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Webhook_pkey",
+ "schema": "public",
+ "table": "Webhook",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WebhookExecution_pkey",
+ "schema": "public",
+ "table": "WebhookExecution",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WhatsappBusinessAccount_pkey",
+ "schema": "public",
+ "table": "WhatsappBusinessAccount",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WhatsappCall_pkey",
+ "schema": "public",
+ "table": "WhatsappCall",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WhatsappCallPermission_pkey",
+ "schema": "public",
+ "table": "WhatsappCallPermission",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WhatsappCoexistStaging_pkey",
+ "schema": "public",
+ "table": "WhatsappCoexistStaging",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WhatsappFlow_pkey",
+ "schema": "public",
+ "table": "WhatsappFlow",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WhatsappMessageTemplate_pkey",
+ "schema": "public",
+ "table": "WhatsappMessageTemplate",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WhatsappSignupSession_pkey",
+ "schema": "public",
+ "table": "WhatsappSignupSession",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkingHours_pkey",
+ "schema": "public",
+ "table": "WorkingHours",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkingHoursDateOverride_pkey",
+ "schema": "public",
+ "table": "WorkingHoursDateOverride",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkingHoursInterval_pkey",
+ "schema": "public",
+ "table": "WorkingHoursInterval",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkingHoursMember_pkey",
+ "schema": "public",
+ "table": "WorkingHoursMember",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "Workspace_pkey",
+ "schema": "public",
+ "table": "Workspace",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkspaceApiToken_pkey",
+ "schema": "public",
+ "table": "WorkspaceApiToken",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkspaceBotMessageUsage_pkey",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkspaceDeletionRecord_pkey",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkspaceMac_pkey",
+ "schema": "public",
+ "table": "WorkspaceMac",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "WorkspaceMember_pkey",
+ "schema": "public",
+ "table": "WorkspaceMember",
+ "entityType": "pks"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "contactInboxId",
+ "sourceId",
+ "createdAt"
+ ],
+ "nullsNotDistinct": false,
+ "name": "Message_source_dedup_idx",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "Message"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workspaceId",
+ "source",
+ "parentId",
+ "name"
+ ],
+ "nullsNotDistinct": true,
+ "name": "ProductCategory_workspaceId_parent_name_key",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "ProductCategory"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workspaceId"
+ ],
+ "nullsNotDistinct": false,
+ "name": "ResponseSlaPolicy_workspaceId_key",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "token"
+ ],
+ "nullsNotDistinct": false,
+ "name": "UserDeviceToken_token_key",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "UserDeviceToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "id",
+ "workspaceId"
+ ],
+ "nullsNotDistinct": false,
+ "name": "WorkingHours_id_workspaceId_key",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "WorkingHours"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workspaceId",
+ "userId"
+ ],
+ "nullsNotDistinct": false,
+ "name": "WorkingHoursMember_workspaceId_userId_key",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "WorkingHoursMember"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "tokenHash"
+ ],
+ "nullsNotDistinct": false,
+ "name": "WorkspaceApiToken_tokenHash_key",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "WorkspaceApiToken"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workspaceId",
+ "periodStart"
+ ],
+ "nullsNotDistinct": false,
+ "name": "WorkspaceBotMessageUsage_workspaceId_periodStart_key",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "WorkspaceBotMessageUsage"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workspaceId"
+ ],
+ "nullsNotDistinct": false,
+ "name": "WorkspaceDeletionRecord_workspaceId_key",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "WorkspaceDeletionRecord"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "workspaceId",
+ "periodStart",
+ "periodEnd"
+ ],
+ "nullsNotDistinct": false,
+ "name": "WorkspaceMac_workspaceId_periodStart_periodEnd_unique",
+ "entityType": "uniques",
+ "schema": "public",
+ "table": "WorkspaceMac"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "userId"
+ ],
+ "nullsNotDistinct": false,
+ "name": "UserQuota_userId_key",
+ "schema": "public",
+ "table": "UserQuota",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "workspaceId"
+ ],
+ "nullsNotDistinct": false,
+ "name": "WorkspaceUsage_workspaceId_key",
+ "schema": "public",
+ "table": "WorkspaceUsage",
+ "entityType": "uniques"
+ },
+ {
+ "value": "(\"channel\" = 'whatsapp' AND \"integrationWhatsappId\" IS NOT NULL AND \"ctwaClid\" IS NOT NULL AND \"wabaId\" IS NOT NULL) OR (\"channel\" = 'messenger' AND \"integrationMessengerId\" IS NOT NULL) OR (\"channel\" = 'instagram' AND \"integrationInstagramId\" IS NOT NULL)",
+ "name": "AdsConversionEvent_channel_integration_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "AdsConversionEvent"
+ },
+ {
+ "value": "\"parentBroadcastId\" IS NULL OR \"occurrenceAt\" IS NOT NULL",
+ "name": "Broadcast_occurrence_pair_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Broadcast"
+ },
+ {
+ "value": "((\"actorUserId\" IS NOT NULL)::int + (\"actorTokenId\" IS NOT NULL)::int) <= 1",
+ "name": "ConnectSession_actor_at_most_one",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "value": "\"status\" IN ('pending', 'authorized', 'awaiting_selection', 'completed', 'failed', 'expired', 'cancelled')",
+ "name": "ConnectSession_status_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "value": "\"purpose\" IN ('connect', 'reconnect', 'facebook_ads', 'messaging_ads', 'lead_ads', 'meta_catalog')",
+ "name": "ConnectSession_purpose_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "value": "\"errorCode\" IN ('state_mismatch', 'expired', 'provider_denied', 'exchange_failed', 'provider_error', 'no_candidates', 'already_connected', 'quota_exceeded', 'trial_expired', 'internal_error')",
+ "name": "ConnectSession_errorCode_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "value": "\"errorCode\" IS NULL OR \"status\" IN ('failed', 'expired', 'cancelled')",
+ "name": "ConnectSession_errorCode_terminal_failure_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "value": "(\"status\" IN ('completed', 'failed', 'expired', 'cancelled')) = (\"consumedAt\" IS NOT NULL)",
+ "name": "ConnectSession_terminal_consumedAt_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "value": "\"status\" NOT IN ('completed', 'failed', 'expired', 'cancelled') OR \"encryptedAuth\" IS NULL",
+ "name": "ConnectSession_terminal_clears_encryptedAuth_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "value": "\"purpose\" <> 'reconnect' OR \"status\" IN ('completed', 'failed', 'expired', 'cancelled') OR \"targetConnectionId\" IS NOT NULL",
+ "name": "ConnectSession_active_reconnect_requires_target_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ConnectSession"
+ },
+ {
+ "value": "(\n (\"kind\" = 'channel' AND \"inboxId\" IS NOT NULL AND \"channel\" IS NOT NULL)\n OR\n (\"kind\" = 'integration' AND \"inboxId\" IS NULL AND \"channel\" IS NULL AND \"integrationId\" IS NOT NULL)\n )",
+ "name": "Connection_kind_relation_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "value": "NOT (\"inboxId\" IS NOT NULL AND \"integrationId\" IS NOT NULL)",
+ "name": "Connection_inbox_integration_exclusive_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "value": "\"kind\" IN ('channel', 'integration')",
+ "name": "Connection_kind_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "value": "\"status\" IN ('connected', 'degraded', 'needs_reauth', 'paused', 'disconnected')",
+ "name": "Connection_status_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "value": "\"statusReason\" IN ('manual', 'workspace_purge', 'trial_expired', 'tenant_suspended', 'token_revoked', 'provider_revoked', 'provider_offboarded', 'refresh_failed', 'verify_failed', 'quota_exceeded', 'orphaned_webhook')",
+ "name": "Connection_statusReason_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "value": "\"providerEventKind\" IS NULL OR \"providerEventKind\" IN ('revoked', 'offboarded', 'reconnected')",
+ "name": "Connection_providerEventKind_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "value": "(\"status\" = 'connected') = (\"statusReason\" IS NULL)",
+ "name": "Connection_status_reason_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "value": "(\"status\" = 'disconnected') = (\"disconnectedAt\" IS NOT NULL)",
+ "name": "Connection_disconnectedAt_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Connection"
+ },
+ {
+ "value": "(\"activityType\" = 'flowExecuted' AND \"referenceType\" = 'flow' AND \"parentReferenceId\" = 0) OR (\"activityType\" = 'flowNodeExecuted' AND \"referenceType\" = 'flowNode' AND \"parentReferenceId\" <> 0) OR (\"activityType\" = 'automatedResponseMatched' AND \"referenceType\" = 'automatedResponse' AND \"parentReferenceId\" = 0) OR (\"activityType\" = 'formCompleted' AND \"referenceType\" = 'whatsappFlow' AND \"parentReferenceId\" = 0) OR (\"activityType\" = 'messageSent' AND \"referenceType\" = 'emailTopic' AND \"parentReferenceId\" = 0) OR (\"activityType\" = 'messageDelivered' AND \"referenceType\" = 'emailTopic' AND \"parentReferenceId\" = 0) OR (\"activityType\" = 'messageOpened' AND \"referenceType\" = 'emailTopic' AND \"parentReferenceId\" = 0) OR (\"activityType\" = 'messageClicked' AND \"referenceType\" = 'emailTopic' AND \"parentReferenceId\" = 0) OR (\"activityType\" = 'adClicked' AND \"referenceType\" = 'ad' AND \"parentReferenceId\" = 0)",
+ "name": "ContactActivity_allowed_pair_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ContactActivity"
+ },
+ {
+ "value": "\"type\" IN ('ad', 'refLink', 'shortLink', 'qr')",
+ "name": "ContactReferralEvent_type_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "value": "\"provider\" IS NULL OR \"provider\" IN ('meta', 'google')",
+ "name": "ContactReferralEvent_provider_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "value": "\"clickIdType\" IS NULL OR \"clickIdType\" IN ('ctwa', 'gclid', 'gbraid')",
+ "name": "ContactReferralEvent_clickIdType_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "value": "(\"clickId\" IS NULL) = (\"clickIdType\" IS NULL)",
+ "name": "ContactReferralEvent_clickId_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ContactReferralEvent"
+ },
+ {
+ "value": "\"usedCount\" >= 0 AND (\"usageLimit\" IS NULL OR \"usedCount\" <= \"usageLimit\")",
+ "name": "DiscountCode_usedCount_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "DiscountCode"
+ },
+ {
+ "value": "\"serviceFeePercent\" >= 0 AND \"serviceFeePercent\" <= 100",
+ "name": "EcommerceSettings_serviceFeePercent_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "EcommerceSettings"
+ },
+ {
+ "value": "\"status\" NOT IN ('sent', 'processed') OR (\"requestId\" IS NOT NULL AND \"sentAt\" IS NOT NULL)",
+ "name": "GoogleAdsConversionEvent_sent_requires_request_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "\"status\" <> 'sending' OR (\"claimToken\" IS NOT NULL AND \"claimedAt\" IS NOT NULL)",
+ "name": "GoogleAdsConversionEvent_sending_requires_claim_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "\"processingStatus\" IS NULL OR \"status\" IN ('sent', 'processed', 'failed')",
+ "name": "GoogleAdsConversionEvent_processing_status_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "\"failureStage\" IS NULL OR \"status\" = 'failed'",
+ "name": "GoogleAdsConversionEvent_failure_stage_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "(\"value\" IS NULL) = (\"currency\" IS NULL)",
+ "name": "GoogleAdsConversionEvent_value_currency_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "\"value\" IS NULL OR \"value\" >= 0",
+ "name": "GoogleAdsConversionEvent_value_non_negative_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "length(\"clickId\") BETWEEN 10 AND 512",
+ "name": "GoogleAdsConversionEvent_clickId_length_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "\"uploadMethod\" IN ('dataManager', 'legacy')",
+ "name": "GoogleAdsConversionEvent_uploadMethod_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "\"attempt\" >= 0 AND \"processingAttempts\" >= 0",
+ "name": "GoogleAdsConversionEvent_attempt_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "GoogleAdsConversionEvent"
+ },
+ {
+ "value": "(\"registrationStatus\" <> 'failed' OR \"registrationError\" IS NOT NULL)\n AND (\"registrationStatus\" <> 'registered' OR \"registrationError\" IS NULL)",
+ "name": "IntegrationWhatsapp_registrationStatus_error_consistent",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "IntegrationWhatsapp"
+ },
+ {
+ "value": "(\"channel\" = 'whatsapp' AND \"integrationWhatsappId\" IS NOT NULL AND \"integrationMessengerId\" IS NULL AND \"integrationInstagramId\" IS NULL) OR (\"channel\" = 'messenger' AND \"integrationMessengerId\" IS NOT NULL AND \"integrationWhatsappId\" IS NULL AND \"integrationInstagramId\" IS NULL) OR (\"channel\" = 'instagram' AND \"integrationInstagramId\" IS NOT NULL AND \"integrationWhatsappId\" IS NULL AND \"integrationMessengerId\" IS NULL)",
+ "name": "MessagingAdOperation_channel_integration_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "MessagingAdOperation"
+ },
+ {
+ "value": "(\"channel\" = 'whatsapp' AND \"integrationWhatsappId\" IS NOT NULL AND \"integrationMessengerId\" IS NULL AND \"integrationInstagramId\" IS NULL) OR (\"channel\" = 'messenger' AND \"integrationMessengerId\" IS NOT NULL AND \"integrationWhatsappId\" IS NULL AND \"integrationInstagramId\" IS NULL) OR (\"channel\" = 'instagram' AND \"integrationInstagramId\" IS NOT NULL AND \"integrationWhatsappId\" IS NULL AND \"integrationMessengerId\" IS NULL)",
+ "name": "MessagingAdsConnection_channel_integration_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "MessagingAdsConnection"
+ },
+ {
+ "value": "\"channel\" IN ('messenger', 'instagram', 'whatsapp')",
+ "name": "MetaCapiEvent_channel_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "value": "\"actionSource\" IN ('business_messaging', 'email', 'phone_call', 'chat', 'physical_store', 'system_generated', 'other')",
+ "name": "MetaCapiEvent_actionSource_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "value": "\"contentType\" IN ('product', 'product_group')",
+ "name": "MetaCapiEvent_contentType_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "MetaCapiEvent"
+ },
+ {
+ "value": "(\"workspaceMemberId\" IS NULL) <> (\"inboxTeamId\" IS NULL)",
+ "name": "PipelineItemAssignee_one_target_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "PipelineItemAssignee"
+ },
+ {
+ "value": "\"latitude\" BETWEEN -90 AND 90",
+ "name": "PlaceLocation_latitude_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "value": "\"longitude\" BETWEEN -180 AND 180",
+ "name": "PlaceLocation_longitude_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "PlaceLocation"
+ },
+ {
+ "value": "(\"customFieldId\" IS NULL) OR (\"systemFieldKey\" IS NULL)",
+ "name": "QuestionnaireQuestion_customFieldId_systemFieldKey_exclusive",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "QuestionnaireQuestion"
+ },
+ {
+ "value": "\"firstResponseTargetSeconds\" > 0 AND (\"nextResponseTargetSeconds\" IS NULL OR \"nextResponseTargetSeconds\" > 0)",
+ "name": "ResponseSlaPolicy_targets_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "value": "\"breachingThresholdPercent\" BETWEEN 1 AND 99",
+ "name": "ResponseSlaPolicy_threshold_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "ResponseSlaPolicy"
+ },
+ {
+ "value": "\"discountPercent\" >= 0 AND \"discountPercent\" <= 100",
+ "name": "Vendor_discountPercent_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "Vendor"
+ },
+ {
+ "value": "cardinality(\"candidatePhoneNumberIds\") > 0",
+ "name": "WhatsappSignupSession_candidates_not_empty",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "WhatsappSignupSession"
+ },
+ {
+ "value": "\"weekday\" BETWEEN 0 AND 6",
+ "name": "WorkingHoursInterval_weekday_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ },
+ {
+ "value": "0 <= \"startMinute\" AND \"startMinute\" < \"endMinute\" AND \"endMinute\" <= 1440",
+ "name": "WorkingHoursInterval_minutes_check",
+ "entityType": "checks",
+ "schema": "public",
+ "table": "WorkingHoursInterval"
+ }
+ ],
+ "renames": []
+}
\ No newline at end of file
diff --git a/packages/database/src/partials/broadcast.ts b/packages/database/src/partials/broadcast.ts
index cc609691da..c39b0badeb 100644
--- a/packages/database/src/partials/broadcast.ts
+++ b/packages/database/src/partials/broadcast.ts
@@ -32,6 +32,20 @@ export const broadcastStatuses = z.enum([
])
export type BroadcastStatus = z.infer
+/**
+ * Why the system (not the customer) changed a broadcast's status. Set together
+ * with `statusErrorMessage` and `statusInboxId`; cleared when the customer
+ * resumes or moves the broadcast back to draft.
+ */
+export const broadcastStatusReasons = z.enum([
+ "accountPolicyBlocked",
+ "accountSendRestricted",
+])
+export type BroadcastStatusReason = z.infer
+
+/** Longest provider error text kept in `Broadcast.statusErrorMessage`. */
+export const BROADCAST_STATUS_ERROR_MESSAGE_MAX_LENGTH = 500
+
/**
* What happened to one slot of a repeating broadcast. `created` means a run
* (child broadcast) exists — not that it was delivered; `skipped` is an
diff --git a/packages/database/src/partials/coexist-sync-run.ts b/packages/database/src/partials/coexist-sync-run.ts
index 6c70e82276..8803818301 100644
--- a/packages/database/src/partials/coexist-sync-run.ts
+++ b/packages/database/src/partials/coexist-sync-run.ts
@@ -29,14 +29,26 @@ export const coexistScanRunStatuses = [
"partial",
] as const
+/**
+ * What a scan run is shown as. `cancelled` is derived, never stored: a cancelled
+ * scan is a `partial` row whose `currentError` is the cancel sentinel
+ * (`CONTACT_SCAN_ERRORS.cancelled`), so no enum value or migration is needed.
+ */
+export const contactScanRunStatuses = [
+ ...coexistScanRunStatuses,
+ "cancelled",
+] as const
+
+export type ContactScanRunStatus = (typeof contactScanRunStatuses)[number]
+
/**
* View-level statuses the Contact Scan builder UI keys its copy/polling off
- * of: every stored status the scan can be in, plus `"idle"` — a
+ * of: every status a scan run is shown as, plus `"idle"` — a
* `ContactScanService`-only synthetic status meaning "no scan has ever been
* requested for this inbox" (never persisted).
*/
export const contactScanViewStatuses = [
- ...coexistScanRunStatuses,
+ ...contactScanRunStatuses,
"idle",
] as const
diff --git a/packages/database/src/partials/message.ts b/packages/database/src/partials/message.ts
index aa4ad50afd..582416fbb4 100644
--- a/packages/database/src/partials/message.ts
+++ b/packages/database/src/partials/message.ts
@@ -67,3 +67,61 @@ export const productMessageUnresolvableDataSchema = z.object({
"Comma-separated ids that are not sendable (`productsNotSendable`).",
),
})
+
+/**
+ * The fields {@link isResendableMessage} reads, typed loosely (the builder's
+ * resource and the stored row differ in how narrow these are).
+ */
+export type ResendableMessageFields = {
+ messageType: string
+ senderType: string
+ type: string
+ contentAttributes: unknown
+ sendError: string | null
+ sourceId: string | null
+ /** Empty on a row only the browser knows (a rejected submit): nothing to resend. */
+ contactInboxId: string | null
+ parentId?: string | null | undefined
+}
+
+/** `contentAttributes` key that keeps a private reply's comment createdAt (ISO string). */
+export const REPLY_TARGET_CREATED_AT_KEY = "replyToMessageCreatedAt"
+
+const hasReplyTargetCreatedAt = (contentAttributes: unknown): boolean =>
+ typeof contentAttributes === "object" &&
+ contentAttributes !== null &&
+ REPLY_TARGET_CREATED_AT_KEY in contentAttributes &&
+ typeof contentAttributes[REPLY_TARGET_CREATED_AT_KEY] === "string"
+
+const isPrivateReplyAttributes = (contentAttributes: unknown): boolean =>
+ typeof contentAttributes === "object" &&
+ contentAttributes !== null &&
+ "isPrivateReply" in contentAttributes &&
+ contentAttributes.isPrivateReply === true
+
+/**
+ * A message that can be sent again: an outgoing message a person or the API
+ * typed (never a bot or a flow), a DM or a private reply (stored as a `comment`
+ * but delivered as a DM), that failed and was never given a provider id. A
+ * public comment reply is excluded. One rule for the resend service and the
+ * inbox's Resend button, so the button is never offered for a message the
+ * service would refuse.
+ */
+export const isResendableMessage = (
+ message: ResendableMessageFields,
+): boolean => {
+ const isDirectMessage =
+ message.type === "message" ||
+ (message.type === "comment" &&
+ isPrivateReplyAttributes(message.contentAttributes))
+ return (
+ message.messageType === "outgoing" &&
+ (message.senderType === "user" || message.senderType === "api") &&
+ isDirectMessage &&
+ message.sendError !== null &&
+ message.sourceId === null &&
+ Boolean(message.contactInboxId) &&
+ // A reply to a comment can only be rebuilt when its createdAt was kept.
+ (!message.parentId || hasReplyTargetCreatedAt(message.contentAttributes))
+ )
+}
diff --git a/packages/database/src/relations/broadcast.ts b/packages/database/src/relations/broadcast.ts
index 05d74af4c2..1c6e98214f 100644
--- a/packages/database/src/relations/broadcast.ts
+++ b/packages/database/src/relations/broadcast.ts
@@ -26,6 +26,12 @@ export const broadcastRelations = defineRelationsPart(schema, (r) => ({
from: r.broadcastModel.integrationMessengerId,
to: r.integrationMessengerModel.id,
}),
+ // The inbox behind `statusReason`; ORM-level only (no FK), null once deleted.
+ statusInbox: r.one.inboxModel({
+ from: r.broadcastModel.statusInboxId,
+ to: r.inboxModel.id,
+ alias: "broadcastStatusInbox",
+ }),
targets: r.many.broadcastTargetModel({
from: r.broadcastModel.id,
to: r.broadcastTargetModel.broadcastId,
diff --git a/packages/database/src/repositories/broadcast/repository.ts b/packages/database/src/repositories/broadcast/repository.ts
index 98cce8b6d9..543b7c8b34 100644
--- a/packages/database/src/repositories/broadcast/repository.ts
+++ b/packages/database/src/repositories/broadcast/repository.ts
@@ -3,17 +3,28 @@ import {
type DatabaseClient,
db,
eq,
+ exists,
inArray,
isNull,
ne,
+ or,
relationsFilterToSQL,
} from "../../client"
import {
type BroadcastScheduleType,
type BroadcastStatus,
+ broadcastStatuses,
+ broadcastTargetModes,
withBroadcastTargets,
} from "../../partials/broadcast"
-import { broadcastModel, contactsOnBroadcastsModel } from "../../schema"
+import { channelTypes } from "../../partials/channel"
+import {
+ broadcastModel,
+ broadcastTargetModel,
+ contactsOnBroadcastsModel,
+ integrationMessengerModel,
+ integrationWhatsappModel,
+} from "../../schema"
import {
getPaginationWithDefaults,
likeContains,
@@ -133,6 +144,7 @@ export const broadcastRepository = {
name: true,
},
},
+ statusInbox: { columns: { id: true, name: true } },
...withBroadcastTargets,
...withBroadcastRecurrence,
},
@@ -197,6 +209,95 @@ export const broadcastRepository = {
)
},
+ /**
+ * Ids of the `sending` broadcasts that send through `inboxId`, in one query.
+ * `targets` mode matches a `BroadcastTarget` row. `channel` (legacy) mode
+ * matches the broadcast's integration column, or — when both integration
+ * columns are null — a whole-channel broadcast on the inbox's channel or an
+ * omnichannel one (which reaches every channel). Adding a channel needs no
+ * change here: whole-channel rows are matched on `channel` alone.
+ */
+ async listSendingIdsForInbox(
+ input: { workspaceId: string; inboxId: string; channel: string },
+ tx: DatabaseClient = db,
+ ): Promise<{ id: string; parentBroadcastId: string | null }[]> {
+ const viaTarget = and(
+ eq(broadcastModel.targetMode, broadcastTargetModes.enum.targets),
+ exists(
+ tx
+ .select({ one: broadcastTargetModel.broadcastId })
+ .from(broadcastTargetModel)
+ .where(
+ and(
+ eq(broadcastTargetModel.broadcastId, broadcastModel.id),
+ eq(broadcastTargetModel.inboxId, input.inboxId),
+ ),
+ ),
+ ),
+ )
+ const viaIntegration = or(
+ exists(
+ tx
+ .select({ one: integrationMessengerModel.id })
+ .from(integrationMessengerModel)
+ .where(
+ and(
+ eq(
+ integrationMessengerModel.id,
+ broadcastModel.integrationMessengerId,
+ ),
+ eq(integrationMessengerModel.inboxId, input.inboxId),
+ ),
+ ),
+ ),
+ exists(
+ tx
+ .select({ one: integrationWhatsappModel.id })
+ .from(integrationWhatsappModel)
+ .where(
+ and(
+ eq(
+ integrationWhatsappModel.id,
+ broadcastModel.integrationWhatsappId,
+ ),
+ eq(integrationWhatsappModel.inboxId, input.inboxId),
+ ),
+ ),
+ ),
+ )
+ const wholeChannel = and(
+ isNull(broadcastModel.integrationMessengerId),
+ isNull(broadcastModel.integrationWhatsappId),
+ inArray(broadcastModel.channel, [
+ input.channel,
+ channelTypes.enum.omnichannel,
+ ]),
+ )
+
+ const rows = await tx
+ .select({
+ id: broadcastModel.id,
+ parentBroadcastId: broadcastModel.parentBroadcastId,
+ })
+ .from(broadcastModel)
+ .where(
+ and(
+ eq(broadcastModel.workspaceId, input.workspaceId),
+ eq(broadcastModel.status, broadcastStatuses.enum.sending),
+ isNull(broadcastModel.deletedAt),
+ or(
+ viaTarget,
+ and(
+ eq(broadcastModel.targetMode, broadcastTargetModes.enum.channel),
+ or(viaIntegration, wholeChannel),
+ ),
+ ),
+ ),
+ )
+
+ return rows
+ },
+
/** id-or-name lookup, scoped to a non-deleted broadcast in the workspace. */
async findByIdOrName(
input: { workspaceId: string; idOrName: string },
@@ -211,7 +312,11 @@ export const broadcastRepository = {
return await tx.query.broadcastModel.findFirst({
where,
- with: { ...withBroadcastTargets, ...withBroadcastRecurrence },
+ with: {
+ statusInbox: { columns: { id: true, name: true } },
+ ...withBroadcastTargets,
+ ...withBroadcastRecurrence,
+ },
})
},
}
diff --git a/packages/database/src/repositories/coexist-sync-run/repository.ts b/packages/database/src/repositories/coexist-sync-run/repository.ts
index b9e17d12d7..052d0cda6f 100644
--- a/packages/database/src/repositories/coexist-sync-run/repository.ts
+++ b/packages/database/src/repositories/coexist-sync-run/repository.ts
@@ -134,6 +134,8 @@ export type CoexistRunProgressInput = {
| "syncProgress"
// Contact-scan-only: provider `after` cursor for continuation resume.
| "resumeCursor"
+ // Scan progress resets it to 1 (the running claim), so only consecutive failures count.
+ | "attempts"
>
>
/**
@@ -173,6 +175,13 @@ export type PickDueRunsInput = {
type: CoexistRunType
batchSize: number
maxAttempts: number
+ /**
+ * Also picks a `running` row whose claim was released (`claimToken IS NULL`)
+ * and whose heartbeat is older than this. For a run parked on a delayed job:
+ * if that job is lost the sweeper recovers it after this grace instead of
+ * after the one-hour stale window. Omitted by coexist, which stays unchanged.
+ */
+ releasedGraceMs?: number
tx?: DatabaseClient
}
@@ -478,6 +487,10 @@ export class CoexistSyncRunRepository {
*/
async pickDueRuns(input: PickDueRunsInput): Promise {
const { tx = db } = input
+ const releasedClause =
+ input.releasedGraceMs === undefined
+ ? sql``
+ : sql`OR (status = 'running' AND "claimToken" IS NULL AND "lastHeartbeatAt" < NOW() - make_interval(secs => ${input.releasedGraceMs / 1000}))`
const picked = await tx.execute(sql`
UPDATE "CoexistSyncRun"
SET attempts = attempts + 1,
@@ -488,6 +501,7 @@ export class CoexistSyncRunRepository {
WHERE (
(status = 'init' AND "updatedAt" < NOW() - INTERVAL '10 seconds')
OR (status = 'running' AND "lastHeartbeatAt" < NOW() - INTERVAL '1 hour')
+ ${releasedClause}
)
AND type = ${input.type}
AND attempts < ${input.maxAttempts}
@@ -1019,12 +1033,15 @@ export class CoexistSyncRunRepository {
async yieldForContinuation(input: {
runId: string
expect: CoexistRunWriteGuard
+ /** Written with the release; omitted leaves the count as it is. */
+ attempts?: number
tx?: DatabaseClient
}): Promise {
const { tx = db, runId, expect } = input
const rows = await tx
.update(coexistSyncRunModel)
.set({
+ ...(input.attempts === undefined ? {} : { attempts: input.attempts }),
claimToken: null,
lastHeartbeatAt: new Date(),
updatedAt: new Date(),
@@ -1107,6 +1124,97 @@ export class CoexistSyncRunRepository {
return run ?? null
}
+ /**
+ * Ends a live (`init`/`running`) scan on an integration as `partial` with the
+ * caller's sentinel, in one conditional UPDATE. Clearing `claimToken` and
+ * `resumeCursor` makes the worker's next fenced write match zero rows, so the
+ * walk stops without a new chunk (imported contacts stay). `workspaceId` is
+ * required for the operator's Cancel and omitted by the channel-disconnect
+ * teardown, which already holds the integration.
+ *
+ * @returns how many scans were ended (0 or 1: one live scan per integration).
+ */
+ async cancelActiveContactScanRuns(input: {
+ channel: CoexistChannel
+ integrationId: string
+ workspaceId?: string
+ currentError: string
+ tx?: DatabaseClient
+ }): Promise {
+ const { tx = db } = input
+ const now = new Date()
+ const rows = await tx
+ .update(coexistSyncRunModel)
+ .set({
+ status: "partial",
+ currentError: input.currentError,
+ claimToken: null,
+ resumeCursor: null,
+ finishedAt: now,
+ updatedAt: now,
+ })
+ .where(
+ and(
+ eq(coexistSyncRunModel.type, "contact_scan"),
+ eq(coexistSyncRunModel.channel, input.channel),
+ eq(coexistSyncRunModel.integrationId, input.integrationId),
+ input.workspaceId === undefined
+ ? undefined
+ : eq(coexistSyncRunModel.workspaceId, input.workspaceId),
+ inArray(coexistSyncRunModel.status, PULL_CLAIMABLE_STATUSES),
+ ),
+ )
+ .returning({ id: coexistSyncRunModel.id })
+
+ return rows.length
+ }
+
+ /**
+ * Hands a scan back after a transient failure, in ONE atomic UPDATE: back to
+ * `init` for the sweeper to re-drive while it still has attempts left, else
+ * `failed` right now. It cannot wait for `markMaxAttemptsFailed`, which only
+ * ends a scan whose heartbeat is 10 minutes stale, and `pickDueRuns` no longer
+ * picks it at `maxAttempts`. `attempts` is the sweeper's pick count (a running
+ * claim is 1), so the Nth consecutive failure sees N: a completed page resets
+ * it to 1 and the 5th failure in a row fails the run.
+ *
+ * @returns the outcome, or `null` when the `expect` guard did not hold (the
+ * claim was taken over or the run was cancelled).
+ */
+ async retryOrFailContactScanRun(input: {
+ runId: string
+ maxAttempts: number
+ retryError: string
+ exhaustedError: string
+ expect: CoexistRunWriteGuard
+ tx?: DatabaseClient
+ }): Promise {
+ const { tx = db } = input
+ const exhausted = sql`${coexistSyncRunModel.attempts} >= ${input.maxAttempts}`
+ const [row] = await tx
+ .update(coexistSyncRunModel)
+ .set({
+ status: sql`CASE WHEN ${exhausted} THEN 'failed'::"coexistRunStatus" ELSE 'init'::"coexistRunStatus" END`,
+ currentError: sql`CASE WHEN ${exhausted} THEN ${input.exhaustedError} ELSE ${input.retryError} END`,
+ finishedAt: sql`CASE WHEN ${exhausted} THEN NOW() ELSE ${coexistSyncRunModel.finishedAt} END`,
+ resumeCursor: sql`CASE WHEN ${exhausted} THEN NULL ELSE ${coexistSyncRunModel.resumeCursor} END`,
+ lastHeartbeatAt: new Date(),
+ updatedAt: new Date(),
+ })
+ .where(
+ and(
+ eq(coexistSyncRunModel.type, "contact_scan"),
+ ...runWriteFilter(input.runId, input.expect),
+ ),
+ )
+ .returning({ status: coexistSyncRunModel.status })
+
+ if (!row) {
+ return null
+ }
+ return row.status === "failed" ? "failed" : "retry"
+ }
+
/** Newest scan run for this integration, workspace-scoped. */
async findLatestContactScanRun(input: {
workspaceId: string
@@ -1175,4 +1283,7 @@ export class CoexistSyncRunRepository {
}
}
+/** What `retryOrFailContactScanRun` did: handed the run back, or ended it. */
+export type ContactScanRetryOutcome = "retry" | "failed"
+
export const coexistSyncRunRepository = new CoexistSyncRunRepository()
diff --git a/packages/database/src/repositories/message/message-repository.ts b/packages/database/src/repositories/message/message-repository.ts
index 2bd25af926..3e868d1f91 100644
--- a/packages/database/src/repositories/message/message-repository.ts
+++ b/packages/database/src/repositories/message/message-repository.ts
@@ -252,6 +252,19 @@ export interface IMessageRepository {
overlay: Record
}): Promise<{ id: string } | null>
+ /**
+ * Atomically clears a failed outgoing message's `sendError` so it can be sent
+ * again, only while it is still a failed send that never reached the channel
+ * (`sendError IS NOT NULL AND sourceId IS NULL`). Of two concurrent callers
+ * exactly one gets the row; the other (and a message that is not resendable)
+ * gets `null`, and must not enqueue anything.
+ */
+ claimForResend(params: {
+ id: string
+ workspaceId: string
+ createdAt: Date
+ }): Promise<{ id: string } | null>
+
create(message: CreateMessageInput): Promise
createOrUpdate(message: CreateMessageInput): Promise
diff --git a/packages/database/src/schema/broadcast.ts b/packages/database/src/schema/broadcast.ts
index 76585b08ea..357bb552e3 100644
--- a/packages/database/src/schema/broadcast.ts
+++ b/packages/database/src/schema/broadcast.ts
@@ -12,8 +12,10 @@ import {
uniqueIndex,
} from "drizzle-orm/pg-core"
import {
+ type BroadcastStatusReason,
broadcastScheduleTypes,
broadcastStatuses,
+ broadcastStatusReasons,
broadcastTargetModes,
} from "../partials"
import {
@@ -30,6 +32,10 @@ export const broadcastStatus = pgEnum(
"broadcastStatus",
broadcastStatuses.options as [string, ...string[]],
)
+export const broadcastStatusReason = pgEnum(
+ "broadcastStatusReason",
+ broadcastStatusReasons.options as [string, ...string[]],
+)
export const broadcastScheduleType = pgEnum(
"broadcastScheduleType",
broadcastScheduleTypes.options as [string, ...string[]],
@@ -76,6 +82,12 @@ export const broadcastModel = pgTable(
*/
targetMode: text().notNull().default(broadcastTargetModes.enum.channel),
status: broadcastStatus().notNull(),
+ /** Set when the system stopped the broadcast (see `broadcastStatusReasons`); null for a customer-driven status. No default. */
+ statusReason: broadcastStatusReason().$type(),
+ /** The provider's error text behind `statusReason`, truncated to `BROADCAST_STATUS_ERROR_MESSAGE_MAX_LENGTH`. */
+ statusErrorMessage: text(),
+ /** The inbox whose send error caused `statusReason`. No FK: resolved through the ORM-only `statusInbox` relation, null once the inbox is gone. */
+ statusInboxId: bigintAsString(),
schedulesType: broadcastScheduleType().notNull(),
schedulesAt: timestamp(timestampConfig).notNull(),
contactFilter: jsonb(),
diff --git a/packages/database/src/sharding/message/repository/sharded-message-repository.ts b/packages/database/src/sharding/message/repository/sharded-message-repository.ts
index 17884ea913..772b664bb2 100644
--- a/packages/database/src/sharding/message/repository/sharded-message-repository.ts
+++ b/packages/database/src/sharding/message/repository/sharded-message-repository.ts
@@ -809,6 +809,21 @@ export class ShardedMessageRepository implements IMessageRepository {
)
}
+ claimForResend(params: {
+ id: string
+ workspaceId: string
+ createdAt: Date
+ }): Promise<{ id: string } | null> {
+ return this.updateAcrossShards(
+ params.id,
+ params.workspaceId,
+ { sendError: null },
+ "claimForResend",
+ params.createdAt,
+ sql`${messageModel.sendError} IS NOT NULL AND ${messageModel.sourceId} IS NULL`,
+ )
+ }
+
updateSendError(
id: string,
sendError: string | null,
diff --git a/packages/sdk/__tests__/channel-error-reason.test.ts b/packages/sdk/__tests__/channel-error-reason.test.ts
new file mode 100644
index 0000000000..401848eb68
--- /dev/null
+++ b/packages/sdk/__tests__/channel-error-reason.test.ts
@@ -0,0 +1,76 @@
+import { describe, expect, test } from "vitest"
+import {
+ ChannelError,
+ ChannelErrorCategory,
+ ChannelErrorReason,
+ isAccountSendBlocked,
+ isRateLimited,
+ ThreadControlTakeRefusedError,
+} from "../src"
+import { parsedErrorSchema } from "../src/lib/schemas"
+
+describe("ChannelError reason", () => {
+ test("survives getErrorData and parsedErrorSchema", async () => {
+ const error = new ChannelError("blocked", ChannelErrorCategory.UNKNOWN, {
+ code: 2022,
+ reason: ChannelErrorReason.ACCOUNT_POLICY_BLOCKED,
+ })
+
+ const data = await error.getErrorData()
+
+ expect(data.reason).toBe(ChannelErrorReason.ACCOUNT_POLICY_BLOCKED)
+ expect(parsedErrorSchema.parse(data).reason).toBe(
+ ChannelErrorReason.ACCOUNT_POLICY_BLOCKED,
+ )
+ })
+
+ test("is absent when not assigned", async () => {
+ const error = new ChannelError("x", ChannelErrorCategory.UNKNOWN)
+ expect((await error.getErrorData()).reason).toBeUndefined()
+ })
+
+ test("survives ThreadControlTakeRefusedError.fromChannelError", () => {
+ const origin = new ChannelError(
+ "x",
+ ChannelErrorCategory.PERMISSION_DENIED,
+ {
+ reason: ChannelErrorReason.ACCOUNT_SEND_RESTRICTED,
+ },
+ )
+
+ expect(ThreadControlTakeRefusedError.fromChannelError(origin).reason).toBe(
+ ChannelErrorReason.ACCOUNT_SEND_RESTRICTED,
+ )
+ })
+})
+
+describe("reason predicates", () => {
+ test("isAccountSendBlocked covers both account reasons only", () => {
+ expect(
+ isAccountSendBlocked({
+ reason: ChannelErrorReason.ACCOUNT_POLICY_BLOCKED,
+ }),
+ ).toBe(true)
+ expect(
+ isAccountSendBlocked({
+ reason: ChannelErrorReason.ACCOUNT_SEND_RESTRICTED,
+ }),
+ ).toBe(true)
+ expect(
+ isAccountSendBlocked({ reason: ChannelErrorReason.RATE_LIMITED }),
+ ).toBe(false)
+ expect(isAccountSendBlocked({})).toBe(false)
+ })
+
+ test("isRateLimited accepts category or reason", () => {
+ expect(isRateLimited({ category: ChannelErrorCategory.RATE_LIMITED })).toBe(
+ true,
+ )
+ expect(isRateLimited({ reason: ChannelErrorReason.RATE_LIMITED })).toBe(
+ true,
+ )
+ expect(isRateLimited({ category: ChannelErrorCategory.UNKNOWN })).toBe(
+ false,
+ )
+ })
+})
diff --git a/packages/sdk/src/lib/channel-error-codes.ts b/packages/sdk/src/lib/channel-error-codes.ts
index 1ce84f1e8c..b68ebaf265 100644
--- a/packages/sdk/src/lib/channel-error-codes.ts
+++ b/packages/sdk/src/lib/channel-error-codes.ts
@@ -26,3 +26,36 @@ export const PERMANENT_CATEGORIES = new Set([
ChannelErrorCategory.PAYLOAD_INVALID,
ChannelErrorCategory.QUOTA_EXCEEDED,
])
+
+/**
+ * Channel-agnostic finer-grained meaning of an error, assigned by each
+ * integration's error mapper. Independent of {@link ChannelErrorCategory}, so
+ * assigning a reason never changes retry behaviour.
+ */
+export const ChannelErrorReason = {
+ /** The account was blocked from sending after a policy violation. */
+ ACCOUNT_POLICY_BLOCKED: "account_policy_blocked",
+ /** The account is temporarily restricted from sending. */
+ ACCOUNT_SEND_RESTRICTED: "account_send_restricted",
+ /** The provider's rate limit was hit. */
+ RATE_LIMITED: "rate_limited",
+} as const
+
+export type ChannelErrorReason =
+ (typeof ChannelErrorReason)[keyof typeof ChannelErrorReason]
+
+export const channelErrorReasonValues = Object.values(ChannelErrorReason)
+
+export type ErrorWithReason = {
+ category?: string
+ reason?: ChannelErrorReason
+}
+
+/** The whole account (not one recipient) may not send right now. */
+export const isAccountSendBlocked = (error: ErrorWithReason): boolean =>
+ error.reason === ChannelErrorReason.ACCOUNT_POLICY_BLOCKED ||
+ error.reason === ChannelErrorReason.ACCOUNT_SEND_RESTRICTED
+
+export const isRateLimited = (error: ErrorWithReason): boolean =>
+ error.category === ChannelErrorCategory.RATE_LIMITED ||
+ error.reason === ChannelErrorReason.RATE_LIMITED
diff --git a/packages/sdk/src/lib/channel-error.ts b/packages/sdk/src/lib/channel-error.ts
index a2f22cfeb5..78e285c946 100644
--- a/packages/sdk/src/lib/channel-error.ts
+++ b/packages/sdk/src/lib/channel-error.ts
@@ -1,21 +1,25 @@
import {
type ChannelErrorCategory,
+ type ChannelErrorReason,
PERMANENT_CATEGORIES,
RETRYABLE_CATEGORIES,
} from "./channel-error-codes"
import { SdkException, UNKNOWN_ERROR } from "./exception"
+import type { ParsedError } from "./schemas"
export type ChannelErrorOptions = {
code?: string | number
httpStatusCode?: number
subCode?: string | number | null
type?: string
+ reason?: ChannelErrorReason
}
export class ChannelError extends SdkException {
readonly category: ChannelErrorCategory
readonly isRetryable: boolean
readonly isPermanent: boolean
+ readonly reason?: ChannelErrorReason
constructor(
message: string,
@@ -27,6 +31,7 @@ export class ChannelError extends SdkException {
httpStatusCode = 400,
subCode = null,
type,
+ reason,
} = options
super(message, "channelError", httpStatusCode, null, type)
@@ -35,6 +40,11 @@ export class ChannelError extends SdkException {
this.category = category
this.isRetryable = RETRYABLE_CATEGORIES.has(category)
this.isPermanent = PERMANENT_CATEGORIES.has(category)
+ this.reason = reason
+ }
+
+ override async getErrorData(): Promise {
+ return { ...(await super.getErrorData()), reason: this.reason }
}
}
@@ -52,6 +62,7 @@ export class ThreadControlTakeRefusedError extends ChannelError {
httpStatusCode: error.httpStatusCode,
subCode: error.subCode ?? null,
type: error.type,
+ reason: error.reason,
}).setOriginError(error.getOriginError())
}
}
diff --git a/packages/sdk/src/lib/schemas.ts b/packages/sdk/src/lib/schemas.ts
index 80d891e7b8..fa9a2ca1bb 100644
--- a/packages/sdk/src/lib/schemas.ts
+++ b/packages/sdk/src/lib/schemas.ts
@@ -1,4 +1,5 @@
import { z } from "zod"
+import { channelErrorReasonValues } from "./channel-error-codes"
export const integrationPropsSchema = z.object({
name: z.string().trim().min(1),
@@ -11,6 +12,7 @@ export const parsedErrorSchema = z.object({
statusCode: z.number(),
subcode: z.union([z.string(), z.number()]),
category: z.string().optional(),
+ reason: z.enum(channelErrorReasonValues).optional(),
isRetryable: z.boolean().optional(),
isPermanent: z.boolean().optional(),
})
diff --git a/packages/worker-config/__tests__/contact-scan-job-ids.test.ts b/packages/worker-config/__tests__/contact-scan-job-ids.test.ts
new file mode 100644
index 0000000000..9f34e44c57
--- /dev/null
+++ b/packages/worker-config/__tests__/contact-scan-job-ids.test.ts
@@ -0,0 +1,56 @@
+import { describe, expect, it } from "vitest"
+import {
+ buildContactScanJobId,
+ buildContactScanPageJobId,
+} from "../src/queues/integration/contact-scan-job-ids"
+
+describe("contact scan job ids", () => {
+ it("a scheduler job id carries the attempt", () => {
+ expect(buildContactScanJobId({ runId: "r1", attempts: 2 })).toBe(
+ "contact-scan-r1-2",
+ )
+ })
+
+ it("a forward continuation id is deterministic", () => {
+ const input = { runId: "r1", attempts: 2, pageNumber: 6 }
+ expect(buildContactScanPageJobId(input)).toBe("contact-scan-r1-2-page-6")
+ expect(buildContactScanPageJobId(input)).toBe(
+ buildContactScanPageJobId(input),
+ )
+ })
+
+ it("a same-page retry gets a distinct id from the job still running that page", () => {
+ const running = buildContactScanPageJobId({
+ runId: "r1",
+ attempts: 2,
+ pageNumber: 6,
+ })
+ const retry = buildContactScanPageJobId({
+ runId: "r1",
+ attempts: 2,
+ pageNumber: 6,
+ generation: 1_700_000_000_000,
+ })
+
+ expect(retry).not.toBe(running)
+ expect(retry).toBe("contact-scan-r1-2-page-6-gen-1700000000000")
+ })
+
+ it("two retries of the same page differ", () => {
+ const base = { runId: "r1", attempts: 2, pageNumber: 6 }
+ expect(buildContactScanPageJobId({ ...base, generation: 1 })).not.toBe(
+ buildContactScanPageJobId({ ...base, generation: 2 }),
+ )
+ })
+
+ it("ids stay colon-free (they appear in BullMQ Redis keys)", () => {
+ expect(
+ buildContactScanPageJobId({
+ runId: "r1",
+ attempts: 1,
+ pageNumber: 2,
+ generation: 3,
+ }),
+ ).not.toContain(":")
+ })
+})
diff --git a/packages/worker-config/src/queues/integration/contact-scan-job-ids.ts b/packages/worker-config/src/queues/integration/contact-scan-job-ids.ts
index f8ca3790cb..60479e30f9 100644
--- a/packages/worker-config/src/queues/integration/contact-scan-job-ids.ts
+++ b/packages/worker-config/src/queues/integration/contact-scan-job-ids.ts
@@ -20,10 +20,19 @@ export const buildContactScanJobId = (input: {
/**
* Id for a run's continuation chunk: same run and attempts, next page.
+ *
+ * `generation` is for a chunk that retries the SAME page (after a rate limit):
+ * its id would equal the id of the job still running it, and BullMQ silently
+ * drops an add whose id still exists. Omitted when the walk moves forward.
*/
export const buildContactScanPageJobId = (input: {
runId: string
attempts: number
pageNumber: number
-}): string =>
- `${buildContactScanJobId({ runId: input.runId, attempts: input.attempts })}-page-${input.pageNumber}`
+ generation?: number
+}): string => {
+ const base = `${buildContactScanJobId({ runId: input.runId, attempts: input.attempts })}-page-${input.pageNumber}`
+ return input.generation === undefined
+ ? base
+ : `${base}-gen-${input.generation}`
+}
From eb4158c861af2bfd48aefdaf9e427cadadc94881 Mon Sep 17 00:00:00 2001
From: Hung Phan Viet
Date: Sat, 14 Nov 2026 12:14:25 +0700
Subject: [PATCH 2/6] fix(messaging): keep booking buttons on resend and pause
only affected series
---
.../__tests__/message-resend-outgoing.test.ts | 41 +++++++++++++++++++
packages/business/src/broadcast/service.ts | 16 +++++++-
.../business/src/message/resend-outgoing.ts | 27 ++++++++++++
3 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/packages/business/__tests__/message-resend-outgoing.test.ts b/packages/business/__tests__/message-resend-outgoing.test.ts
index 814e3e168b..b1c9b04d3a 100644
--- a/packages/business/__tests__/message-resend-outgoing.test.ts
+++ b/packages/business/__tests__/message-resend-outgoing.test.ts
@@ -121,6 +121,47 @@ describe("messageService.resendOutgoing", () => {
)
})
+ test("a booking message is resent with its button, which some channels build their keyboard from", async () => {
+ const button = { type: "web_url", title: "Book", url: "https://x.test/b" }
+ mocks.findById.mockResolvedValue(
+ failedMessage({
+ contentAttributes: {
+ type: "template",
+ payload: { templateType: "button", buttons: [button] },
+ },
+ }),
+ )
+
+ await resend()
+
+ expect(mocks.chatQueueAdd).toHaveBeenCalledWith(
+ "sendChannelMessage",
+ expect.objectContaining({
+ data: expect.objectContaining({ quickReplies: [button] }),
+ }),
+ )
+ })
+
+ test.each([
+ ["no attributes", null],
+ [
+ "another template",
+ { type: "template", payload: { templateType: "generic" } },
+ ],
+ ["a malformed payload", { type: "template", payload: "oops" }],
+ ])("a message with %s is resent without buttons", async (_name, contentAttributes) => {
+ mocks.findById.mockResolvedValue(failedMessage({ contentAttributes }))
+
+ await resend()
+
+ expect(mocks.chatQueueAdd).toHaveBeenCalledWith(
+ "sendChannelMessage",
+ expect.objectContaining({
+ data: expect.objectContaining({ quickReplies: undefined }),
+ }),
+ )
+ })
+
test("a message with files is resent whole, with resolved attachment urls", async () => {
mocks.findById.mockResolvedValue(
failedMessage({
diff --git a/packages/business/src/broadcast/service.ts b/packages/business/src/broadcast/service.ts
index 09e8106c83..a256c0fe8b 100644
--- a/packages/business/src/broadcast/service.ts
+++ b/packages/business/src/broadcast/service.ts
@@ -1577,11 +1577,23 @@ class BroadcastService extends BaseService {
isNull(broadcastModel.deletedAt),
),
)
- .returning({ id: broadcastModel.id })
+ .returning({
+ id: broadcastModel.id,
+ parentBroadcastId: broadcastModel.parentBroadcastId,
+ })
+ // Only series with a run this block actually stopped are paused: a run
+ // that ended or was stopped since the list was read leaves its series be.
+ const stoppedParentIds = new Set(
+ stopped.flatMap((row) =>
+ row.parentBroadcastId === null ? [] : [row.parentBroadcastId],
+ ),
+ )
await this.pauseSeriesForBlockedAccount(tx, {
workspaceId: input.workspaceId,
- series,
+ series: series.filter((recurrence) =>
+ stoppedParentIds.has(recurrence.broadcastId),
+ ),
reasonColumns,
})
return stopped.map((row) => row.id)
diff --git a/packages/business/src/message/resend-outgoing.ts b/packages/business/src/message/resend-outgoing.ts
index 7a20ae5dfc..a965feb2aa 100644
--- a/packages/business/src/message/resend-outgoing.ts
+++ b/packages/business/src/message/resend-outgoing.ts
@@ -4,6 +4,7 @@ import {
} from "@chatbotx.io/database/partials"
import { createMessageRepository } from "@chatbotx.io/database/repositories"
import type { MessageModel } from "@chatbotx.io/database/types"
+import type { MessageButtonTemplate } from "@chatbotx.io/sdk"
import { ChatJobAction, chatQueue } from "@chatbotx.io/worker-config"
import { contactInboxService } from "../contact-inbox/service"
import { conversationService } from "../conversation/service"
@@ -25,6 +26,31 @@ const readReplyTargetCreatedAt = (
return Number.isNaN(date.getTime()) ? null : date
}
+/**
+ * The buttons a message was created with (a booking link), kept on the row as a
+ * button template: some channels (Telegram) build their keyboard only from the
+ * send job's `quickReplies`, so a resend must pass them again.
+ */
+const readStoredButtons = (
+ contentAttributes: MessageModel["contentAttributes"],
+): MessageButtonTemplate[] | undefined => {
+ if (contentAttributes?.type !== "template") {
+ return
+ }
+ const payload: unknown = contentAttributes.payload
+ if (
+ typeof payload !== "object" ||
+ payload === null ||
+ !("templateType" in payload) ||
+ payload.templateType !== "button" ||
+ !("buttons" in payload) ||
+ !Array.isArray(payload.buttons)
+ ) {
+ return
+ }
+ return payload.buttons
+}
+
/**
* Re-queues a failed outgoing message for delivery, whole (no record is kept of
* which part reached the customer). Safe against a double click: the failed
@@ -111,6 +137,7 @@ export const resendOutgoing = async (props: {
conversation,
contactInbox,
message: { ...messageWithAttachments, parentCreatedAt },
+ quickReplies: readStoredButtons(message.contentAttributes),
sendFrom: "inbox",
},
})
From be0b4f136050d7a9c4f11a0bc86ebb6b19ccc1d7 Mon Sep 17 00:00:00 2001
From: Hung Phan Viet
Date: Sat, 14 Nov 2026 12:54:35 +0700
Subject: [PATCH 3/6] fix(messaging): tighten resend rules, send queue holds
and contact scan job ids
---
.../__tests__/api-parity-manifest.json | 1 -
.../__tests__/messages-public-api.test.ts | 20 +++---
.../__tests__/resend-message-button.test.tsx | 1 -
.../__tests__/send-queue-notice.test.tsx | 20 ++++--
apps/builder/messages/ar.json | 3 +-
apps/builder/messages/az.json | 3 +-
apps/builder/messages/da.json | 3 +-
apps/builder/messages/de.json | 3 +-
apps/builder/messages/en.json | 3 +-
apps/builder/messages/es.json | 3 +-
apps/builder/messages/fi.json | 3 +-
apps/builder/messages/fr.json | 3 +-
apps/builder/messages/he.json | 3 +-
apps/builder/messages/id.json | 3 +-
apps/builder/messages/it.json | 3 +-
apps/builder/messages/ja.json | 3 +-
apps/builder/messages/nl.json | 3 +-
apps/builder/messages/pt-BR.json | 3 +-
apps/builder/messages/pt-PT.json | 3 +-
apps/builder/messages/ro.json | 3 +-
apps/builder/messages/sv.json | 3 +-
apps/builder/messages/tr.json | 3 +-
apps/builder/messages/vi.json | 3 +-
apps/builder/messages/zh-CN.json | 3 +-
apps/builder/messages/zh-TW.json | 3 +-
.../src/features/chat/store/chat-store.ts | 4 +-
.../components/contact-scan-history-table.tsx | 8 ++-
.../messages/actions/resend-message.action.ts | 25 +++-----
.../src/features/messages/api/public.ts | 6 +-
.../components/resend-message-button.tsx | 14 +----
.../messages/components/send-queue-notice.tsx | 23 +++----
.../messages/lib/__tests__/send-queue.test.ts | 26 +++++++-
.../src/features/messages/lib/send-queue.ts | 30 ++++++++-
.../src/features/messages/schema/mutation.ts | 2 +-
.../__tests__/contact-scan-engine.test.ts | 26 ++++++++
.../__tests__/send-message-handler.test.ts | 61 +++++++++++++++++++
apps/worker/src/chat/handlers/send-message.ts | 15 +++--
.../handlers/contact-scan/engine.ts | 8 ++-
.../schedule/handlers/scan-contact-scans.ts | 1 +
docs/contact-scan.md | 12 ++--
.../messenger/src/handlers/conversation.ts | 1 +
.../broadcast-stop-blocked-account-db.test.ts | 47 ++++++++++++++
.../message-resendable-partial.test.ts | 5 ++
packages/database/src/partials/message.ts | 14 +++++
.../repository/sharded-message-repository.ts | 2 +-
.../__tests__/contact-scan-job-ids.test.ts | 11 ++++
.../integration/contact-scan-job-ids.ts | 13 +++-
47 files changed, 354 insertions(+), 105 deletions(-)
diff --git a/apps/builder/__tests__/api-parity-manifest.json b/apps/builder/__tests__/api-parity-manifest.json
index 28a2458650..ece481377c 100644
--- a/apps/builder/__tests__/api-parity-manifest.json
+++ b/apps/builder/__tests__/api-parity-manifest.json
@@ -350,7 +350,6 @@
"messages/delete-message.action:deleteMessageAction": "covered:messages",
"messages/edit-message.action:editMessage": "covered:messages",
"messages/edit-message.action:editMessageAction": "covered:messages",
- "messages/resend-message.action:resendMessage": "covered:messages",
"messages/resend-message.action:resendMessageAction": "covered:messages",
"messages/generate-call-ai-summary.action:generateCallAiSummaryAction": "covered:messages",
"messages/get-call-recording-url.action:getCallRecordingUrlAction": "covered:messages",
diff --git a/apps/builder/__tests__/messages-public-api.test.ts b/apps/builder/__tests__/messages-public-api.test.ts
index 5ca48b4125..ef7ee99c2f 100644
--- a/apps/builder/__tests__/messages-public-api.test.ts
+++ b/apps/builder/__tests__/messages-public-api.test.ts
@@ -53,6 +53,7 @@ const conversationService = {
const messageService = {
findByIdWithUrls: vi.fn(),
createOutgoing: vi.fn(),
+ resendOutgoing: vi.fn(),
}
const resolveTemplateParams = vi.fn()
vi.mock("@chatbotx.io/business", () => ({
@@ -98,11 +99,6 @@ vi.mock("@/features/messages/actions/delete-message.action", () => ({
deleteMessage,
}))
-const resendMessage = vi.fn()
-vi.mock("@/features/messages/actions/resend-message.action", () => ({
- resendMessage,
-}))
-
const changeMessageAttributes = vi.fn()
vi.mock("@/features/messages/actions/change-message-attributes.action", () => ({
changeMessageAttributes,
@@ -419,19 +415,23 @@ describe("POST /v1/conversations/{conversationId}/messages/{messageId}/resend",
expect(procedure.route.tags).toContain("Messages")
})
- test("delegates to resendMessage with the id field it expects and returns its result", async () => {
+ test("delegates to messageService.resendOutgoing with the id field it expects and returns its result", async () => {
const createdAt = new Date("2026-01-01T00:00:00Z")
- resendMessage.mockResolvedValueOnce({ id: "msg-1", queued: true })
+ messageService.resendOutgoing.mockResolvedValueOnce({
+ id: "msg-1",
+ queued: true,
+ })
const result = await procedure.handler?.({
context,
input: { conversationId: "conv-1", messageId: "msg-1", createdAt },
})
- expect(resendMessage).toHaveBeenCalledWith({
+ expect(messageService.resendOutgoing).toHaveBeenCalledWith({
workspaceId: "ws-1",
conversationId: "conv-1",
- parsedInput: { id: "msg-1", createdAt },
+ messageId: "msg-1",
+ createdAt,
})
expect(result).toEqual({ id: "msg-1", queued: true })
})
@@ -452,7 +452,7 @@ describe("POST /v1/conversations/{conversationId}/messages/{messageId}/resend",
}),
).rejects.toThrow("Conversation not found")
- expect(resendMessage).not.toHaveBeenCalled()
+ expect(messageService.resendOutgoing).not.toHaveBeenCalled()
})
})
diff --git a/apps/builder/__tests__/resend-message-button.test.tsx b/apps/builder/__tests__/resend-message-button.test.tsx
index f511e3e413..1feb5d692f 100644
--- a/apps/builder/__tests__/resend-message-button.test.tsx
+++ b/apps/builder/__tests__/resend-message-button.test.tsx
@@ -112,7 +112,6 @@ describe("ResendMessageButton", () => {
const { conversationId, update } = lastQueueUpdate(0)
expect(conversationId).toBe("conv-1")
expect(update(createSendQueue()).inFlight?.messageId).toBe("msg-1")
- expect(el.querySelector("button")?.disabled).toBe(true)
await act(async () => finish({ data: { id: "msg-1", queued: true } }))
expect(toast.error).not.toHaveBeenCalled()
diff --git a/apps/builder/__tests__/send-queue-notice.test.tsx b/apps/builder/__tests__/send-queue-notice.test.tsx
index 8303d5e4fd..279d431a46 100644
--- a/apps/builder/__tests__/send-queue-notice.test.tsx
+++ b/apps/builder/__tests__/send-queue-notice.test.tsx
@@ -34,7 +34,7 @@ afterEach(() => {
})
describe("SendQueueNotice", () => {
- test("after a failure it says how many are held and offers only Discard (the resend is on the failed message)", () => {
+ test("after a failure it says so and offers to keep sending or discard the queued messages", () => {
const onDiscard = vi.fn()
const onContinue = vi.fn()
const el = render({
@@ -46,8 +46,8 @@ describe("SendQueueNotice", () => {
expect(el.getAttribute("role")).toBeNull()
expect(el.querySelector('[role="alert"]')).not.toBeNull()
- expect(el.textContent).toContain("messages.sendQueue.failed:3")
- expect(buttonWithText(el, "messages.sendQueue.continue")).toBeUndefined()
+ expect(el.textContent).toContain("messages.sendQueue.failed")
+ expect(buttonWithText(el, "messages.sendQueue.continue")).toBeDefined()
act(() => {
buttonWithText(el, "messages.sendQueue.discard")?.click()
@@ -56,6 +56,18 @@ describe("SendQueueNotice", () => {
expect(onContinue).not.toHaveBeenCalled()
})
+ test("with nothing queued the discard button reads Dismiss", () => {
+ const el = render({
+ heldCount: 0,
+ reason: "failed",
+ onContinue: vi.fn(),
+ onDiscard: vi.fn(),
+ })
+
+ expect(buttonWithText(el, "messages.sendQueue.dismiss")).toBeDefined()
+ expect(buttonWithText(el, "messages.sendQueue.discard")).toBeUndefined()
+ })
+
test("after a lost answer it offers to send the rest or discard them", () => {
const onDiscard = vi.fn()
const onContinue = vi.fn()
@@ -66,7 +78,7 @@ describe("SendQueueNotice", () => {
onDiscard,
})
- expect(el.textContent).toContain("messages.sendQueue.unconfirmed:2")
+ expect(el.textContent).toContain("messages.sendQueue.unconfirmed")
act(() => {
buttonWithText(el, "messages.sendQueue.continue")?.click()
diff --git a/apps/builder/messages/ar.json b/apps/builder/messages/ar.json
index e7cf20c475..20bad25666 100644
--- a/apps/builder/messages/ar.json
+++ b/apps/builder/messages/ar.json
@@ -4599,7 +4599,8 @@
"failed": "فشل إرسال رسالة. أعد إرسالها لمتابعة الإرسال.",
"unconfirmed": "تعذّر تأكيد إرسال آخر رسالة. اختر ما إذا كنت تريد متابعة الإرسال.",
"continue": "متابعة الإرسال",
- "discard": "إغلاق"
+ "discard": "تجاهل الرسائل في قائمة الانتظار",
+ "dismiss": "تجاهل"
}
},
"instagram": {
diff --git a/apps/builder/messages/az.json b/apps/builder/messages/az.json
index 9eb658bcc3..bbf7cb31ed 100644
--- a/apps/builder/messages/az.json
+++ b/apps/builder/messages/az.json
@@ -5281,7 +5281,8 @@
"failed": "Mesaj göndərilmədi. Göndərməyə davam etmək üçün onu yenidən göndərin.",
"unconfirmed": "Son mesajın göndərildiyini təsdiqləyə bilmədik. Göndərməyə davam edib-etməyəcəyinizi seçin.",
"continue": "Göndərməyə davam et",
- "discard": "Bağla"
+ "discard": "Növbədəki mesajları sil",
+ "dismiss": "Bağla"
}
},
"instagram": {
diff --git a/apps/builder/messages/da.json b/apps/builder/messages/da.json
index a2d33dd9a3..3f0b38df94 100644
--- a/apps/builder/messages/da.json
+++ b/apps/builder/messages/da.json
@@ -4599,7 +4599,8 @@
"failed": "En besked kunne ikke sendes. Send den igen for at fortsætte.",
"unconfirmed": "Vi kunne ikke bekræfte, at den sidste besked blev sendt. Vælg, om du vil fortsætte.",
"continue": "Fortsæt med at sende",
- "discard": "Afvis"
+ "discard": "Kassér beskeder i kø",
+ "dismiss": "Afvis"
}
},
"instagram": {
diff --git a/apps/builder/messages/de.json b/apps/builder/messages/de.json
index b0c030a3d5..08f02ac907 100644
--- a/apps/builder/messages/de.json
+++ b/apps/builder/messages/de.json
@@ -4599,7 +4599,8 @@
"failed": "Eine Nachricht konnte nicht gesendet werden. Sende sie erneut, um fortzufahren.",
"unconfirmed": "Wir konnten nicht bestätigen, dass die letzte Nachricht gesendet wurde. Wähle, ob du weitersenden möchtest.",
"continue": "Weitersenden",
- "discard": "Schließen"
+ "discard": "Wartende Nachrichten verwerfen",
+ "dismiss": "Schließen"
}
},
"instagram": {
diff --git a/apps/builder/messages/en.json b/apps/builder/messages/en.json
index 65108b7d35..ebaef68bf0 100644
--- a/apps/builder/messages/en.json
+++ b/apps/builder/messages/en.json
@@ -5281,7 +5281,8 @@
"failed": "A message failed to send. Resend it to continue sending.",
"unconfirmed": "We couldn't confirm the last message was sent. Choose whether to keep sending.",
"continue": "Keep sending",
- "discard": "Dismiss"
+ "discard": "Discard queued messages",
+ "dismiss": "Dismiss"
}
},
"instagram": {
diff --git a/apps/builder/messages/es.json b/apps/builder/messages/es.json
index 7e8677d400..fe8b40df16 100644
--- a/apps/builder/messages/es.json
+++ b/apps/builder/messages/es.json
@@ -4599,7 +4599,8 @@
"failed": "No se pudo enviar un mensaje. Reenvíalo para seguir enviando.",
"unconfirmed": "No pudimos confirmar que el último mensaje se envió. Elige si quieres seguir enviando.",
"continue": "Seguir enviando",
- "discard": "Descartar"
+ "discard": "Descartar mensajes en cola",
+ "dismiss": "Descartar"
}
},
"instagram": {
diff --git a/apps/builder/messages/fi.json b/apps/builder/messages/fi.json
index 139cac4255..31541eb755 100644
--- a/apps/builder/messages/fi.json
+++ b/apps/builder/messages/fi.json
@@ -4599,7 +4599,8 @@
"failed": "Viestin lähetys epäonnistui. Lähetä se uudelleen jatkaaksesi.",
"unconfirmed": "Emme voineet vahvistaa, että viimeisin viesti lähetettiin. Valitse, jatketaanko lähettämistä.",
"continue": "Jatka lähettämistä",
- "discard": "Hylkää"
+ "discard": "Hylkää jonossa olevat viestit",
+ "dismiss": "Hylkää"
}
},
"instagram": {
diff --git a/apps/builder/messages/fr.json b/apps/builder/messages/fr.json
index cee6e1f1a8..cb36383954 100644
--- a/apps/builder/messages/fr.json
+++ b/apps/builder/messages/fr.json
@@ -4599,7 +4599,8 @@
"failed": "Un message n'a pas pu être envoyé. Renvoyez-le pour continuer.",
"unconfirmed": "Nous n'avons pas pu confirmer l'envoi du dernier message. Choisissez de continuer ou non.",
"continue": "Continuer l'envoi",
- "discard": "Ignorer"
+ "discard": "Supprimer les messages en attente",
+ "dismiss": "Ignorer"
}
},
"instagram": {
diff --git a/apps/builder/messages/he.json b/apps/builder/messages/he.json
index 402117e0e8..a232c1331f 100644
--- a/apps/builder/messages/he.json
+++ b/apps/builder/messages/he.json
@@ -2232,7 +2232,8 @@
"failed": "שליחת הודעה נכשלה. שלח אותה שוב כדי להמשיך.",
"unconfirmed": "לא הצלחנו לאשר שההודעה האחרונה נשלחה. בחר אם להמשיך לשלוח.",
"continue": "המשך לשלוח",
- "discard": "סגור"
+ "discard": "מחק הודעות בתור",
+ "dismiss": "סגור"
}
},
"instagram": {
diff --git a/apps/builder/messages/id.json b/apps/builder/messages/id.json
index 9f3438fb9e..5a30dfc9a6 100644
--- a/apps/builder/messages/id.json
+++ b/apps/builder/messages/id.json
@@ -4599,7 +4599,8 @@
"failed": "Sebuah pesan gagal terkirim. Kirim ulang untuk melanjutkan.",
"unconfirmed": "Kami tidak dapat memastikan pesan terakhir terkirim. Pilih apakah akan terus mengirim.",
"continue": "Lanjutkan pengiriman",
- "discard": "Tutup"
+ "discard": "Buang pesan dalam antrean",
+ "dismiss": "Tutup"
}
},
"instagram": {
diff --git a/apps/builder/messages/it.json b/apps/builder/messages/it.json
index 82a997e6d5..eebbb79fa0 100644
--- a/apps/builder/messages/it.json
+++ b/apps/builder/messages/it.json
@@ -4599,7 +4599,8 @@
"failed": "Un messaggio non è stato inviato. Invialo di nuovo per continuare.",
"unconfirmed": "Non siamo riusciti a confermare l'invio dell'ultimo messaggio. Scegli se continuare a inviare.",
"continue": "Continua a inviare",
- "discard": "Ignora"
+ "discard": "Elimina i messaggi in coda",
+ "dismiss": "Ignora"
}
},
"instagram": {
diff --git a/apps/builder/messages/ja.json b/apps/builder/messages/ja.json
index 13737841f2..b6c9413dcd 100644
--- a/apps/builder/messages/ja.json
+++ b/apps/builder/messages/ja.json
@@ -4576,7 +4576,8 @@
"failed": "メッセージを送信できませんでした。再送信すると続行できます。",
"unconfirmed": "最後のメッセージが送信されたか確認できませんでした。送信を続けるか選択してください。",
"continue": "送信を続ける",
- "discard": "閉じる"
+ "discard": "待機中のメッセージを破棄",
+ "dismiss": "閉じる"
}
},
"instagram": {
diff --git a/apps/builder/messages/nl.json b/apps/builder/messages/nl.json
index 014491adbe..b42fbe475e 100644
--- a/apps/builder/messages/nl.json
+++ b/apps/builder/messages/nl.json
@@ -4599,7 +4599,8 @@
"failed": "Een bericht kon niet worden verzonden. Verstuur het opnieuw om door te gaan.",
"unconfirmed": "We konden niet bevestigen dat het laatste bericht is verzonden. Kies of je wilt doorgaan met verzenden.",
"continue": "Doorgaan met verzenden",
- "discard": "Sluiten"
+ "discard": "Berichten in de wachtrij verwijderen",
+ "dismiss": "Sluiten"
}
},
"instagram": {
diff --git a/apps/builder/messages/pt-BR.json b/apps/builder/messages/pt-BR.json
index 7231566f1d..9b738d42e8 100644
--- a/apps/builder/messages/pt-BR.json
+++ b/apps/builder/messages/pt-BR.json
@@ -4576,7 +4576,8 @@
"failed": "Uma mensagem não foi enviada. Reenvie-a para continuar.",
"unconfirmed": "Não foi possível confirmar o envio da última mensagem. Escolha se quer continuar enviando.",
"continue": "Continuar enviando",
- "discard": "Dispensar"
+ "discard": "Descartar mensagens na fila",
+ "dismiss": "Dispensar"
}
},
"instagram": {
diff --git a/apps/builder/messages/pt-PT.json b/apps/builder/messages/pt-PT.json
index 1ee1511d7b..97de55e4a7 100644
--- a/apps/builder/messages/pt-PT.json
+++ b/apps/builder/messages/pt-PT.json
@@ -4599,7 +4599,8 @@
"failed": "Uma mensagem não foi enviada. Reenvie-a para continuar.",
"unconfirmed": "Não foi possível confirmar o envio da última mensagem. Escolha se quer continuar a enviar.",
"continue": "Continuar a enviar",
- "discard": "Dispensar"
+ "discard": "Descartar mensagens em fila",
+ "dismiss": "Dispensar"
}
},
"instagram": {
diff --git a/apps/builder/messages/ro.json b/apps/builder/messages/ro.json
index 31a143eb7a..25cc98b4fe 100644
--- a/apps/builder/messages/ro.json
+++ b/apps/builder/messages/ro.json
@@ -4599,7 +4599,8 @@
"failed": "Un mesaj nu a putut fi trimis. Retrimite-l pentru a continua.",
"unconfirmed": "Nu am putut confirma că ultimul mesaj a fost trimis. Alege dacă vrei să continui trimiterea.",
"continue": "Continuă trimiterea",
- "discard": "Închide"
+ "discard": "Renunță la mesajele din coadă",
+ "dismiss": "Închide"
}
},
"instagram": {
diff --git a/apps/builder/messages/sv.json b/apps/builder/messages/sv.json
index 5f33b9bba0..42f8ba1278 100644
--- a/apps/builder/messages/sv.json
+++ b/apps/builder/messages/sv.json
@@ -5752,7 +5752,8 @@
"failed": "Ett meddelande kunde inte skickas. Skicka det igen för att fortsätta.",
"unconfirmed": "Vi kunde inte bekräfta att det senaste meddelandet skickades. Välj om du vill fortsätta skicka.",
"continue": "Fortsätt skicka",
- "discard": "Avfärda"
+ "discard": "Kasta meddelanden i kön",
+ "dismiss": "Avfärda"
}
},
"messenger": {
diff --git a/apps/builder/messages/tr.json b/apps/builder/messages/tr.json
index 0b59a80139..4f191868dc 100644
--- a/apps/builder/messages/tr.json
+++ b/apps/builder/messages/tr.json
@@ -4599,7 +4599,8 @@
"failed": "Bir mesaj gönderilemedi. Devam etmek için yeniden gönderin.",
"unconfirmed": "Son mesajın gönderildiği doğrulanamadı. Göndermeye devam edip etmeyeceğinizi seçin.",
"continue": "Göndermeye devam et",
- "discard": "Kapat"
+ "discard": "Kuyruktaki mesajları sil",
+ "dismiss": "Kapat"
}
},
"instagram": {
diff --git a/apps/builder/messages/vi.json b/apps/builder/messages/vi.json
index a534349e62..dc3a0b51f6 100644
--- a/apps/builder/messages/vi.json
+++ b/apps/builder/messages/vi.json
@@ -4641,7 +4641,8 @@
"failed": "Một tin nhắn gửi thất bại. Hãy gửi lại để tiếp tục gửi.",
"unconfirmed": "Chưa xác nhận được tin nhắn cuối đã gửi. Hãy chọn có tiếp tục gửi hay không.",
"continue": "Tiếp tục gửi",
- "discard": "Bỏ qua"
+ "discard": "Hủy các tin đang chờ",
+ "dismiss": "Bỏ qua"
}
},
"instagram": {
diff --git a/apps/builder/messages/zh-CN.json b/apps/builder/messages/zh-CN.json
index 7d6395fc9b..5acc17bfca 100644
--- a/apps/builder/messages/zh-CN.json
+++ b/apps/builder/messages/zh-CN.json
@@ -5752,7 +5752,8 @@
"failed": "有一条消息发送失败。请重新发送以继续。",
"unconfirmed": "无法确认最后一条消息是否已发送。请选择是否继续发送。",
"continue": "继续发送",
- "discard": "忽略"
+ "discard": "丢弃排队中的消息",
+ "dismiss": "忽略"
}
},
"messenger": {
diff --git a/apps/builder/messages/zh-TW.json b/apps/builder/messages/zh-TW.json
index 8144246a54..a9561af870 100644
--- a/apps/builder/messages/zh-TW.json
+++ b/apps/builder/messages/zh-TW.json
@@ -1910,7 +1910,8 @@
"failed": "有一則訊息傳送失敗。請重新傳送以繼續。",
"unconfirmed": "無法確認最後一則訊息是否已傳送。請選擇是否繼續傳送。",
"continue": "繼續傳送",
- "discard": "忽略"
+ "discard": "捨棄佇列中的訊息",
+ "dismiss": "忽略"
}
},
"productCategories": {
diff --git a/apps/builder/src/features/chat/store/chat-store.ts b/apps/builder/src/features/chat/store/chat-store.ts
index 059fd3ec1c..54a6d110f9 100644
--- a/apps/builder/src/features/chat/store/chat-store.ts
+++ b/apps/builder/src/features/chat/store/chat-store.ts
@@ -1212,7 +1212,9 @@ export const createChatStore = (initialState: ChatStoreInitialState = {}) => {
changed ||= next !== queue
sendQueues[conversationId] = next
}
- return changed ? { sendQueues } : state
+ return changed
+ ? { sendQueues: pruneIdleSendQueues(sendQueues, Date.now()) }
+ : state
})
},
diff --git a/apps/builder/src/features/contact-scan/components/contact-scan-history-table.tsx b/apps/builder/src/features/contact-scan/components/contact-scan-history-table.tsx
index 962601e8cd..92f94fb7c5 100644
--- a/apps/builder/src/features/contact-scan/components/contact-scan-history-table.tsx
+++ b/apps/builder/src/features/contact-scan/components/contact-scan-history-table.tsx
@@ -158,7 +158,13 @@ export function ContactScanHistoryTable({
size: 280,
header: t("contactScan.histories.columns.error"),
cell: ({ row }) => (
-
+
),
enableSorting: false,
enableHiding: false,
diff --git a/apps/builder/src/features/messages/actions/resend-message.action.ts b/apps/builder/src/features/messages/actions/resend-message.action.ts
index 100b97d41e..f44e389020 100644
--- a/apps/builder/src/features/messages/actions/resend-message.action.ts
+++ b/apps/builder/src/features/messages/actions/resend-message.action.ts
@@ -3,23 +3,7 @@
import { messageService } from "@chatbotx.io/business"
import { zodBigintAsString } from "@chatbotx.io/utils"
import { workspaceActionClient } from "@/lib/safe-action"
-import {
- type ResendMessageRequest,
- resendMessageRequest,
-} from "../schema/mutation"
-
-/** Shared by the builder action and the public route: one service call. */
-export const resendMessage = async (props: {
- workspaceId: string
- conversationId: string
- parsedInput: ResendMessageRequest
-}) =>
- await messageService.resendOutgoing({
- workspaceId: props.workspaceId,
- conversationId: props.conversationId,
- messageId: props.parsedInput.id,
- createdAt: props.parsedInput.createdAt,
- })
+import { resendMessageRequest } from "../schema/mutation"
export const resendMessageAction = workspaceActionClient
.bindArgsSchemas([zodBigintAsString(), zodBigintAsString()])
@@ -30,5 +14,10 @@ export const resendMessageAction = workspaceActionClient
parsedInput,
} = props
- return await resendMessage({ workspaceId, conversationId, parsedInput })
+ return await messageService.resendOutgoing({
+ workspaceId,
+ conversationId,
+ messageId: parsedInput.id,
+ createdAt: parsedInput.createdAt,
+ })
})
diff --git a/apps/builder/src/features/messages/api/public.ts b/apps/builder/src/features/messages/api/public.ts
index 95be27fbcd..8cd4f4ec59 100644
--- a/apps/builder/src/features/messages/api/public.ts
+++ b/apps/builder/src/features/messages/api/public.ts
@@ -16,7 +16,6 @@ import {
import { changeMessageAttributes } from "@/features/messages/actions/change-message-attributes.action"
import { deleteMessage } from "@/features/messages/actions/delete-message.action"
import { editMessage } from "@/features/messages/actions/edit-message.action"
-import { resendMessage } from "@/features/messages/actions/resend-message.action"
import { getWhatsappFlowResponseView } from "@/features/messages/lib/get-whatsapp-flow-response"
import { sendWhatsappTemplateToConversation } from "@/features/messages/lib/send-whatsapp-template"
import { listMessages } from "@/features/messages/queries"
@@ -329,10 +328,11 @@ export const messagesPublicRouter = {
.errors(possibleErrorsOnResendingMessage)
.handler(async ({ context, input }) => {
await assertConversationAccessForCaller(context, input.conversationId)
- return await resendMessage({
+ return await messageService.resendOutgoing({
workspaceId: context.workspace.id,
conversationId: input.conversationId,
- parsedInput: { id: input.messageId, createdAt: input.createdAt },
+ messageId: input.messageId,
+ createdAt: input.createdAt,
})
}),
diff --git a/apps/builder/src/features/messages/components/resend-message-button.tsx b/apps/builder/src/features/messages/components/resend-message-button.tsx
index e175ad458f..6707bb80bf 100644
--- a/apps/builder/src/features/messages/components/resend-message-button.tsx
+++ b/apps/builder/src/features/messages/components/resend-message-button.tsx
@@ -1,9 +1,8 @@
"use client"
import { Button } from "@chatbotx.io/ui/components/ui/button"
-import { Loader2Icon, RotateCcwIcon } from "lucide-react"
+import { RotateCcwIcon } from "lucide-react"
import { useTranslations } from "next-intl"
-import { useState } from "react"
import { toast } from "sonner"
import { useChatStore } from "../../chat/store/chat-store-provider"
import { resendMessageAction } from "../actions/resend-message.action"
@@ -38,10 +37,8 @@ export function ResendMessageButton({ message }: ResendMessageButtonProps) {
const markMessageFailed = useChatStore((state) => state.markMessageFailed)
const updateSendQueue = useChatStore((state) => state.updateSendQueue)
const updateAllSendQueues = useChatStore((state) => state.updateAllSendQueues)
- const [isPending, setIsPending] = useState(false)
const resend = async () => {
- setIsPending(true)
markMessageFailed(message.id, undefined, null)
const ref = { messageId: message.id, clientId: message.clientId }
const now = Date.now()
@@ -71,25 +68,18 @@ export function ResendMessageButton({ message }: ResendMessageButtonProps) {
restore(
error instanceof Error ? error.message : t("messages.unknownError"),
)
- } finally {
- setIsPending(false)
}
}
return (
- {isPending ? (
-
- ) : (
-
- )}
+
{t("actions.resend")}
)
diff --git a/apps/builder/src/features/messages/components/send-queue-notice.tsx b/apps/builder/src/features/messages/components/send-queue-notice.tsx
index 4b6a58b08b..f6ebbb4a86 100644
--- a/apps/builder/src/features/messages/components/send-queue-notice.tsx
+++ b/apps/builder/src/features/messages/components/send-queue-notice.tsx
@@ -17,8 +17,8 @@ type SendQueueNoticeProps = {
/**
* Shown while messages typed after a failed (or unconfirmed) one are held back.
- * A failed message is resent from its own row; an unconfirmed one needs the
- * person to say whether to go on. Either way the held messages can be dropped.
+ * A failed message is resent from its own row (when it can be); either way the
+ * person can go on regardless or drop what is held.
*/
export function SendQueueNotice({
heldCount,
@@ -46,18 +46,15 @@ export function SendQueueNotice({
- {isUnconfirmed && (
-
- {t("messages.sendQueue.continue")}
-
- )}
+
+ {t("messages.sendQueue.continue")}
+
- {t("messages.sendQueue.discard")}
+ {t(
+ heldCount > 0
+ ? "messages.sendQueue.discard"
+ : "messages.sendQueue.dismiss",
+ )}
diff --git a/apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts b/apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts
index e98b3239ef..7d9a349e30 100644
--- a/apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts
+++ b/apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts
@@ -320,11 +320,33 @@ describe("a lost answer", () => {
expect(isSendQueueLocked(queue)).toBe(true)
})
- test("a late answer after the expiry changes nothing", () => {
+ test("a late success after the expiry lifts the hold so the queue goes on", () => {
let queue = submitNext(queueWith("a", "b"), 0)
queue = expireInFlightSend(queue, AGENT_SEND_CONFIRM_TIMEOUT_MS)
- expect(settleSend(queue, { clientId: "a", error: null }, 40_000)).toBe(
+ queue = settleSend(queue, { clientId: "a", error: null }, 40_000)
+
+ expect(queue.holdReason).toBeNull()
+ expect(nextSendToSubmit(queue, 40_000 + AGENT_SEND_GAP_MS)?.clientId).toBe(
+ "b",
+ )
+ })
+
+ test("a late failure after the expiry turns the hold into a failure", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = expireInFlightSend(queue, AGENT_SEND_CONFIRM_TIMEOUT_MS)
+
+ queue = settleSend(queue, { clientId: "a", error: "refused" }, 40_000)
+
+ expect(queue.holdReason).toBe("failed")
+ expect(queue.waiting.map((item) => item.clientId)).toEqual(["b"])
+ })
+
+ test("a late answer for some other message changes nothing", () => {
+ let queue = submitNext(queueWith("a", "b"), 0)
+ queue = expireInFlightSend(queue, AGENT_SEND_CONFIRM_TIMEOUT_MS)
+
+ expect(settleSend(queue, { clientId: "zzz", error: null }, 40_000)).toBe(
queue,
)
})
diff --git a/apps/builder/src/features/messages/lib/send-queue.ts b/apps/builder/src/features/messages/lib/send-queue.ts
index 0154fb7a4b..589589a4c2 100644
--- a/apps/builder/src/features/messages/lib/send-queue.ts
+++ b/apps/builder/src/features/messages/lib/send-queue.ts
@@ -219,6 +219,34 @@ const matchesInFlight = (
(signal.clientId !== undefined && signal.clientId === inFlight.clientId) ||
(signal.messageId !== undefined && signal.messageId === inFlight.messageId)
+/**
+ * The answer for a message the queue already stopped waiting for (the 30 s
+ * "unconfirmed" hold): it is now known, so the hold becomes a failure or ends.
+ * Any other message's answer changes nothing.
+ */
+const settleLateSend = (
+ queue: SendQueue,
+ signal: SendResultSignal,
+ now: number,
+): SendQueue => {
+ const isLateAnswer =
+ queue.holdReason === SEND_QUEUE_HOLD_REASONS.unconfirmed &&
+ queue.heldBy !== null &&
+ sameMessage(queue.heldBy, signal)
+ if (!isLateAnswer) {
+ return queue
+ }
+ if (signal.error === null) {
+ return {
+ ...queue,
+ holdReason: null,
+ heldBy: null,
+ nextAllowedAt: now + AGENT_SEND_GAP_MS,
+ }
+ }
+ return { ...queue, holdReason: SEND_QUEUE_HOLD_REASONS.failed }
+}
+
/**
* Applies the channel's answer. A result for a message that is not the one in
* flight (another tab's, an old retry, the clearing of an error) changes
@@ -230,7 +258,7 @@ export const settleSend = (
now: number,
): SendQueue => {
if (!(queue.inFlight && matchesInFlight(queue.inFlight, signal))) {
- return queue
+ return settleLateSend(queue, signal, now)
}
if (signal.error === null) {
return {
diff --git a/apps/builder/src/features/messages/schema/mutation.ts b/apps/builder/src/features/messages/schema/mutation.ts
index 1bef811bbf..c74e8f6380 100644
--- a/apps/builder/src/features/messages/schema/mutation.ts
+++ b/apps/builder/src/features/messages/schema/mutation.ts
@@ -224,7 +224,7 @@ export const deleteMessageRequest = z.object({
export type DeleteMessageRequest = z.infer
export const resendMessageRequest = z.object({
- id: z.string().min(1),
+ id: zodBigintAsString().describe("Message id."),
createdAt: z.coerce.date(),
})
export type ResendMessageRequest = z.infer
diff --git a/apps/worker/__tests__/contact-scan-engine.test.ts b/apps/worker/__tests__/contact-scan-engine.test.ts
index 6875f74b38..33635265dc 100644
--- a/apps/worker/__tests__/contact-scan-engine.test.ts
+++ b/apps/worker/__tests__/contact-scan-engine.test.ts
@@ -147,6 +147,7 @@ const { runContactScan } = await import(
"../src/integration/handlers/contact-scan/engine"
)
+const RESTARTED_WALK_JOB_ID = /^contact-scan-run-1-\d+-page-\d+-gen-\d+$/
const SAME_PAGE_RETRY_JOB_ID = /^contact-scan-run-1-3-page-4-gen-\d+$/
const RUN_ID = "run-1"
const WORKSPACE_ID = "ws-1"
@@ -407,6 +408,31 @@ describe("runContactScan", () => {
)
})
+ it("after a restart from page 1 the next chunk gets a unique job id, so it cannot collide with one used earlier", async () => {
+ mockClaim.mockResolvedValue(
+ baseRun({ resumeCursor: "stale-cursor", currentPageNumber: 5 }),
+ )
+ mockClassifyError.mockReturnValue("unknown")
+ const startedAt = Date.now()
+ mockListPage
+ .mockRejectedValueOnce(new Error("invalid paging cursor"))
+ .mockImplementationOnce(() => {
+ vi.spyOn(Date, "now").mockReturnValue(startedAt + 5 * 60 * 1000)
+ return Promise.resolve({ entries: [], after: "cursor-2" })
+ })
+
+ await runContactScan({ runId: RUN_ID, workspaceId: WORKSPACE_ID })
+
+ expect(mockQueueAdd).toHaveBeenCalledWith(
+ "contactScan",
+ expect.anything(),
+ expect.objectContaining({
+ jobId: expect.stringMatching(RESTARTED_WALK_JOB_ID),
+ }),
+ )
+ vi.restoreAllMocks()
+ })
+
it("a RETRYABLE first-page failure does not clear the cursor — it goes straight to error classification", async () => {
mockClaim.mockResolvedValue(baseRun({ resumeCursor: "stale-cursor" }))
mockClassifyError.mockReturnValue("retryable")
diff --git a/apps/worker/__tests__/send-message-handler.test.ts b/apps/worker/__tests__/send-message-handler.test.ts
index 3b5a9f9b0b..7f10c1cdf7 100644
--- a/apps/worker/__tests__/send-message-handler.test.ts
+++ b/apps/worker/__tests__/send-message-handler.test.ts
@@ -60,6 +60,11 @@ vi.mock("@chatbotx.io/analytics", () => ({
commentAutomationAnalyticsService: { settleEvent: mockSettleEvent },
}))
+const mockReconcileAccountSendBlocked = vi.hoisted(() => vi.fn())
+vi.mock("../src/chat/handlers/account-send-blocked", () => ({
+ reconcileAccountSendBlocked: mockReconcileAccountSendBlocked,
+}))
+
vi.mock("@chatbotx.io/business", () => ({
contactActivityService: { recordDelivered: mockRecordDelivered },
contactInboxService: {
@@ -924,6 +929,62 @@ describe("chat send-message handlers", () => {
expect(mockEmit.mock.calls.filter(isBotSentDashboardCall)).toHaveLength(0)
})
+ describe("hands the broadcast metadata to the account-block reconciler", () => {
+ const metadata = { type: "broadcast", broadcastId: "b-1" }
+
+ test("when sendMessageToChannel's send is refused", async () => {
+ mockReconcileAccountSendBlocked.mockResolvedValue(false)
+ mockRunChannelHandler.mockRejectedValueOnce(new Error("blocked"))
+
+ await sendMessageToChannel({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ message: {
+ id: "msg-1",
+ workspaceId: "ws-1",
+ conversationId: "conv-1",
+ contactInboxId: "ci-1",
+ contentType: "text",
+ messageType: "outgoing",
+ senderType: "bot",
+ text: "hello",
+ createdAt: new Date("2026-09-15T06:11:52.105Z"),
+ } as never,
+ metadata: metadata as never,
+ }).catch(() => undefined)
+
+ expect(mockReconcileAccountSendBlocked).toHaveBeenCalledWith(
+ expect.objectContaining({ metadata }),
+ )
+ })
+
+ test("when sendFlowStepToChannel's send is refused", async () => {
+ mockReconcileAccountSendBlocked.mockResolvedValue(false)
+ mockRunChannelHandler.mockRejectedValueOnce(new Error("blocked"))
+
+ await sendFlowStepToChannel({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ flowId: "flow-1",
+ step: {
+ id: "step-1",
+ nodeId: "node-1",
+ stepType: "sendText",
+ text: "hello",
+ } as never,
+ metadata: metadata as never,
+ botSentAnalytics: {
+ triggerHandler: "sendFlowStepToChannel",
+ triggerType: "message_bot_sent_flow_step_channel",
+ },
+ }).catch(() => undefined)
+
+ expect(mockReconcileAccountSendBlocked).toHaveBeenCalledWith(
+ expect.objectContaining({ metadata }),
+ )
+ })
+ })
+
test("passes sendFrom to sendFlowStep channel handler", async () => {
await sendFlowStepToChannel({
conversation: conversation as never,
diff --git a/apps/worker/src/chat/handlers/send-message.ts b/apps/worker/src/chat/handlers/send-message.ts
index 4f86d7ff2b..1a1af0425f 100644
--- a/apps/worker/src/chat/handlers/send-message.ts
+++ b/apps/worker/src/chat/handlers/send-message.ts
@@ -544,11 +544,14 @@ export async function sendMessageToChannel(
})
logger.error(error, "An error occurred while sending the message")
const errorData = await parseSdkError(error)
- const willRetry = willSendRetry({
- error,
- channel: contactInbox.channel,
- willRetryOnThrow,
- })
+ // A reconciled error returns instead of throwing, so it is never retried.
+ const willRetry =
+ !isReconciledSendError &&
+ willSendRetry({
+ error,
+ channel: contactInbox.channel,
+ willRetryOnThrow,
+ })
await emit(messageEventTypeSchema.enum["message:failed"], {
context: {
workspaceId: conversation.workspaceId,
@@ -921,7 +924,7 @@ const queueConversationScopedMessageEvent = async (input: {
* published for inbox sends only (broadcasts, flows and sequences stay silent).
*/
const publishInboxSendConfirmation = async (input: {
- sendFrom: "inbox" | undefined
+ sendFrom: ChatJobSendChannelMessage["data"]["sendFrom"]
silent: boolean
conversation: Pick
message: Pick & { clientId?: string | undefined }
diff --git a/apps/worker/src/integration/handlers/contact-scan/engine.ts b/apps/worker/src/integration/handlers/contact-scan/engine.ts
index d7856e8836..deeafa2dc5 100644
--- a/apps/worker/src/integration/handlers/contact-scan/engine.ts
+++ b/apps/worker/src/integration/handlers/contact-scan/engine.ts
@@ -38,7 +38,7 @@ type ContinuationInput = {
pageNumber: number
expect: CoexistRunWriteGuard
delayMs: number
- /** Set when the next chunk re-runs the SAME page: its job id must be unique. */
+ /** Set when the next chunk's page number may already have been used (a same-page retry, a restarted walk): its job id must be unique. */
retriesSamePage: boolean
/** Writes `attempts = 1` with the release (a wait that is not a failure). */
resetAttempts?: boolean
@@ -249,6 +249,9 @@ export const runContactScan = async (
// rejected-resume-cursor recovery (clear + restart from page 1); every
// later page failure goes straight to the outer error classification.
let firstPageCursorRecoveryAvailable = Boolean(cursor)
+ // After a cursor restart the page numbers count again from 1, so a later
+ // continuation id could equal one used earlier in this run.
+ let walkRestarted = false
// Pages walked in THIS chunk, and a wait the pacing asked for after a page.
let pagesInChunk = 0
@@ -319,6 +322,7 @@ export const runContactScan = async (
)
cursor = undefined
pageNumber = 0
+ walkRestarted = true
continue
}
throw error
@@ -469,7 +473,7 @@ export const runContactScan = async (
pageNumber,
expect,
delayMs: nextChunkDelayMs,
- retriesSamePage: false,
+ retriesSamePage: walkRestarted,
})
return
}
diff --git a/apps/worker/src/schedule/handlers/scan-contact-scans.ts b/apps/worker/src/schedule/handlers/scan-contact-scans.ts
index 24bc443a4f..80fbc83525 100644
--- a/apps/worker/src/schedule/handlers/scan-contact-scans.ts
+++ b/apps/worker/src/schedule/handlers/scan-contact-scans.ts
@@ -61,6 +61,7 @@ export async function scanContactScans(): Promise {
jobId: buildContactScanJobId({
runId: run.id,
attempts: run.attempts,
+ generation: Date.now(),
}),
attempts: 1,
removeOnComplete: true,
diff --git a/docs/contact-scan.md b/docs/contact-scan.md
index 15615bccb3..a4ae5b55ae 100644
--- a/docs/contact-scan.md
+++ b/docs/contact-scan.md
@@ -55,10 +55,10 @@ scanContactScans cron (1 min, distributedLock) ── pickDueRuns({ type:'conta
│
runContactScan engine ── claimContactScanRun (mints claimToken) ── walk /conversations DESC
│ stop at scanFromAt (ceiling); skip above lastSyncedAt (frontier); bulkImportChannelContacts per page
- │ 4-min chunk budget → yieldForContinuation (release token, stay 'running') → enqueue next chunk → reclaim
+ │ chunk (5 pages or 4 min) → yieldForContinuation (release token, stay 'running') → enqueue next chunk → reclaim
├── done → succeeded | partial (page cap) | failed
├── cancelled → partial + `cancelled` sentinel (operator Cancel, or channel disconnected)
- ├── rate limit / high usage → park (running, no claim) + delayed job; attempts untouched
+ ├── rate limit / high usage → park (running, no claim) + delayed job; attempts reset to 1
├── transient err → retryOrFail: back to 'init' for the sweeper, or failed on the 5th in a row
└── auth/permission err → failed (currentError sentinel)
```
@@ -69,8 +69,9 @@ runContactScan engine ── claimContactScanRun (mints claimToken) ── walk
The worker's next write is fenced out, so at most the page in flight finishes.
It is shown as `cancelled` (one mapping, `resolveContactScanRunStatus`, used by
the status view and the history list; no new enum value). Nothing running is
- `cancelled: false`, not an error. Disconnecting Messenger or Instagram cancels
- the integration's scan in the same transaction. A cancelled scan still counts
+ `cancelled: false`, not an error. Disconnecting Messenger or Instagram from the
+ inbox cancels the integration's scan in the same transaction (workspace
+ teardown instead ends it as failed, since the workspace is going away). A cancelled scan still counts
toward the 24 h cooldown (measured from `createdAt`).
- **Cooldown**: 24 h from `createdAt` before the same inbox can scan again
(`resolveContactScanAvailability`). ETA shown to the user is `createdAt + 4 h`
@@ -131,7 +132,8 @@ worker slot. The scan path no longer uses `withInlineRetry` or
scan back off without changing how messages are sent.
- **Error accounting**: `attempts` is the sweeper's pick count, so a running
claim is 1 and the Nth consecutive failure sees N. A finished page resets it
- to 1 (same write as the heartbeat); a rate limit leaves it alone; a
+ to 1 (same write as the heartbeat); so does the release for a rate-limit
+ wait (an idle released run must not be failed by the sweeper); a
transient failure goes through `retryOrFailContactScanRun`, one atomic UPDATE
that returns the run to `init` or, on the 5th failure in a row, fails it at
once (it cannot wait for `markMaxAttemptsFailed`).
diff --git a/integrations/messenger/src/handlers/conversation.ts b/integrations/messenger/src/handlers/conversation.ts
index bb58824497..1807b630f1 100644
--- a/integrations/messenger/src/handlers/conversation.ts
+++ b/integrations/messenger/src/handlers/conversation.ts
@@ -104,6 +104,7 @@ const toThreadControlChannelError = (
httpStatusCode: error.httpStatusCode,
subCode: error.subCode ?? null,
type: error.type,
+ reason: error.reason,
})
: error
diff --git a/packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts b/packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts
index bbfb8e3dcc..c245d39e3f 100644
--- a/packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts
+++ b/packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts
@@ -58,6 +58,8 @@ const workspaceId = createId()
const blockedInboxId = createId()
const otherInboxId = createId()
const messengerIntegrationId = createId()
+const otherMessengerIntegrationId = createId()
+const otherWorkspaceId = createId()
const baseRow = {
workspaceId,
@@ -205,6 +207,51 @@ describe.skipIf(!databaseUrl)("stopSendingForBlockedAccount", () => {
.where(eq(integrationMessengerModel.id, messengerIntegrationId))
})
+ test("legacy by integration: a broadcast pinned to ANOTHER page's integration keeps sending", async () => {
+ await db.insert(integrationMessengerModel).values({
+ id: otherMessengerIntegrationId,
+ name: "Other integration",
+ pageId: `page-${otherMessengerIntegrationId}`,
+ auth: {},
+ conversationStarters: [],
+ persistentMenus: [],
+ personas: [],
+ coexistEnabled: false,
+ coexistAiReadsSyncedHistory: false,
+ hasCapiScope: false,
+ workspaceId,
+ inboxId: otherInboxId,
+ })
+ const pinnedElsewhere = await insertBroadcast({
+ integrationMessengerId: otherMessengerIntegrationId,
+ })
+
+ const { stoppedIds } = await stop()
+
+ expect(stoppedIds).not.toContain(pinnedElsewhere)
+ expect((await readRow(pinnedElsewhere)).status).toBe("sending")
+ await db
+ .delete(integrationMessengerModel)
+ .where(eq(integrationMessengerModel.id, otherMessengerIntegrationId))
+ })
+
+ test("another workspace's whole-channel broadcast is never stopped", async () => {
+ await db
+ .insert(workspaceModel)
+ .values({ id: otherWorkspaceId, name: "stop-blocked-other", ownerId })
+ const foreign = await insertBroadcast({ workspaceId: otherWorkspaceId })
+
+ await stop()
+
+ expect((await readRow(foreign)).status).toBe("sending")
+ await db
+ .delete(broadcastModel)
+ .where(eq(broadcastModel.workspaceId, otherWorkspaceId))
+ await db
+ .delete(workspaceModel)
+ .where(eq(workspaceModel.id, otherWorkspaceId))
+ })
+
test("rows that are not sending are untouched, and a second call is a no-op", async () => {
const draft = await insertBroadcast({ status: "draft" })
const sent = await insertBroadcast({ status: "sent" })
diff --git a/packages/database/__tests__/message-resendable-partial.test.ts b/packages/database/__tests__/message-resendable-partial.test.ts
index 10a2609cb5..c6c55d6df7 100644
--- a/packages/database/__tests__/message-resendable-partial.test.ts
+++ b/packages/database/__tests__/message-resendable-partial.test.ts
@@ -30,6 +30,11 @@ describe("isResendableMessage", () => {
["sent by a bot", { senderType: "bot" }],
["incoming", { messageType: "incoming" }],
["a public comment reply", { type: "comment" }],
+ ["deleted", { deletedAt: new Date("2026-11-01T00:00:00Z") }],
+ [
+ "a call-permission request",
+ { contentAttributes: { type: "whatsapp_call_permission_request" } },
+ ],
])("%s is not resendable", (_name, override) => {
expect(isResendableMessage({ ...failed, ...override })).toBe(false)
})
diff --git a/packages/database/src/partials/message.ts b/packages/database/src/partials/message.ts
index 582416fbb4..70a4a8684e 100644
--- a/packages/database/src/partials/message.ts
+++ b/packages/database/src/partials/message.ts
@@ -82,11 +82,21 @@ export type ResendableMessageFields = {
/** Empty on a row only the browser knows (a rejected submit): nothing to resend. */
contactInboxId: string | null
parentId?: string | null | undefined
+ deletedAt?: Date | null | undefined
}
/** `contentAttributes` key that keeps a private reply's comment createdAt (ISO string). */
export const REPLY_TARGET_CREATED_AT_KEY = "replyToMessageCreatedAt"
+/** Same marker as the SDK's `getWhatsappCallPermissionRequest` (kept local: partials stay free of the SDK). */
+const isCallPermissionRequestAttributes = (
+ contentAttributes: unknown,
+): boolean =>
+ typeof contentAttributes === "object" &&
+ contentAttributes !== null &&
+ "type" in contentAttributes &&
+ contentAttributes.type === "whatsapp_call_permission_request"
+
const hasReplyTargetCreatedAt = (contentAttributes: unknown): boolean =>
typeof contentAttributes === "object" &&
contentAttributes !== null &&
@@ -121,6 +131,10 @@ export const isResendableMessage = (
message.sendError !== null &&
message.sourceId === null &&
Boolean(message.contactInboxId) &&
+ !message.deletedAt &&
+ // A call-permission request is created behind its own gates (call access,
+ // Meta's request limits) that a plain resend would skip.
+ !isCallPermissionRequestAttributes(message.contentAttributes) &&
// A reply to a comment can only be rebuilt when its createdAt was kept.
(!message.parentId || hasReplyTargetCreatedAt(message.contentAttributes))
)
diff --git a/packages/database/src/sharding/message/repository/sharded-message-repository.ts b/packages/database/src/sharding/message/repository/sharded-message-repository.ts
index 772b664bb2..351943d778 100644
--- a/packages/database/src/sharding/message/repository/sharded-message-repository.ts
+++ b/packages/database/src/sharding/message/repository/sharded-message-repository.ts
@@ -820,7 +820,7 @@ export class ShardedMessageRepository implements IMessageRepository {
{ sendError: null },
"claimForResend",
params.createdAt,
- sql`${messageModel.sendError} IS NOT NULL AND ${messageModel.sourceId} IS NULL`,
+ sql`${messageModel.sendError} IS NOT NULL AND ${messageModel.sourceId} IS NULL AND ${messageModel.deletedAt} IS NULL`,
)
}
diff --git a/packages/worker-config/__tests__/contact-scan-job-ids.test.ts b/packages/worker-config/__tests__/contact-scan-job-ids.test.ts
index 9f34e44c57..99544968b9 100644
--- a/packages/worker-config/__tests__/contact-scan-job-ids.test.ts
+++ b/packages/worker-config/__tests__/contact-scan-job-ids.test.ts
@@ -11,6 +11,17 @@ describe("contact scan job ids", () => {
)
})
+ it("a scheduler pick with a generation never repeats an id used before", () => {
+ expect(
+ buildContactScanJobId({ runId: "r1", attempts: 2, generation: 100 }),
+ ).toBe("contact-scan-r1-2-gen-100")
+ expect(
+ buildContactScanJobId({ runId: "r1", attempts: 2, generation: 100 }),
+ ).not.toBe(
+ buildContactScanJobId({ runId: "r1", attempts: 2, generation: 200 }),
+ )
+ })
+
it("a forward continuation id is deterministic", () => {
const input = { runId: "r1", attempts: 2, pageNumber: 6 }
expect(buildContactScanPageJobId(input)).toBe("contact-scan-r1-2-page-6")
diff --git a/packages/worker-config/src/queues/integration/contact-scan-job-ids.ts b/packages/worker-config/src/queues/integration/contact-scan-job-ids.ts
index 60479e30f9..cdfd20e03d 100644
--- a/packages/worker-config/src/queues/integration/contact-scan-job-ids.ts
+++ b/packages/worker-config/src/queues/integration/contact-scan-job-ids.ts
@@ -11,12 +11,21 @@
/**
* Id for a run the scheduler enqueues. `attempts` is part of the id so a
- * retry of the same run is a distinct job.
+ * retry of the same run is a distinct job. The count goes back to 1 after a
+ * finished page or a rate limit, so the same value can come round again:
+ * `generation` (the pick time) keeps such a pick from being swallowed by a
+ * failed job BullMQ still retains under the old id.
*/
export const buildContactScanJobId = (input: {
runId: string
attempts: number
-}): string => `contact-scan-${input.runId}-${input.attempts}`
+ generation?: number
+}): string => {
+ const base = `contact-scan-${input.runId}-${input.attempts}`
+ return input.generation === undefined
+ ? base
+ : `${base}-gen-${input.generation}`
+}
/**
* Id for a run's continuation chunk: same run and attempts, next page.
From 1bc89ce08845bc51d37ccbc8c675cb116b3b3725 Mon Sep 17 00:00:00 2001
From: Hung Phan Viet
Date: Sat, 14 Nov 2026 13:48:15 +0700
Subject: [PATCH 4/6] fix(messaging): keep bot send errors, flush queued sends
on exit and end scans on teardown
---
.../message-input-client-id.test.tsx | 26 ++++++++++
.../messages/lib/use-send-queue-runner.ts | 50 ++++++++++++++++++-
.../__tests__/scan-contact-scans.test.ts | 9 +++-
apps/worker/__tests__/send-flow-step.test.ts | 14 ++++++
.../src/chat/handlers/send-flow-step.ts | 7 ++-
apps/worker/src/chat/worker.ts | 2 +-
.../handlers/contact-scan/engine.ts | 2 +
docs/contact-scan.md | 2 +-
.../__tests__/contact-scan.service.test.ts | 1 +
...ifecycle.channel-switch-exhaustive.test.ts | 4 ++
.../workspace-lifecycle.service.test.ts | 10 ++++
packages/business/src/broadcast/service.ts | 1 +
packages/business/src/contact-scan/service.ts | 1 +
.../src/workspace-lifecycle/service.ts | 8 +++
.../coexist-sync-run/repository.ts | 4 +-
15 files changed, 131 insertions(+), 10 deletions(-)
diff --git a/apps/builder/__tests__/message-input-client-id.test.tsx b/apps/builder/__tests__/message-input-client-id.test.tsx
index e7c54cd26d..bb4e017cbf 100644
--- a/apps/builder/__tests__/message-input-client-id.test.tsx
+++ b/apps/builder/__tests__/message-input-client-id.test.tsx
@@ -484,6 +484,32 @@ describe("message composers", () => {
expect(textarea.value).toBe("4")
})
+ test("leaving while messages still wait sends them in order instead of dropping them", async () => {
+ act(() => root.render( ))
+ await submitMessages(["1", "2", "3"])
+ // Only the first has gone out: the others wait for its answer.
+ expect(action.executeAsync).toHaveBeenCalledTimes(1)
+
+ await act(async () => {
+ root.unmount()
+ await Promise.resolve()
+ })
+ root = createRoot(container)
+
+ // Each one is sent only after the previous request has returned.
+ for (let index = 1; index < 3; index += 1) {
+ await act(async () => {
+ action.resolveRequests[index]?.({ data: {} })
+ await Promise.resolve()
+ })
+ }
+
+ const sent = action.executeAsync.mock.calls.map(
+ ([input]) => (input as { text: string }).text,
+ )
+ expect(sent).toEqual(["1", "2", "3"])
+ })
+
test("discarding the held messages unlocks the composer", async () => {
act(() => root.render( ))
await submitMessages(["1", "2"])
diff --git a/apps/builder/src/features/messages/lib/use-send-queue-runner.ts b/apps/builder/src/features/messages/lib/use-send-queue-runner.ts
index f698222592..f84719c89b 100644
--- a/apps/builder/src/features/messages/lib/use-send-queue-runner.ts
+++ b/apps/builder/src/features/messages/lib/use-send-queue-runner.ts
@@ -1,7 +1,7 @@
"use client"
import { useTranslations } from "next-intl"
-import { useCallback, useEffect, useState } from "react"
+import { useCallback, useEffect, useRef, useState } from "react"
import { toast } from "sonner"
import { useWorkspaceId } from "@/hooks/routing"
import { useChatStore } from "../../chat/store/chat-store-provider"
@@ -14,6 +14,7 @@ import {
nextSendToSubmit,
nextSendWakeAt,
type QueuedSend,
+ type SendQueue,
} from "./send-queue"
import { flattenValidationErrors } from "./validation-errors"
@@ -39,6 +40,19 @@ export const useSendQueueRunner = (props: {
// Bumped by a timer to re-evaluate the queues when a gap or deadline passes.
const [tick, setTick] = useState(0)
+ // When the runner goes away (the person leaves the inbox, or closes the
+ // pipeline item chat) the queues go with it. Messages already cleared from
+ // the composer must not be lost, so the ones still waiting are sent now, in
+ // order. A held queue is left alone: its owner never chose to go on.
+ const latest = useRef({ sendQueues, workspaceId })
+ latest.current = { sendQueues, workspaceId }
+ useEffect(
+ () => () => {
+ flushWaitingSends(latest.current)
+ },
+ [],
+ )
+
const submit = useCallback(
async (
conversationId: string,
@@ -116,3 +130,37 @@ export const useSendQueueRunner = (props: {
}
}, [sendQueues, submit, tick, updateSendQueue])
}
+
+/** Sends one conversation's waiting messages in order; failures only toast. */
+const sendInOrder = async (
+ workspaceId: string,
+ conversationId: string,
+ waiting: QueuedSend[],
+): Promise => {
+ for (const item of waiting) {
+ try {
+ const result = await createMessageAction(
+ workspaceId,
+ conversationId,
+ item.input,
+ )
+ if (result?.serverError) {
+ toast.error(result.serverError)
+ }
+ } catch (error) {
+ toast.error(error instanceof Error ? error.message : String(error))
+ }
+ }
+}
+
+/** Sends what is still waiting in unheld queues (one chain per conversation). */
+const flushWaitingSends = (state: {
+ sendQueues: Record>
+ workspaceId: string
+}): void => {
+ for (const [conversationId, queue] of Object.entries(state.sendQueues)) {
+ if (queue.holdReason === null && queue.waiting.length > 0) {
+ sendInOrder(state.workspaceId, conversationId, queue.waiting)
+ }
+ }
+}
diff --git a/apps/worker/__tests__/scan-contact-scans.test.ts b/apps/worker/__tests__/scan-contact-scans.test.ts
index dc62405bfe..452d591c53 100644
--- a/apps/worker/__tests__/scan-contact-scans.test.ts
+++ b/apps/worker/__tests__/scan-contact-scans.test.ts
@@ -48,14 +48,19 @@ vi.mock("@chatbotx.io/worker-config", () => ({
buildContactScanJobId: ({
runId,
attempts,
+ generation,
}: {
runId: string
attempts: number
- }) => `contact-scan-${runId}-${attempts}`,
+ generation?: number
+ }) =>
+ `contact-scan-${runId}-${attempts}${generation === undefined ? "" : `-gen-${generation}`}`,
IntegrationJobAction: { contactScan: "contactScan" },
integrationQueue: { add: mockQueueAdd },
}))
+const SCHEDULER_JOB_ID = /^contact-scan-run-a-2-gen-\d+$/
+
const { scanContactScans } = await import(
"../src/schedule/handlers/scan-contact-scans"
)
@@ -127,7 +132,7 @@ describe("scanContactScans", () => {
data: { runId: "run-a", workspaceId: "ws-1" },
},
expect.objectContaining({
- jobId: "contact-scan-run-a-2",
+ jobId: expect.stringMatching(SCHEDULER_JOB_ID),
attempts: 1,
removeOnComplete: true,
}),
diff --git a/apps/worker/__tests__/send-flow-step.test.ts b/apps/worker/__tests__/send-flow-step.test.ts
index 30ef80350f..21655bc4d9 100644
--- a/apps/worker/__tests__/send-flow-step.test.ts
+++ b/apps/worker/__tests__/send-flow-step.test.ts
@@ -2230,6 +2230,20 @@ describe("sendChatMessage", () => {
})
})
+ test("never tells the send it will be retried: sendChatMessage swallows failures, so the send error must be recorded at once", async () => {
+ await sendChatMessage({
+ conversation: fakeConversation as never,
+ contactInbox: fakeContactInbox as never,
+ text: "hello from chat",
+ })
+
+ expect(mockSendMessageToChannel).toHaveBeenCalledWith(
+ expect.anything(),
+ 0,
+ false,
+ )
+ })
+
test("uses the resolved fallback inbox when routing the realtime message", async () => {
mockFindContactInbox.mockResolvedValue(fakeContactInbox)
diff --git a/apps/worker/src/chat/handlers/send-flow-step.ts b/apps/worker/src/chat/handlers/send-flow-step.ts
index b1de525e32..feec64a24b 100644
--- a/apps/worker/src/chat/handlers/send-flow-step.ts
+++ b/apps/worker/src/chat/handlers/send-flow-step.ts
@@ -1230,9 +1230,6 @@ export async function sendFlowStep({
export const sendChatMessage = async (
props: ChatJobSendChatMessage["data"],
- // Forwarded from the chat worker: this function rethrows, so a BullMQ attempt
- // still in hand means another `message:failed` is coming for the same send.
- willRetryOnThrow = false,
) => {
const {
conversation,
@@ -1361,7 +1358,9 @@ export const sendChatMessage = async (
isBulkBroadcast,
},
0,
- willRetryOnThrow,
+ // This function catches every failure below and never rethrows, so no
+ // retry follows: the send error must be recorded now.
+ false,
),
]
if (!isBulkOutbound) {
diff --git a/apps/worker/src/chat/worker.ts b/apps/worker/src/chat/worker.ts
index a30908472e..551270154b 100644
--- a/apps/worker/src/chat/worker.ts
+++ b/apps/worker/src/chat/worker.ts
@@ -97,7 +97,7 @@ function startChatWorker() {
await sendFlowStep(job.data.data)
return
case ChatJobAction.sendChatMessage:
- await sendChatMessage(job.data.data, !isFinalAttempt(job))
+ await sendChatMessage(job.data.data)
return
case ChatJobAction.sendWhatsappTemplateMessage:
await sendWhatsappTemplateMessage(
diff --git a/apps/worker/src/integration/handlers/contact-scan/engine.ts b/apps/worker/src/integration/handlers/contact-scan/engine.ts
index deeafa2dc5..d29b5971af 100644
--- a/apps/worker/src/integration/handlers/contact-scan/engine.ts
+++ b/apps/worker/src/integration/handlers/contact-scan/engine.ts
@@ -80,6 +80,8 @@ const scheduleContinuation = async (
delay: input.delayMs,
attempts: 1,
removeOnComplete: true,
+ // A failed job keeps its id reserved; do not keep it forever.
+ removeOnFail: { count: 100 },
},
)
logger.info(
diff --git a/docs/contact-scan.md b/docs/contact-scan.md
index a4ae5b55ae..a433ad7bc8 100644
--- a/docs/contact-scan.md
+++ b/docs/contact-scan.md
@@ -71,7 +71,7 @@ runContactScan engine ── claimContactScanRun (mints claimToken) ── walk
the status view and the history list; no new enum value). Nothing running is
`cancelled: false`, not an error. Disconnecting Messenger or Instagram from the
inbox cancels the integration's scan in the same transaction (workspace
- teardown instead ends it as failed, since the workspace is going away). A cancelled scan still counts
+ teardown ends it too: cancelled for Instagram, failed for Messenger). A cancelled scan still counts
toward the 24 h cooldown (measured from `createdAt`).
- **Cooldown**: 24 h from `createdAt` before the same inbox can scan again
(`resolveContactScanAvailability`). ETA shown to the user is `createdAt + 4 h`
diff --git a/packages/business/__tests__/contact-scan.service.test.ts b/packages/business/__tests__/contact-scan.service.test.ts
index 44f33c73c2..fc40500111 100644
--- a/packages/business/__tests__/contact-scan.service.test.ts
+++ b/packages/business/__tests__/contact-scan.service.test.ts
@@ -376,6 +376,7 @@ describe("contactScanService thin delegations", () => {
expect(mocks.markMaxAttemptsFailed).toHaveBeenCalledWith({
maxAttempts: 5,
type: "contact_scan",
+ currentError: "maxAttempts",
})
})
diff --git a/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts b/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts
index ba8c625439..b5f479ebbb 100644
--- a/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts
+++ b/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts
@@ -83,6 +83,10 @@ vi.mock("../src/coexist/service", () => ({
},
}))
+vi.mock("../src/contact-scan/service", () => ({
+ contactScanService: { cancelForIntegration: vi.fn() },
+}))
+
vi.mock("../src/logger", () => ({
logger: { error: vi.fn(), info: vi.fn(), warn: vi.fn() },
}))
diff --git a/packages/business/__tests__/workspace-lifecycle.service.test.ts b/packages/business/__tests__/workspace-lifecycle.service.test.ts
index d9fda1c37f..5376cb71aa 100644
--- a/packages/business/__tests__/workspace-lifecycle.service.test.ts
+++ b/packages/business/__tests__/workspace-lifecycle.service.test.ts
@@ -73,6 +73,11 @@ vi.mock("../src/coexist/service", () => ({
},
}))
+const cancelContactScanMock = vi.hoisted(() => vi.fn())
+vi.mock("../src/contact-scan/service", () => ({
+ contactScanService: { cancelForIntegration: cancelContactScanMock },
+}))
+
vi.mock("../src/logger", () => ({
logger: {
error: vi.fn(),
@@ -242,6 +247,11 @@ test("disconnectWorkspaceChannels tears down active native Instagram coexist run
currentError: "Integration disconnected",
tx,
})
+ expect(cancelContactScanMock).toHaveBeenCalledWith({
+ channel: "instagram",
+ integrationId: "integration-ig-1",
+ tx,
+ })
})
test("disconnectWorkspaceChannels does not apply native coexist teardown to instagram-facebook", async () => {
diff --git a/packages/business/src/broadcast/service.ts b/packages/business/src/broadcast/service.ts
index a256c0fe8b..d97d9d185a 100644
--- a/packages/business/src/broadcast/service.ts
+++ b/packages/business/src/broadcast/service.ts
@@ -2968,6 +2968,7 @@ class BroadcastService extends BaseService {
flow: { columns: { id: true, name: true } },
integrationWhatsapp: { columns: { id: true, name: true } },
integrationMessenger: { columns: { id: true, name: true } },
+ statusInbox: { columns: { id: true, name: true } },
...withBroadcastTargets,
},
orderBy: { schedulesAt: "asc" },
diff --git a/packages/business/src/contact-scan/service.ts b/packages/business/src/contact-scan/service.ts
index 1a7cd6a547..41c9af6176 100644
--- a/packages/business/src/contact-scan/service.ts
+++ b/packages/business/src/contact-scan/service.ts
@@ -357,6 +357,7 @@ class ContactScanService extends BaseService {
return coexistSyncRunRepository.markMaxAttemptsFailed({
...input,
type: "contact_scan",
+ currentError: CONTACT_SCAN_ERRORS.maxAttempts,
})
}
diff --git a/packages/business/src/workspace-lifecycle/service.ts b/packages/business/src/workspace-lifecycle/service.ts
index 28b7ede608..08ef83ecca 100644
--- a/packages/business/src/workspace-lifecycle/service.ts
+++ b/packages/business/src/workspace-lifecycle/service.ts
@@ -50,6 +50,7 @@ import {
connectionStateService,
type PendingQuotaRelease,
} from "../connection/state-service"
+import { contactScanService } from "../contact-scan/service"
import { WorkspacePurgeIncompleteError } from "../errors"
import { inboxService } from "../inbox/service"
import { integrationActiveCampaignService } from "../integration-active-campaign/service"
@@ -789,6 +790,13 @@ class WorkspaceLifecycleService extends BaseService {
tx,
})
}
+ // Both Instagram variants support the contact scan, so this is not
+ // gated on the integration type.
+ await contactScanService.cancelForIntegration({
+ channel: "instagram",
+ integrationId: inbox.integrationInstagram.id,
+ tx,
+ })
await tx
.delete(integrationInstagramModel)
.where(
diff --git a/packages/database/src/repositories/coexist-sync-run/repository.ts b/packages/database/src/repositories/coexist-sync-run/repository.ts
index 052d0cda6f..4cc668734f 100644
--- a/packages/database/src/repositories/coexist-sync-run/repository.ts
+++ b/packages/database/src/repositories/coexist-sync-run/repository.ts
@@ -444,6 +444,8 @@ export class CoexistSyncRunRepository {
*/
type: CoexistRunType
maxAttempts: number
+ /** What `currentError` says; defaults to the coexist wording. */
+ currentError?: string
tx?: DatabaseClient
}): Promise {
const { tx = db } = input
@@ -451,7 +453,7 @@ export class CoexistSyncRunRepository {
.update(coexistSyncRunModel)
.set({
status: "failed",
- currentError: "Max scheduler retries exceeded",
+ currentError: input.currentError ?? "Max scheduler retries exceeded",
finishedAt: new Date(),
// Terminal write clears the scan continuation cursor (no-op for
// coexist rows, which never set it).
From 831e9ea17e73698a2c6ea3295449a084b173b4ab Mon Sep 17 00:00:00 2001
From: Hung Phan Viet
Date: Sat, 14 Nov 2026 18:16:37 +0700
Subject: [PATCH 5/6] fix(contact-scan): break the import cycle from workspace
teardown
---
...rkspace-lifecycle.channel-switch-exhaustive.test.ts | 5 +----
.../__tests__/workspace-lifecycle.service.test.ts | 10 +++++-----
packages/business/src/workspace-lifecycle/service.ts | 9 +++++++--
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts b/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts
index b5f479ebbb..c50b9b6713 100644
--- a/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts
+++ b/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts
@@ -43,6 +43,7 @@ vi.mock("@chatbotx.io/database/client", () => ({
}))
vi.mock("@chatbotx.io/database/repositories", () => ({
+ coexistSyncRunRepository: { cancelActiveContactScanRuns: vi.fn() },
connectionRepository: { findByInboxId: findByInboxIdMock },
LIVE_RUN_STATUSES: [],
PULL_CLAIMABLE_STATUSES: [],
@@ -83,10 +84,6 @@ vi.mock("../src/coexist/service", () => ({
},
}))
-vi.mock("../src/contact-scan/service", () => ({
- contactScanService: { cancelForIntegration: vi.fn() },
-}))
-
vi.mock("../src/logger", () => ({
logger: { error: vi.fn(), info: vi.fn(), warn: vi.fn() },
}))
diff --git a/packages/business/__tests__/workspace-lifecycle.service.test.ts b/packages/business/__tests__/workspace-lifecycle.service.test.ts
index 5376cb71aa..658617541f 100644
--- a/packages/business/__tests__/workspace-lifecycle.service.test.ts
+++ b/packages/business/__tests__/workspace-lifecycle.service.test.ts
@@ -29,7 +29,11 @@ vi.mock("@chatbotx.io/sequence-scheduler/dispatch-cancel", () => ({
WORKSPACE_DISPATCH_CANCEL_BATCH_SIZE: 500,
}))
+const cancelContactScanMock = vi.hoisted(() => vi.fn())
vi.mock("@chatbotx.io/database/repositories", () => ({
+ coexistSyncRunRepository: {
+ cancelActiveContactScanRuns: cancelContactScanMock,
+ },
connectionRepository: { findByInboxId: findByInboxIdMock },
HEAVY_WORKSPACE_TABLES: [],
LIVE_RUN_STATUSES: [],
@@ -73,11 +77,6 @@ vi.mock("../src/coexist/service", () => ({
},
}))
-const cancelContactScanMock = vi.hoisted(() => vi.fn())
-vi.mock("../src/contact-scan/service", () => ({
- contactScanService: { cancelForIntegration: cancelContactScanMock },
-}))
-
vi.mock("../src/logger", () => ({
logger: {
error: vi.fn(),
@@ -250,6 +249,7 @@ test("disconnectWorkspaceChannels tears down active native Instagram coexist run
expect(cancelContactScanMock).toHaveBeenCalledWith({
channel: "instagram",
integrationId: "integration-ig-1",
+ currentError: "cancelled",
tx,
})
})
diff --git a/packages/business/src/workspace-lifecycle/service.ts b/packages/business/src/workspace-lifecycle/service.ts
index 08ef83ecca..1b509a05ac 100644
--- a/packages/business/src/workspace-lifecycle/service.ts
+++ b/packages/business/src/workspace-lifecycle/service.ts
@@ -10,6 +10,7 @@ import {
type InboxDisconnectReason,
} from "@chatbotx.io/database/partials"
import {
+ coexistSyncRunRepository,
connectionRepository,
HEAVY_WORKSPACE_TABLES,
LIVE_RUN_STATUSES,
@@ -50,7 +51,7 @@ import {
connectionStateService,
type PendingQuotaRelease,
} from "../connection/state-service"
-import { contactScanService } from "../contact-scan/service"
+import { CONTACT_SCAN_ERRORS } from "../contact-scan/constants"
import { WorkspacePurgeIncompleteError } from "../errors"
import { inboxService } from "../inbox/service"
import { integrationActiveCampaignService } from "../integration-active-campaign/service"
@@ -792,9 +793,13 @@ class WorkspaceLifecycleService extends BaseService {
}
// Both Instagram variants support the contact scan, so this is not
// gated on the integration type.
- await contactScanService.cancelForIntegration({
+ // Through the repository, not `contactScanService`: importing the
+ // service here closes an import cycle (contact-scan → inbox →
+ // quota → tenant → workspace-lifecycle).
+ await coexistSyncRunRepository.cancelActiveContactScanRuns({
channel: "instagram",
integrationId: inbox.integrationInstagram.id,
+ currentError: CONTACT_SCAN_ERRORS.cancelled,
tx,
})
await tx
From 70b4985d5b74b8a22628e89d52e4276ec19d698b Mon Sep 17 00:00:00 2001
From: Hung Phan Viet
Date: Sat, 14 Nov 2026 21:15:47 +0700
Subject: [PATCH 6/6] fix(messaging): keep send error recording for non-inbox
sends and stop catch-up sends on failure
---
.../message-input-client-id.test.tsx | 21 ++++++++
apps/builder/messages/ar.json | 2 +-
apps/builder/messages/az.json | 2 +-
apps/builder/messages/da.json | 2 +-
apps/builder/messages/de.json | 2 +-
apps/builder/messages/en.json | 2 +-
apps/builder/messages/es.json | 2 +-
apps/builder/messages/fi.json | 2 +-
apps/builder/messages/fr.json | 2 +-
apps/builder/messages/he.json | 2 +-
apps/builder/messages/id.json | 2 +-
apps/builder/messages/it.json | 2 +-
apps/builder/messages/ja.json | 2 +-
apps/builder/messages/nl.json | 2 +-
apps/builder/messages/pt-BR.json | 2 +-
apps/builder/messages/pt-PT.json | 2 +-
apps/builder/messages/ro.json | 2 +-
apps/builder/messages/sv.json | 2 +-
apps/builder/messages/tr.json | 2 +-
apps/builder/messages/vi.json | 2 +-
apps/builder/messages/zh-CN.json | 2 +-
apps/builder/messages/zh-TW.json | 2 +-
.../messages/lib/use-send-queue-runner.ts | 33 ++++++++++---
.../__tests__/send-message-handler.test.ts | 48 +++++++++++++++++--
apps/worker/src/chat/handlers/send-message.ts | 18 +++++--
25 files changed, 126 insertions(+), 36 deletions(-)
diff --git a/apps/builder/__tests__/message-input-client-id.test.tsx b/apps/builder/__tests__/message-input-client-id.test.tsx
index bb4e017cbf..3728054d6a 100644
--- a/apps/builder/__tests__/message-input-client-id.test.tsx
+++ b/apps/builder/__tests__/message-input-client-id.test.tsx
@@ -510,6 +510,27 @@ describe("message composers", () => {
expect(sent).toEqual(["1", "2", "3"])
})
+ test("leaving: the catch-up sends stop at the first one the server refuses", async () => {
+ act(() => root.render( ))
+ await submitMessages(["1", "2", "3"])
+
+ await act(async () => {
+ root.unmount()
+ await Promise.resolve()
+ })
+ root = createRoot(container)
+
+ await act(async () => {
+ action.resolveRequests[1]?.({ serverError: "Send failed" })
+ await Promise.resolve()
+ })
+
+ const sent = action.executeAsync.mock.calls.map(
+ ([input]) => (input as { text: string }).text,
+ )
+ expect(sent).toEqual(["1", "2"])
+ })
+
test("discarding the held messages unlocks the composer", async () => {
act(() => root.render( ))
await submitMessages(["1", "2"])
diff --git a/apps/builder/messages/ar.json b/apps/builder/messages/ar.json
index 20bad25666..85710246f2 100644
--- a/apps/builder/messages/ar.json
+++ b/apps/builder/messages/ar.json
@@ -4596,7 +4596,7 @@
"reference": "المرجع {referenceId}"
},
"sendQueue": {
- "failed": "فشل إرسال رسالة. أعد إرسالها لمتابعة الإرسال.",
+ "failed": "فشل إرسال رسالة. أعد إرسالها من المحادثة إن أمكن، أو اختر متابعة الإرسال.",
"unconfirmed": "تعذّر تأكيد إرسال آخر رسالة. اختر ما إذا كنت تريد متابعة الإرسال.",
"continue": "متابعة الإرسال",
"discard": "تجاهل الرسائل في قائمة الانتظار",
diff --git a/apps/builder/messages/az.json b/apps/builder/messages/az.json
index bbf7cb31ed..1c2d78d155 100644
--- a/apps/builder/messages/az.json
+++ b/apps/builder/messages/az.json
@@ -5278,7 +5278,7 @@
"reference": "İstinad {referenceId}"
},
"sendQueue": {
- "failed": "Mesaj göndərilmədi. Göndərməyə davam etmək üçün onu yenidən göndərin.",
+ "failed": "Mesaj göndərilmədi. Mümkünsə onu söhbətdən yenidən göndərin və ya göndərməyə davam edin.",
"unconfirmed": "Son mesajın göndərildiyini təsdiqləyə bilmədik. Göndərməyə davam edib-etməyəcəyinizi seçin.",
"continue": "Göndərməyə davam et",
"discard": "Növbədəki mesajları sil",
diff --git a/apps/builder/messages/da.json b/apps/builder/messages/da.json
index 3f0b38df94..8eb87d9d31 100644
--- a/apps/builder/messages/da.json
+++ b/apps/builder/messages/da.json
@@ -4596,7 +4596,7 @@
"reference": "Reference {referenceId}"
},
"sendQueue": {
- "failed": "En besked kunne ikke sendes. Send den igen for at fortsætte.",
+ "failed": "En besked kunne ikke sendes. Send den igen fra samtalen, hvis det er muligt, eller fortsæt med at sende.",
"unconfirmed": "Vi kunne ikke bekræfte, at den sidste besked blev sendt. Vælg, om du vil fortsætte.",
"continue": "Fortsæt med at sende",
"discard": "Kassér beskeder i kø",
diff --git a/apps/builder/messages/de.json b/apps/builder/messages/de.json
index 08f02ac907..2ddcbb76bf 100644
--- a/apps/builder/messages/de.json
+++ b/apps/builder/messages/de.json
@@ -4596,7 +4596,7 @@
"reference": "Referenz {referenceId}"
},
"sendQueue": {
- "failed": "Eine Nachricht konnte nicht gesendet werden. Sende sie erneut, um fortzufahren.",
+ "failed": "Eine Nachricht konnte nicht gesendet werden. Sende sie wenn möglich aus dem Chat erneut oder sende weiter.",
"unconfirmed": "Wir konnten nicht bestätigen, dass die letzte Nachricht gesendet wurde. Wähle, ob du weitersenden möchtest.",
"continue": "Weitersenden",
"discard": "Wartende Nachrichten verwerfen",
diff --git a/apps/builder/messages/en.json b/apps/builder/messages/en.json
index ebaef68bf0..b5ba32698b 100644
--- a/apps/builder/messages/en.json
+++ b/apps/builder/messages/en.json
@@ -5278,7 +5278,7 @@
"reference": "Reference {referenceId}"
},
"sendQueue": {
- "failed": "A message failed to send. Resend it to continue sending.",
+ "failed": "A message failed to send. Resend it from the conversation if possible, or keep sending.",
"unconfirmed": "We couldn't confirm the last message was sent. Choose whether to keep sending.",
"continue": "Keep sending",
"discard": "Discard queued messages",
diff --git a/apps/builder/messages/es.json b/apps/builder/messages/es.json
index fe8b40df16..3778b377bb 100644
--- a/apps/builder/messages/es.json
+++ b/apps/builder/messages/es.json
@@ -4596,7 +4596,7 @@
"reference": "Referencia {referenceId}"
},
"sendQueue": {
- "failed": "No se pudo enviar un mensaje. Reenvíalo para seguir enviando.",
+ "failed": "No se pudo enviar un mensaje. Reenvíalo desde la conversación si es posible o sigue enviando.",
"unconfirmed": "No pudimos confirmar que el último mensaje se envió. Elige si quieres seguir enviando.",
"continue": "Seguir enviando",
"discard": "Descartar mensajes en cola",
diff --git a/apps/builder/messages/fi.json b/apps/builder/messages/fi.json
index 31541eb755..dc13cbae7e 100644
--- a/apps/builder/messages/fi.json
+++ b/apps/builder/messages/fi.json
@@ -4596,7 +4596,7 @@
"reference": "Viite {referenceId}"
},
"sendQueue": {
- "failed": "Viestin lähetys epäonnistui. Lähetä se uudelleen jatkaaksesi.",
+ "failed": "Viestin lähetys epäonnistui. Lähetä se keskustelusta uudelleen, jos mahdollista, tai jatka lähettämistä.",
"unconfirmed": "Emme voineet vahvistaa, että viimeisin viesti lähetettiin. Valitse, jatketaanko lähettämistä.",
"continue": "Jatka lähettämistä",
"discard": "Hylkää jonossa olevat viestit",
diff --git a/apps/builder/messages/fr.json b/apps/builder/messages/fr.json
index cb36383954..6e3f8a91bc 100644
--- a/apps/builder/messages/fr.json
+++ b/apps/builder/messages/fr.json
@@ -4596,7 +4596,7 @@
"reference": "Référence {referenceId}"
},
"sendQueue": {
- "failed": "Un message n'a pas pu être envoyé. Renvoyez-le pour continuer.",
+ "failed": "Un message n'a pas pu être envoyé. Renvoyez-le depuis la conversation si possible, ou continuez l'envoi.",
"unconfirmed": "Nous n'avons pas pu confirmer l'envoi du dernier message. Choisissez de continuer ou non.",
"continue": "Continuer l'envoi",
"discard": "Supprimer les messages en attente",
diff --git a/apps/builder/messages/he.json b/apps/builder/messages/he.json
index a232c1331f..6479f90286 100644
--- a/apps/builder/messages/he.json
+++ b/apps/builder/messages/he.json
@@ -2229,7 +2229,7 @@
"reference": "אסמכתה {referenceId}"
},
"sendQueue": {
- "failed": "שליחת הודעה נכשלה. שלח אותה שוב כדי להמשיך.",
+ "failed": "שליחת הודעה נכשלה. שלח אותה שוב מהשיחה אם אפשר, או המשך לשלוח.",
"unconfirmed": "לא הצלחנו לאשר שההודעה האחרונה נשלחה. בחר אם להמשיך לשלוח.",
"continue": "המשך לשלוח",
"discard": "מחק הודעות בתור",
diff --git a/apps/builder/messages/id.json b/apps/builder/messages/id.json
index 5a30dfc9a6..47422aacf2 100644
--- a/apps/builder/messages/id.json
+++ b/apps/builder/messages/id.json
@@ -4596,7 +4596,7 @@
"reference": "Referensi {referenceId}"
},
"sendQueue": {
- "failed": "Sebuah pesan gagal terkirim. Kirim ulang untuk melanjutkan.",
+ "failed": "Sebuah pesan gagal terkirim. Kirim ulang dari percakapan jika bisa, atau lanjutkan pengiriman.",
"unconfirmed": "Kami tidak dapat memastikan pesan terakhir terkirim. Pilih apakah akan terus mengirim.",
"continue": "Lanjutkan pengiriman",
"discard": "Buang pesan dalam antrean",
diff --git a/apps/builder/messages/it.json b/apps/builder/messages/it.json
index eebbb79fa0..afb842a803 100644
--- a/apps/builder/messages/it.json
+++ b/apps/builder/messages/it.json
@@ -4596,7 +4596,7 @@
"reference": "Riferimento {referenceId}"
},
"sendQueue": {
- "failed": "Un messaggio non è stato inviato. Invialo di nuovo per continuare.",
+ "failed": "Un messaggio non è stato inviato. Invialo di nuovo dalla conversazione se possibile, o continua a inviare.",
"unconfirmed": "Non siamo riusciti a confermare l'invio dell'ultimo messaggio. Scegli se continuare a inviare.",
"continue": "Continua a inviare",
"discard": "Elimina i messaggi in coda",
diff --git a/apps/builder/messages/ja.json b/apps/builder/messages/ja.json
index b6c9413dcd..4bb16de755 100644
--- a/apps/builder/messages/ja.json
+++ b/apps/builder/messages/ja.json
@@ -4573,7 +4573,7 @@
"reference": "参照番号 {referenceId}"
},
"sendQueue": {
- "failed": "メッセージを送信できませんでした。再送信すると続行できます。",
+ "failed": "メッセージを送信できませんでした。可能なら会話から再送信するか、送信を続けてください。",
"unconfirmed": "最後のメッセージが送信されたか確認できませんでした。送信を続けるか選択してください。",
"continue": "送信を続ける",
"discard": "待機中のメッセージを破棄",
diff --git a/apps/builder/messages/nl.json b/apps/builder/messages/nl.json
index b42fbe475e..f8e818ce79 100644
--- a/apps/builder/messages/nl.json
+++ b/apps/builder/messages/nl.json
@@ -4596,7 +4596,7 @@
"reference": "Referentie {referenceId}"
},
"sendQueue": {
- "failed": "Een bericht kon niet worden verzonden. Verstuur het opnieuw om door te gaan.",
+ "failed": "Een bericht kon niet worden verzonden. Verstuur het indien mogelijk opnieuw vanuit het gesprek, of ga door met verzenden.",
"unconfirmed": "We konden niet bevestigen dat het laatste bericht is verzonden. Kies of je wilt doorgaan met verzenden.",
"continue": "Doorgaan met verzenden",
"discard": "Berichten in de wachtrij verwijderen",
diff --git a/apps/builder/messages/pt-BR.json b/apps/builder/messages/pt-BR.json
index 9b738d42e8..deb0262b19 100644
--- a/apps/builder/messages/pt-BR.json
+++ b/apps/builder/messages/pt-BR.json
@@ -4573,7 +4573,7 @@
"reference": "Referência {referenceId}"
},
"sendQueue": {
- "failed": "Uma mensagem não foi enviada. Reenvie-a para continuar.",
+ "failed": "Uma mensagem não foi enviada. Reenvie-a pela conversa se possível ou continue enviando.",
"unconfirmed": "Não foi possível confirmar o envio da última mensagem. Escolha se quer continuar enviando.",
"continue": "Continuar enviando",
"discard": "Descartar mensagens na fila",
diff --git a/apps/builder/messages/pt-PT.json b/apps/builder/messages/pt-PT.json
index 97de55e4a7..bea76f2a08 100644
--- a/apps/builder/messages/pt-PT.json
+++ b/apps/builder/messages/pt-PT.json
@@ -4596,7 +4596,7 @@
"reference": "Referência {referenceId}"
},
"sendQueue": {
- "failed": "Uma mensagem não foi enviada. Reenvie-a para continuar.",
+ "failed": "Uma mensagem não foi enviada. Reenvie-a a partir da conversa se possível ou continue a enviar.",
"unconfirmed": "Não foi possível confirmar o envio da última mensagem. Escolha se quer continuar a enviar.",
"continue": "Continuar a enviar",
"discard": "Descartar mensagens em fila",
diff --git a/apps/builder/messages/ro.json b/apps/builder/messages/ro.json
index 25cc98b4fe..2d932c5a13 100644
--- a/apps/builder/messages/ro.json
+++ b/apps/builder/messages/ro.json
@@ -4596,7 +4596,7 @@
"reference": "Referință {referenceId}"
},
"sendQueue": {
- "failed": "Un mesaj nu a putut fi trimis. Retrimite-l pentru a continua.",
+ "failed": "Un mesaj nu a putut fi trimis. Retrimite-l din conversație dacă se poate sau continuă trimiterea.",
"unconfirmed": "Nu am putut confirma că ultimul mesaj a fost trimis. Alege dacă vrei să continui trimiterea.",
"continue": "Continuă trimiterea",
"discard": "Renunță la mesajele din coadă",
diff --git a/apps/builder/messages/sv.json b/apps/builder/messages/sv.json
index 42f8ba1278..a5d3446769 100644
--- a/apps/builder/messages/sv.json
+++ b/apps/builder/messages/sv.json
@@ -5749,7 +5749,7 @@
"reference": "Referens {referenceId}"
},
"sendQueue": {
- "failed": "Ett meddelande kunde inte skickas. Skicka det igen för att fortsätta.",
+ "failed": "Ett meddelande kunde inte skickas. Skicka det igen från konversationen om möjligt, eller fortsätt skicka.",
"unconfirmed": "Vi kunde inte bekräfta att det senaste meddelandet skickades. Välj om du vill fortsätta skicka.",
"continue": "Fortsätt skicka",
"discard": "Kasta meddelanden i kön",
diff --git a/apps/builder/messages/tr.json b/apps/builder/messages/tr.json
index 4f191868dc..bd134a4c2a 100644
--- a/apps/builder/messages/tr.json
+++ b/apps/builder/messages/tr.json
@@ -4596,7 +4596,7 @@
"reference": "Referans {referenceId}"
},
"sendQueue": {
- "failed": "Bir mesaj gönderilemedi. Devam etmek için yeniden gönderin.",
+ "failed": "Bir mesaj gönderilemedi. Mümkünse sohbetten yeniden gönderin veya göndermeye devam edin.",
"unconfirmed": "Son mesajın gönderildiği doğrulanamadı. Göndermeye devam edip etmeyeceğinizi seçin.",
"continue": "Göndermeye devam et",
"discard": "Kuyruktaki mesajları sil",
diff --git a/apps/builder/messages/vi.json b/apps/builder/messages/vi.json
index dc3a0b51f6..9242da861d 100644
--- a/apps/builder/messages/vi.json
+++ b/apps/builder/messages/vi.json
@@ -4638,7 +4638,7 @@
"reference": "Mã tham chiếu {referenceId}"
},
"sendQueue": {
- "failed": "Một tin nhắn gửi thất bại. Hãy gửi lại để tiếp tục gửi.",
+ "failed": "Một tin nhắn gửi thất bại. Hãy gửi lại từ cuộc trò chuyện nếu được, hoặc tiếp tục gửi.",
"unconfirmed": "Chưa xác nhận được tin nhắn cuối đã gửi. Hãy chọn có tiếp tục gửi hay không.",
"continue": "Tiếp tục gửi",
"discard": "Hủy các tin đang chờ",
diff --git a/apps/builder/messages/zh-CN.json b/apps/builder/messages/zh-CN.json
index 5acc17bfca..35c5d6f81c 100644
--- a/apps/builder/messages/zh-CN.json
+++ b/apps/builder/messages/zh-CN.json
@@ -5749,7 +5749,7 @@
"reference": "参考号 {referenceId}"
},
"sendQueue": {
- "failed": "有一条消息发送失败。请重新发送以继续。",
+ "failed": "有一条消息发送失败。如可以,请在对话中重新发送,或继续发送。",
"unconfirmed": "无法确认最后一条消息是否已发送。请选择是否继续发送。",
"continue": "继续发送",
"discard": "丢弃排队中的消息",
diff --git a/apps/builder/messages/zh-TW.json b/apps/builder/messages/zh-TW.json
index a9561af870..c85e12baab 100644
--- a/apps/builder/messages/zh-TW.json
+++ b/apps/builder/messages/zh-TW.json
@@ -1907,7 +1907,7 @@
"reference": "參考編號 {referenceId}"
},
"sendQueue": {
- "failed": "有一則訊息傳送失敗。請重新傳送以繼續。",
+ "failed": "有一則訊息傳送失敗。如可以,請在對話中重新傳送,或繼續傳送。",
"unconfirmed": "無法確認最後一則訊息是否已傳送。請選擇是否繼續傳送。",
"continue": "繼續傳送",
"discard": "捨棄佇列中的訊息",
diff --git a/apps/builder/src/features/messages/lib/use-send-queue-runner.ts b/apps/builder/src/features/messages/lib/use-send-queue-runner.ts
index f84719c89b..9deed5bccd 100644
--- a/apps/builder/src/features/messages/lib/use-send-queue-runner.ts
+++ b/apps/builder/src/features/messages/lib/use-send-queue-runner.ts
@@ -44,8 +44,9 @@ export const useSendQueueRunner = (props: {
// pipeline item chat) the queues go with it. Messages already cleared from
// the composer must not be lost, so the ones still waiting are sent now, in
// order. A held queue is left alone: its owner never chose to go on.
- const latest = useRef({ sendQueues, workspaceId })
- latest.current = { sendQueues, workspaceId }
+ const fallbackError = t("messages.unknownError")
+ const latest = useRef({ sendQueues, workspaceId, fallbackError })
+ latest.current = { sendQueues, workspaceId, fallbackError }
useEffect(
() => () => {
flushWaitingSends(latest.current)
@@ -131,11 +132,15 @@ export const useSendQueueRunner = (props: {
}, [sendQueues, submit, tick, updateSendQueue])
}
-/** Sends one conversation's waiting messages in order; failures only toast. */
+/**
+ * Sends one conversation's waiting messages in order. Stops at the first one
+ * the server refuses, so nothing behind a failure overtakes it.
+ */
const sendInOrder = async (
workspaceId: string,
conversationId: string,
waiting: QueuedSend[],
+ fallbackError: string,
): Promise => {
for (const item of waiting) {
try {
@@ -144,11 +149,19 @@ const sendInOrder = async (
conversationId,
item.input,
)
- if (result?.serverError) {
- toast.error(result.serverError)
+ const refusal =
+ result?.serverError ??
+ (result?.validationErrors
+ ? (flattenValidationErrors(result.validationErrors)[0]?.message ??
+ fallbackError)
+ : undefined)
+ if (refusal) {
+ toast.error(refusal)
+ return
}
} catch (error) {
- toast.error(error instanceof Error ? error.message : String(error))
+ toast.error(error instanceof Error ? error.message : fallbackError)
+ return
}
}
}
@@ -157,10 +170,16 @@ const sendInOrder = async (
const flushWaitingSends = (state: {
sendQueues: Record>
workspaceId: string
+ fallbackError: string
}): void => {
for (const [conversationId, queue] of Object.entries(state.sendQueues)) {
if (queue.holdReason === null && queue.waiting.length > 0) {
- sendInOrder(state.workspaceId, conversationId, queue.waiting)
+ sendInOrder(
+ state.workspaceId,
+ conversationId,
+ queue.waiting,
+ state.fallbackError,
+ )
}
}
}
diff --git a/apps/worker/__tests__/send-message-handler.test.ts b/apps/worker/__tests__/send-message-handler.test.ts
index 7f10c1cdf7..c5e0f1fb9f 100644
--- a/apps/worker/__tests__/send-message-handler.test.ts
+++ b/apps/worker/__tests__/send-message-handler.test.ts
@@ -820,6 +820,35 @@ describe("chat send-message handlers", () => {
)
})
+ test("a bookkeeping failure before the stats does not skip counting a delivered bot message", async () => {
+ mockRunChannelHandler.mockResolvedValueOnce({
+ messageIds: ["mid-1"],
+ sentCount: 1,
+ })
+ mockRecordOutboundMessageSent.mockRejectedValueOnce(new Error("db down"))
+
+ await expect(
+ sendMessageToChannel({
+ conversation: conversation as never,
+ contactInbox: contactInbox as never,
+ message: {
+ id: "msg-bot-2",
+ workspaceId: "ws-1",
+ conversationId: "conv-1",
+ contactInboxId: "ci-1",
+ contentType: "text",
+ messageType: "outgoing",
+ senderType: "bot",
+ sourceId: null,
+ text: "automated reply",
+ createdAt: new Date("2026-07-09T08:37:21.108Z"),
+ } as never,
+ }),
+ ).resolves.toEqual({ messageIds: ["mid-1"], sentCount: 1 })
+
+ expect(mockEmit.mock.calls.some(isBotSentDashboardCall)).toBe(true)
+ })
+
test("does not retry the send when persisting a comment reply's sourceId fails", async () => {
// Regression: the reply is already live on the channel at this point — a
// thrown error here must be swallowed, not rethrown, or BullMQ redelivers
@@ -1993,7 +2022,7 @@ describe("chat send-message handlers", () => {
})
describe("send error is recorded only once it is final", () => {
- const failing = (willRetryOnThrow: boolean) => {
+ const failing = (willRetryOnThrow: boolean, sendFrom?: "inbox") => {
mockRunChannelHandler.mockRejectedValueOnce(
new ChannelError("rate limited", ChannelErrorCategory.RATE_LIMITED, {
code: "rate_limited",
@@ -2015,7 +2044,7 @@ describe("chat send-message handlers", () => {
clientId: "client-1",
createdAt: new Date("2026-07-09T08:37:21.108Z"),
} as never,
- sendFrom: "inbox",
+ sendFrom,
},
0,
willRetryOnThrow,
@@ -2023,7 +2052,7 @@ describe("chat send-message handlers", () => {
}
test("while the job will still retry, nothing is persisted or shown", async () => {
- await expect(failing(true)).rejects.toBeInstanceOf(ChannelError)
+ await expect(failing(true, "inbox")).rejects.toBeInstanceOf(ChannelError)
expect(mockUpdateSendError).not.toHaveBeenCalled()
expect(mockQueueWorkspaceRealtimeEvent).not.toHaveBeenCalled()
@@ -2035,7 +2064,7 @@ describe("chat send-message handlers", () => {
})
test("on the final failure the error is persisted and published", async () => {
- await expect(failing(false)).rejects.toBeInstanceOf(ChannelError)
+ await expect(failing(false, "inbox")).rejects.toBeInstanceOf(ChannelError)
expect(mockUpdateSendError).toHaveBeenCalledWith(
"msg-1",
@@ -2051,5 +2080,16 @@ describe("chat send-message handlers", () => {
}),
)
})
+
+ test("a send not from the inbox records every failure, as before, so a retry that never runs still leaves one", async () => {
+ await expect(failing(true)).rejects.toBeInstanceOf(ChannelError)
+
+ expect(mockUpdateSendError).toHaveBeenCalledWith(
+ "msg-1",
+ "sdk error",
+ "ws-1",
+ new Date("2026-07-09T08:37:21.108Z"),
+ )
+ })
})
})
diff --git a/apps/worker/src/chat/handlers/send-message.ts b/apps/worker/src/chat/handlers/send-message.ts
index 1a1af0425f..9aa1f5fc7d 100644
--- a/apps/worker/src/chat/handlers/send-message.ts
+++ b/apps/worker/src/chat/handlers/send-message.ts
@@ -492,7 +492,16 @@ export async function sendMessageToChannel(
logger.warn(error, "Auto-unblock on successful send failed")
}
}
+ } catch (err) {
+ logger.error(
+ { err, messageId: message.id, workspaceId: conversation.workspaceId },
+ "Post-send bookkeeping failed after the channel accepted the message",
+ )
+ }
+ // Quota and agent stats in their own block: a failure in the bookkeeping
+ // above must not also skip counting a message that was delivered.
+ try {
// Bot-message quota accounting: `chat/worker.ts`'s pre-send gate blocks this
// job type when `senderType === "bot"` (`isBotMessageQuotaReached`), but
// nothing previously counted it — the quota gate and the quota meter must
@@ -573,10 +582,11 @@ export async function sendMessageToChannel(
metadata,
willRetry,
})
- // Only a FINAL failure is recorded and shown: while the job will still be
- // retried the message may yet go out, and an error badge now would invite a
- // Resend that duplicates it.
- if (!willRetry) {
+ // An inbox message records only its FINAL failure: while the job will still
+ // be retried it may yet go out, and an error badge now would invite a
+ // Resend that duplicates it. Other sends keep recording every failure, so
+ // a retry that never runs (quota, blocked workspace) still leaves one.
+ if (!willRetry || sendFrom !== "inbox") {
await recordMessageSendError(
message?.id,
message?.clientId,