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..ece481377c 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,7 @@ "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: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) => ( + + ), +})) + +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..3728054d6a 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,201 @@ 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("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("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"]) + 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 +608,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 +629,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 +650,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 +712,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 +733,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 +772,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 +802,7 @@ describe("message composers", () => { id: "message-1", } as never action.executeAsync.mockResolvedValueOnce({ data: {} }) - act(() => root.render()) + act(() => root.render()) await submitMessages(["hello"]) @@ -560,7 +817,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..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", () => ({ @@ -403,6 +404,58 @@ 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 messageService.resendOutgoing with the id field it expects and returns its result", async () => { + const createdAt = new Date("2026-01-01T00:00:00Z") + messageService.resendOutgoing.mockResolvedValueOnce({ + id: "msg-1", + queued: true, + }) + + const result = await procedure.handler?.({ + context, + input: { conversationId: "conv-1", messageId: "msg-1", createdAt }, + }) + + expect(messageService.resendOutgoing).toHaveBeenCalledWith({ + workspaceId: "ws-1", + conversationId: "conv-1", + messageId: "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(messageService.resendOutgoing).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..1feb5d692f --- /dev/null +++ b/apps/builder/__tests__/resend-message-button.test.tsx @@ -0,0 +1,186 @@ +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") + + 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..279d431a46 --- /dev/null +++ b/apps/builder/__tests__/send-queue-notice.test.tsx @@ -0,0 +1,89 @@ +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 so and offers to keep sending or discard the queued messages", () => { + 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") + expect(buttonWithText(el, "messages.sendQueue.continue")).toBeDefined() + + act(() => { + buttonWithText(el, "messages.sendQueue.discard")?.click() + }) + expect(onDiscard).toHaveBeenCalledTimes(1) + 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() + const el = render({ + heldCount: 2, + reason: "unconfirmed", + onContinue, + onDiscard, + }) + + expect(el.textContent).toContain("messages.sendQueue.unconfirmed") + + 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..85710246f2 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,13 @@ "cardEnding": "بطاقة تنتهي بـ {lastFourDigits}", "notCharged": "لم يتم الخصم بعد. اخصمه عبر مزود الدفع.", "reference": "المرجع {referenceId}" + }, + "sendQueue": { + "failed": "فشل إرسال رسالة. أعد إرسالها من المحادثة إن أمكن، أو اختر متابعة الإرسال.", + "unconfirmed": "تعذّر تأكيد إرسال آخر رسالة. اختر ما إذا كنت تريد متابعة الإرسال.", + "continue": "متابعة الإرسال", + "discard": "تجاهل الرسائل في قائمة الانتظار", + "dismiss": "تجاهل" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..1c2d78d155 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,13 @@ "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. 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", + "dismiss": "Bağla" } }, "instagram": { @@ -6796,7 +6815,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 +6842,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..8eb87d9d31 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,13 @@ "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 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ø", + "dismiss": "Afvis" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..2ddcbb76bf 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,13 @@ "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 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", + "dismiss": "Schließen" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..b5ba32698b 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,13 @@ "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 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", + "dismiss": "Dismiss" } }, "instagram": { @@ -6796,7 +6815,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 +6842,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..3778b377bb 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,13 @@ "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 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", + "dismiss": "Descartar" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..dc13cbae7e 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,13 @@ "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 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", + "dismiss": "Hylkää" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..6e3f8a91bc 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,13 @@ "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 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", + "dismiss": "Ignorer" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..6479f90286 100644 --- a/apps/builder/messages/he.json +++ b/apps/builder/messages/he.json @@ -2227,6 +2227,13 @@ "cardEnding": "כרטיס המסתיים ב-{lastFourDigits}", "notCharged": "עדיין לא חויב. חייב דרך ספק התשלומים שלך.", "reference": "אסמכתה {referenceId}" + }, + "sendQueue": { + "failed": "שליחת הודעה נכשלה. שלח אותה שוב מהשיחה אם אפשר, או המשך לשלוח.", + "unconfirmed": "לא הצלחנו לאשר שההודעה האחרונה נשלחה. בחר אם להמשיך לשלוח.", + "continue": "המשך לשלוח", + "discard": "מחק הודעות בתור", + "dismiss": "סגור" } }, "instagram": { @@ -3759,7 +3766,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 +3793,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 +7671,11 @@ "paused": "מושהה", "ended": "הסתיים" }, + "statusReason": { + "accountPolicyBlocked": "נעצר אוטומטית: חשבון הערוץ נחסם מלשלוח בעקבות הפרת מדיניות.", + "accountSendRestricted": "נעצר אוטומטית: חשבון הערוץ מוגבל זמנית מלשלוח.", + "page": "עמוד: {name}" + }, "stats": { "sent": "נשלח", "delivered": "נמסר", @@ -7800,7 +7824,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..47422aacf2 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,13 @@ "cardEnding": "Kartu berakhiran {lastFourDigits}", "notCharged": "Belum ditagih. Tagih melalui penyedia pembayaran Anda.", "reference": "Referensi {referenceId}" + }, + "sendQueue": { + "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", + "dismiss": "Tutup" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..afb842a803 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,13 @@ "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 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", + "dismiss": "Ignora" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..4bb16de755 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,13 @@ "cardEnding": "末尾 {lastFourDigits} のカード", "notCharged": "まだ請求されていません。決済プロバイダーで請求してください。", "reference": "参照番号 {referenceId}" + }, + "sendQueue": { + "failed": "メッセージを送信できませんでした。可能なら会話から再送信するか、送信を続けてください。", + "unconfirmed": "最後のメッセージが送信されたか確認できませんでした。送信を続けるか選択してください。", + "continue": "送信を続ける", + "discard": "待機中のメッセージを破棄", + "dismiss": "閉じる" } }, "instagram": { @@ -6091,7 +6110,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 +6137,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..f8e818ce79 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,13 @@ "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 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", + "dismiss": "Sluiten" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..deb0262b19 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,13 @@ "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 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", + "dismiss": "Dispensar" } }, "instagram": { @@ -5747,7 +5766,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 +5793,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..bea76f2a08 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,13 @@ "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 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", + "dismiss": "Dispensar" } }, "instagram": { @@ -6110,7 +6129,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 +6156,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..2d932c5a13 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,13 @@ "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 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ă", + "dismiss": "Închide" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..a5d3446769 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,13 @@ "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 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", + "dismiss": "Avfärda" } }, "messenger": { diff --git a/apps/builder/messages/tr.json b/apps/builder/messages/tr.json index fd76c7c569..bd134a4c2a 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,13 @@ "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. 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", + "dismiss": "Kapat" } }, "instagram": { @@ -6114,7 +6133,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 +6160,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..9242da861d 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,13 @@ "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 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ờ", + "dismiss": "Bỏ qua" } }, "instagram": { @@ -5819,7 +5838,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 +5865,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..35c5d6f81c 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,13 @@ "cardEnding": "尾号 {lastFourDigits} 的卡", "notCharged": "尚未扣款,请通过您的支付服务商扣款。", "reference": "参考号 {referenceId}" + }, + "sendQueue": { + "failed": "有一条消息发送失败。如可以,请在对话中重新发送,或继续发送。", + "unconfirmed": "无法确认最后一条消息是否已发送。请选择是否继续发送。", + "continue": "继续发送", + "discard": "丢弃排队中的消息", + "dismiss": "忽略" } }, "messenger": { diff --git a/apps/builder/messages/zh-TW.json b/apps/builder/messages/zh-TW.json index ae15ed6db9..c85e12baab 100644 --- a/apps/builder/messages/zh-TW.json +++ b/apps/builder/messages/zh-TW.json @@ -1905,6 +1905,13 @@ "cardEnding": "末四碼 {lastFourDigits} 的卡", "notCharged": "尚未扣款,請透過您的金流服務商扣款。", "reference": "參考編號 {referenceId}" + }, + "sendQueue": { + "failed": "有一則訊息傳送失敗。如可以,請在對話中重新傳送,或繼續傳送。", + "unconfirmed": "無法確認最後一則訊息是否已傳送。請選擇是否繼續傳送。", + "continue": "繼續傳送", + "discard": "捨棄佇列中的訊息", + "dismiss": "忽略" } }, "productCategories": { @@ -2480,6 +2487,11 @@ "paused": "已暫停", "ended": "已結束" }, + "statusReason": { + "accountPolicyBlocked": "已自動停止:頻道帳號因違反政策而被禁止傳送。", + "accountSendRestricted": "已自動停止:頻道帳號的傳送功能暫時受到限制。", + "page": "粉絲專頁:{name}" + }, "stats": { "sent": "已傳送", "delivered": "已交付", @@ -2628,7 +2640,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 +6179,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 +6206,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..54a6d110f9 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,56 @@ 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: pruneIdleSendQueues(sendQueues, Date.now()) } + : 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")} + + } + /> + + + + + ) +} 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-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/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..f44e389020 --- /dev/null +++ b/apps/builder/src/features/messages/actions/resend-message.action.ts @@ -0,0 +1,23 @@ +"use server" + +import { messageService } from "@chatbotx.io/business" +import { zodBigintAsString } from "@chatbotx.io/utils" +import { workspaceActionClient } from "@/lib/safe-action" +import { resendMessageRequest } from "../schema/mutation" + +export const resendMessageAction = workspaceActionClient + .bindArgsSchemas([zodBigintAsString(), zodBigintAsString()]) + .inputSchema(resendMessageRequest) + .action(async (props) => { + const { + bindArgsParsedInputs: [workspaceId, conversationId], + parsedInput, + } = props + + 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 cdbcec7c2f..8cd4f4ec59 100644 --- a/apps/builder/src/features/messages/api/public.ts +++ b/apps/builder/src/features/messages/api/public.ts @@ -34,6 +34,7 @@ import { possibleErrorsOnDeletingResource, possibleErrorsOnFindingResource, possibleErrorsOnMutatingResource, + possibleErrorsOnResendingMessage, productMessageUnresolvable, } from "@/lib/orpc/orpc-error-helper" import { @@ -50,6 +51,7 @@ import { messageIdPathParam, messageIdWithCreatedAtParam, requestCallPermissionPublicRequest, + resendMessagePublicResponse, sendWhatsappTemplatePublicRequest, } from "../schema/public" @@ -311,6 +313,29 @@ 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 messageService.resendOutgoing({ + workspaceId: context.workspace.id, + conversationId: input.conversationId, + messageId: 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..6707bb80bf --- /dev/null +++ b/apps/builder/src/features/messages/components/resend-message-button.tsx @@ -0,0 +1,86 @@ +"use client" + +import { Button } from "@chatbotx.io/ui/components/ui/button" +import { RotateCcwIcon } from "lucide-react" +import { useTranslations } from "next-intl" +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 resend = async () => { + 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"), + ) + } + } + + return ( + + ) +} 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..f6ebbb4a86 --- /dev/null +++ b/apps/builder/src/features/messages/components/send-queue-notice.tsx @@ -0,0 +1,62 @@ +"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 (when it can be); either way the + * person can go on regardless or drop what is held. + */ +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 }, + )} + +

+
+ + +
+
+ ) +} 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..7d9a349e30 --- /dev/null +++ b/apps/builder/src/features/messages/lib/__tests__/send-queue.test.ts @@ -0,0 +1,381 @@ +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 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) + + 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, + ) + }) + + 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..589589a4c2 --- /dev/null +++ b/apps/builder/src/features/messages/lib/send-queue.ts @@ -0,0 +1,349 @@ +/** + * 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) + +/** + * 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 + * nothing. + */ +export const settleSend = ( + queue: SendQueue, + signal: SendResultSignal, + now: number, +): SendQueue => { + if (!(queue.inFlight && matchesInFlight(queue.inFlight, signal))) { + return settleLateSend(queue, signal, now) + } + 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..9deed5bccd --- /dev/null +++ b/apps/builder/src/features/messages/lib/use-send-queue-runner.ts @@ -0,0 +1,185 @@ +"use client" + +import { useTranslations } from "next-intl" +import { useCallback, useEffect, useRef, 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, + type SendQueue, +} 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) + + // 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 fallbackError = t("messages.unknownError") + const latest = useRef({ sendQueues, workspaceId, fallbackError }) + latest.current = { sendQueues, workspaceId, fallbackError } + useEffect( + () => () => { + flushWaitingSends(latest.current) + }, + [], + ) + + 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]) +} + +/** + * 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 { + const result = await createMessageAction( + workspaceId, + conversationId, + item.input, + ) + 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 : fallbackError) + return + } + } +} + +/** Sends what is still waiting in unheld queues (one chain per conversation). */ +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, + state.fallbackError, + ) + } + } +} 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..c74e8f6380 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: zodBigintAsString().describe("Message id."), + 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..33635265dc 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,8 @@ 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" const INTEGRATION_ID = "int-1" @@ -177,7 +204,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 +278,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() @@ -382,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") @@ -390,9 +441,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 +459,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 +492,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 +519,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 +625,7 @@ describe("runContactScan", () => { }, expect.objectContaining({ jobId: "contact-scan-run-1-4-page-2", + delay: 5000, attempts: 1, removeOnComplete: true, }), @@ -614,6 +665,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 +932,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 +945,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__/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/__tests__/send-message-handler.test.ts b/apps/worker/__tests__/send-message-handler.test.ts index 0247946dc6..c5e0f1fb9f 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: { @@ -815,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 @@ -924,6 +958,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, @@ -1819,4 +1909,187 @@ 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, sendFrom?: "inbox") => { + 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, + }, + 0, + willRetryOnThrow, + ) + } + + test("while the job will still retry, nothing is persisted or shown", async () => { + await expect(failing(true, "inbox")).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, "inbox")).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" }), + }), + ) + }) + + 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/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-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/handlers/send-message.ts b/apps/worker/src/chat/handlers/send-message.ts index e15efc12b2..9aa1f5fc7d 100644 --- a/apps/worker/src/chat/handlers/send-message.ts +++ b/apps/worker/src/chat/handlers/send-message.ts @@ -362,154 +362,182 @@ 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") + } + } + } 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 + // 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,14 +549,18 @@ 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) - 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, @@ -550,14 +582,20 @@ 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 }, - ) + // 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, + 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 +927,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: ChatJobSendChannelMessage["data"]["sendFrom"] + 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 +1292,7 @@ export async function sendFlowStepToChannel({ conversation, contactInbox, contentAttributes: undefined, + metadata, }) throw error } 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/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..d29b5971af 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,136 @@ 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'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 +} /** - * 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, + // A failed job keeps its id reserved; do not keep it forever. + removeOnFail: { count: 100 }, + }, + ) + 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 +224,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 } @@ -183,26 +251,13 @@ 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 - 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 +281,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({ @@ -258,12 +324,13 @@ export const runContactScan = async ( ) cursor = undefined pageNumber = 0 + walkRestarted = true continue } throw error } firstPageCursorRecoveryAvailable = false - applyUsageThrottle(page.usageSignal) + pagesInChunk += 1 const filtered = filterConversationWindow({ items: page.entries, @@ -277,9 +344,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 +364,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 +430,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 +448,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 +468,21 @@ export const runContactScan = async ( } if (continueLater) { - const yieldRows = await contactScanService.yieldForContinuation({ + await scheduleContinuation({ runId, + workspaceId, + attempts: run.attempts, + pageNumber, expect, + delayMs: nextChunkDelayMs, + retriesSamePage: walkRestarted, }) - 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 +493,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/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/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..a433ad7bc8 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**. @@ -55,12 +55,24 @@ 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 + │ 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 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) ``` +- **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 from the + inbox cancels the integration's scan in the same transaction (workspace + 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` (derived, not stored). @@ -81,7 +93,55 @@ 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); 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`). +- **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/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/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..fc40500111 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, }) }) @@ -372,6 +376,7 @@ describe("contactScanService thin delegations", () => { expect(mocks.markMaxAttemptsFailed).toHaveBeenCalledWith({ maxAttempts: 5, type: "contact_scan", + currentError: "maxAttempts", }) }) @@ -523,26 +528,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 +576,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..c245d39e3f --- /dev/null +++ b/packages/business/__tests__/integration/broadcast-stop-blocked-account-db.test.ts @@ -0,0 +1,436 @@ +// @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 otherMessengerIntegrationId = createId() +const otherWorkspaceId = 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("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" }) + 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..b1c9b04d3a --- /dev/null +++ b/packages/business/__tests__/message-resend-outgoing.test.ts @@ -0,0 +1,322 @@ +// @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 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({ + 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/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts b/packages/business/__tests__/workspace-lifecycle.channel-switch-exhaustive.test.ts index ba8c625439..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: [], diff --git a/packages/business/__tests__/workspace-lifecycle.service.test.ts b/packages/business/__tests__/workspace-lifecycle.service.test.ts index d9fda1c37f..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: [], @@ -242,6 +246,12 @@ test("disconnectWorkspaceChannels tears down active native Instagram coexist run currentError: "Integration disconnected", tx, }) + expect(cancelContactScanMock).toHaveBeenCalledWith({ + channel: "instagram", + integrationId: "integration-ig-1", + currentError: "cancelled", + 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 75d67e5acc..d97d9d185a 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,146 @@ 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, + 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.filter((recurrence) => + stoppedParentIds.has(recurrence.broadcastId), + ), + 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 +1701,7 @@ class BroadcastService extends BaseService { status: broadcastStatuses.enum.sending, handoffCompletedAt: null, resumeCount: sql`${broadcastModel.resumeCount} + 1`, + ...CLEARED_STATUS_REASON, ...override, }) .where(scope) @@ -1639,7 +1789,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, { @@ -2815,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/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..41c9af6176 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, }) } @@ -297,6 +357,7 @@ class ContactScanService extends BaseService { return coexistSyncRunRepository.markMaxAttemptsFailed({ ...input, type: "contact_scan", + currentError: CONTACT_SCAN_ERRORS.maxAttempts, }) } @@ -308,6 +369,7 @@ class ContactScanService extends BaseService { yieldForContinuation(input: { runId: string expect: CoexistRunWriteGuard + attempts?: number }): Promise { return coexistSyncRunRepository.yieldForContinuation(input) } @@ -362,24 +424,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..a965feb2aa --- /dev/null +++ b/packages/business/src/message/resend-outgoing.ts @@ -0,0 +1,163 @@ +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 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" +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 +} + +/** + * 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 + * 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 }, + quickReplies: readStoredButtons(message.contentAttributes), + 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/business/src/workspace-lifecycle/service.ts b/packages/business/src/workspace-lifecycle/service.ts index 28b7ede608..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,6 +51,7 @@ import { connectionStateService, type PendingQuotaRelease, } from "../connection/state-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" @@ -789,6 +791,17 @@ class WorkspaceLifecycleService extends BaseService { tx, }) } + // Both Instagram variants support the contact scan, so this is not + // gated on the integration type. + // 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 .delete(integrationInstagramModel) .where( 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..c6c55d6df7 --- /dev/null +++ b/packages/database/__tests__/message-resendable-partial.test.ts @@ -0,0 +1,74 @@ +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" }], + ["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) + }) + + 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..70a4a8684e 100644 --- a/packages/database/src/partials/message.ts +++ b/packages/database/src/partials/message.ts @@ -67,3 +67,75 @@ 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 + 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 && + 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) && + !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/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..4cc668734f 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 } @@ -435,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 @@ -442,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). @@ -478,6 +489,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 +503,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 +1035,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 +1126,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 +1285,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..351943d778 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 AND ${messageModel.deletedAt} 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..99544968b9 --- /dev/null +++ b/packages/worker-config/__tests__/contact-scan-job-ids.test.ts @@ -0,0 +1,67 @@ +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 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") + 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..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,19 +11,37 @@ /** * 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. + * + * `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}` +}