([
+ { kind: 'personal_api_key', userId: 'owner', keyId: 'key' },
+ { kind: 'workspace_api_key', workspaceId: 'workspace', keyId: 'key' },
+ {
+ kind: 'oauth_access_token',
+ userId: 'owner',
+ tokenId: 'token',
+ clientId: 'client',
+ scopes: ['api:write'],
+ expiresAt: new Date('2099-01-01'),
+ },
+ ])('refuses $kind before scope lookup or preparation', async (caller) => {
+ const prepare = vi.fn().mockResolvedValue({ ready: true })
+ const execute = vi.fn()
+ const getScope = vi.fn().mockReturnValue(scope)
+ const useCase = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.create,
+ scope: getScope,
+ prepare,
+ execute,
+ })
+ await expect(useCase.execute({ principal: caller, input })).rejects.toThrow('signed-in user')
+ expect(getScope).not.toHaveBeenCalled()
+ expect(mocks.authorize).not.toHaveBeenCalled()
+ expect(prepare).not.toHaveBeenCalled()
+ expect(execute).not.toHaveBeenCalled()
+ })
+
+ it('does not prepare or execute when the initial authorization fails', async () => {
+ mocks.authorize.mockRejectedValue(new OrchestrationError('not_found', 'Workspace not found'))
+ const prepare = vi.fn()
+ const execute = vi.fn()
+ const useCase = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.create,
+ scope: () => scope,
+ mutation: true,
+ prepare,
+ execute,
+ })
+ await expect(useCase.execute({ principal, input })).rejects.toThrow('Workspace not found')
+ expect(prepare).not.toHaveBeenCalled()
+ expect(db.transaction).not.toHaveBeenCalled()
+ })
+
+ it('prepares outside locks, then rechecks the original scope and incarnation before mutating', async () => {
+ const prepared = { catalog: ['governed-item'] }
+ const prepare = vi.fn().mockResolvedValue(prepared)
+ const execute = vi.fn().mockResolvedValue({ id: 'request' })
+ const useCase = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.create,
+ scope: () => scope,
+ mutation: true,
+ prepare,
+ execute,
+ })
+ await expect(useCase.execute({ principal, input })).resolves.toEqual({ id: 'request' })
+ expect(prepare).toHaveBeenCalledExactlyOnceWith({ principal, input, context })
+ expect(prepare.mock.invocationCallOrder[0]).toBeLessThan(
+ vi.mocked(db.transaction).mock.invocationCallOrder[0]
+ )
+ expect(mocks.lock).toHaveBeenCalledExactlyOnceWith(transaction, 'org')
+ expect(mocks.authorize).toHaveBeenNthCalledWith(
+ 2,
+ principal,
+ accessRequestOperations.create,
+ scope,
+ transaction,
+ true,
+ context
+ )
+ expect(mocks.lock.mock.invocationCallOrder[0]).toBeLessThan(
+ mocks.authorize.mock.invocationCallOrder[1]
+ )
+ expect(execute).toHaveBeenCalledExactlyOnceWith({
+ principal,
+ input,
+ context,
+ executor: transaction,
+ prepared,
+ })
+ })
+
+ it('never executes or audits after membership is removed during preparation', async () => {
+ mocks.authorize
+ .mockResolvedValueOnce(context)
+ .mockRejectedValueOnce(new OrchestrationError('not_found', 'Access request scope not found'))
+ const execute = vi.fn()
+ const projectAudit = vi.fn().mockReturnValue([])
+ const useCase = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.create,
+ scope: () => scope,
+ mutation: true,
+ prepare: async () => true,
+ execute,
+ projectAudit,
+ })
+ await expect(useCase.execute({ principal, input })).rejects.toThrow(
+ 'Access request scope not found'
+ )
+ expect(execute).not.toHaveBeenCalled()
+ expect(projectAudit).not.toHaveBeenCalled()
+ expect(mocks.audit).not.toHaveBeenCalled()
+ })
+
+ it('does not acquire locks when preparation fails', async () => {
+ const execute = vi.fn()
+ const useCase = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.create,
+ scope: () => scope,
+ mutation: true,
+ prepare: async () => {
+ throw new Error('Catalog unavailable')
+ },
+ execute,
+ })
+ await expect(useCase.execute({ principal, input })).rejects.toThrow('Catalog unavailable')
+ expect(db.transaction).not.toHaveBeenCalled()
+ expect(mocks.lock).not.toHaveBeenCalled()
+ expect(execute).not.toHaveBeenCalled()
+ })
+
+ it('supports authorization-only probes without preparing or running business behavior', async () => {
+ const prepare = vi.fn()
+ const execute = vi.fn()
+ const useCase = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.listMine,
+ scope: () => scope,
+ prepare,
+ execute,
+ })
+ await useCase.authorize?.({ principal, input })
+ expect(mocks.authorize).toHaveBeenCalledExactlyOnceWith(
+ principal,
+ accessRequestOperations.listMine,
+ scope
+ )
+ expect(prepare).not.toHaveBeenCalled()
+ expect(execute).not.toHaveBeenCalled()
+ })
+
+ it('keeps the acting session principal for reads and audits', async () => {
+ const execute = vi.fn().mockResolvedValue('result')
+ const projectAudit = vi.fn().mockReturnValue([])
+ const useCase = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.listMine,
+ scope: () => scope,
+ execute,
+ projectAudit,
+ })
+ await useCase.execute({ principal, input })
+ expect(execute).toHaveBeenCalledExactlyOnceWith({
+ principal,
+ input,
+ context,
+ executor: db,
+ prepared: undefined,
+ })
+ expect(mocks.outbound).toHaveBeenCalledWith('org', expect.any(Function))
+ expect(mocks.audit).toHaveBeenCalledWith(
+ accessRequestOperations.listMine,
+ 'workspace',
+ principal,
+ undefined,
+ [],
+ 'org'
+ )
+ expect(db.transaction).not.toHaveBeenCalled()
+ })
+})
diff --git a/apps/sim/lib/permission-access-requests/application/authorized-use-case.ts b/apps/sim/lib/permission-access-requests/application/authorized-use-case.ts
new file mode 100644
index 00000000000..7eea4a76977
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/application/authorized-use-case.ts
@@ -0,0 +1,113 @@
+import type { Principal, SessionPrincipal } from '@sim/auth/principal'
+import { db } from '@sim/db'
+import { acquireOrganizationMutationLock } from '@/lib/billing/organizations/membership'
+import {
+ recordProjectedUseCaseAuditEntries,
+ type WorkspaceUseCaseAuditEntry,
+} from '@/lib/core/application/authorized-workspace-use-case'
+import type { OperationUseCase } from '@/lib/core/application/operation'
+import { runWithOutboundOrganization } from '@/lib/core/network/context.server'
+import { OrchestrationError } from '@/lib/core/orchestration/types'
+import type { DbOrTx } from '@/lib/db/types'
+import {
+ type AccessRequestContext,
+ authorizeAccessRequestScope,
+} from '@/lib/permission-access-requests/application/authorization'
+import type { AccessRequestOperation } from '@/lib/permission-access-requests/application/operations'
+import type { AccessRequestScope } from '@/lib/permission-groups/access-requests/targets'
+
+interface AccessRequestPreparationArgs {
+ principal: SessionPrincipal
+ input: I
+ context: AccessRequestContext
+}
+
+interface AccessRequestUseCaseArgs extends AccessRequestPreparationArgs {
+ executor: DbOrTx
+}
+
+interface AccessRequestUseCaseDefinition {
+ operation: AccessRequestOperation
+ scope(input: I): AccessRequestScope
+ mutation?: boolean
+ projectAudit?(args: AccessRequestUseCaseArgs & { result: R }): WorkspaceUseCaseAuditEntry[]
+}
+
+interface PreparedAccessRequestUseCase extends AccessRequestUseCaseDefinition {
+ prepare(args: AccessRequestPreparationArgs): Promise
+ execute(args: AccessRequestUseCaseArgs & { prepared: P }): Promise
+}
+
+interface UnpreparedAccessRequestUseCase extends AccessRequestUseCaseDefinition {
+ prepare?: never
+ execute(args: AccessRequestUseCaseArgs & { prepared: undefined }): Promise
+}
+
+function requireSession(principal: Principal): asserts principal is SessionPrincipal {
+ if (principal.kind !== 'session') {
+ throw new OrchestrationError('forbidden', 'A signed-in user is required')
+ }
+}
+
+export function defineAuthorizedAccessRequestUseCase(
+ definition: PreparedAccessRequestUseCase
+): OperationUseCase
+export function defineAuthorizedAccessRequestUseCase(
+ definition: UnpreparedAccessRequestUseCase
+): OperationUseCase
+/** Shared session-only funnel; preparation finishes before any transaction acquires locks. */
+export function defineAuthorizedAccessRequestUseCase(
+ definition: PreparedAccessRequestUseCase | UnpreparedAccessRequestUseCase
+): OperationUseCase {
+ return {
+ operation: definition.operation,
+ async authorize({ principal, input }) {
+ requireSession(principal)
+ await authorizeAccessRequestScope(principal, definition.operation, definition.scope(input))
+ },
+ async execute({ principal, input, request }) {
+ requireSession(principal)
+ const scope = definition.scope(input)
+ const initial = await authorizeAccessRequestScope(principal, definition.operation, scope)
+ return runWithOutboundOrganization(initial.organizationId, async () => {
+ let execute: (args: AccessRequestUseCaseArgs) => Promise
+ if (definition.prepare) {
+ const prepared = await definition.prepare({ principal, input, context: initial })
+ const executePrepared = definition.execute
+ execute = (args) => executePrepared({ ...args, prepared })
+ } else {
+ const executeUnprepared = definition.execute
+ execute = (args) => executeUnprepared({ ...args, prepared: undefined })
+ }
+ let context = initial
+ const result = definition.mutation
+ ? await db.transaction(async (executor) => {
+ if (initial.organizationId) {
+ await acquireOrganizationMutationLock(executor, initial.organizationId)
+ }
+ context = await authorizeAccessRequestScope(
+ principal,
+ definition.operation,
+ scope,
+ executor,
+ true,
+ initial
+ )
+ return execute({ principal, input, context, executor })
+ })
+ : await execute({ principal, input, context, executor: db })
+ if (definition.projectAudit) {
+ recordProjectedUseCaseAuditEntries(
+ definition.operation,
+ context.workspaceId,
+ principal,
+ request,
+ definition.projectAudit({ principal, input, context, executor: db, result }),
+ context.organizationId ?? undefined
+ )
+ }
+ return result
+ })
+ },
+ }
+}
diff --git a/apps/sim/lib/permission-access-requests/application/operations.ts b/apps/sim/lib/permission-access-requests/application/operations.ts
new file mode 100644
index 00000000000..fd6e959ffcf
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/application/operations.ts
@@ -0,0 +1,66 @@
+import { defineOrganizationOperation } from '@/lib/core/application/organization-operation'
+import { defineWorkspaceOperation } from '@/lib/core/application/workspace-operation'
+
+function defineAccessRequestOperation(id: string, admin = false) {
+ const organizationOperation = defineOrganizationOperation({
+ id,
+ minimumRole: admin ? 'admin' : 'member',
+ principalKinds: ['session'],
+ /**
+ * permission-group-exempt: reviewing and requesting withheld access must remain reachable.
+ */
+ capability: 'none',
+ })
+ const workspaceOperation = defineWorkspaceOperation({
+ id,
+ minimumRole: 'read',
+ workspaceApiKey: 'deny',
+ principalKinds: ['session'],
+ /**
+ * permission-group-exempt: requests never grant a withheld capability without administrator review.
+ */
+ capability: 'none',
+ })
+ return Object.freeze({ ...workspaceOperation, organizationOperation, admin })
+}
+
+export const accessRequestOperations = {
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ discover: defineAccessRequestOperation('access_requests.discover'),
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ listMine: defineAccessRequestOperation('access_requests.list_mine'),
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ create: defineAccessRequestOperation('access_requests.create'),
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ cancel: defineAccessRequestOperation('access_requests.cancel'),
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ listOrganization: defineAccessRequestOperation('access_requests.list_organization', true),
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ preview: defineAccessRequestOperation('access_requests.preview', true),
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ resolve: defineAccessRequestOperation('access_requests.resolve', true),
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ getSettings: defineAccessRequestOperation('access_requests.get_settings', true),
+ /**
+ * permission-group-exempt: requesting and reviewing access must remain reachable when the requested capability is denied.
+ */
+ updateSettings: defineAccessRequestOperation('access_requests.update_settings', true),
+} as const
+
+export type AccessRequestOperation = ReturnType
diff --git a/apps/sim/lib/permission-access-requests/application/prepare.ts b/apps/sim/lib/permission-access-requests/application/prepare.ts
new file mode 100644
index 00000000000..a05269b1f9d
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/application/prepare.ts
@@ -0,0 +1,37 @@
+import { isOrganizationOnEnterprisePlan } from '@/lib/billing/core/subscription'
+import { isAccessControlEnabled, isHosted } from '@/lib/core/config/env-flags'
+import { isFeatureEnabled } from '@/lib/core/config/feature-flags'
+import { OrchestrationError } from '@/lib/core/orchestration/types'
+import type { AccessRequestContext } from '@/lib/permission-access-requests/application/authorization'
+import { loadAccessRequestCatalog } from '@/lib/permission-access-requests/catalog'
+import type { AccessRequestTarget } from '@/lib/permission-groups/access-requests/targets'
+
+/** Resolve deployment metadata before opening a transaction or taking policy locks. */
+export async function prepareAccessRequestPolicy(
+ context: Pick,
+ userId: string,
+ targetKind?: AccessRequestTarget['kind']
+) {
+ if (!context.organizationId)
+ throw new OrchestrationError(
+ 'forbidden',
+ 'Access requests require an organization-owned workspace'
+ )
+ const [catalog, entitled, globalEnabled] = await Promise.all([
+ loadAccessRequestCatalog(
+ {
+ organizationId: context.organizationId,
+ workspaceId: context.workspaceId,
+ userId,
+ },
+ targetKind
+ ),
+ isHosted
+ ? isOrganizationOnEnterprisePlan(context.organizationId)
+ : Promise.resolve(isAccessControlEnabled),
+ isFeatureEnabled('permission-access-requests'),
+ ])
+ return { catalog, entitled, globalEnabled }
+}
+
+export type PreparedAccessRequestPolicy = Awaited>
diff --git a/apps/sim/lib/permission-access-requests/application/requests.test.ts b/apps/sim/lib/permission-access-requests/application/requests.test.ts
new file mode 100644
index 00000000000..fd2e3400605
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/application/requests.test.ts
@@ -0,0 +1,525 @@
+/**
+ * @vitest-environment node
+ */
+import { db } from '@sim/db'
+import {
+ organizationMemberUsageLimit,
+ permissionAccessRequest,
+ permissionGroup,
+ workspace,
+} from '@sim/db/schema'
+import { dbChainMockFns, queueTableRows, resetDbChainMock } from '@sim/testing'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+import type { AccessRequestRecord, AccessRequestTarget } from '@/lib/api/contracts/access-requests'
+import type { StoredAccessRequest } from '@/lib/permission-access-requests/repository'
+import { createAccessRequestCatalog } from '@/lib/permission-groups/access-requests/targets'
+import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields'
+
+const mocks = vi.hoisted(() => ({
+ authorize: vi.fn(),
+ membership: vi.fn(),
+ organizationLock: vi.fn(),
+ groupLock: vi.fn(),
+ audit: vi.fn(),
+ outbox: vi.fn(),
+ enabled: vi.fn(),
+ featureEnabled: vi.fn(),
+ enterprise: vi.fn(),
+ catalog: vi.fn(),
+ targets: vi.fn(),
+ deploymentReason: vi.fn(),
+ group: vi.fn(),
+ present: vi.fn(),
+ stored: vi.fn(),
+ list: vi.fn(),
+}))
+
+vi.mock('@/lib/permission-access-requests/application/authorization', () => ({
+ authorizeAccessRequestScope: mocks.authorize,
+ loadAccessRequestMembership: mocks.membership,
+}))
+vi.mock('@/lib/billing/organizations/membership', () => ({
+ acquireOrganizationMutationLock: mocks.organizationLock,
+}))
+vi.mock('@/lib/core/application/authorized-workspace-use-case', () => ({
+ recordProjectedUseCaseAuditEntries: mocks.audit,
+}))
+vi.mock('@/lib/core/outbox/service', () => ({ enqueueOutboxEvent: mocks.outbox }))
+vi.mock('@/lib/permission-groups/locks', () => ({ acquirePermissionGroupOrgLock: mocks.groupLock }))
+vi.mock('@/lib/permission-access-requests/settings', () => ({
+ isAccessRequestEnabled: mocks.enabled,
+ readAccessRequestSettings: vi.fn(),
+}))
+vi.mock('@/lib/core/config/feature-flags', () => ({ isFeatureEnabled: mocks.featureEnabled }))
+vi.mock('@/lib/core/config/env-flags', () => ({ isHosted: true, isAccessControlEnabled: true }))
+vi.mock('@/lib/billing/core/subscription', () => ({
+ isOrganizationOnEnterprisePlan: mocks.enterprise,
+}))
+vi.mock('@/lib/permission-access-requests/catalog', () => ({
+ loadAccessRequestCatalog: mocks.catalog,
+ listAccessRequestTargets: mocks.targets,
+ getAccessRequestDeploymentUnavailableReason: mocks.deploymentReason,
+}))
+vi.mock('@/lib/permission-groups/resolve.server', () => ({
+ resolveWorkspaceGroup: mocks.group,
+ resolveDefaultGroup: mocks.group,
+}))
+vi.mock('@/lib/permission-access-requests/repository', () => ({
+ presentAccessRequest: mocks.present,
+ loadStoredAccessRequest: mocks.stored,
+ listAccessRequestRecords: mocks.list,
+}))
+
+import {
+ cancelAccessRequest,
+ createAccessRequest,
+ discoverAccessRequests,
+ listMyAccessRequests,
+} from '@/lib/permission-access-requests/application/requests'
+import {
+ PERMISSION_ACCESS_REQUEST_CREATED_EVENT,
+ PERMISSION_ACCESS_REQUEST_DECIDED_EVENT,
+} from '@/lib/permission-access-requests/notification-events'
+
+const principal = { kind: 'session', userId: 'requester', sessionId: 'session' } as const
+const scope = { kind: 'workspace', workspaceId: 'workspace' } as const
+const context = {
+ organizationId: 'organization',
+ workspaceId: 'workspace',
+ membershipId: 'membership',
+ role: 'write',
+} as const
+const target = { kind: 'feature', configKey: 'hideTablesTab' } as const
+const catalog = createAccessRequestCatalog({
+ integrations: [{ id: 'slack_v2', label: 'Slack' }],
+ providers: [],
+ models: [],
+ tools: [],
+ knowledgeConnectors: [],
+})
+const group = {
+ permissionGroupId: 'group',
+ groupName: 'Restricted group',
+ resolution: 'explicit-member',
+ config: { ...DEFAULT_PERMISSION_GROUP_CONFIG, hideTablesTab: true, hideFilesTab: true },
+} as const
+
+function stored(overrides: Partial = {}): StoredAccessRequest {
+ return {
+ id: 'request',
+ organizationId: 'organization',
+ requesterId: 'requester',
+ workspaceId: 'workspace',
+ scopeKey: 'workspace:workspace',
+ targetKey: 'feature:hideTablesTab',
+ target,
+ targetLabel: 'Tables',
+ membershipId: 'membership',
+ groupId: 'group',
+ groupName: 'Restricted group',
+ reason: 'I need tables',
+ status: 'pending',
+ decisionReason: null,
+ decidedBy: null,
+ decision: null,
+ createdAt: new Date('2026-09-01T00:00:00Z'),
+ updatedAt: new Date('2026-09-01T00:00:00Z'),
+ decidedAt: null,
+ ...overrides,
+ }
+}
+
+function record(row: StoredAccessRequest): AccessRequestRecord {
+ return {
+ id: row.id,
+ organizationId: row.organizationId,
+ workspaceId: row.workspaceId,
+ target: row.target as AccessRequestTarget,
+ targetLabel: row.targetLabel,
+ reason: row.reason,
+ status: row.status,
+ decisionReason: row.decisionReason,
+ createdAt: row.createdAt.toISOString(),
+ decidedAt: row.decidedAt?.toISOString() ?? null,
+ groupName: row.groupName,
+ requester: { id: row.requesterId, name: 'Requester', email: 'requester@example.com' },
+ }
+}
+
+beforeEach(() => {
+ vi.resetAllMocks()
+ resetDbChainMock()
+ mocks.authorize.mockResolvedValue(context)
+ mocks.membership.mockResolvedValue(null)
+ mocks.enabled.mockResolvedValue(true)
+ mocks.featureEnabled.mockResolvedValue(true)
+ mocks.enterprise.mockResolvedValue(true)
+ mocks.catalog.mockResolvedValue(catalog)
+ mocks.deploymentReason.mockReturnValue(null)
+ mocks.targets.mockReturnValue([target])
+ mocks.group.mockResolvedValue(group)
+ mocks.stored.mockResolvedValue(stored())
+ mocks.present.mockImplementation((_executor, row: StoredAccessRequest) => record(row))
+ mocks.list.mockResolvedValue({ requests: [record(stored())], total: 1, hasMore: false })
+})
+
+describe('create access requests', () => {
+ it('rejects unknown or deployment-excluded catalog IDs without creating a request', async () => {
+ for (const id of ['private-custom-block', 'environment-disabled-block']) {
+ await expect(
+ createAccessRequest.execute({
+ principal,
+ input: { scope, target: { kind: 'integration', id } },
+ })
+ ).rejects.toThrow('unavailable')
+ }
+ expect(dbChainMockFns.insert).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('refuses a feature with a hard deployment blocker even when a group also denies it', async () => {
+ mocks.deploymentReason.mockReturnValue('Disabled by this deployment.')
+ await expect(
+ createAccessRequest.execute({ principal, input: { scope, target } })
+ ).rejects.toThrow('Disabled by this deployment')
+ expect(dbChainMockFns.insert).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('returns an existing pending request without another notification or policy mutation', async () => {
+ queueTableRows(permissionAccessRequest, [stored()])
+ const result = await createAccessRequest.execute({ principal, input: { scope, target } })
+ expect(result).toMatchObject({ changed: false, request: { id: 'request', status: 'pending' } })
+ expect(dbChainMockFns.insert).not.toHaveBeenCalled()
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('creates the durable request and outbox in the transaction without granting access', async () => {
+ queueTableRows(permissionAccessRequest, [])
+ queueTableRows(permissionAccessRequest, [{ total: 0 }])
+ dbChainMockFns.returning.mockResolvedValueOnce([stored()])
+ const result = await createAccessRequest.execute({
+ principal,
+ input: { scope, target, reason: 'I need tables' },
+ })
+ expect(result.changed).toBe(true)
+ expect(dbChainMockFns.transaction).toHaveBeenCalledOnce()
+ expect(dbChainMockFns.values).toHaveBeenCalledWith(
+ expect.objectContaining({
+ requesterId: principal.userId,
+ membershipId: 'membership',
+ groupId: 'group',
+ target,
+ })
+ )
+ expect(mocks.outbox).toHaveBeenCalledWith(db, PERMISSION_ACCESS_REQUEST_CREATED_EVENT, {
+ requestId: 'request',
+ })
+ expect(dbChainMockFns.update).not.toHaveBeenCalledWith(permissionGroup)
+ expect(mocks.authorize).toHaveBeenCalledTimes(2)
+ })
+
+ it('rejects an action unavailable to the baseline workspace role', async () => {
+ mocks.authorize.mockResolvedValue({ ...context, role: 'read' })
+ await expect(
+ createAccessRequest.execute({
+ principal,
+ input: { scope, target: { kind: 'feature', configKey: 'disableTableCreation' } },
+ })
+ ).rejects.toThrow('workspace role')
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('blocks new requests while the toggle is off', async () => {
+ mocks.enabled.mockResolvedValue(false)
+ await expect(
+ createAccessRequest.execute({ principal, input: { scope, target } })
+ ).rejects.toThrow('turned off')
+ expect(dbChainMockFns.insert).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('closes an obsolete pending request before recording its replacement', async () => {
+ queueTableRows(permissionAccessRequest, [stored({ groupId: 'previous-group' })])
+ dbChainMockFns.returning
+ .mockResolvedValueOnce([stored({ status: 'closed' })])
+ .mockResolvedValueOnce([stored({ id: 'replacement' })])
+ const result = await createAccessRequest.execute({ principal, input: { scope, target } })
+ expect(result.request.id).toBe('replacement')
+ expect(mocks.audit.mock.calls[0]?.[4]).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({
+ action: 'permission_access_request.closed',
+ resourceId: 'request',
+ }),
+ expect.objectContaining({
+ action: 'permission_access_request.created',
+ resourceId: 'replacement',
+ }),
+ ])
+ )
+ expect(dbChainMockFns.set).toHaveBeenCalledWith(expect.objectContaining({ status: 'closed' }))
+ expect(mocks.outbox.mock.calls.map(([, event, payload]) => [event, payload])).toEqual([
+ [PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, { requestId: 'request' }],
+ [PERMISSION_ACCESS_REQUEST_CREATED_EVENT, { requestId: 'replacement' }],
+ ])
+ })
+
+ it('closes an existing pending request if access is already available', async () => {
+ mocks.group.mockResolvedValue({ ...group, config: DEFAULT_PERMISSION_GROUP_CONFIG })
+ queueTableRows(permissionAccessRequest, [stored()])
+ dbChainMockFns.returning.mockResolvedValueOnce([
+ stored({ status: 'closed', decisionReason: 'Access is already available.' }),
+ ])
+ const result = await createAccessRequest.execute({ principal, input: { scope, target } })
+ expect(result.request).toMatchObject({
+ status: 'closed',
+ decisionReason: 'Access is already available.',
+ })
+ expect(dbChainMockFns.insert).not.toHaveBeenCalled()
+ expect(mocks.outbox).toHaveBeenCalledWith(db, PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, {
+ requestId: 'request',
+ })
+ })
+
+ it.each([
+ { pending: 100, daily: 0, message: '100 pending requests' },
+ { pending: 0, daily: 25, message: 'maximum of 25 requests today' },
+ ])('enforces bounded admissions ($message)', async ({ pending, daily, message }) => {
+ queueTableRows(permissionAccessRequest, [])
+ queueTableRows(permissionAccessRequest, [{ total: pending }])
+ queueTableRows(permissionAccessRequest, [{ total: daily }])
+ await expect(
+ createAccessRequest.execute({ principal, input: { scope, target } })
+ ).rejects.toThrow(message)
+ expect(dbChainMockFns.insert).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('normalizes member cap requests to one organization-wide request across workspaces', async () => {
+ const cap = stored({
+ target: { kind: 'usage_limit', id: 'member' },
+ targetKey: 'usage_limit:member',
+ scopeKey: 'organization:organization:member-limit',
+ workspaceId: null,
+ membershipId: 'org-membership',
+ groupId: null,
+ groupName: null,
+ })
+ mocks.membership.mockResolvedValue({ membershipId: 'org-membership', role: 'read' })
+ queueTableRows(organizationMemberUsageLimit, [{ usageLimit: '10', updatedAt: new Date() }])
+ dbChainMockFns.returning.mockResolvedValueOnce([cap])
+ const first = await createAccessRequest.execute({
+ principal,
+ input: { scope, target: { kind: 'usage_limit', id: 'member' } },
+ })
+ expect(first.changed).toBe(true)
+ expect(dbChainMockFns.values).toHaveBeenCalledWith(
+ expect.objectContaining({
+ workspaceId: null,
+ membershipId: 'org-membership',
+ scopeKey: 'organization:organization:member-limit',
+ })
+ )
+ mocks.authorize.mockResolvedValue({
+ ...context,
+ workspaceId: 'another-workspace',
+ membershipId: 'another-grant',
+ })
+ queueTableRows(organizationMemberUsageLimit, [{ usageLimit: '10', updatedAt: new Date() }])
+ queueTableRows(permissionAccessRequest, [cap])
+ const second = await createAccessRequest.execute({
+ principal,
+ input: {
+ scope: { kind: 'workspace', workspaceId: 'another-workspace' },
+ target: { kind: 'usage_limit', id: 'member' },
+ },
+ })
+ expect(second).toMatchObject({ changed: false, request: { id: cap.id } })
+ expect(mocks.outbox).toHaveBeenCalledOnce()
+ expect(dbChainMockFns.insert).toHaveBeenCalledOnce()
+ })
+
+ it('preserves workspace membership provenance for an external member cap request', async () => {
+ queueTableRows(organizationMemberUsageLimit, [{ usageLimit: '10', updatedAt: new Date() }])
+ dbChainMockFns.returning.mockResolvedValueOnce([
+ stored({ target: { kind: 'usage_limit', id: 'member' }, groupId: null }),
+ ])
+ await createAccessRequest.execute({
+ principal,
+ input: { scope, target: { kind: 'usage_limit', id: 'member' } },
+ })
+ expect(dbChainMockFns.values).toHaveBeenCalledWith(
+ expect.objectContaining({
+ workspaceId: 'workspace',
+ membershipId: 'membership',
+ scopeKey: 'organization:organization:member-limit',
+ })
+ )
+ })
+
+ it.each([true, false])(
+ 'deduplicates an external member cap only while its original access remains valid (%s)',
+ async (originValid) => {
+ const cap = stored({
+ target: { kind: 'usage_limit', id: 'member' },
+ targetKey: 'usage_limit:member',
+ scopeKey: 'organization:organization:member-limit',
+ workspaceId: 'original-workspace',
+ membershipId: 'original-grant',
+ groupId: null,
+ groupName: null,
+ })
+ mocks.membership
+ .mockResolvedValueOnce(null)
+ .mockResolvedValueOnce({ membershipId: 'original-grant', role: 'read' })
+ queueTableRows(organizationMemberUsageLimit, [{ usageLimit: '10', updatedAt: new Date() }])
+ queueTableRows(permissionAccessRequest, [cap])
+ queueTableRows(workspace, originValid ? [{ id: 'original-workspace' }] : [])
+ if (!originValid) {
+ dbChainMockFns.returning.mockResolvedValueOnce([stored({ ...cap, status: 'closed' })])
+ dbChainMockFns.returning.mockResolvedValueOnce([stored({ ...cap, id: 'replacement' })])
+ }
+ const result = await createAccessRequest.execute({
+ principal,
+ input: { scope, target: { kind: 'usage_limit', id: 'member' } },
+ })
+ expect(result.changed).toBe(!originValid)
+ if (originValid) {
+ expect(result.request.id).toBe(cap.id)
+ expect(dbChainMockFns.insert).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ } else {
+ expect(result.request.id).toBe('replacement')
+ expect(mocks.outbox).toHaveBeenCalledTimes(2)
+ }
+ }
+ )
+})
+
+describe('discovery and request history', () => {
+ it('filters requestable state before pagination and reports pending request IDs', async () => {
+ mocks.targets.mockReturnValue([
+ { kind: 'feature', configKey: 'hideKnowledgeBaseTab' },
+ target,
+ { kind: 'feature', configKey: 'hideFilesTab' },
+ ])
+ queueTableRows(permissionAccessRequest, [
+ {
+ id: 'existing-file-request',
+ targetKey: 'feature:hideFilesTab',
+ membershipId: 'membership',
+ groupId: 'group',
+ },
+ ])
+ const result = await discoverAccessRequests.execute({
+ principal,
+ input: { ...scope, state: 'requestable', limit: 1, offset: 1 },
+ })
+ expect(result).toMatchObject({
+ total: 2,
+ hasMore: false,
+ entries: [
+ {
+ target: { kind: 'feature', configKey: 'hideFilesTab' },
+ pendingRequestId: 'existing-file-request',
+ },
+ ],
+ })
+ expect(mocks.group).toHaveBeenCalledOnce()
+ })
+
+ it.each([true, false])(
+ 'only advertises a pending member cap for its current membership (%s)',
+ async (valid) => {
+ mocks.targets.mockReturnValue([{ kind: 'usage_limit', id: 'member' }])
+ queueTableRows(organizationMemberUsageLimit, [{ usageLimit: '10', updatedAt: new Date() }])
+ queueTableRows(permissionAccessRequest, [
+ stored({
+ targetKey: 'usage_limit:member',
+ groupId: null,
+ membershipId: valid ? context.membershipId : 'old-membership',
+ }),
+ ])
+ const result = await discoverAccessRequests.execute({
+ principal,
+ input: { ...scope, limit: 50, offset: 0 },
+ })
+ expect(result.entries[0]?.pendingRequestId).toBe(valid ? 'request' : null)
+ }
+ )
+
+ it('allows a new request when a pending request belongs to a previous governing group', async () => {
+ queueTableRows(permissionAccessRequest, [stored({ groupId: 'previous-group' })])
+ const result = await discoverAccessRequests.execute({
+ principal,
+ input: { ...scope, state: 'requestable', limit: 50, offset: 0 },
+ })
+ expect(result.entries).toEqual([expect.objectContaining({ target, pendingRequestId: null })])
+ })
+
+ it('hides discovery while disabled but retains requester history', async () => {
+ mocks.enabled.mockResolvedValue(false)
+ const discovery = await discoverAccessRequests.execute({
+ principal,
+ input: { ...scope, limit: 50, offset: 0 },
+ })
+ expect(discovery).toMatchObject({ enabled: false, entries: [] })
+ const history = await listMyAccessRequests.execute({
+ principal,
+ input: { scope, limit: 50, offset: 0 },
+ })
+ expect(history.requests).toHaveLength(1)
+ expect(mocks.list).toHaveBeenCalledWith(db, expect.anything(), 50, 0)
+ expect(mocks.list.mock.calls[0]?.[1]).toMatchObject({
+ conditions: expect.arrayContaining([
+ expect.objectContaining({
+ type: 'or',
+ conditions: expect.arrayContaining([
+ expect.objectContaining({
+ left: permissionAccessRequest.scopeKey,
+ right: 'organization:organization:member-limit',
+ }),
+ ]),
+ }),
+ ]),
+ })
+ })
+})
+
+describe('cancel access requests', () => {
+ it('allows cancellation while disabled and does not resend a decision for terminal requests', async () => {
+ mocks.enabled.mockResolvedValue(false)
+ dbChainMockFns.returning.mockResolvedValueOnce([stored({ status: 'cancelled' })])
+ const first = await cancelAccessRequest.execute({
+ principal,
+ input: { scope, requestId: 'request' },
+ })
+ expect(first.request.status).toBe('cancelled')
+ expect(mocks.outbox).toHaveBeenCalledWith(db, PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, {
+ requestId: 'request',
+ })
+ mocks.stored.mockResolvedValue(stored({ status: 'cancelled' }))
+ const second = await cancelAccessRequest.execute({
+ principal,
+ input: { scope, requestId: 'request' },
+ })
+ expect(second.changed).toBe(false)
+ expect(mocks.outbox).toHaveBeenCalledOnce()
+ })
+
+ it('conceals requests belonging to another user or another workspace', async () => {
+ for (const row of [
+ stored({ requesterId: 'other-user' }),
+ stored({ scopeKey: 'workspace:other-workspace' }),
+ ]) {
+ mocks.stored.mockResolvedValue(row)
+ await expect(
+ cancelAccessRequest.execute({ principal, input: { scope, requestId: row.id } })
+ ).rejects.toThrow('not found')
+ }
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+})
diff --git a/apps/sim/lib/permission-access-requests/application/requests.ts b/apps/sim/lib/permission-access-requests/application/requests.ts
new file mode 100644
index 00000000000..b4b9c0ce1cd
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/application/requests.ts
@@ -0,0 +1,565 @@
+import { AuditAction, AuditResourceType } from '@sim/audit'
+import {
+ organizationAccessRequestSettings,
+ permissionAccessRequest,
+ workspace,
+} from '@sim/db/schema'
+import { generateId } from '@sim/utils/id'
+import { and, count, eq, gte, isNull, or } from 'drizzle-orm'
+import { OrchestrationError } from '@/lib/core/orchestration/types'
+import { enqueueOutboxEvent } from '@/lib/core/outbox/service'
+import type { DbOrTx } from '@/lib/db/types'
+import type { AccessRequestContext } from '@/lib/permission-access-requests/application/authorization'
+import { loadAccessRequestMembership } from '@/lib/permission-access-requests/application/authorization'
+import { defineAuthorizedAccessRequestUseCase } from '@/lib/permission-access-requests/application/authorized-use-case'
+import { accessRequestOperations } from '@/lib/permission-access-requests/application/operations'
+import { prepareAccessRequestPolicy } from '@/lib/permission-access-requests/application/prepare'
+import {
+ listAccessRequestTargets,
+ loadAccessRequestCatalog,
+} from '@/lib/permission-access-requests/catalog'
+import {
+ PERMISSION_ACCESS_REQUEST_CREATED_EVENT,
+ PERMISSION_ACCESS_REQUEST_DECIDED_EVENT,
+} from '@/lib/permission-access-requests/notification-events'
+import {
+ evaluateAccessRequestTarget,
+ loadAccessRequestPolicy,
+} from '@/lib/permission-access-requests/policy'
+import {
+ listAccessRequestRecords,
+ loadStoredAccessRequest,
+ presentAccessRequest,
+} from '@/lib/permission-access-requests/repository'
+import {
+ isAccessRequestEnabled,
+ readAccessRequestSettings,
+} from '@/lib/permission-access-requests/settings'
+import type {
+ AccessRequestDiscovery,
+ AccessRequestRecord,
+ AccessRequestSettings,
+ AccessRequestStatus,
+ CreateAccessRequestInput,
+ DiscoverAccessRequestsInput,
+} from '@/lib/permission-access-requests/types'
+import type { AccessRequestScope } from '@/lib/permission-groups/access-requests/targets'
+import {
+ describeAccessRequestTarget,
+ getAccessRequestTargetKey,
+ validateAccessRequestTarget,
+} from '@/lib/permission-groups/access-requests/targets'
+import { acquirePermissionGroupOrgLock } from '@/lib/permission-groups/locks'
+
+function requireOrganization(organizationId: string | null): string {
+ if (!organizationId)
+ throw new OrchestrationError(
+ 'forbidden',
+ 'Access requests require an organization-owned workspace'
+ )
+ return organizationId
+}
+
+export function accessRequestScopeKey(scope: AccessRequestScope): string {
+ return scope.kind === 'workspace'
+ ? `workspace:${scope.workspaceId}`
+ : `organization:${scope.organizationId}`
+}
+
+function memberLimitScopeKey(organizationId: string): string {
+ return `organization:${organizationId}:member-limit`
+}
+
+async function hasCurrentMemberLimitMembership(
+ executor: DbOrTx,
+ context: AccessRequestContext,
+ userId: string,
+ pending: { workspaceId: string | null; membershipId: string }
+): Promise {
+ if (!context.organizationId) return false
+ if (pending.workspaceId && pending.workspaceId === context.workspaceId)
+ return pending.membershipId === context.membershipId
+ if (pending.workspaceId) {
+ const [origin] = await executor
+ .select({ id: workspace.id })
+ .from(workspace)
+ .where(
+ and(
+ eq(workspace.id, pending.workspaceId),
+ eq(workspace.organizationId, context.organizationId),
+ isNull(workspace.archivedAt)
+ )
+ )
+ .limit(1)
+ if (!origin) return false
+ }
+ const membership = await loadAccessRequestMembership(
+ executor,
+ userId,
+ pending.workspaceId
+ ? { kind: 'workspace', workspaceId: pending.workspaceId }
+ : { kind: 'organization', organizationId: context.organizationId },
+ context.organizationId
+ )
+ return membership?.membershipId === pending.membershipId
+}
+
+export const discoverAccessRequests = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.discover,
+ scope: (input: DiscoverAccessRequestsInput) => input,
+ async execute({ input, principal, context, executor }): Promise {
+ const organizationId = context.organizationId
+ if (!organizationId || !(await isAccessRequestEnabled(organizationId, executor)))
+ return { enabled: false, organizationId, entries: [], total: 0, hasMore: false }
+ const catalog = await loadAccessRequestCatalog(
+ {
+ userId: principal.userId,
+ organizationId,
+ workspaceId: context.workspaceId,
+ },
+ input.targetKind
+ )
+ const search = input.search?.toLowerCase() ?? ''
+ const targets = listAccessRequestTargets(catalog).filter((target) => {
+ const description = describeAccessRequestTarget(target, catalog)
+ return (
+ description &&
+ (description.scope === 'workspace-or-organization' || description.scope === input.kind) &&
+ (!input.targetKind || input.targetKind === target.kind) &&
+ (!search || description.label.toLowerCase().includes(search))
+ )
+ })
+ const offset = input.offset ?? 0
+ const policy = await loadAccessRequestPolicy(executor, context, principal.userId)
+ const pending = await executor
+ .select({
+ id: permissionAccessRequest.id,
+ targetKey: permissionAccessRequest.targetKey,
+ membershipId: permissionAccessRequest.membershipId,
+ groupId: permissionAccessRequest.groupId,
+ workspaceId: permissionAccessRequest.workspaceId,
+ })
+ .from(permissionAccessRequest)
+ .where(
+ and(
+ eq(permissionAccessRequest.organizationId, organizationId),
+ eq(permissionAccessRequest.requesterId, principal.userId),
+ or(
+ eq(permissionAccessRequest.scopeKey, accessRequestScopeKey(input)),
+ eq(permissionAccessRequest.scopeKey, memberLimitScopeKey(organizationId))
+ ),
+ eq(permissionAccessRequest.status, 'pending')
+ )
+ )
+ .limit(100)
+ const pendingMemberLimit = pending.find((row) => row.targetKey === 'usage_limit:member')
+ const memberLimitMembershipMatches = pendingMemberLimit
+ ? await hasCurrentMemberLimitMembership(
+ executor,
+ context,
+ principal.userId,
+ pendingMemberLimit
+ )
+ : false
+ const pendingByTarget = new Map(
+ pending
+ .filter((row) =>
+ row.targetKey === 'usage_limit:member'
+ ? memberLimitMembershipMatches
+ : row.membershipId === context.membershipId &&
+ row.groupId === (policy.group?.permissionGroupId ?? null)
+ )
+ .map((row) => [row.targetKey, row.id])
+ )
+ const entries: AccessRequestDiscovery['entries'] = []
+ for (const target of targets) {
+ const result = await evaluateAccessRequestTarget(
+ executor,
+ context,
+ principal.userId,
+ input,
+ target,
+ catalog,
+ policy,
+ false
+ )
+ if (input.state && result.state !== input.state) continue
+ entries.push({
+ target,
+ label: describeAccessRequestTarget(target, catalog)!.label,
+ state: result.state,
+ reason: result.reason,
+ pendingRequestId: pendingByTarget.get(getAccessRequestTargetKey(target)) ?? null,
+ })
+ }
+ const page = entries.slice(offset, offset + (input.limit ?? 50))
+ return {
+ enabled: true,
+ organizationId,
+ entries: page,
+ total: entries.length,
+ hasMore: offset + page.length < entries.length,
+ }
+ },
+})
+
+interface MutationResult {
+ request: AccessRequestRecord
+ changed: boolean
+}
+
+export const createAccessRequest = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.create,
+ scope: (input: CreateAccessRequestInput) => input.scope,
+ prepare: ({ principal, context, input }) =>
+ prepareAccessRequestPolicy(context, principal.userId, input.target.kind),
+ mutation: true,
+ async execute({
+ principal,
+ input,
+ context,
+ executor,
+ prepared,
+ }): Promise {
+ const organizationId = requireOrganization(context.organizationId)
+ if (!(await isAccessRequestEnabled(organizationId, executor, prepared.globalEnabled)))
+ throw new OrchestrationError(
+ 'forbidden',
+ 'Access requests are turned off for this organization'
+ )
+ await acquirePermissionGroupOrgLock(executor, organizationId, {
+ lockTimeoutAlreadyBounded: true,
+ })
+ const catalog = prepared.catalog
+ const target = validateAccessRequestTarget(input.target, catalog)
+ if (!target)
+ throw new OrchestrationError('validation', 'This item is unavailable for access requests')
+ const targetKey = getAccessRequestTargetKey(target)
+ const memberLimitMembership =
+ target.kind === 'usage_limit'
+ ? await loadAccessRequestMembership(
+ executor,
+ principal.userId,
+ { kind: 'organization', organizationId },
+ organizationId
+ )
+ : null
+ const requestMembershipId = memberLimitMembership?.membershipId ?? context.membershipId
+ const requestWorkspaceId = memberLimitMembership ? null : context.workspaceId
+ const scopeKey =
+ target.kind === 'usage_limit'
+ ? memberLimitScopeKey(organizationId)
+ : accessRequestScopeKey(input.scope)
+ const currentPolicy = await loadAccessRequestPolicy(
+ executor,
+ context,
+ principal.userId,
+ prepared.entitled
+ )
+ const policy = await evaluateAccessRequestTarget(
+ executor,
+ context,
+ principal.userId,
+ input.scope,
+ target,
+ catalog,
+ currentPolicy
+ )
+ const [pending] = await executor
+ .select()
+ .from(permissionAccessRequest)
+ .where(
+ and(
+ eq(permissionAccessRequest.organizationId, organizationId),
+ eq(permissionAccessRequest.requesterId, principal.userId),
+ eq(permissionAccessRequest.scopeKey, scopeKey),
+ eq(permissionAccessRequest.targetKey, targetKey),
+ eq(permissionAccessRequest.status, 'pending')
+ )
+ )
+ .limit(1)
+ let pendingMembershipMatches = pending?.membershipId === requestMembershipId
+ if (
+ pending &&
+ target.kind === 'usage_limit' &&
+ !memberLimitMembership &&
+ pending.workspaceId &&
+ pending.workspaceId !== requestWorkspaceId
+ ) {
+ const [origin] = await executor
+ .select({ id: workspace.id })
+ .from(workspace)
+ .where(
+ and(
+ eq(workspace.id, pending.workspaceId),
+ eq(workspace.organizationId, organizationId),
+ isNull(workspace.archivedAt)
+ )
+ )
+ .limit(1)
+ const membership = origin
+ ? await loadAccessRequestMembership(
+ executor,
+ principal.userId,
+ { kind: 'workspace', workspaceId: pending.workspaceId },
+ organizationId
+ )
+ : null
+ pendingMembershipMatches = membership?.membershipId === pending.membershipId
+ }
+ if (
+ pending &&
+ pendingMembershipMatches &&
+ pending.groupId === (policy.group?.permissionGroupId ?? null) &&
+ policy.state === 'requestable'
+ )
+ return { request: await presentAccessRequest(executor, pending), changed: false }
+ let closedRequest: AccessRequestRecord | undefined
+ if (pending) {
+ const [closed] = await executor
+ .update(permissionAccessRequest)
+ .set({
+ status: 'closed',
+ decisionReason:
+ policy.state === 'allowed'
+ ? 'Access is already available.'
+ : 'Membership or the governing policy changed after this request was created.',
+ decidedAt: new Date(),
+ updatedAt: new Date(),
+ })
+ .where(eq(permissionAccessRequest.id, pending.id))
+ .returning()
+ await enqueueOutboxEvent(executor, PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, {
+ requestId: pending.id,
+ })
+ if (policy.state === 'allowed')
+ return { request: await presentAccessRequest(executor, closed), changed: true }
+ closedRequest = await presentAccessRequest(executor, closed)
+ }
+ if (policy.state !== 'requestable')
+ throw new OrchestrationError(
+ 'conflict',
+ policy.reason ?? 'You already have access to this item'
+ )
+ const [outstanding] = await executor
+ .select({ total: count() })
+ .from(permissionAccessRequest)
+ .where(
+ and(
+ eq(permissionAccessRequest.organizationId, organizationId),
+ eq(permissionAccessRequest.requesterId, principal.userId),
+ eq(permissionAccessRequest.status, 'pending')
+ )
+ )
+ if ((outstanding?.total ?? 0) >= 100)
+ throw new OrchestrationError(
+ 'conflict',
+ 'You have 100 pending requests. Cancel an existing request before sending another.'
+ )
+ const [daily] = await executor
+ .select({ total: count() })
+ .from(permissionAccessRequest)
+ .where(
+ and(
+ eq(permissionAccessRequest.organizationId, organizationId),
+ eq(permissionAccessRequest.requesterId, principal.userId),
+ gte(permissionAccessRequest.createdAt, new Date(Date.now() - 86_400_000))
+ )
+ )
+ if ((daily?.total ?? 0) >= 25)
+ throw new OrchestrationError(
+ 'conflict',
+ 'You have sent the maximum of 25 requests today. Try again tomorrow.'
+ )
+ const [row] = await executor
+ .insert(permissionAccessRequest)
+ .values({
+ id: generateId(),
+ organizationId,
+ requesterId: principal.userId,
+ workspaceId: requestWorkspaceId,
+ scopeKey,
+ targetKey,
+ target,
+ targetLabel: describeAccessRequestTarget(target, catalog)!.label,
+ membershipId: requestMembershipId,
+ groupId: policy.group?.permissionGroupId ?? null,
+ groupName: policy.group?.groupName ?? null,
+ reason: input.reason ?? '',
+ })
+ .returning()
+ await enqueueOutboxEvent(executor, PERMISSION_ACCESS_REQUEST_CREATED_EVENT, {
+ requestId: row.id,
+ })
+ return { request: await presentAccessRequest(executor, row), changed: true, closedRequest }
+ },
+ projectAudit: ({ result }) =>
+ result.changed
+ ? [
+ ...(result.closedRequest
+ ? [
+ {
+ action: AuditAction.PERMISSION_ACCESS_REQUEST_CLOSED,
+ resourceType: AuditResourceType.PERMISSION_ACCESS_REQUEST,
+ resourceId: result.closedRequest.id,
+ metadata: { target: result.closedRequest.target },
+ },
+ ]
+ : []),
+ {
+ action:
+ result.request.status === 'closed'
+ ? AuditAction.PERMISSION_ACCESS_REQUEST_CLOSED
+ : AuditAction.PERMISSION_ACCESS_REQUEST_CREATED,
+ resourceType: AuditResourceType.PERMISSION_ACCESS_REQUEST,
+ resourceId: result.request.id,
+ metadata: { target: result.request.target },
+ },
+ ]
+ : [],
+})
+
+interface ListMineInput {
+ requestId?: string
+ scope: AccessRequestScope
+ limit: number
+ offset: number
+}
+export const listMyAccessRequests = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.listMine,
+ scope: (input: ListMineInput) => input.scope,
+ async execute({ principal, input, context, executor }) {
+ if (!context.organizationId) return { requests: [], total: 0, hasMore: false }
+ return listAccessRequestRecords(
+ executor,
+ and(
+ eq(permissionAccessRequest.organizationId, context.organizationId),
+ eq(permissionAccessRequest.requesterId, principal.userId),
+ input.requestId ? eq(permissionAccessRequest.id, input.requestId) : undefined,
+ or(
+ eq(permissionAccessRequest.scopeKey, accessRequestScopeKey(input.scope)),
+ eq(permissionAccessRequest.scopeKey, memberLimitScopeKey(context.organizationId))
+ )
+ )!,
+ input.limit,
+ input.offset
+ )
+ },
+})
+
+interface CancelInput {
+ scope: AccessRequestScope
+ requestId: string
+}
+export const cancelAccessRequest = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.cancel,
+ scope: (input: CancelInput) => input.scope,
+ mutation: true,
+ async execute({ principal, input, context, executor }): Promise {
+ const row = await loadStoredAccessRequest(
+ executor,
+ requireOrganization(context.organizationId),
+ input.requestId,
+ true
+ )
+ if (
+ row.requesterId !== principal.userId ||
+ (row.scopeKey !== accessRequestScopeKey(input.scope) &&
+ row.scopeKey !== memberLimitScopeKey(row.organizationId))
+ )
+ throw new OrchestrationError('not_found', 'Access request not found')
+ if (row.status !== 'pending')
+ return { request: await presentAccessRequest(executor, row), changed: false }
+ const [updated] = await executor
+ .update(permissionAccessRequest)
+ .set({
+ status: 'cancelled',
+ decidedBy: principal.userId,
+ decidedAt: new Date(),
+ updatedAt: new Date(),
+ })
+ .where(eq(permissionAccessRequest.id, row.id))
+ .returning()
+ await enqueueOutboxEvent(executor, PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, {
+ requestId: row.id,
+ })
+ return { request: await presentAccessRequest(executor, updated), changed: true }
+ },
+ projectAudit: ({ result }) =>
+ result.changed
+ ? [
+ {
+ action: AuditAction.PERMISSION_ACCESS_REQUEST_CANCELLED,
+ resourceType: AuditResourceType.PERMISSION_ACCESS_REQUEST,
+ resourceId: result.request.id,
+ },
+ ]
+ : [],
+})
+
+interface OrganizationInput {
+ organizationId: string
+}
+interface OrganizationListInput extends OrganizationInput {
+ limit: number
+ offset: number
+ status?: AccessRequestStatus
+}
+const organizationScope = (input: OrganizationInput): AccessRequestScope => ({
+ kind: 'organization',
+ organizationId: input.organizationId,
+})
+
+export const listOrganizationAccessRequests = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.listOrganization,
+ scope: (input: OrganizationListInput) => organizationScope(input),
+ execute: ({ input, executor }) =>
+ listAccessRequestRecords(
+ executor,
+ and(
+ eq(permissionAccessRequest.organizationId, input.organizationId),
+ input.status ? eq(permissionAccessRequest.status, input.status) : undefined
+ )!,
+ input.limit,
+ input.offset
+ ),
+})
+
+export const getAccessRequestSettings = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.getSettings,
+ scope: organizationScope,
+ execute: ({ input, executor }) => readAccessRequestSettings(input.organizationId, executor),
+})
+
+interface UpdateSettingsInput extends OrganizationInput, AccessRequestSettings {}
+export const updateAccessRequestSettings = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.updateSettings,
+ scope: (input: UpdateSettingsInput) => organizationScope(input),
+ mutation: true,
+ async execute({ principal, input, executor }): Promise {
+ await executor
+ .insert(organizationAccessRequestSettings)
+ .values({
+ organizationId: input.organizationId,
+ allowRequests: input.allowRequests,
+ updatedBy: principal.userId,
+ })
+ .onConflictDoUpdate({
+ target: organizationAccessRequestSettings.organizationId,
+ set: {
+ allowRequests: input.allowRequests,
+ updatedBy: principal.userId,
+ updatedAt: new Date(),
+ },
+ })
+ return { allowRequests: input.allowRequests }
+ },
+ projectAudit: ({ input }) => [
+ {
+ action: AuditAction.PERMISSION_ACCESS_REQUEST_SETTINGS_CHANGED,
+ resourceType: AuditResourceType.PERMISSION_ACCESS_REQUEST,
+ resourceId: input.organizationId,
+ metadata: { allowRequests: input.allowRequests },
+ },
+ ],
+})
diff --git a/apps/sim/lib/permission-access-requests/application/review.test.ts b/apps/sim/lib/permission-access-requests/application/review.test.ts
new file mode 100644
index 00000000000..7bbc7e830ae
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/application/review.test.ts
@@ -0,0 +1,526 @@
+/**
+ * @vitest-environment node
+ */
+import { db } from '@sim/db'
+import {
+ organizationMemberUsageLimit,
+ permissionAccessRequest,
+ permissionGroup,
+ workspace,
+} from '@sim/db/schema'
+import { dbChainMockFns, queueTableRows, resetDbChainMock } from '@sim/testing'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+import type { AccessRequestRecord, AccessRequestTarget } from '@/lib/api/contracts/access-requests'
+import type { StoredAccessRequest } from '@/lib/permission-access-requests/repository'
+import { createAccessRequestCatalog } from '@/lib/permission-groups/access-requests/targets'
+import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields'
+
+const mocks = vi.hoisted(() => ({
+ authorize: vi.fn(),
+ membership: vi.fn(),
+ organizationLock: vi.fn(),
+ groupLock: vi.fn(),
+ audit: vi.fn(),
+ outbox: vi.fn(),
+ enabled: vi.fn(),
+ featureEnabled: vi.fn(),
+ enterprise: vi.fn(),
+ catalog: vi.fn(),
+ deploymentReason: vi.fn(),
+ group: vi.fn(),
+ impact: vi.fn(),
+ present: vi.fn(),
+ stored: vi.fn(),
+ setLimit: vi.fn(),
+}))
+
+vi.mock('@/lib/permission-access-requests/application/authorization', () => ({
+ authorizeAccessRequestScope: mocks.authorize,
+ loadAccessRequestMembership: mocks.membership,
+}))
+vi.mock('@/lib/billing/organizations/membership', () => ({
+ acquireOrganizationMutationLock: mocks.organizationLock,
+}))
+vi.mock('@/lib/core/application/authorized-workspace-use-case', () => ({
+ recordProjectedUseCaseAuditEntries: mocks.audit,
+}))
+vi.mock('@/lib/core/outbox/service', () => ({ enqueueOutboxEvent: mocks.outbox }))
+vi.mock('@/lib/permission-groups/locks', () => ({ acquirePermissionGroupOrgLock: mocks.groupLock }))
+vi.mock('@/lib/permission-access-requests/settings', () => ({
+ isAccessRequestEnabled: mocks.enabled,
+}))
+vi.mock('@/lib/core/config/feature-flags', () => ({ isFeatureEnabled: mocks.featureEnabled }))
+vi.mock('@/lib/core/config/env-flags', () => ({ isHosted: true, isAccessControlEnabled: true }))
+vi.mock('@/lib/billing/core/subscription', () => ({
+ isOrganizationOnEnterprisePlan: mocks.enterprise,
+}))
+vi.mock('@/lib/permission-access-requests/catalog', () => ({
+ loadAccessRequestCatalog: mocks.catalog,
+ getAccessRequestDeploymentUnavailableReason: mocks.deploymentReason,
+}))
+vi.mock('@/lib/permission-groups/resolve.server', () => ({
+ resolveWorkspaceGroup: mocks.group,
+ resolveDefaultGroup: mocks.group,
+}))
+vi.mock('@/lib/permission-access-requests/impact', () => ({
+ loadAccessRequestGroupImpact: mocks.impact,
+}))
+vi.mock('@/lib/permission-access-requests/repository', () => ({
+ presentAccessRequest: mocks.present,
+ loadStoredAccessRequest: mocks.stored,
+}))
+vi.mock('@/lib/billing/organizations/member-limits', () => ({
+ setOrgMemberUsageLimit: mocks.setLimit,
+}))
+
+import {
+ previewAccessRequest,
+ resolveAccessRequest,
+} from '@/lib/permission-access-requests/application/review'
+import { PERMISSION_ACCESS_REQUEST_DECIDED_EVENT } from '@/lib/permission-access-requests/notification-events'
+
+const principal = { kind: 'session', userId: 'admin', sessionId: 'session' } as const
+const input = { organizationId: 'organization', requestId: 'request' }
+const target = { kind: 'model', id: 'gpt-example' } as const
+const catalog = createAccessRequestCatalog({
+ integrations: [],
+ providers: [{ id: 'openai', label: 'OpenAI' }],
+ models: [{ id: 'gpt-example', label: 'Example model', providerId: 'openai' }],
+ tools: [],
+ knowledgeConnectors: [],
+})
+const group = {
+ permissionGroupId: 'group',
+ groupName: 'Restricted group',
+ resolution: 'explicit-member',
+ config: {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ allowedModelProviders: [],
+ deniedModels: ['gpt-example', 'keep-denied'],
+ hideTablesTab: true,
+ },
+}
+const impact = {
+ memberCount: 12,
+ workspaceCount: 2,
+ workspaceNames: ['One', 'Two'],
+ truncated: false,
+}
+
+function stored(overrides: Partial = {}): StoredAccessRequest {
+ return {
+ id: 'request',
+ organizationId: 'organization',
+ requesterId: 'requester',
+ workspaceId: 'workspace',
+ scopeKey: 'workspace:workspace',
+ targetKey: 'model:gpt-example',
+ target,
+ targetLabel: 'Example model',
+ membershipId: 'membership',
+ groupId: 'group',
+ groupName: 'Restricted group',
+ reason: '',
+ status: 'pending',
+ decisionReason: null,
+ decidedBy: null,
+ decision: null,
+ createdAt: new Date('2026-09-01T00:00:00Z'),
+ updatedAt: new Date('2026-09-01T00:00:00Z'),
+ decidedAt: null,
+ ...overrides,
+ }
+}
+
+function record(row: StoredAccessRequest): AccessRequestRecord {
+ return {
+ id: row.id,
+ organizationId: row.organizationId,
+ workspaceId: row.workspaceId,
+ target: row.target as AccessRequestTarget,
+ targetLabel: row.targetLabel,
+ reason: row.reason,
+ status: row.status,
+ decisionReason: row.decisionReason,
+ createdAt: row.createdAt.toISOString(),
+ decidedAt: row.decidedAt?.toISOString() ?? null,
+ groupName: row.groupName,
+ requester: { id: row.requesterId, name: 'Requester', email: 'requester@example.com' },
+ }
+}
+
+function queueWorkspace() {
+ queueTableRows(workspace, [{ organizationId: 'organization', allowPersonalApiKeys: true }])
+}
+
+function queueLimit(credits: number) {
+ const row = { usageLimit: String(credits / 200), updatedAt: new Date('2026-09-01T00:00:00Z') }
+ queueTableRows(organizationMemberUsageLimit, [row])
+ queueTableRows(organizationMemberUsageLimit, [row])
+}
+
+async function preview() {
+ queueWorkspace()
+ return previewAccessRequest.execute({ principal, input })
+}
+
+beforeEach(() => {
+ vi.resetAllMocks()
+ resetDbChainMock()
+ mocks.authorize.mockResolvedValue({
+ organizationId: 'organization',
+ workspaceId: null,
+ membershipId: 'admin-membership',
+ role: 'admin',
+ })
+ mocks.membership.mockResolvedValue({ membershipId: 'membership', role: 'read' })
+ mocks.enabled.mockResolvedValue(true)
+ mocks.featureEnabled.mockResolvedValue(true)
+ mocks.enterprise.mockResolvedValue(true)
+ mocks.catalog.mockResolvedValue(catalog)
+ mocks.deploymentReason.mockReturnValue(null)
+ mocks.group.mockResolvedValue(group)
+ mocks.impact.mockResolvedValue({ impact, revision: 'cohort-v1' })
+ mocks.stored.mockResolvedValue(stored())
+ mocks.present.mockImplementation((_executor, row: StoredAccessRequest) => record(row))
+})
+
+describe('permission request review', () => {
+ it('shows the provider expansion, exact model removal, and affected scope together', async () => {
+ const result = await preview()
+ expect(result).toMatchObject({
+ canApply: true,
+ resolutionKind: 'permission',
+ group: { id: 'group' },
+ impact,
+ })
+ expect(result.changes).toEqual([
+ expect.objectContaining({
+ configKey: 'allowedModelProviders',
+ before: [],
+ after: ['openai'],
+ }),
+ expect.objectContaining({
+ configKey: 'deniedModels',
+ before: ['gpt-example', 'keep-denied'],
+ after: ['keep-denied'],
+ }),
+ ])
+ })
+
+ it('rechecks enterprise entitlement after admission on the transaction executor', async () => {
+ const before = await preview()
+ mocks.enterprise.mockResolvedValueOnce(true).mockResolvedValueOnce(false)
+ queueWorkspace()
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: {
+ ...input,
+ decision: { action: 'apply', expectedFingerprint: before.fingerprint },
+ },
+ })
+ ).rejects.toThrow('Permission groups are unavailable')
+ expect(mocks.enterprise).toHaveBeenLastCalledWith('organization', 'return-false', db)
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('preserves valid legacy policy values and long names in fulfilled snapshots', async () => {
+ const longName = 'x'.repeat(600)
+ mocks.group.mockResolvedValue({
+ ...group,
+ groupName: longName,
+ config: {
+ ...group.config,
+ deniedModels: [
+ target.id,
+ ...Array.from({ length: 10_001 }, (_, index) => `${longName}${index}`),
+ ],
+ },
+ })
+ mocks.impact.mockResolvedValue({
+ impact: { ...impact, workspaceNames: [longName] },
+ revision: 'large-policy',
+ })
+ const before = await preview()
+ queueWorkspace()
+ dbChainMockFns.returning.mockResolvedValueOnce([stored({ status: 'fulfilled' })])
+ const result = await resolveAccessRequest.execute({
+ principal,
+ input: {
+ ...input,
+ decision: { action: 'apply', expectedFingerprint: before.fingerprint },
+ },
+ })
+ const decision = 'decision' in result ? result.decision : undefined
+ expect(
+ decision?.changes.find((change) => change.configKey === 'deniedModels')?.after
+ ).toHaveLength(10_001)
+ mocks.stored.mockResolvedValue(stored({ status: 'fulfilled', decision }))
+ const history = await previewAccessRequest.execute({ principal, input })
+ expect(history.impact.workspaceNames).toEqual([longName])
+ expect(history.group?.name).toBe(longName)
+ })
+
+ it('rejects a stale preview when either policy or audience changes', async () => {
+ const before = await preview()
+ mocks.impact.mockResolvedValue({ impact, revision: 'cohort-v2' })
+ queueWorkspace()
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'apply', expectedFingerprint: before.fingerprint } },
+ })
+ ).rejects.toThrow('Review the updated preview')
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('refuses an approval after the requester moves into another governing group', async () => {
+ const before = await preview()
+ mocks.group.mockResolvedValue({ ...group, permissionGroupId: 'replacement-group' })
+ queueWorkspace()
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'apply', expectedFingerprint: before.fingerprint } },
+ })
+ ).rejects.toThrow('governing permission group changed')
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ })
+
+ it('requires a fresh preview when catalog parent rules change the proposed patch', async () => {
+ const before = await preview()
+ mocks.catalog.mockResolvedValue(
+ createAccessRequestCatalog({
+ integrations: [],
+ providers: [{ id: 'replacement-provider', label: 'Replacement provider' }],
+ models: [{ id: 'gpt-example', label: 'Example model', providerId: 'replacement-provider' }],
+ tools: [],
+ knowledgeConnectors: [],
+ })
+ )
+ queueWorkspace()
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'apply', expectedFingerprint: before.fingerprint } },
+ })
+ ).rejects.toThrow('Review the updated preview')
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('refuses an approval after the requester leaves and rejoins', async () => {
+ const before = await preview()
+ mocks.membership.mockResolvedValue({ membershipId: 'new-membership', role: 'read' })
+ queueWorkspace()
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'apply', expectedFingerprint: before.fingerprint } },
+ })
+ ).rejects.toThrow('membership changed')
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+
+ it('rejects a newly imposed deployment ceiling before writing a group policy', async () => {
+ const before = await preview()
+ mocks.deploymentReason.mockReturnValue('Disabled by this deployment.')
+ queueWorkspace()
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'apply', expectedFingerprint: before.fingerprint } },
+ })
+ ).rejects.toThrow('Disabled by this deployment')
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ })
+
+ it('applies the complete group patch, durable decision, and outbox with one executor', async () => {
+ const before = await preview()
+ queueWorkspace()
+ dbChainMockFns.returning.mockResolvedValueOnce([stored({ status: 'fulfilled' })])
+ const result = await resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'apply', expectedFingerprint: before.fingerprint } },
+ })
+ expect(result.request.status).toBe('fulfilled')
+ expect(dbChainMockFns.transaction).toHaveBeenCalledOnce()
+ expect(dbChainMockFns.update.mock.calls.map(([table]) => table)).toEqual([
+ permissionGroup,
+ permissionAccessRequest,
+ ])
+ expect(dbChainMockFns.set).toHaveBeenCalledWith(
+ expect.objectContaining({
+ config: {
+ ...group.config,
+ allowedModelProviders: ['openai'],
+ deniedModels: ['keep-denied'],
+ },
+ })
+ )
+ expect(dbChainMockFns.set).toHaveBeenCalledWith(
+ expect.objectContaining({
+ status: 'fulfilled',
+ decision: expect.objectContaining({
+ changes: before.changes,
+ impact,
+ group: { id: 'group', name: 'Restricted group' },
+ }),
+ })
+ )
+ expect(mocks.membership).toHaveBeenLastCalledWith(
+ db,
+ 'requester',
+ { kind: 'workspace', workspaceId: 'workspace' },
+ 'organization',
+ true
+ )
+ expect(mocks.outbox).toHaveBeenCalledWith(db, PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, {
+ requestId: 'request',
+ })
+ expect(mocks.setLimit).not.toHaveBeenCalled()
+ })
+
+ it('blocks approval while requests are disabled but still permits an explicit decline', async () => {
+ const before = await preview()
+ mocks.enabled.mockResolvedValue(false)
+ queueWorkspace()
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'apply', expectedFingerprint: before.fingerprint } },
+ })
+ ).rejects.toThrow('turned off')
+ dbChainMockFns.returning.mockResolvedValueOnce([
+ stored({ status: 'declined', decisionReason: 'Use the existing provider.' }),
+ ])
+ const result = await resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'decline', reason: 'Use the existing provider.' } },
+ })
+ expect(result.request.status).toBe('declined')
+ expect(dbChainMockFns.update).not.toHaveBeenCalledWith(permissionGroup)
+ expect(mocks.outbox).toHaveBeenCalledOnce()
+ })
+
+ it('does not apply or notify a second time after resolution', async () => {
+ mocks.stored.mockResolvedValue(stored({ status: 'fulfilled' }))
+ const result = await resolveAccessRequest.execute({
+ principal,
+ input: { ...input, decision: { action: 'apply', expectedFingerprint: 'obsolete' } },
+ })
+ expect(result.changed).toBe(false)
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ expect(mocks.catalog).not.toHaveBeenCalled()
+ })
+
+ it('reads fulfilled history from its stored decision without rebuilding the catalog', async () => {
+ const decision = {
+ resolutionKind: 'permission',
+ changes: [{ configKey: 'hideTablesTab', label: 'Tables', before: true, after: false }],
+ impact,
+ group: { id: 'original-group', name: 'Original group' },
+ currentLimitCredits: null,
+ newLimitCredits: null,
+ fingerprint: 'original-preview',
+ }
+ mocks.stored.mockResolvedValue(stored({ status: 'fulfilled', decision }))
+ const result = await previewAccessRequest.execute({ principal, input })
+ expect(result).toMatchObject({ ...decision, canApply: false })
+ expect(mocks.catalog).not.toHaveBeenCalled()
+ expect(mocks.membership).not.toHaveBeenCalled()
+ expect(mocks.group).not.toHaveBeenCalled()
+ })
+})
+
+describe('member limit review', () => {
+ beforeEach(() => {
+ mocks.stored.mockResolvedValue(
+ stored({
+ workspaceId: null,
+ target: { kind: 'usage_limit', id: 'member' },
+ targetKey: 'usage_limit:member',
+ scopeKey: 'organization:organization:member-limit',
+ groupId: null,
+ groupName: null,
+ })
+ )
+ })
+
+ it.each([undefined, 2000, 1999, 2000.5])(
+ 'requires a whole-number limit greater than the current value (%s)',
+ async (newLimitCredits) => {
+ queueLimit(2000)
+ const before = await previewAccessRequest.execute({ principal, input })
+ queueLimit(2000)
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: {
+ ...input,
+ decision: { action: 'apply', expectedFingerprint: before.fingerprint, newLimitCredits },
+ },
+ })
+ ).rejects.toThrow('greater than the current limit')
+ expect(mocks.setLimit).not.toHaveBeenCalled()
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ }
+ )
+
+ it('changes the requester cap in stored dollars without changing group policy', async () => {
+ queueLimit(2000)
+ const before = await previewAccessRequest.execute({ principal, input })
+ expect(before).toMatchObject({
+ resolutionKind: 'usage_limit',
+ group: null,
+ currentLimitCredits: 2000,
+ canApply: true,
+ })
+ queueLimit(2000)
+ dbChainMockFns.returning.mockResolvedValueOnce([
+ stored({ status: 'fulfilled', target: { kind: 'usage_limit', id: 'member' } }),
+ ])
+ await resolveAccessRequest.execute({
+ principal,
+ input: {
+ ...input,
+ decision: {
+ action: 'apply',
+ expectedFingerprint: before.fingerprint,
+ newLimitCredits: 3000,
+ },
+ },
+ })
+ expect(mocks.setLimit).toHaveBeenCalledWith('organization', 'requester', 15, 'admin', db)
+ expect(dbChainMockFns.update).not.toHaveBeenCalledWith(permissionGroup)
+ expect(mocks.outbox).toHaveBeenCalledWith(db, PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, {
+ requestId: 'request',
+ })
+ })
+
+ it('requires another review if the current cap changes after preview', async () => {
+ queueLimit(2000)
+ const before = await previewAccessRequest.execute({ principal, input })
+ queueLimit(2500)
+ await expect(
+ resolveAccessRequest.execute({
+ principal,
+ input: {
+ ...input,
+ decision: {
+ action: 'apply',
+ expectedFingerprint: before.fingerprint,
+ newLimitCredits: 3000,
+ },
+ },
+ })
+ ).rejects.toThrow('Review the updated preview')
+ expect(mocks.setLimit).not.toHaveBeenCalled()
+ expect(mocks.outbox).not.toHaveBeenCalled()
+ })
+})
diff --git a/apps/sim/lib/permission-access-requests/application/review.ts b/apps/sim/lib/permission-access-requests/application/review.ts
new file mode 100644
index 00000000000..9f349d0e1fd
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/application/review.ts
@@ -0,0 +1,397 @@
+import { createHash } from 'node:crypto'
+import { AuditAction, AuditResourceType } from '@sim/audit'
+import { db } from '@sim/db'
+import { permissionAccessRequest, permissionGroup, workspace } from '@sim/db/schema'
+import { and, eq, isNull } from 'drizzle-orm'
+import { creditsToDollars } from '@/lib/billing/credits/conversion'
+import { setOrgMemberUsageLimit } from '@/lib/billing/organizations/member-limits'
+import type { WorkspaceUseCaseAuditEntry } from '@/lib/core/application/authorized-workspace-use-case'
+import { OrchestrationError } from '@/lib/core/orchestration/types'
+import { enqueueOutboxEvent } from '@/lib/core/outbox/service'
+import type { DbOrTx } from '@/lib/db/types'
+import { loadAccessRequestMembership } from '@/lib/permission-access-requests/application/authorization'
+import { defineAuthorizedAccessRequestUseCase } from '@/lib/permission-access-requests/application/authorized-use-case'
+import { accessRequestOperations } from '@/lib/permission-access-requests/application/operations'
+import {
+ type PreparedAccessRequestPolicy,
+ prepareAccessRequestPolicy,
+} from '@/lib/permission-access-requests/application/prepare'
+import { loadAccessRequestGroupImpact } from '@/lib/permission-access-requests/impact'
+import { PERMISSION_ACCESS_REQUEST_DECIDED_EVENT } from '@/lib/permission-access-requests/notification-events'
+import {
+ evaluateAccessRequestTarget,
+ loadAccessRequestPolicy,
+ loadMemberLimit,
+} from '@/lib/permission-access-requests/policy'
+import {
+ loadStoredAccessRequest,
+ presentAccessRequest,
+ type StoredAccessRequest,
+} from '@/lib/permission-access-requests/repository'
+import {
+ storedAccessRequestDecisionSchema,
+ storedAccessRequestTargetSchema,
+} from '@/lib/permission-access-requests/schemas'
+import { isAccessRequestEnabled } from '@/lib/permission-access-requests/settings'
+import type {
+ AccessRequestPreview,
+ ResolveAccessRequestDecision,
+} from '@/lib/permission-access-requests/types'
+import type { AccessRequestScope } from '@/lib/permission-groups/access-requests/targets'
+import { acquirePermissionGroupOrgLock } from '@/lib/permission-groups/locks'
+
+interface ReviewInput {
+ organizationId: string
+ requestId: string
+}
+interface ResolveInput extends ReviewInput {
+ decision: ResolveAccessRequestDecision
+}
+const organizationScope = (input: ReviewInput): AccessRequestScope => ({
+ kind: 'organization',
+ organizationId: input.organizationId,
+})
+
+/** Checks the requester's present scope before inspecting or modifying any governing policy. */
+async function loadReviewPreview(
+ executor: DbOrTx,
+ row: StoredAccessRequest,
+ prepared: PreparedAccessRequestPolicy | null,
+ forUpdate = false
+) {
+ const request = await presentAccessRequest(executor, row)
+ if (row.status === 'fulfilled' && row.decision) {
+ const snapshot = storedAccessRequestDecisionSchema.parse(row.decision)
+ const common = {
+ request,
+ changes: snapshot.changes,
+ impact: snapshot.impact,
+ fingerprint: snapshot.fingerprint,
+ canApply: false,
+ unavailableReason: 'This request has already been fulfilled.',
+ newLimitCredits: snapshot.newLimitCredits,
+ }
+ const preview: AccessRequestPreview =
+ snapshot.resolutionKind === 'usage_limit'
+ ? {
+ ...common,
+ resolutionKind: 'usage_limit',
+ group: null,
+ currentLimitCredits: snapshot.currentLimitCredits,
+ }
+ : {
+ ...common,
+ resolutionKind: 'permission',
+ group: snapshot.group,
+ currentLimitCredits: null,
+ }
+ return { preview, policy: null }
+ }
+ if (!prepared) throw new OrchestrationError('internal', 'Request preview preparation is missing')
+ const scope: AccessRequestScope = row.workspaceId
+ ? { kind: 'workspace', workspaceId: row.workspaceId }
+ : { kind: 'organization', organizationId: row.organizationId }
+ let canonicalWorkspaceValid = true
+ if (row.workspaceId) {
+ const query = executor
+ .select({
+ organizationId: workspace.organizationId,
+ allowPersonalApiKeys: workspace.allowPersonalApiKeys,
+ })
+ .from(workspace)
+ .where(and(eq(workspace.id, row.workspaceId), isNull(workspace.archivedAt)))
+ const [canonical] = forUpdate ? await query.for('update').limit(1) : await query.limit(1)
+ canonicalWorkspaceValid = Boolean(canonical && canonical.organizationId === row.organizationId)
+ }
+ const membership = canonicalWorkspaceValid
+ ? await loadAccessRequestMembership(
+ executor,
+ row.requesterId,
+ scope,
+ row.organizationId,
+ forUpdate
+ )
+ : null
+ const context = {
+ organizationId: row.organizationId,
+ workspaceId: row.workspaceId,
+ membershipId: membership?.membershipId ?? '',
+ role: membership?.role ?? ('read' as const),
+ }
+ if (forUpdate)
+ await acquirePermissionGroupOrgLock(executor, row.organizationId, {
+ lockTimeoutAlreadyBounded: true,
+ })
+ const catalog = prepared.catalog
+ const currentPolicy = await loadAccessRequestPolicy(
+ executor,
+ context,
+ row.requesterId,
+ prepared.entitled
+ )
+ const target = storedAccessRequestTargetSchema.parse(row.target)
+ const policy = await evaluateAccessRequestTarget(
+ executor,
+ context,
+ row.requesterId,
+ scope,
+ target,
+ catalog,
+ currentPolicy
+ )
+ const enabled = await isAccessRequestEnabled(row.organizationId, executor, prepared.globalEnabled)
+ const audience = policy.group
+ ? await loadAccessRequestGroupImpact(
+ executor,
+ row.organizationId,
+ policy.group.permissionGroupId
+ )
+ : {
+ impact: {
+ memberCount: 1,
+ workspaceCount: row.workspaceId ? 1 : 0,
+ workspaceNames: [],
+ truncated: false,
+ },
+ revision: '',
+ }
+ const limit =
+ target.kind === 'usage_limit'
+ ? await loadMemberLimit(executor, row.organizationId, row.requesterId, forUpdate)
+ : null
+ const unavailableReason =
+ row.status !== 'pending'
+ ? 'This request has already been resolved.'
+ : !enabled
+ ? 'Access requests are turned off for this organization.'
+ : !membership || membership.membershipId !== row.membershipId
+ ? 'The requester’s membership changed. Ask them to send a new request.'
+ : policy.state === 'unavailable'
+ ? policy.reason
+ : target.kind !== 'usage_limit' && policy.group?.permissionGroupId !== row.groupId
+ ? 'The governing permission group changed. Ask the requester to send a new request.'
+ : target.kind === 'usage_limit' && !limit
+ ? 'The requester no longer has a member credit cap.'
+ : null
+ const fingerprint = createHash('sha256')
+ .update(
+ JSON.stringify({
+ requestId: row.id,
+ status: row.status,
+ target,
+ membership: membership?.membershipId,
+ role: membership?.role,
+ groupId: policy.group?.permissionGroupId,
+ config: policy.group?.config,
+ changes: policy.delta?.changes,
+ audience: audience.revision,
+ limit,
+ enabled,
+ unavailableReason,
+ })
+ )
+ .digest('hex')
+ const common = {
+ newLimitCredits: null,
+ request,
+ changes: policy.delta?.changes ?? [],
+ impact: audience.impact,
+ fingerprint,
+ canApply: !unavailableReason,
+ unavailableReason,
+ }
+ const preview: AccessRequestPreview =
+ target.kind === 'usage_limit'
+ ? {
+ ...common,
+ resolutionKind: 'usage_limit',
+ group: null,
+ currentLimitCredits: limit?.credits ?? null,
+ }
+ : {
+ ...common,
+ resolutionKind: 'permission',
+ group: policy.group
+ ? { id: policy.group.permissionGroupId, name: policy.group.groupName }
+ : null,
+ currentLimitCredits: null,
+ }
+ return { preview, policy }
+}
+
+export const previewAccessRequest = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.preview,
+ scope: organizationScope,
+ prepare: async ({ input }) => {
+ const row = await loadStoredAccessRequest(db, input.organizationId, input.requestId)
+ if (row.status === 'fulfilled' && row.decision) return null
+ return prepareAccessRequestPolicy(
+ row,
+ row.requesterId,
+ storedAccessRequestTargetSchema.parse(row.target).kind
+ )
+ },
+ async execute({ input, executor, prepared }) {
+ const row = await loadStoredAccessRequest(executor, input.organizationId, input.requestId)
+ return (await loadReviewPreview(executor, row, prepared)).preview
+ },
+})
+
+export const resolveAccessRequest = defineAuthorizedAccessRequestUseCase({
+ operation: accessRequestOperations.resolve,
+ scope: (input: ResolveInput) => organizationScope(input),
+ mutation: true,
+ prepare: async ({ input }) => {
+ if (input.decision.action === 'decline') return null
+ const row = await loadStoredAccessRequest(db, input.organizationId, input.requestId)
+ if (row.status !== 'pending') return null
+ return prepareAccessRequestPolicy(
+ row,
+ row.requesterId,
+ storedAccessRequestTargetSchema.parse(row.target).kind
+ )
+ },
+ async execute({ principal, input, executor, prepared }) {
+ const row = await loadStoredAccessRequest(executor, input.organizationId, input.requestId, true)
+ if (row.status !== 'pending')
+ return { request: await presentAccessRequest(executor, row), changed: false }
+ const now = new Date()
+ if (input.decision.action === 'decline') {
+ const [updated] = await executor
+ .update(permissionAccessRequest)
+ .set({
+ status: 'declined',
+ decisionReason: input.decision.reason,
+ decidedBy: principal.userId,
+ decidedAt: now,
+ updatedAt: now,
+ })
+ .where(eq(permissionAccessRequest.id, row.id))
+ .returning()
+ await enqueueOutboxEvent(executor, PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, {
+ requestId: row.id,
+ })
+ return { request: await presentAccessRequest(executor, updated), changed: true }
+ }
+ if (!prepared)
+ throw new OrchestrationError('internal', 'Request preview preparation is missing')
+ const { preview, policy } = await loadReviewPreview(executor, row, prepared, true)
+ if (!preview.canApply)
+ throw new OrchestrationError(
+ 'conflict',
+ preview.unavailableReason ?? 'This request can no longer be fulfilled'
+ )
+ if (preview.fingerprint !== input.decision.expectedFingerprint)
+ throw new OrchestrationError(
+ 'conflict',
+ 'The policy or affected scope changed. Review the updated preview before applying.'
+ )
+ if (!policy) throw new OrchestrationError('conflict', 'This request has already been fulfilled')
+ const newLimitCredits = input.decision.newLimitCredits
+ if (preview.resolutionKind === 'usage_limit') {
+ if (
+ newLimitCredits === undefined ||
+ !Number.isSafeInteger(newLimitCredits) ||
+ newLimitCredits <= (preview.currentLimitCredits ?? 0)
+ )
+ throw new OrchestrationError(
+ 'validation',
+ 'Enter a whole-number credit limit greater than the current limit'
+ )
+ await setOrgMemberUsageLimit(
+ row.organizationId,
+ row.requesterId,
+ creditsToDollars(newLimitCredits),
+ principal.userId,
+ executor
+ )
+ } else {
+ if (newLimitCredits !== undefined)
+ throw new OrchestrationError(
+ 'validation',
+ 'A credit limit cannot be applied to a permission request'
+ )
+ if (!policy.group || !policy.delta)
+ throw new OrchestrationError(
+ 'conflict',
+ 'The governing permission group is no longer available'
+ )
+ if (policy.delta.changes.length)
+ await executor
+ .update(permissionGroup)
+ .set({ config: policy.delta.config, updatedAt: now })
+ .where(
+ and(
+ eq(permissionGroup.id, policy.group.permissionGroupId),
+ eq(permissionGroup.organizationId, row.organizationId)
+ )
+ )
+ }
+ const decision = storedAccessRequestDecisionSchema.parse({
+ resolutionKind: preview.resolutionKind,
+ changes: preview.changes,
+ impact: preview.impact,
+ group: preview.group,
+ currentLimitCredits: preview.currentLimitCredits,
+ newLimitCredits: newLimitCredits ?? null,
+ fingerprint: preview.fingerprint,
+ })
+ const [updated] = await executor
+ .update(permissionAccessRequest)
+ .set({
+ status: 'fulfilled',
+ decidedBy: principal.userId,
+ decidedAt: now,
+ updatedAt: now,
+ decision,
+ })
+ .where(eq(permissionAccessRequest.id, row.id))
+ .returning()
+ await enqueueOutboxEvent(executor, PERMISSION_ACCESS_REQUEST_DECIDED_EVENT, {
+ requestId: row.id,
+ })
+ return { request: await presentAccessRequest(executor, updated), changed: true, decision }
+ },
+ projectAudit: ({ result }) => {
+ if (!result.changed) return []
+ const decision = 'decision' in result ? result.decision : undefined
+ const entries: WorkspaceUseCaseAuditEntry[] = [
+ {
+ action:
+ result.request.status === 'fulfilled'
+ ? AuditAction.PERMISSION_ACCESS_REQUEST_FULFILLED
+ : AuditAction.PERMISSION_ACCESS_REQUEST_DECLINED,
+ resourceType: AuditResourceType.PERMISSION_ACCESS_REQUEST,
+ resourceId: result.request.id,
+ metadata: {
+ target: result.request.target,
+ requesterId: result.request.requester.id,
+ ...(decision ? { decision } : {}),
+ },
+ },
+ ]
+ if (decision?.resolutionKind === 'permission' && decision.group && decision.changes.length) {
+ entries.push({
+ action: AuditAction.PERMISSION_GROUP_UPDATED,
+ resourceType: AuditResourceType.PERMISSION_GROUP,
+ resourceId: decision.group.id,
+ resourceName: decision.group.name,
+ metadata: { requestId: result.request.id, changes: decision.changes },
+ })
+ }
+ if (decision?.resolutionKind === 'usage_limit') {
+ entries.push({
+ action: AuditAction.ORG_MEMBER_USAGE_LIMIT_CHANGED,
+ resourceType: AuditResourceType.ORGANIZATION,
+ resourceId: result.request.organizationId,
+ metadata: {
+ requestId: result.request.id,
+ userId: result.request.requester.id,
+ creditLimit: decision.newLimitCredits,
+ previousCreditLimit: decision.currentLimitCredits,
+ },
+ })
+ }
+ return entries
+ },
+})
diff --git a/apps/sim/lib/permission-access-requests/catalog-registry.ts b/apps/sim/lib/permission-access-requests/catalog-registry.ts
new file mode 100644
index 00000000000..c3678f3ae4a
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/catalog-registry.ts
@@ -0,0 +1,158 @@
+import { getBlockVisibility } from '@/lib/core/config/block-visibility'
+import { env } from '@/lib/core/config/env'
+import {
+ getAllowedIntegrationsFromEnv,
+ getBlacklistedProvidersFromEnv,
+ isHosted,
+} from '@/lib/core/config/env-flags'
+import { isOllamaUrlConfigured } from '@/lib/core/utils/urls'
+import { isScopedCredentialGroupsAvailable } from '@/lib/credential-groups/scoped-availability'
+import {
+ isIntegrationDeploymentAvailableForVisibility,
+ isOAuthServiceDeploymentAvailable,
+} from '@/lib/integrations/availability.server'
+import {
+ type AccessRequestCatalog,
+ type AccessRequestCatalogItem,
+ type AccessRequestModelItem,
+ type AccessRequestTarget,
+ type AccessRequestToolItem,
+ createAccessRequestCatalog,
+} from '@/lib/permission-groups/access-requests/targets'
+import {
+ resolveAccessControlBlockType,
+ toAccessControlAllowlist,
+} from '@/lib/permission-groups/integration-allowlist'
+import { getBlockRegistry } from '@/blocks/registry'
+import { isHiddenUnder } from '@/blocks/visibility/context'
+import { CONNECTOR_META_REGISTRY } from '@/connectors/registry'
+import { getStaticProviderModels, PROVIDER_DEFINITIONS } from '@/providers/models'
+import { filterBlacklistedModels } from '@/providers/utils'
+import { getToolMetadata } from '@/tools/metadata'
+
+export interface AccessRequestCatalogContext {
+ userId: string
+ organizationId: string
+ workspaceId: string | null
+}
+
+function isProviderDeploymentAvailable(providerId: string): boolean {
+ if (providerId === 'ollama') return !isHosted || isOllamaUrlConfigured()
+ if (providerId === 'vllm') return Boolean(env.VLLM_BASE_URL?.trim())
+ if (providerId === 'litellm') return Boolean(env.LITELLM_BASE_URL?.trim())
+ return true
+}
+
+/**
+ * Public, built-in choices available to an already-authorized viewer. No custom block, credential,
+ * sandbox, or tenant model names are read. The permission group is intentionally not applied here:
+ * callers compare it with this deployment ceiling to distinguish requestable restrictions.
+ */
+export async function loadAccessRequestRegistryCatalog(
+ context: AccessRequestCatalogContext,
+ targetKind?: AccessRequestTarget['kind']
+): Promise {
+ const needsBlocks = !targetKind || targetKind === 'integration' || targetKind === 'tool'
+ const needsTools = !targetKind || targetKind === 'tool'
+ const [visibility, credentialGroupsAvailable] = needsBlocks
+ ? await Promise.all([
+ getBlockVisibility({
+ userId: context.userId,
+ orgId: context.organizationId,
+ workspaceId: context.workspaceId,
+ }),
+ isScopedCredentialGroupsAvailable({
+ kind: 'organization',
+ organizationId: context.organizationId,
+ }),
+ ])
+ : [null, false]
+ const allowedIntegrations = toAccessControlAllowlist(getAllowedIntegrationsFromEnv())
+ const integrations: AccessRequestCatalogItem[] = []
+ const tools = new Map()
+ const ambiguousTools = new Set()
+
+ if (needsBlocks) {
+ for (const item of [
+ { id: 'loop', label: 'Loop' },
+ { id: 'parallel', label: 'Parallel' },
+ ]) {
+ if (allowedIntegrations === null || allowedIntegrations.has(item.id)) integrations.push(item)
+ }
+ }
+
+ for (const block of needsBlocks ? Object.values(getBlockRegistry()) : []) {
+ if (
+ block.type.startsWith('custom_block_') ||
+ block.type === 'start_trigger' ||
+ block.hideFromToolbar ||
+ (visibility && isHiddenUnder(visibility, block)) ||
+ resolveAccessControlBlockType(block.type) !== block.type ||
+ (block.type === 'credential_group' && !credentialGroupsAvailable) ||
+ (allowedIntegrations !== null && !allowedIntegrations.has(block.type)) ||
+ (visibility && !isIntegrationDeploymentAvailableForVisibility(block.type, visibility))
+ ) {
+ continue
+ }
+ integrations.push({ id: block.type, label: block.name })
+ for (const toolId of needsTools ? (block.tools?.access ?? []) : []) {
+ if (ambiguousTools.has(toolId)) continue
+ const existing = tools.get(toolId)
+ if (existing && existing.integrationId !== block.type) {
+ tools.delete(toolId)
+ ambiguousTools.add(toolId)
+ continue
+ }
+ const metadata = getToolMetadata(toolId)
+ if (!metadata) continue
+ tools.set(toolId, {
+ id: toolId,
+ label: `${block.name}: ${metadata.name || toolId}`,
+ integrationId: block.type,
+ })
+ }
+ }
+
+ const blacklistedProviders = new Set(getBlacklistedProvidersFromEnv())
+ const providers: AccessRequestCatalogItem[] = []
+ const models: AccessRequestModelItem[] = []
+ for (const provider of !targetKind || targetKind === 'provider' || targetKind === 'model'
+ ? Object.values(PROVIDER_DEFINITIONS)
+ : []) {
+ if (
+ blacklistedProviders.has(provider.id.toLowerCase()) ||
+ !isProviderDeploymentAvailable(provider.id)
+ ) {
+ continue
+ }
+ providers.push({ id: provider.id, label: provider.name })
+ if (targetKind === 'provider') continue
+ const availableModelIds = filterBlacklistedModels(
+ getStaticProviderModels(provider.id)
+ .filter((model) => model.sunset?.status !== 'deprecated')
+ .map((model) => model.id)
+ )
+ for (const id of availableModelIds) models.push({ id, label: id, providerId: provider.id })
+ }
+
+ const knowledgeConnectors = (
+ !targetKind || targetKind === 'knowledge_connector'
+ ? Object.values(CONNECTOR_META_REGISTRY)
+ : []
+ )
+ .filter(
+ (connector) =>
+ connector.auth.mode !== 'oauth' ||
+ Boolean(connector.auth.apiKey) ||
+ isOAuthServiceDeploymentAvailable(connector.auth.provider)
+ )
+ .map((connector) => ({ id: connector.id, label: connector.name }))
+
+ return createAccessRequestCatalog({
+ integrations,
+ providers,
+ models,
+ tools: [...tools.values()],
+ knowledgeConnectors,
+ })
+}
diff --git a/apps/sim/lib/permission-access-requests/catalog.test.ts b/apps/sim/lib/permission-access-requests/catalog.test.ts
new file mode 100644
index 00000000000..cb156e9300e
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/catalog.test.ts
@@ -0,0 +1,259 @@
+/**
+ * @vitest-environment node
+ */
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+
+const mocks = vi.hoisted(() => ({
+ blocks: vi.fn(),
+ visibility: vi.fn(),
+ credentialGroups: vi.fn(),
+ allowedIntegrations: vi.fn(),
+ blacklistedProviders: vi.fn(),
+ integrationAvailable: vi.fn(),
+ oauthAvailable: vi.fn(),
+ filterModels: vi.fn(),
+ toolMetadata: vi.fn(),
+}))
+
+vi.mock('@/blocks/registry', () => ({
+ getBlockRegistry: mocks.blocks,
+ getBlock: (id: string) => mocks.blocks()[id],
+}))
+vi.mock('@/lib/core/config/block-visibility', () => ({ getBlockVisibility: mocks.visibility }))
+vi.mock('@/lib/credential-groups/scoped-availability', () => ({
+ isScopedCredentialGroupsAvailable: mocks.credentialGroups,
+}))
+vi.mock('@/lib/core/config/env', () => ({ env: { VLLM_BASE_URL: '', LITELLM_BASE_URL: '' } }))
+vi.mock('@/lib/core/config/env-flags', () => ({
+ getAllowedIntegrationsFromEnv: mocks.allowedIntegrations,
+ getBlacklistedProvidersFromEnv: mocks.blacklistedProviders,
+ isHosted: true,
+ isChatEnabled: false,
+ isInboxEnabled: true,
+ isInvitationsDisabled: true,
+ isPublicApiDisabled: true,
+ isSandboxesEnabled: false,
+ isSsoEnabled: false,
+}))
+vi.mock('@/lib/core/utils/urls', () => ({ isOllamaUrlConfigured: () => false }))
+vi.mock('@/lib/integrations/availability.server', () => ({
+ isIntegrationDeploymentAvailableForVisibility: mocks.integrationAvailable,
+ isOAuthServiceDeploymentAvailable: mocks.oauthAvailable,
+}))
+vi.mock('@/providers/utils', () => ({ filterBlacklistedModels: mocks.filterModels }))
+vi.mock('@/tools/metadata', () => ({ getToolMetadata: mocks.toolMetadata }))
+vi.mock('@/providers/models', () => {
+ const publicModels = {
+ openai: [
+ { id: 'public-model' },
+ { id: 'blocked-model' },
+ { id: 'retired-model', sunset: { status: 'deprecated' } },
+ ],
+ fireworks: [{ id: 'fireworks/public-model' }],
+ }
+ return {
+ getStaticProviderModels: (providerId: string) =>
+ publicModels[providerId as keyof typeof publicModels] ?? [],
+ PROVIDER_DEFINITIONS: {
+ openai: { id: 'openai', name: 'OpenAI', models: publicModels.openai },
+ anthropic: { id: 'anthropic', name: 'Anthropic', models: [{ id: 'anthropic-model' }] },
+ ollama: { id: 'ollama', name: 'Ollama', models: [{ id: 'private-local' }] },
+ vllm: { id: 'vllm', name: 'vLLM', models: [] },
+ litellm: { id: 'litellm', name: 'LiteLLM', models: [] },
+ openrouter: {
+ id: 'openrouter',
+ name: 'OpenRouter',
+ models: [{ id: 'private-tenant-model' }],
+ },
+ fireworks: {
+ id: 'fireworks',
+ name: 'Fireworks',
+ models: [...publicModels.fireworks, { id: 'fireworks/private-model' }],
+ },
+ },
+ }
+})
+vi.mock('@/connectors/registry', () => ({
+ CONNECTOR_META_REGISTRY: {
+ available: {
+ id: 'available',
+ name: 'Available connector',
+ auth: { mode: 'oauth', provider: 'available' },
+ },
+ unavailable: {
+ id: 'unavailable',
+ name: 'Unavailable connector',
+ auth: { mode: 'oauth', provider: 'unavailable' },
+ },
+ token: { id: 'token', name: 'Token connector', auth: { mode: 'apiKey' } },
+ fallback: {
+ id: 'fallback',
+ name: 'Token fallback',
+ auth: { mode: 'oauth', provider: 'unavailable', apiKey: { label: 'Token' } },
+ },
+ },
+}))
+
+import {
+ getAccessRequestDeploymentUnavailableReason,
+ listAccessRequestTargets,
+ loadAccessRequestCatalog,
+} from '@/lib/permission-access-requests/catalog'
+import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access'
+
+const context = { userId: 'viewer', organizationId: 'org', workspaceId: 'ws' }
+
+describe('access request catalog deployment ceilings', () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ mocks.visibility.mockResolvedValue({
+ revealed: new Set(['revealed']),
+ disabled: new Set(['killed']),
+ previewTagged: new Set(),
+ })
+ mocks.credentialGroups.mockResolvedValue(false)
+ mocks.allowedIntegrations.mockReturnValue(null)
+ mocks.blacklistedProviders.mockReturnValue(['anthropic'])
+ mocks.integrationAvailable.mockImplementation((id: string) => id !== 'misconfigured')
+ mocks.oauthAvailable.mockImplementation((id: string) => id === 'available')
+ mocks.filterModels.mockImplementation((models: string[]) =>
+ models.filter((id) => id !== 'blocked-model')
+ )
+ mocks.toolMetadata.mockImplementation((id: string) =>
+ id === 'missing' ? undefined : { id, name: id }
+ )
+ mocks.blocks.mockReturnValue({
+ slack_v2: {
+ type: 'slack_v2',
+ name: 'Slack',
+ tools: { access: ['slack_send_message_v2', 'missing'] },
+ },
+ github_v2: { type: 'github_v2', name: 'GitHub', tools: { access: ['github_create_issue'] } },
+ github: {
+ type: 'github',
+ name: 'Retired GitHub',
+ tools: { access: ['retired_github_tool'] },
+ },
+ hidden: { type: 'hidden', name: 'Hidden', hideFromToolbar: true },
+ unrevealed: { type: 'unrevealed', name: 'Unrevealed', preview: true },
+ revealed: { type: 'revealed', name: 'Revealed', preview: true },
+ killed: { type: 'killed', name: 'Killed' },
+ misconfigured: { type: 'misconfigured', name: 'Misconfigured' },
+ credential_group: { type: 'credential_group', name: 'Credential Group' },
+ custom_block_private: { type: 'custom_block_private', name: 'Secret Customer Name' },
+ start_trigger: { type: 'start_trigger', name: 'Start' },
+ })
+ })
+
+ it('exposes only public visible and deployment-available block/tool metadata', async () => {
+ const catalog = await loadAccessRequestCatalog(context)
+ expect([...catalog.integrations.keys()]).toEqual([
+ 'loop',
+ 'parallel',
+ 'slack_v2',
+ 'github_v2',
+ 'revealed',
+ ])
+ expect([...catalog.tools.keys()]).toEqual(['slack_send_message_v2', 'github_create_issue'])
+ expect(mocks.visibility).toHaveBeenCalledWith({
+ userId: 'viewer',
+ orgId: 'org',
+ workspaceId: 'ws',
+ })
+ expect(JSON.stringify(listAccessRequestTargets(catalog))).not.toContain('private')
+ })
+
+ it.each(['feature', 'usage_limit', 'file_share_auth', 'chat_deploy_auth'] as const)(
+ 'keeps %s discovery independent of registry and visibility work',
+ async (kind) => {
+ const catalog = await loadAccessRequestCatalog(context, kind)
+ expect(catalog.integrations.size).toBe(0)
+ expect(mocks.visibility).not.toHaveBeenCalled()
+ expect(mocks.credentialGroups).not.toHaveBeenCalled()
+ expect(mocks.blocks).not.toHaveBeenCalled()
+ expect(mocks.toolMetadata).not.toHaveBeenCalled()
+ }
+ )
+
+ it('loads only the relevant catalog family', async () => {
+ const integrations = await loadAccessRequestCatalog(context, 'integration')
+ expect(integrations.integrations.size).toBeGreaterThan(0)
+ expect(integrations.providers.size).toBe(0)
+ expect(integrations.tools.size).toBe(0)
+ expect(mocks.toolMetadata).not.toHaveBeenCalled()
+ mocks.visibility.mockClear()
+ const models = await loadAccessRequestCatalog(context, 'model')
+ expect(models.models.size).toBeGreaterThan(0)
+ expect(models.integrations.size).toBe(0)
+ expect(mocks.visibility).not.toHaveBeenCalled()
+ })
+
+ it('canonicalizes the deployment integration allowlist before matching', async () => {
+ mocks.allowedIntegrations.mockReturnValue(['SLACK'])
+ const catalog = await loadAccessRequestCatalog(context)
+ expect([...catalog.integrations.keys()]).toEqual(['slack_v2'])
+ expect([...catalog.tools.keys()]).toEqual(['slack_send_message_v2'])
+ mocks.allowedIntegrations.mockReturnValue([])
+ expect((await loadAccessRequestCatalog(context)).integrations.size).toBe(0)
+ })
+
+ it('omits blacklisted/retired models, unconfigured endpoints, and private dynamic names', async () => {
+ const catalog = await loadAccessRequestCatalog(context)
+ expect([...catalog.providers.keys()]).toEqual(['openai', 'openrouter', 'fireworks'])
+ expect([...catalog.models.keys()]).toEqual(['public-model', 'fireworks/public-model'])
+ expect([...catalog.knowledgeConnectors.keys()]).toEqual(['available', 'token', 'fallback'])
+ })
+
+ it('keeps public models of dynamic providers requestable without exposing private names', async () => {
+ const catalog = await loadAccessRequestCatalog(context, 'model')
+
+ expect(catalog.models.get('fireworks/public-model')).toEqual({
+ id: 'fireworks/public-model',
+ label: 'fireworks/public-model',
+ providerId: 'fireworks',
+ })
+ expect(catalog.models.has('fireworks/private-model')).toBe(false)
+ expect(catalog.models.has('private-tenant-model')).toBe(false)
+ })
+
+ it('refuses ambiguous tool parent policies instead of choosing one silently', async () => {
+ mocks.blocks.mockReturnValue({
+ first: { type: 'first', name: 'First', tools: { access: ['shared_tool'] } },
+ second: { type: 'second', name: 'Second', tools: { access: ['shared_tool'] } },
+ })
+ expect((await loadAccessRequestCatalog(context)).tools.has('shared_tool')).toBe(false)
+ })
+
+ it('reports deployment flags as unavailable, independently of group config', () => {
+ expect(
+ getAccessRequestDeploymentUnavailableReason({ kind: 'feature', configKey: 'hideCopilot' })
+ ).not.toBeNull()
+ expect(
+ getAccessRequestDeploymentUnavailableReason({
+ kind: 'feature',
+ configKey: 'disableInvitations',
+ })
+ ).not.toBeNull()
+ expect(
+ getAccessRequestDeploymentUnavailableReason({ kind: 'file_share_auth', id: 'sso' })
+ ).not.toBeNull()
+ expect(
+ getAccessRequestDeploymentUnavailableReason({ kind: 'feature', configKey: 'hideTablesTab' })
+ ).toBeNull()
+ })
+
+ it('retains genuinely governed core blocks while omitting canonical exemptions', async () => {
+ mocks.blocks.mockReturnValue({
+ agent: { type: 'agent', name: 'Agent' },
+ condition: { type: 'condition', name: 'Condition' },
+ thinking: { type: 'thinking', name: 'Retired thinking', hideFromToolbar: true },
+ start_trigger: { type: 'start_trigger', name: 'Start' },
+ })
+ const catalog = await loadAccessRequestCatalog(context)
+ expect(isBlockTypeAccessControlExempt('agent')).toBe(false)
+ expect(isBlockTypeAccessControlExempt('condition')).toBe(false)
+ expect(isBlockTypeAccessControlExempt('thinking')).toBe(true)
+ expect(isBlockTypeAccessControlExempt('start_trigger')).toBe(true)
+ expect([...catalog.integrations.keys()]).toEqual(['loop', 'parallel', 'agent', 'condition'])
+ })
+})
diff --git a/apps/sim/lib/permission-access-requests/catalog.ts b/apps/sim/lib/permission-access-requests/catalog.ts
new file mode 100644
index 00000000000..983be1eda05
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/catalog.ts
@@ -0,0 +1,82 @@
+import {
+ isChatEnabled,
+ isInboxEnabled,
+ isInvitationsDisabled,
+ isPublicApiDisabled,
+ isSandboxesEnabled,
+ isSsoEnabled,
+} from '@/lib/core/config/env-flags'
+import type { AccessRequestCatalogContext } from '@/lib/permission-access-requests/catalog-registry'
+import {
+ type AccessRequestCatalog,
+ type AccessRequestTarget,
+ createAccessRequestCatalog,
+} from '@/lib/permission-groups/access-requests/targets'
+import { PLATFORM_FEATURES } from '@/lib/permission-groups/features'
+import { FILE_SHARE_AUTH_TYPES } from '@/lib/permission-groups/fields'
+
+/** Small navigation and credit-limit checks never load or enumerate the integration registries. */
+export async function loadAccessRequestCatalog(
+ context: AccessRequestCatalogContext,
+ targetKind?: AccessRequestTarget['kind']
+): Promise {
+ if (
+ targetKind &&
+ ['feature', 'usage_limit', 'file_share_auth', 'chat_deploy_auth'].includes(targetKind)
+ )
+ return createAccessRequestCatalog({
+ integrations: [],
+ providers: [],
+ models: [],
+ tools: [],
+ knowledgeConnectors: [],
+ })
+ const { loadAccessRequestRegistryCatalog } = await import(
+ '@/lib/permission-access-requests/catalog-registry'
+ )
+ return loadAccessRequestRegistryCatalog(context, targetKind)
+}
+
+/** Enumerates public targets; scope, role, current policy, usage, and pending state remain caller-owned. */
+export function listAccessRequestTargets(catalog: AccessRequestCatalog): AccessRequestTarget[] {
+ return [
+ ...PLATFORM_FEATURES.map(
+ (feature): AccessRequestTarget => ({ kind: 'feature', configKey: feature.configKey })
+ ),
+ ...[...catalog.integrations.keys()].map(
+ (id): AccessRequestTarget => ({ kind: 'integration', id })
+ ),
+ ...[...catalog.providers.keys()].map((id): AccessRequestTarget => ({ kind: 'provider', id })),
+ ...[...catalog.models.values()].map(({ id }): AccessRequestTarget => ({ kind: 'model', id })),
+ ...[...catalog.tools.keys()].map((id): AccessRequestTarget => ({ kind: 'tool', id })),
+ ...[...catalog.knowledgeConnectors.keys()].map(
+ (id): AccessRequestTarget => ({ kind: 'knowledge_connector', id })
+ ),
+ ...FILE_SHARE_AUTH_TYPES.map((id): AccessRequestTarget => ({ kind: 'file_share_auth', id })),
+ ...FILE_SHARE_AUTH_TYPES.map((id): AccessRequestTarget => ({ kind: 'chat_deploy_auth', id })),
+ { kind: 'usage_limit', id: 'member' },
+ ]
+}
+
+/** Group edits cannot enable a deployment-disabled feature or sharing authentication mode. */
+export function getAccessRequestDeploymentUnavailableReason(
+ target: AccessRequestTarget
+): string | null {
+ if (
+ (target.kind === 'file_share_auth' || target.kind === 'chat_deploy_auth') &&
+ target.id === 'sso' &&
+ !isSsoEnabled
+ ) {
+ return 'SSO is not available on this deployment.'
+ }
+ if (target.kind !== 'feature') return null
+ const disabled =
+ (target.configKey === 'hideCopilot' && !isChatEnabled) ||
+ (target.configKey === 'hideInboxTab' && !isInboxEnabled) ||
+ (target.configKey === 'hideSandboxesTab' && !isSandboxesEnabled) ||
+ (target.configKey === 'disableInvitations' && isInvitationsDisabled) ||
+ (target.configKey === 'disablePublicApi' && isPublicApiDisabled)
+ return disabled
+ ? 'This feature is disabled for this deployment. An organization permission change cannot enable it.'
+ : null
+}
diff --git a/apps/sim/lib/permission-access-requests/constants.ts b/apps/sim/lib/permission-access-requests/constants.ts
new file mode 100644
index 00000000000..b43ff32b5ed
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/constants.ts
@@ -0,0 +1,4 @@
+export const ACCESS_REQUEST_LIST_PAGE_SIZE = 25
+export const ACCESS_REQUEST_MAX_OFFSET = 1_000_000
+export const ACCESS_REQUEST_MAX_SEARCH_LENGTH = 200
+export const ACCESS_REQUEST_MAX_ID_LENGTH = 128
diff --git a/apps/sim/lib/permission-access-requests/impact.postgres.test.ts b/apps/sim/lib/permission-access-requests/impact.postgres.test.ts
new file mode 100644
index 00000000000..26782c5e21d
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/impact.postgres.test.ts
@@ -0,0 +1,103 @@
+/**
+ * @vitest-environment node
+ */
+import { generateId } from '@sim/utils/id'
+import { drizzle } from 'drizzle-orm/postgres-js'
+import postgres from 'postgres'
+import { describe, expect, it, vi } from 'vitest'
+import { loadAccessRequestGroupImpact } from '@/lib/permission-access-requests/impact'
+
+vi.unmock('@sim/db/schema')
+vi.unmock('drizzle-orm')
+
+const databaseUrl = process.env.ACCESS_REQUESTS_TEST_DATABASE_URL
+
+async function createFixture() {
+ const url = new URL(databaseUrl ?? '')
+ if (
+ !['localhost', '127.0.0.1'].includes(url.hostname) ||
+ url.pathname !== '/sim_access_requests_test'
+ )
+ throw new Error('Use a disposable local sim_access_requests_test database')
+ const schema = `access_impact_${generateId().replaceAll('-', '')}`
+ const client = postgres(url.toString(), { max: 1, onnotice: () => undefined })
+ await client.unsafe(`CREATE SCHEMA "${schema}"`)
+ await client.unsafe(`SET search_path TO "${schema}"`)
+ await client.unsafe(`
+ CREATE TABLE workspace (id text PRIMARY KEY, name text, organization_id text, archived_at timestamp);
+ CREATE TABLE permission_group (id text PRIMARY KEY, organization_id text, is_default boolean, updated_at timestamp, membership_mode text);
+ CREATE TABLE permissions (id text PRIMARY KEY, user_id text, entity_id text, entity_type text, permission_type text, updated_at timestamp);
+ CREATE TABLE member (id text PRIMARY KEY, user_id text, organization_id text, role text);
+ CREATE TABLE permission_group_member (id text PRIMARY KEY, organization_id text, permission_group_id text, user_id text);
+ CREATE TABLE permission_group_workspace (id text PRIMARY KEY, organization_id text, permission_group_id text, workspace_id text);
+ INSERT INTO permission_group VALUES ('group', 'org', false, now(), 'explicit');
+ INSERT INTO workspace VALUES ('one', 'One', 'org', null), ('two', 'Two', 'org', null), ('foreign', 'Foreign', 'another-org', null);
+ INSERT INTO permission_group_workspace VALUES ('scope', 'org', 'group', 'one');
+ INSERT INTO member VALUES ('m1', 'admin', 'org', 'admin'), ('m2', 'member', 'org', 'member'), ('m3', 'outside', 'another-org', 'admin');
+ INSERT INTO permissions VALUES ('p1', 'admin', 'one', 'workspace', 'read', now()), ('p2', 'guest', 'one', 'workspace', 'read', now()), ('p3', 'guest', 'two', 'workspace', 'read', now()), ('p4', 'outside', 'foreign', 'workspace', 'read', now());
+ INSERT INTO permission_group_member VALUES ('assignment', 'org', 'group', 'member');
+ `)
+ return {
+ client,
+ executor: drizzle(client),
+ async cleanup() {
+ try {
+ await client.unsafe(`DROP SCHEMA "${schema}" CASCADE`)
+ } finally {
+ await client.end()
+ }
+ },
+ }
+}
+
+describe.skipIf(!databaseUrl)('access request impact on PostgreSQL', () => {
+ it('counts scoped people once without requiring or scanning the global user table', async () => {
+ const fixture = await createFixture()
+ try {
+ const scoped = await loadAccessRequestGroupImpact(fixture.executor, 'org', 'group')
+ expect(scoped.impact).toEqual({
+ memberCount: 2,
+ workspaceCount: 1,
+ workspaceNames: ['One'],
+ truncated: false,
+ })
+ await fixture.client`UPDATE permission_group SET is_default = true WHERE id = 'group'`
+ const defaultGroup = await loadAccessRequestGroupImpact(fixture.executor, 'org', 'group')
+ expect(defaultGroup.impact).toEqual({
+ memberCount: 3,
+ workspaceCount: 2,
+ workspaceNames: ['One', 'Two'],
+ truncated: false,
+ })
+ } finally {
+ await fixture.cleanup()
+ }
+ })
+
+ it('detects in-place assignment, grant, and workspace changes with a bounded revision', async () => {
+ const fixture = await createFixture()
+ try {
+ const load = () => loadAccessRequestGroupImpact(fixture.executor, 'org', 'group')
+ const initial = await load()
+ expect((await load()).revision).toBe(initial.revision)
+ await fixture.client`UPDATE permission_group_member SET user_id = 'guest' WHERE id = 'assignment'`
+ const reassigned = await load()
+ expect(reassigned.revision).not.toBe(initial.revision)
+ await fixture.client`UPDATE permissions SET permission_type = 'write' WHERE id = 'p2'`
+ const promoted = await load()
+ expect(promoted.revision).not.toBe(reassigned.revision)
+ await fixture.client`UPDATE workspace SET name = 'Renamed' WHERE id = 'one'`
+ const renamed = await load()
+ expect(renamed.revision).not.toBe(promoted.revision)
+ await fixture.client`INSERT INTO workspace SELECT 'ws-' || n, 'Workspace ' || n, 'org', null FROM generate_series(1, 150) n`
+ await fixture.client`UPDATE permission_group SET is_default = true WHERE id = 'group'`
+ const large = await load()
+ expect(large.impact.workspaceCount).toBe(152)
+ expect(large.impact.workspaceNames).toHaveLength(100)
+ expect(large.impact.truncated).toBe(true)
+ expect(large.revision.length).toBeLessThan(1000)
+ } finally {
+ await fixture.cleanup()
+ }
+ })
+})
diff --git a/apps/sim/lib/permission-access-requests/impact.ts b/apps/sim/lib/permission-access-requests/impact.ts
new file mode 100644
index 00000000000..f4ff2beb49a
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/impact.ts
@@ -0,0 +1,136 @@
+import {
+ member,
+ permissionGroup,
+ permissionGroupMember,
+ permissionGroupWorkspace,
+ permissions,
+ workspace,
+} from '@sim/db/schema'
+import { and, count, eq, inArray, isNull, type SQL, sql } from 'drizzle-orm'
+import type { DbOrTx } from '@/lib/db/types'
+import type { AccessRequestImpact } from '@/lib/permission-access-requests/types'
+
+/** Order-independent change detector with fixed-size aggregate state instead of sorted row strings. */
+function membershipRevision(value: SQL): SQL {
+ return sql`count(*)::text || ':' ||
+ coalesce(sum(('x' || substr(md5(${value}), 1, 16))::bit(64)::bigint::numeric), 0)::text || ':' ||
+ coalesce(sum(('x' || substr(md5(${value}), 17, 16))::bit(64)::bigint::numeric), 0)::text`
+}
+
+/** Counts a conservative audience on the database and returns at most 100 workspace names. */
+export async function loadAccessRequestGroupImpact(
+ executor: DbOrTx,
+ organizationId: string,
+ groupId: string
+): Promise<{ impact: AccessRequestImpact; revision: string }> {
+ const [group] = await executor
+ .select({ isDefault: permissionGroup.isDefault, updatedAt: permissionGroup.updatedAt })
+ .from(permissionGroup)
+ .where(and(eq(permissionGroup.id, groupId), eq(permissionGroup.organizationId, organizationId)))
+ .limit(1)
+ const scope = and(
+ eq(workspace.organizationId, organizationId),
+ isNull(workspace.archivedAt),
+ group?.isDefault
+ ? undefined
+ : sql`exists (select 1 from ${permissionGroupWorkspace} where ${permissionGroupWorkspace.permissionGroupId} = ${groupId} and ${permissionGroupWorkspace.workspaceId} = ${workspace.id})`
+ )
+ const names = await executor
+ .select({ name: workspace.name })
+ .from(workspace)
+ .where(scope)
+ .orderBy(workspace.name, workspace.id)
+ .limit(100)
+ const [workspaces] = await executor
+ .select({
+ total: count(),
+ revision: membershipRevision(
+ sql`jsonb_build_array(${workspace.id}, ${workspace.name})::text`
+ ),
+ })
+ .from(workspace)
+ .where(scope)
+ const [grants] = await executor
+ .select({
+ revision: membershipRevision(
+ sql`jsonb_build_array(${permissions.id}, ${permissions.userId}, ${permissions.entityId}, ${permissions.permissionType}, ${permissions.updatedAt})::text`
+ ),
+ })
+ .from(permissions)
+ .innerJoin(
+ workspace,
+ and(eq(workspace.id, permissions.entityId), eq(permissions.entityType, 'workspace'))
+ )
+ .where(scope)
+ const [orgMembers] = await executor
+ .select({
+ total: count(),
+ revision: membershipRevision(
+ sql`jsonb_build_array(${member.id}, ${member.userId}, ${member.role})::text`
+ ),
+ })
+ .from(member)
+ .where(eq(member.organizationId, organizationId))
+ const [assignments] = await executor
+ .select({
+ revision: membershipRevision(
+ sql`jsonb_build_array(${permissionGroupMember.id}, ${permissionGroupMember.userId}, ${permissionGroupMember.permissionGroupId})::text`
+ ),
+ })
+ .from(permissionGroupMember)
+ .where(eq(permissionGroupMember.organizationId, organizationId))
+ const [scopes] = await executor
+ .select({
+ revision: membershipRevision(
+ sql`jsonb_build_array(${permissionGroupWorkspace.id}, ${permissionGroupWorkspace.workspaceId}, ${permissionGroupWorkspace.permissionGroupId})::text`
+ ),
+ })
+ .from(permissionGroupWorkspace)
+ .where(eq(permissionGroupWorkspace.organizationId, organizationId))
+ const candidates = executor
+ .select({ userId: permissions.userId })
+ .from(permissions)
+ .innerJoin(
+ workspace,
+ and(eq(workspace.id, permissions.entityId), eq(permissions.entityType, 'workspace'))
+ )
+ .where(scope)
+ .union(
+ executor
+ .select({ userId: member.userId })
+ .from(member)
+ .where(
+ and(
+ eq(member.organizationId, organizationId),
+ group?.isDefault ? undefined : inArray(member.role, ['admin', 'owner'])
+ )
+ )
+ )
+ .as('affected_people')
+ const [people] = await executor.select({ total: count() }).from(candidates)
+ const [groupVersions] = await executor
+ .select({
+ revision: membershipRevision(
+ sql`jsonb_build_array(${permissionGroup.id}, ${permissionGroup.updatedAt}, ${permissionGroup.membershipMode}, ${permissionGroup.isDefault})::text`
+ ),
+ })
+ .from(permissionGroup)
+ .where(eq(permissionGroup.organizationId, organizationId))
+ return {
+ impact: {
+ memberCount: Number(people?.total ?? 0),
+ workspaceCount: workspaces?.total ?? 0,
+ workspaceNames: names.map((row) => row.name),
+ truncated: (workspaces?.total ?? 0) > names.length,
+ },
+ revision: JSON.stringify([
+ group?.updatedAt,
+ workspaces?.revision,
+ grants?.revision,
+ orgMembers?.revision,
+ groupVersions?.revision,
+ assignments?.revision,
+ scopes?.revision,
+ ]),
+ }
+}
diff --git a/apps/sim/lib/permission-access-requests/notification-events.ts b/apps/sim/lib/permission-access-requests/notification-events.ts
new file mode 100644
index 00000000000..3adf1aa1897
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/notification-events.ts
@@ -0,0 +1,2 @@
+export const PERMISSION_ACCESS_REQUEST_CREATED_EVENT = 'permission-access-request.created'
+export const PERMISSION_ACCESS_REQUEST_DECIDED_EVENT = 'permission-access-request.decided'
diff --git a/apps/sim/lib/permission-access-requests/notifications.test.ts b/apps/sim/lib/permission-access-requests/notifications.test.ts
new file mode 100644
index 00000000000..9d11dda7fac
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/notifications.test.ts
@@ -0,0 +1,388 @@
+/**
+ * @vitest-environment node
+ */
+import { db } from '@sim/db'
+import { member, outboxEvent, permissionAccessRequest, user, workspace } from '@sim/db/schema'
+import { dbChainMockFns, queueTableRows, resetDbChainMock } from '@sim/testing'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+import type { OutboxEventContext } from '@/lib/core/outbox/service'
+
+const { mockRender, mockSend, mockHasEmailService, mockMembership, mockEnabled } = vi.hoisted(
+ () => ({
+ mockRender: vi.fn(),
+ mockSend: vi.fn(),
+ mockHasEmailService: vi.fn(),
+ mockMembership: vi.fn(),
+ mockEnabled: vi.fn(),
+ })
+)
+
+vi.mock('@/components/emails/render', () => ({
+ renderPermissionAccessRequestEmail: mockRender,
+}))
+vi.mock('@/components/emails/subjects', () => ({ getEmailSubject: (kind: string) => kind }))
+vi.mock('@/lib/messaging/email/mailer', () => ({
+ sendEmail: mockSend,
+ hasEmailService: mockHasEmailService,
+}))
+vi.mock('@/lib/permission-access-requests/application/authorization', () => ({
+ loadAccessRequestMembership: mockMembership,
+}))
+vi.mock('@/lib/core/utils/urls', () => ({ getBaseUrl: () => 'https://sim.example' }))
+vi.mock('@/lib/permission-access-requests/settings', () => ({
+ isAccessRequestEnabled: mockEnabled,
+}))
+
+import {
+ PERMISSION_ACCESS_REQUEST_CREATED_EVENT,
+ PERMISSION_ACCESS_REQUEST_DECIDED_EVENT,
+} from '@/lib/permission-access-requests/notification-events'
+import { permissionAccessRequestOutboxHandlers } from '@/lib/permission-access-requests/notifications'
+
+const request = {
+ id: 'request-one',
+ requesterId: 'requester-one',
+ organizationId: 'organization-one',
+ workspaceId: 'workspace-one',
+ status: 'pending',
+ membershipId: '[null,"grant-one"]',
+}
+const adminEvent = 'permission-access-request.notify-admin'
+const createdHandler =
+ permissionAccessRequestOutboxHandlers[PERMISSION_ACCESS_REQUEST_CREATED_EVENT]
+const decidedHandler =
+ permissionAccessRequestOutboxHandlers[PERMISSION_ACCESS_REQUEST_DECIDED_EVENT]
+const adminHandler = permissionAccessRequestOutboxHandlers[adminEvent]
+
+function context(): OutboxEventContext {
+ return {
+ eventId: 'event-one',
+ eventType: PERMISSION_ACCESS_REQUEST_CREATED_EVENT,
+ attempts: 0,
+ maxAttempts: 10,
+ signal: new AbortController().signal,
+ checkpointPayload: vi.fn().mockResolvedValue(undefined),
+ }
+}
+
+function queueWorkspaceRequest(overrides: Partial = {}) {
+ queueTableRows(permissionAccessRequest, [{ ...request, ...overrides }])
+ queueTableRows(workspace, [{ organizationId: request.organizationId }])
+}
+
+beforeEach(() => {
+ vi.clearAllMocks()
+ resetDbChainMock()
+ mockRender.mockResolvedValue('Authenticated request link')
+ mockSend.mockResolvedValue({ success: true })
+ mockHasEmailService.mockReturnValue(true)
+ mockMembership.mockResolvedValue({ role: 'read', membershipId: request.membershipId })
+ mockEnabled.mockResolvedValue(true)
+})
+
+describe('access request administrator notifications', () => {
+ it('bounds fan-out to one page and checkpoints durable progress', async () => {
+ queueWorkspaceRequest()
+ const recipients = Array.from({ length: 50 }, (_, index) => ({
+ id: `member-${index}`,
+ userId: `admin-${index}`,
+ }))
+ queueTableRows(member, recipients)
+ const eventContext = context()
+
+ const result = await createdHandler({ requestId: request.id }, eventContext)
+
+ expect(dbChainMockFns.limit).toHaveBeenCalledWith(50)
+ expect(dbChainMockFns.insert).toHaveBeenCalledExactlyOnceWith(outboxEvent)
+ expect(dbChainMockFns.values).toHaveBeenCalledWith(
+ recipients.map((recipient) => ({
+ id: `${adminEvent}:${request.id}:${recipient.userId}`,
+ eventType: adminEvent,
+ payload: { requestId: request.id, recipientUserId: recipient.userId },
+ }))
+ )
+ expect(dbChainMockFns.onConflictDoNothing).toHaveBeenCalledWith({ target: outboxEvent.id })
+ expect(eventContext.checkpointPayload).toHaveBeenCalledWith({ afterMemberId: 'member-49' })
+ expect(result).toMatchObject({ outcome: 'deferred', consumeAttempt: false })
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('resumes after the saved member cursor and terminates after a partial page', async () => {
+ queueWorkspaceRequest()
+ queueTableRows(member, [{ id: 'member-60', userId: 'admin-60' }])
+
+ await expect(
+ createdHandler({ requestId: request.id, afterMemberId: 'member-59' }, context())
+ ).resolves.toBeUndefined()
+
+ expect(dbChainMockFns.where).toHaveBeenCalledWith(
+ expect.objectContaining({
+ conditions: expect.arrayContaining([{ type: 'gt', left: member.id, right: 'member-59' }]),
+ })
+ )
+ })
+
+ it('reuses child event IDs when a crash interrupts checkpointing', async () => {
+ const failedContext = context()
+ vi.mocked(failedContext.checkpointPayload).mockRejectedValueOnce(new Error('lease lost'))
+ queueWorkspaceRequest()
+ queueTableRows(member, [{ id: 'member-one', userId: 'admin-one' }])
+
+ await expect(createdHandler({ requestId: request.id }, failedContext)).rejects.toThrow(
+ 'lease lost'
+ )
+
+ queueWorkspaceRequest()
+ queueTableRows(member, [{ id: 'member-one', userId: 'admin-one' }])
+ await createdHandler({ requestId: request.id }, context())
+
+ expect(dbChainMockFns.values.mock.calls[0][0]).toEqual(dbChainMockFns.values.mock.calls[1][0])
+ expect(dbChainMockFns.onConflictDoNothing).toHaveBeenCalledTimes(2)
+ })
+
+ it('skips fan-out when email is not configured', async () => {
+ queueWorkspaceRequest()
+ mockHasEmailService.mockReturnValue(false)
+
+ await createdHandler({ requestId: request.id }, context())
+
+ expect(dbChainMockFns.insert).not.toHaveBeenCalled()
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('does not email a former administrator', async () => {
+ queueWorkspaceRequest()
+ queueTableRows(user, [{ email: 'former-admin@example.com' }])
+ queueTableRows(member, [])
+
+ await adminHandler({ requestId: request.id, recipientUserId: 'former-admin' }, context())
+
+ expect(mockSend).not.toHaveBeenCalled()
+ expect(dbChainMockFns.where).toHaveBeenCalledWith(
+ expect.objectContaining({
+ conditions: expect.arrayContaining([
+ { type: 'eq', left: member.userId, right: 'former-admin' },
+ { type: 'eq', left: member.organizationId, right: request.organizationId },
+ { type: 'inArray', column: member.role, values: ['admin', 'owner'] },
+ ]),
+ })
+ )
+ })
+
+ it('emails an eligible administrator after a temporary ban has expired', async () => {
+ queueWorkspaceRequest()
+ queueTableRows(user, [
+ {
+ email: 'admin@example.com',
+ banned: true,
+ banExpires: new Date('2020-01-01'),
+ suspendedAt: null,
+ },
+ ])
+ queueTableRows(member, [{ id: 'admin-member' }])
+
+ await adminHandler({ requestId: request.id, recipientUserId: 'admin-one' }, context())
+
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({ to: 'admin@example.com' }))
+ })
+
+ it.each([
+ { banned: true, banExpires: null, suspendedAt: null },
+ { banned: true, banExpires: new Date('2099-01-01'), suspendedAt: null },
+ { banned: false, banExpires: null, suspendedAt: new Date() },
+ ])('does not email a recipient whose account is currently blocked', async (account) => {
+ queueWorkspaceRequest()
+ queueTableRows(user, [{ email: 'admin@example.com', ...account }])
+
+ await adminHandler({ requestId: request.id, recipientUserId: 'admin-one' }, context())
+
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('skips pending-request emails after the organization disables requests', async () => {
+ queueWorkspaceRequest()
+ mockEnabled.mockResolvedValue(false)
+
+ await adminHandler({ requestId: request.id, recipientUserId: 'admin-one' }, context())
+
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('builds an authenticated review link and loads the current administrator email', async () => {
+ queueWorkspaceRequest()
+ queueTableRows(user, [{ email: 'current-admin@example.com' }])
+ queueTableRows(member, [{ id: 'member-one' }])
+
+ await adminHandler({ requestId: request.id, recipientUserId: 'admin-one' }, context())
+
+ expect(mockRender).toHaveBeenCalledExactlyOnceWith({
+ kind: 'created',
+ requestLink:
+ 'https://sim.example/access-requests?organizationId=organization-one&view=admin&requestId=request-one',
+ })
+ expect(mockSend).toHaveBeenCalledWith(
+ expect.objectContaining({ to: 'current-admin@example.com', emailType: 'transactional' })
+ )
+ })
+
+ it('discards stale creation notifications after a request is resolved', async () => {
+ queueTableRows(permissionAccessRequest, [{ ...request, status: 'fulfilled' }])
+
+ await adminHandler({ requestId: request.id, recipientUserId: 'admin-one' }, context())
+
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('fails delivery for retry without mutating request state', async () => {
+ queueWorkspaceRequest()
+ queueTableRows(user, [{ email: 'admin@example.com' }])
+ queueTableRows(member, [{ id: 'member-one' }])
+ mockSend.mockResolvedValueOnce({ success: false })
+
+ await expect(
+ adminHandler({ requestId: request.id, recipientUserId: 'admin-one' }, context())
+ ).rejects.toThrow('Failed to send access request notification')
+
+ expect(dbChainMockFns.update).not.toHaveBeenCalled()
+ expect(dbChainMockFns.delete).not.toHaveBeenCalled()
+ })
+
+ it('refuses a caller-provided destination or URL in the durable payload', async () => {
+ await expect(
+ adminHandler(
+ { requestId: request.id, recipientUserId: 'admin-one', email: 'attacker@example.com' },
+ context()
+ )
+ ).rejects.toThrow()
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+})
+
+describe('access request requester notifications', () => {
+ it.each(['fulfilled', 'declined', 'cancelled', 'closed'])(
+ 'notifies the requester for %s without putting private request details in email',
+ async (status) => {
+ queueWorkspaceRequest({ status })
+ queueTableRows(user, [{ email: 'requester@example.com' }])
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockRender).toHaveBeenCalledExactlyOnceWith({
+ kind: 'decided',
+ requestLink:
+ 'https://sim.example/workspace/workspace-one/access-requests?requestId=request-one',
+ })
+ expect(mockSend).toHaveBeenCalledWith(
+ expect.objectContaining({ to: 'requester@example.com', emailType: 'transactional' })
+ )
+ }
+ )
+
+ it('supports an external workspace member without organization membership', async () => {
+ queueWorkspaceRequest({ status: 'fulfilled' })
+ queueTableRows(user, [{ email: 'external@example.com' }])
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockMembership).toHaveBeenCalledWith(
+ db,
+ request.requesterId,
+ { kind: 'workspace', workspaceId: request.workspaceId },
+ request.organizationId
+ )
+ expect(mockSend).toHaveBeenCalledWith(expect.objectContaining({ to: 'external@example.com' }))
+ expect(mockRender).toHaveBeenCalledExactlyOnceWith({
+ kind: 'decided',
+ requestLink:
+ 'https://sim.example/workspace/workspace-one/access-requests?requestId=request-one',
+ })
+ })
+
+ it('encodes a canonical workspace identifier as one path segment', async () => {
+ queueWorkspaceRequest({ status: 'fulfilled', workspaceId: 'workspace/with?characters' })
+ queueTableRows(user, [{ email: 'requester@example.com' }])
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockRender).toHaveBeenCalledExactlyOnceWith({
+ kind: 'decided',
+ requestLink:
+ 'https://sim.example/workspace/workspace%2Fwith%3Fcharacters/access-requests?requestId=request-one',
+ })
+ })
+
+ it('skips delivery after the requester loses workspace access', async () => {
+ queueWorkspaceRequest({ status: 'fulfilled' })
+ mockMembership.mockResolvedValueOnce(null)
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('skips delivery after the workspace moves to another organization', async () => {
+ queueTableRows(permissionAccessRequest, [{ ...request, status: 'closed' }])
+ queueTableRows(workspace, [{ organizationId: 'other-organization' }])
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockMembership).not.toHaveBeenCalled()
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('requires current organization membership for an organization-scoped request', async () => {
+ queueTableRows(permissionAccessRequest, [{ ...request, workspaceId: null, status: 'declined' }])
+ mockMembership.mockResolvedValueOnce(null)
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('links organization-scoped decisions to the requester history', async () => {
+ queueTableRows(permissionAccessRequest, [
+ { ...request, workspaceId: null, status: 'fulfilled' },
+ ])
+ queueTableRows(user, [{ email: 'requester@example.com' }])
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockRender).toHaveBeenCalledWith({
+ kind: 'decided',
+ requestLink:
+ 'https://sim.example/access-requests?organizationId=organization-one&requestId=request-one',
+ })
+ })
+
+ it('stops before email delivery when its outbox lease has expired', async () => {
+ queueWorkspaceRequest({ status: 'fulfilled' })
+ queueTableRows(user, [{ email: 'requester@example.com' }])
+ const eventContext = context()
+ eventContext.signal = AbortSignal.abort(new Error('lease expired'))
+
+ await expect(decidedHandler({ requestId: request.id }, eventContext)).rejects.toThrow(
+ 'lease expired'
+ )
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('does not revive an old notification after the requester is removed and reinvited', async () => {
+ queueWorkspaceRequest({ status: 'fulfilled' })
+ mockMembership.mockResolvedValueOnce({ role: 'read', membershipId: '[null,"new-grant"]' })
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockSend).not.toHaveBeenCalled()
+ })
+
+ it('delivers existing decisions after the organization disables new requests', async () => {
+ queueWorkspaceRequest({ status: 'declined' })
+ queueTableRows(user, [{ email: 'requester@example.com' }])
+ mockEnabled.mockResolvedValue(false)
+
+ await decidedHandler({ requestId: request.id }, context())
+
+ expect(mockSend).toHaveBeenCalledOnce()
+ expect(mockEnabled).not.toHaveBeenCalled()
+ })
+})
diff --git a/apps/sim/lib/permission-access-requests/notifications.ts b/apps/sim/lib/permission-access-requests/notifications.ts
new file mode 100644
index 00000000000..5516dde5dd7
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/notifications.ts
@@ -0,0 +1,210 @@
+import { db } from '@sim/db'
+import { member, outboxEvent, permissionAccessRequest, user, workspace } from '@sim/db/schema'
+import { createLogger } from '@sim/logger'
+import { and, asc, eq, gt, inArray, isNull } from 'drizzle-orm'
+import { z } from 'zod'
+import { renderPermissionAccessRequestEmail } from '@/components/emails/render'
+import { getEmailSubject } from '@/components/emails/subjects'
+import { isAccountBlocked } from '@/lib/auth/ban'
+import {
+ continueOutboxHandler,
+ type OutboxEventContext,
+ type OutboxHandlerRegistry,
+} from '@/lib/core/outbox/service'
+import { getBaseUrl } from '@/lib/core/utils/urls'
+import { hasEmailService, sendEmail } from '@/lib/messaging/email/mailer'
+import { loadAccessRequestMembership } from '@/lib/permission-access-requests/application/authorization'
+import {
+ PERMISSION_ACCESS_REQUEST_CREATED_EVENT,
+ PERMISSION_ACCESS_REQUEST_DECIDED_EVENT,
+} from '@/lib/permission-access-requests/notification-events'
+import { isAccessRequestEnabled } from '@/lib/permission-access-requests/settings'
+
+const logger = createLogger('PermissionAccessRequestNotifications')
+const ADMIN_RECIPIENT_PAGE_SIZE = 50
+const ADMIN_NOTIFICATION_EVENT = 'permission-access-request.notify-admin'
+const notificationPayloadSchema = z.object({ requestId: z.string().min(1).max(256) }).strict()
+const createdPayloadSchema = notificationPayloadSchema.extend({
+ afterMemberId: z.string().min(1).max(256).optional(),
+})
+const adminPayloadSchema = notificationPayloadSchema.extend({
+ recipientUserId: z.string().min(1).max(256),
+})
+
+async function loadRequest(requestId: string) {
+ const [request] = await db
+ .select({
+ id: permissionAccessRequest.id,
+ organizationId: permissionAccessRequest.organizationId,
+ requesterId: permissionAccessRequest.requesterId,
+ workspaceId: permissionAccessRequest.workspaceId,
+ status: permissionAccessRequest.status,
+ membershipId: permissionAccessRequest.membershipId,
+ })
+ .from(permissionAccessRequest)
+ .where(eq(permissionAccessRequest.id, requestId))
+ .limit(1)
+ return request ?? null
+}
+
+type NotificationRequest = NonNullable>>
+
+async function requesterHasCurrentAccess(request: NotificationRequest): Promise {
+ if (request.workspaceId) {
+ const [scope] = await db
+ .select({ organizationId: workspace.organizationId })
+ .from(workspace)
+ .where(and(eq(workspace.id, request.workspaceId), isNull(workspace.archivedAt)))
+ .limit(1)
+ if (!scope || scope.organizationId !== request.organizationId) return false
+ }
+ const membership = await loadAccessRequestMembership(
+ db,
+ request.requesterId,
+ request.workspaceId
+ ? { kind: 'workspace', workspaceId: request.workspaceId }
+ : { kind: 'organization', organizationId: request.organizationId },
+ request.organizationId
+ )
+ return membership?.membershipId === request.membershipId
+}
+
+function requestLink(request: NotificationRequest, kind: 'created' | 'decided'): string {
+ const requesterWorkspaceId = kind === 'decided' ? request.workspaceId : null
+ const url = new URL(
+ requesterWorkspaceId
+ ? `/workspace/${encodeURIComponent(requesterWorkspaceId)}/access-requests`
+ : '/access-requests',
+ getBaseUrl()
+ )
+ if (!requesterWorkspaceId) url.searchParams.set('organizationId', request.organizationId)
+ if (kind === 'created') url.searchParams.set('view', 'admin')
+ url.searchParams.set('requestId', request.id)
+ return url.toString()
+}
+
+async function deliverNotification(
+ request: NotificationRequest,
+ kind: 'created' | 'decided',
+ recipientUserId: string,
+ context: OutboxEventContext
+): Promise {
+ const html = await renderPermissionAccessRequestEmail({
+ kind,
+ requestLink: requestLink(request, kind),
+ })
+ const recipientQuery = db
+ .select({
+ email: user.email,
+ suspendedAt: user.suspendedAt,
+ banned: user.banned,
+ banExpires: user.banExpires,
+ })
+ .from(user)
+ .where(eq(user.id, recipientUserId))
+ const [recipient] = await recipientQuery.limit(1)
+ if (!recipient || isAccountBlocked(recipient)) return
+ if (kind === 'created') {
+ const [membership] = await db
+ .select({ id: member.id })
+ .from(member)
+ .where(
+ and(
+ eq(member.userId, recipientUserId),
+ eq(member.organizationId, request.organizationId),
+ inArray(member.role, ['admin', 'owner'])
+ )
+ )
+ .limit(1)
+ if (!membership) return
+ }
+ context.signal.throwIfAborted()
+ const result = await sendEmail({
+ to: recipient.email,
+ subject: getEmailSubject(
+ kind === 'created' ? 'permission-access-request-created' : 'permission-access-request-decided'
+ ),
+ html,
+ emailType: 'transactional',
+ })
+ if (!result.success) throw new Error('Failed to send access request notification')
+}
+
+/**
+ * Fan-out replays insert the same child IDs; one failed recipient cannot prevent
+ * other administrators receiving their messages. Provider sends remain at-least-once
+ * across a crash between delivery and outbox completion.
+ */
+export const permissionAccessRequestOutboxHandlers = {
+ [PERMISSION_ACCESS_REQUEST_CREATED_EVENT]: async (rawPayload, context) => {
+ const { requestId, afterMemberId } = createdPayloadSchema.parse(rawPayload)
+ const request = await loadRequest(requestId)
+ if (
+ !request ||
+ request.status !== 'pending' ||
+ !(await isAccessRequestEnabled(request.organizationId)) ||
+ !(await requesterHasCurrentAccess(request))
+ ) {
+ return
+ }
+ if (!hasEmailService()) {
+ logger.info('Access request email skipped because email is not configured', { requestId })
+ return
+ }
+ const recipients = await db
+ .select({ id: member.id, userId: member.userId })
+ .from(member)
+ .where(
+ and(
+ eq(member.organizationId, request.organizationId),
+ inArray(member.role, ['admin', 'owner']),
+ afterMemberId ? gt(member.id, afterMemberId) : undefined
+ )
+ )
+ .orderBy(asc(member.id))
+ .limit(ADMIN_RECIPIENT_PAGE_SIZE)
+ if (recipients.length === 0) return
+ context.signal.throwIfAborted()
+ await db
+ .insert(outboxEvent)
+ .values(
+ recipients.map((recipient) => ({
+ id: `${ADMIN_NOTIFICATION_EVENT}:${requestId}:${recipient.userId}`,
+ eventType: ADMIN_NOTIFICATION_EVENT,
+ payload: { requestId, recipientUserId: recipient.userId },
+ }))
+ )
+ .onConflictDoNothing({ target: outboxEvent.id })
+ await context.checkpointPayload({ afterMemberId: recipients[recipients.length - 1].id })
+ if (recipients.length === ADMIN_RECIPIENT_PAGE_SIZE) {
+ return continueOutboxHandler('Continue access request administrator notifications')
+ }
+ },
+ [ADMIN_NOTIFICATION_EVENT]: async (rawPayload, context) => {
+ const { requestId, recipientUserId } = adminPayloadSchema.parse(rawPayload)
+ const request = await loadRequest(requestId)
+ if (
+ !request ||
+ request.status !== 'pending' ||
+ !hasEmailService() ||
+ !(await isAccessRequestEnabled(request.organizationId)) ||
+ !(await requesterHasCurrentAccess(request))
+ ) {
+ return
+ }
+ await deliverNotification(request, 'created', recipientUserId, context)
+ },
+ [PERMISSION_ACCESS_REQUEST_DECIDED_EVENT]: async (rawPayload, context) => {
+ const { requestId } = notificationPayloadSchema.parse(rawPayload)
+ const request = await loadRequest(requestId)
+ if (
+ !request ||
+ request.status === 'pending' ||
+ !hasEmailService() ||
+ !(await requesterHasCurrentAccess(request))
+ ) {
+ return
+ }
+ await deliverNotification(request, 'decided', request.requesterId, context)
+ },
+} satisfies OutboxHandlerRegistry
diff --git a/apps/sim/lib/permission-access-requests/policy.ts b/apps/sim/lib/permission-access-requests/policy.ts
new file mode 100644
index 00000000000..29c4459f2c3
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/policy.ts
@@ -0,0 +1,122 @@
+import { organizationMemberUsageLimit } from '@sim/db/schema'
+import { permissionSatisfies } from '@sim/platform-authz/workspace'
+import { and, eq } from 'drizzle-orm'
+import { isOrganizationOnEnterprisePlan } from '@/lib/billing/core/subscription'
+import { dollarsToCredits } from '@/lib/billing/credits/conversion'
+import { isAccessControlEnabled, isHosted } from '@/lib/core/config/env-flags'
+import type { DbOrTx } from '@/lib/db/types'
+import type { AccessRequestContext } from '@/lib/permission-access-requests/application/authorization'
+import { getAccessRequestDeploymentUnavailableReason } from '@/lib/permission-access-requests/catalog'
+import type {
+ AccessRequestScope,
+ AccessRequestTarget,
+} from '@/lib/permission-groups/access-requests/targets'
+import {
+ type AccessRequestCatalog,
+ buildAccessRequestPolicyDelta,
+ describeAccessRequestTarget,
+ isAccessRequestTargetDenied,
+ isAccessRequestTargetInScope,
+ validateAccessRequestTarget,
+} from '@/lib/permission-groups/access-requests/targets'
+import { resolveDefaultGroup, resolveWorkspaceGroup } from '@/lib/permission-groups/resolve.server'
+
+export async function loadMemberLimit(
+ executor: DbOrTx,
+ organizationId: string,
+ userId: string,
+ forUpdate = false
+) {
+ const query = executor
+ .select({
+ usageLimit: organizationMemberUsageLimit.usageLimit,
+ updatedAt: organizationMemberUsageLimit.updatedAt,
+ })
+ .from(organizationMemberUsageLimit)
+ .where(
+ and(
+ eq(organizationMemberUsageLimit.organizationId, organizationId),
+ eq(organizationMemberUsageLimit.userId, userId)
+ )
+ )
+ const [row] = forUpdate ? await query.for('update').limit(1) : await query.limit(1)
+ return row ? { ...row, credits: dollarsToCredits(Number(row.usageLimit)) } : null
+}
+
+export async function loadAccessRequestPolicy(
+ executor: DbOrTx,
+ context: AccessRequestContext,
+ userId: string,
+ entitledAtAdmission?: boolean
+) {
+ if (!context.organizationId) return { entitled: false, group: null, limit: null }
+ const entitled =
+ entitledAtAdmission !== false &&
+ (isHosted
+ ? await isOrganizationOnEnterprisePlan(context.organizationId, 'return-false', executor)
+ : isAccessControlEnabled)
+ const group = !entitled
+ ? null
+ : context.workspaceId
+ ? await resolveWorkspaceGroup(userId, context.organizationId, context.workspaceId, executor)
+ : await resolveDefaultGroup(context.organizationId, executor)
+ const limit = isHosted ? await loadMemberLimit(executor, context.organizationId, userId) : null
+ return { entitled, group, limit }
+}
+
+/** Hard deployment ceilings remain unavailable regardless of the permission group. */
+export async function evaluateAccessRequestTarget(
+ executor: DbOrTx,
+ context: AccessRequestContext,
+ userId: string,
+ scope: AccessRequestScope,
+ target: AccessRequestTarget,
+ catalog: AccessRequestCatalog,
+ preloaded?: Awaited>,
+ includeDelta = true
+) {
+ const canonical = validateAccessRequestTarget(target, catalog)
+ const description = canonical && describeAccessRequestTarget(canonical, catalog)
+ const unavailable = (reason: string) => ({
+ state: 'unavailable' as const,
+ reason,
+ group: null,
+ delta: null,
+ limit: null,
+ })
+ if (!canonical || !description || !isAccessRequestTargetInScope(canonical, scope, catalog))
+ return unavailable('This item is unavailable in this context.')
+ if (!context.organizationId) return unavailable('An organization administrator is required.')
+ const deploymentReason = getAccessRequestDeploymentUnavailableReason(canonical)
+ if (deploymentReason) return unavailable(deploymentReason)
+ if (!permissionSatisfies(context.role, description.minimumRole))
+ return unavailable('Your workspace role does not permit this action.')
+ const policy = preloaded ?? (await loadAccessRequestPolicy(executor, context, userId))
+ if (canonical.kind === 'usage_limit') {
+ if (!isHosted) return unavailable('Member credit limits are unavailable for this deployment.')
+ const limit = policy.limit
+ return {
+ state: limit ? ('requestable' as const) : ('allowed' as const),
+ reason: limit ? 'An organization administrator set your credit limit.' : null,
+ group: null,
+ delta: null,
+ limit,
+ }
+ }
+ if (!policy.entitled)
+ return unavailable('Permission groups are unavailable for this organization.')
+ const group = policy.group
+ if (!group)
+ return { state: 'allowed' as const, reason: null, group: null, delta: null, limit: null }
+ const denied = isAccessRequestTargetDenied(canonical, group.config, catalog)
+ const delta = includeDelta
+ ? buildAccessRequestPolicyDelta(canonical, group.config, catalog)
+ : null
+ return {
+ state: denied ? ('requestable' as const) : ('allowed' as const),
+ reason: denied ? 'Restricted by your permission group.' : null,
+ group,
+ delta,
+ limit: null,
+ }
+}
diff --git a/apps/sim/lib/permission-access-requests/repository.ts b/apps/sim/lib/permission-access-requests/repository.ts
new file mode 100644
index 00000000000..c43e8986bf5
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/repository.ts
@@ -0,0 +1,117 @@
+import { permissionAccessRequest, user } from '@sim/db/schema'
+import { and, count, desc, eq, type SQL } from 'drizzle-orm'
+import { OrchestrationError } from '@/lib/core/orchestration/types'
+import type { DbOrTx } from '@/lib/db/types'
+import { storedAccessRequestTargetSchema } from '@/lib/permission-access-requests/schemas'
+import type { AccessRequestList, AccessRequestRecord } from '@/lib/permission-access-requests/types'
+
+export type StoredAccessRequest = typeof permissionAccessRequest.$inferSelect
+
+export async function loadStoredAccessRequest(
+ executor: DbOrTx,
+ organizationId: string,
+ requestId: string,
+ forUpdate = false
+): Promise {
+ const query = executor
+ .select()
+ .from(permissionAccessRequest)
+ .where(
+ and(
+ eq(permissionAccessRequest.id, requestId),
+ eq(permissionAccessRequest.organizationId, organizationId)
+ )
+ )
+ const [row] = forUpdate ? await query.for('update').limit(1) : await query.limit(1)
+ if (!row) throw new OrchestrationError('not_found', 'Access request not found')
+ return row
+}
+
+export async function presentAccessRequest(
+ executor: DbOrTx,
+ row: StoredAccessRequest
+): Promise {
+ const [requester] = await executor
+ .select({ id: user.id, name: user.name, email: user.email })
+ .from(user)
+ .where(eq(user.id, row.requesterId))
+ .limit(1)
+ if (!requester) throw new OrchestrationError('not_found', 'Access request not found')
+ return projectAccessRequest(row, requester)
+}
+
+type AccessRequestPresentation = Pick<
+ StoredAccessRequest,
+ | 'id'
+ | 'organizationId'
+ | 'workspaceId'
+ | 'target'
+ | 'targetLabel'
+ | 'reason'
+ | 'status'
+ | 'decisionReason'
+ | 'createdAt'
+ | 'decidedAt'
+ | 'groupName'
+>
+
+function projectAccessRequest(
+ row: AccessRequestPresentation,
+ requester: AccessRequestRecord['requester']
+): AccessRequestRecord {
+ return {
+ id: row.id,
+ organizationId: row.organizationId,
+ workspaceId: row.workspaceId,
+ target: storedAccessRequestTargetSchema.parse(row.target),
+ targetLabel: row.targetLabel,
+ reason: row.reason,
+ status: row.status,
+ decisionReason: row.decisionReason,
+ createdAt: row.createdAt.toISOString(),
+ decidedAt: row.decidedAt?.toISOString() ?? null,
+ groupName: row.groupName,
+ requester,
+ }
+}
+
+export async function listAccessRequestRecords(
+ executor: DbOrTx,
+ where: SQL,
+ limit: number,
+ offset: number
+): Promise {
+ const rows = await executor
+ .select({
+ row: {
+ id: permissionAccessRequest.id,
+ organizationId: permissionAccessRequest.organizationId,
+ workspaceId: permissionAccessRequest.workspaceId,
+ target: permissionAccessRequest.target,
+ targetLabel: permissionAccessRequest.targetLabel,
+ reason: permissionAccessRequest.reason,
+ status: permissionAccessRequest.status,
+ decisionReason: permissionAccessRequest.decisionReason,
+ createdAt: permissionAccessRequest.createdAt,
+ decidedAt: permissionAccessRequest.decidedAt,
+ groupName: permissionAccessRequest.groupName,
+ },
+ requester: { id: user.id, name: user.name, email: user.email },
+ })
+ .from(permissionAccessRequest)
+ .innerJoin(user, eq(user.id, permissionAccessRequest.requesterId))
+ .where(where)
+ .orderBy(desc(permissionAccessRequest.createdAt), desc(permissionAccessRequest.id))
+ .limit(limit)
+ .offset(offset)
+ const [aggregate] = await executor
+ .select({ total: count() })
+ .from(permissionAccessRequest)
+ .where(where)
+ const total = aggregate?.total ?? 0
+ return {
+ requests: rows.map(({ row, requester }) => projectAccessRequest(row, requester)),
+ total,
+ hasMore: offset + rows.length < total,
+ }
+}
diff --git a/apps/sim/lib/permission-access-requests/schemas.ts b/apps/sim/lib/permission-access-requests/schemas.ts
new file mode 100644
index 00000000000..b3dcc467c7d
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/schemas.ts
@@ -0,0 +1,56 @@
+import { z } from 'zod'
+import type { AccessRequestTarget as DomainAccessRequestTarget } from '@/lib/permission-groups/access-requests/targets'
+import { PLATFORM_FEATURES } from '@/lib/permission-groups/features'
+import { FILE_SHARE_AUTH_TYPES, PERMISSION_GROUP_FIELDS } from '@/lib/permission-groups/fields'
+
+const targetIdSchema = z.string().min(1, 'Target ID cannot be empty').max(512)
+const fingerprintSchema = z.string().min(1, 'A current preview is required').max(128)
+
+/** Canonical validators for the target and decision JSON persisted with a request. */
+export const storedAccessRequestTargetSchema = z.discriminatedUnion('kind', [
+ z
+ .object({
+ kind: z.literal('feature'),
+ configKey: z.enum(PLATFORM_FEATURES.map((feature) => feature.configKey)),
+ })
+ .strict(),
+ z.object({ kind: z.literal('integration'), id: targetIdSchema }).strict(),
+ z.object({ kind: z.literal('provider'), id: targetIdSchema }).strict(),
+ z.object({ kind: z.literal('model'), id: targetIdSchema }).strict(),
+ z.object({ kind: z.literal('tool'), id: targetIdSchema }).strict(),
+ z.object({ kind: z.literal('knowledge_connector'), id: targetIdSchema }).strict(),
+ z.object({ kind: z.literal('file_share_auth'), id: z.enum(FILE_SHARE_AUTH_TYPES) }).strict(),
+ z.object({ kind: z.literal('chat_deploy_auth'), id: z.enum(FILE_SHARE_AUTH_TYPES) }).strict(),
+ z.object({ kind: z.literal('usage_limit'), id: z.literal('member') }).strict(),
+]) satisfies z.ZodType
+export const storedAccessRequestPolicyValueSchema = z.union([
+ z.boolean(),
+ PERMISSION_GROUP_FIELDS.allowedIntegrations.readSchema,
+])
+
+export const storedAccessRequestPolicyChangeSchema = z.object({
+ configKey: z.enum(
+ Object.keys(PERMISSION_GROUP_FIELDS) as (keyof typeof PERMISSION_GROUP_FIELDS)[]
+ ),
+ label: z.string().min(1).max(512),
+ before: storedAccessRequestPolicyValueSchema,
+ after: storedAccessRequestPolicyValueSchema,
+})
+
+export const storedAccessRequestDecisionSchema = z.object({
+ resolutionKind: z.enum(['permission', 'usage_limit']),
+ changes: z
+ .array(storedAccessRequestPolicyChangeSchema)
+ .max(Object.keys(PERMISSION_GROUP_FIELDS).length),
+ impact: z.object({
+ memberCount: z.number().int().nonnegative(),
+ workspaceCount: z.number().int().nonnegative(),
+ workspaceNames: z.array(z.string()).max(100),
+ truncated: z.boolean(),
+ }),
+ group: z.object({ id: z.string().min(1).max(128), name: z.string() }).nullable(),
+ currentLimitCredits: z.number().finite().nonnegative().nullable(),
+ newLimitCredits: z.number().finite().nonnegative().nullable(),
+ fingerprint: fingerprintSchema,
+})
+export type AccessRequestDecision = z.output
diff --git a/apps/sim/lib/permission-access-requests/settings.test.ts b/apps/sim/lib/permission-access-requests/settings.test.ts
new file mode 100644
index 00000000000..69643b15c04
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/settings.test.ts
@@ -0,0 +1,95 @@
+/**
+ * @vitest-environment node
+ */
+import { organizationAccessRequestSettings } from '@sim/db/schema'
+import { dbChainMockFns, queueTableRows, resetDbChainMock } from '@sim/testing'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+
+const { mockIsFeatureEnabled } = vi.hoisted(() => ({ mockIsFeatureEnabled: vi.fn() }))
+
+vi.mock('@/lib/core/config/feature-flags', () => ({ isFeatureEnabled: mockIsFeatureEnabled }))
+
+import {
+ isAccessRequestEnabled,
+ readAccessRequestSettings,
+} from '@/lib/permission-access-requests/settings'
+
+beforeEach(() => {
+ vi.clearAllMocks()
+ resetDbChainMock()
+ mockIsFeatureEnabled.mockResolvedValue(true)
+})
+
+describe('permission access request settings', () => {
+ it('defaults the organization preference on when no settings row exists', async () => {
+ queueTableRows(organizationAccessRequestSettings, [])
+
+ await expect(readAccessRequestSettings('organization-one')).resolves.toEqual({
+ allowRequests: true,
+ })
+ expect(dbChainMockFns.limit).toHaveBeenCalledWith(1)
+ expect(dbChainMockFns.where).toHaveBeenCalledWith({
+ type: 'eq',
+ left: organizationAccessRequestSettings.organizationId,
+ right: 'organization-one',
+ })
+ })
+
+ it('does not let the default-on preference bypass the global rollout flag', async () => {
+ mockIsFeatureEnabled.mockResolvedValue(false)
+
+ await expect(isAccessRequestEnabled('organization-one')).resolves.toBe(false)
+
+ expect(mockIsFeatureEnabled).toHaveBeenCalledExactlyOnceWith('permission-access-requests')
+ expect(dbChainMockFns.select).not.toHaveBeenCalled()
+ })
+
+ it('enables requests when rollout is active and the organization has not opted out', async () => {
+ queueTableRows(organizationAccessRequestSettings, [])
+
+ await expect(isAccessRequestEnabled('organization-one')).resolves.toBe(true)
+ })
+
+ it('rechecks rollout after an enabled admission snapshot', async () => {
+ mockIsFeatureEnabled.mockResolvedValue(false)
+
+ await expect(isAccessRequestEnabled('organization-one', undefined, true)).resolves.toBe(false)
+
+ expect(mockIsFeatureEnabled).toHaveBeenCalledExactlyOnceWith('permission-access-requests')
+ expect(dbChainMockFns.select).not.toHaveBeenCalled()
+ })
+
+ it('keeps a disabled admission snapshot denied even if rollout is now enabled', async () => {
+ await expect(isAccessRequestEnabled('organization-one', undefined, false)).resolves.toBe(false)
+
+ expect(mockIsFeatureEnabled).not.toHaveBeenCalled()
+ expect(dbChainMockFns.select).not.toHaveBeenCalled()
+ })
+
+ it('requires the current organization preference after an enabled admission snapshot', async () => {
+ queueTableRows(organizationAccessRequestSettings, [{ allowRequests: false }])
+
+ await expect(isAccessRequestEnabled('organization-one', undefined, true)).resolves.toBe(false)
+
+ expect(mockIsFeatureEnabled).toHaveBeenCalledExactlyOnceWith('permission-access-requests')
+ expect(dbChainMockFns.select).toHaveBeenCalledTimes(1)
+ })
+
+ it('honors an organization opt-out while global rollout is active', async () => {
+ queueTableRows(organizationAccessRequestSettings, [{ allowRequests: false }])
+
+ await expect(isAccessRequestEnabled('organization-one')).resolves.toBe(false)
+ })
+
+ it('preserves an explicit enabled preference', async () => {
+ queueTableRows(organizationAccessRequestSettings, [{ allowRequests: true }])
+
+ await expect(isAccessRequestEnabled('organization-one')).resolves.toBe(true)
+ })
+
+ it('does not reinterpret a failed settings lookup as permission to submit', async () => {
+ dbChainMockFns.limit.mockRejectedValueOnce(new Error('database unavailable'))
+
+ await expect(isAccessRequestEnabled('organization-one')).rejects.toThrow('database unavailable')
+ })
+})
diff --git a/apps/sim/lib/permission-access-requests/settings.ts b/apps/sim/lib/permission-access-requests/settings.ts
new file mode 100644
index 00000000000..f2b35394116
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/settings.ts
@@ -0,0 +1,26 @@
+import { db } from '@sim/db'
+import { organizationAccessRequestSettings } from '@sim/db/schema'
+import { eq } from 'drizzle-orm'
+import { isFeatureEnabled } from '@/lib/core/config/feature-flags'
+import type { DbOrTx } from '@/lib/db/types'
+
+/** Missing settings preserve the default-on organization preference. */
+export async function readAccessRequestSettings(organizationId: string, executor: DbOrTx = db) {
+ const [row] = await executor
+ .select({ allowRequests: organizationAccessRequestSettings.allowRequests })
+ .from(organizationAccessRequestSettings)
+ .where(eq(organizationAccessRequestSettings.organizationId, organizationId))
+ .limit(1)
+ return { allowRequests: row?.allowRequests ?? true }
+}
+
+/** The rollout flag is evaluated globally; organization preferences can only narrow it. */
+export async function isAccessRequestEnabled(
+ organizationId: string,
+ executor: DbOrTx = db,
+ enabledAtAdmission?: boolean
+): Promise {
+ if (enabledAtAdmission === false || !(await isFeatureEnabled('permission-access-requests')))
+ return false
+ return (await readAccessRequestSettings(organizationId, executor)).allowRequests
+}
diff --git a/apps/sim/lib/permission-access-requests/types.ts b/apps/sim/lib/permission-access-requests/types.ts
new file mode 100644
index 00000000000..d8324a42c52
--- /dev/null
+++ b/apps/sim/lib/permission-access-requests/types.ts
@@ -0,0 +1,82 @@
+import type { AccessRequestDecision } from '@/lib/permission-access-requests/schemas'
+import type {
+ AccessRequestScope,
+ AccessRequestTarget,
+} from '@/lib/permission-groups/access-requests/targets'
+
+export type AccessRequestStatus = 'pending' | 'fulfilled' | 'declined' | 'cancelled' | 'closed'
+
+export interface AccessRequestSettings {
+ allowRequests: boolean
+}
+
+export interface AccessRequestRecord {
+ id: string
+ organizationId: string
+ workspaceId: string | null
+ target: AccessRequestTarget
+ targetLabel: string
+ reason: string
+ status: AccessRequestStatus
+ decisionReason: string | null
+ createdAt: string
+ decidedAt: string | null
+ groupName: string | null
+ requester: { id: string; name: string | null; email: string }
+}
+
+export interface AccessRequestList {
+ requests: AccessRequestRecord[]
+ total: number
+ hasMore: boolean
+}
+
+export interface CreateAccessRequestInput {
+ scope: AccessRequestScope
+ target: AccessRequestTarget
+ reason?: string
+}
+
+export type DiscoverAccessRequestsInput = AccessRequestScope & {
+ limit: number
+ offset: number
+ search?: string
+ targetKind?: AccessRequestTarget['kind']
+ state?: 'allowed' | 'requestable' | 'unavailable'
+}
+
+export interface AccessRequestDiscovery {
+ enabled: boolean
+ organizationId: string | null
+ entries: {
+ target: AccessRequestTarget
+ label: string
+ state: 'allowed' | 'requestable' | 'unavailable'
+ reason: string | null
+ pendingRequestId: string | null
+ }[]
+ total: number
+ hasMore: boolean
+}
+
+export type ResolveAccessRequestDecision =
+ | { action: 'apply'; expectedFingerprint: string; newLimitCredits?: number }
+ | { action: 'decline'; reason: string }
+
+export type AccessRequestImpact = AccessRequestDecision['impact']
+
+export type AccessRequestPreview = Omit<
+ AccessRequestDecision,
+ 'resolutionKind' | 'group' | 'currentLimitCredits'
+> & {
+ request: AccessRequestRecord
+ canApply: boolean
+ unavailableReason: string | null
+} & (
+ | {
+ resolutionKind: 'permission'
+ group: AccessRequestDecision['group']
+ currentLimitCredits: null
+ }
+ | { resolutionKind: 'usage_limit'; group: null; currentLimitCredits: number | null }
+ )
diff --git a/apps/sim/lib/permission-groups/access-requests/targets.test.ts b/apps/sim/lib/permission-groups/access-requests/targets.test.ts
new file mode 100644
index 00000000000..d5ac0b2db25
--- /dev/null
+++ b/apps/sim/lib/permission-groups/access-requests/targets.test.ts
@@ -0,0 +1,333 @@
+/**
+ * @vitest-environment node
+ */
+import { describe, expect, it } from 'vitest'
+import {
+ type AccessRequestTarget,
+ buildAccessRequestPolicyDelta,
+ createAccessRequestCatalog,
+ describeAccessRequestTarget,
+ getAccessRequestTargetKey,
+ isAccessRequestTargetDenied,
+ isAccessRequestTargetInScope,
+ validateAccessRequestTarget,
+} from '@/lib/permission-groups/access-requests/targets'
+import { CAPABILITY_RULES } from '@/lib/permission-groups/capabilities'
+import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields'
+
+const catalog = createAccessRequestCatalog({
+ integrations: [
+ { id: 'slack_v2', label: 'Slack' },
+ { id: 'github', label: 'GitHub' },
+ ],
+ providers: [
+ { id: 'openai', label: 'OpenAI' },
+ { id: 'anthropic', label: 'Anthropic' },
+ ],
+ models: [
+ { id: 'gpt-example', label: 'Example GPT', providerId: 'openai' },
+ { id: 'other-gpt', label: 'Other GPT', providerId: 'openai' },
+ ],
+ tools: [{ id: 'slack_send_message_v2', label: 'Send message', integrationId: 'slack_v2' }],
+ knowledgeConnectors: [{ id: 'google_drive', label: 'Google Drive' }],
+})
+
+describe('access request targets', () => {
+ it('rejects unknown and prototype-named catalog IDs', () => {
+ for (const id of ['__proto__', 'constructor', 'missing']) {
+ expect(validateAccessRequestTarget({ kind: 'integration', id }, catalog)).toBeNull()
+ expect(validateAccessRequestTarget({ kind: 'provider', id }, catalog)).toBeNull()
+ expect(validateAccessRequestTarget({ kind: 'model', id }, catalog)).toBeNull()
+ expect(validateAccessRequestTarget({ kind: 'tool', id }, catalog)).toBeNull()
+ }
+ })
+
+ it('canonicalizes integration successors before testing or keying a request', () => {
+ const target = validateAccessRequestTarget({ kind: 'integration', id: 'Slack' }, catalog)
+ expect(target).toEqual({ kind: 'integration', id: 'slack_v2' })
+ expect(target && getAccessRequestTargetKey(target)).toBe('integration:slack_v2')
+ const delta = buildAccessRequestPolicyDelta(
+ { kind: 'integration', id: 'slack_v2' },
+ { ...DEFAULT_PERMISSION_GROUP_CONFIG, allowedIntegrations: ['SLACK'] },
+ catalog
+ )
+ expect(delta.changes).toEqual([])
+ })
+
+ it('allows a single member of an empty allowlist without lifting the whole allowlist', () => {
+ const delta = buildAccessRequestPolicyDelta(
+ { kind: 'integration', id: 'slack_v2' },
+ { ...DEFAULT_PERMISSION_GROUP_CONFIG, allowedIntegrations: [] },
+ catalog
+ )
+ expect(delta.config.allowedIntegrations).toEqual(['slack_v2'])
+ expect(delta.changes).toEqual([
+ {
+ configKey: 'allowedIntegrations',
+ label: 'Allowed integrations and blocks',
+ before: [],
+ after: ['slack_v2'],
+ },
+ ])
+ expect(
+ buildAccessRequestPolicyDelta(
+ { kind: 'integration', id: 'slack_v2' },
+ DEFAULT_PERMISSION_GROUP_CONFIG,
+ catalog
+ ).changes
+ ).toEqual([])
+ })
+
+ it('shows both provider and model changes while preserving other explicit denials', () => {
+ const original = {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ allowedModelProviders: ['anthropic'],
+ deniedModels: ['GPT-EXAMPLE', 'other-gpt'],
+ }
+ const delta = buildAccessRequestPolicyDelta(
+ { kind: 'model', id: 'GpT-ExAmPlE' },
+ original,
+ catalog
+ )
+ expect(delta.config.allowedModelProviders).toEqual(['anthropic', 'openai'])
+ expect(delta.config.deniedModels).toEqual(['other-gpt'])
+ expect(delta.changes.map((change) => change.configKey)).toEqual([
+ 'allowedModelProviders',
+ 'deniedModels',
+ ])
+ expect(original.allowedModelProviders).toEqual(['anthropic'])
+ expect(original.deniedModels).toEqual(['GPT-EXAMPLE', 'other-gpt'])
+ })
+
+ it('keeps model denials when requesting a provider', () => {
+ const delta = buildAccessRequestPolicyDelta(
+ { kind: 'provider', id: 'openai' },
+ {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ allowedModelProviders: [],
+ deniedModels: ['gpt-example'],
+ },
+ catalog
+ )
+ expect(delta.config.deniedModels).toEqual(['gpt-example'])
+ expect(delta.changes.map((change) => change.configKey)).toEqual(['allowedModelProviders'])
+ })
+
+ it('shows the tool and parent integration changes using exact tool IDs', () => {
+ const config = {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ allowedIntegrations: ['github'],
+ deniedTools: ['slack_send_message_v2', 'other_tool'],
+ }
+ const delta = buildAccessRequestPolicyDelta(
+ { kind: 'tool', id: 'slack_send_message_v2' },
+ config,
+ catalog
+ )
+ expect(delta.config.allowedIntegrations).toEqual(['github_v2', 'slack_v2'])
+ expect(delta.config.deniedTools).toEqual(['other_tool'])
+ expect(delta.changes.map((change) => change.configKey)).toEqual([
+ 'allowedIntegrations',
+ 'deniedTools',
+ ])
+ expect(
+ validateAccessRequestTarget({ kind: 'tool', id: 'SLACK_SEND_MESSAGE_V2' }, catalog)
+ ).toBeNull()
+ })
+
+ it('opens the parent module for a child action and preserves other child restrictions', () => {
+ const config = {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ hideKnowledgeBaseTab: true,
+ disableKnowledgeBaseCreation: true,
+ disableKnowledgeBaseExport: true,
+ }
+ const delta = buildAccessRequestPolicyDelta(
+ { kind: 'feature', configKey: 'disableKnowledgeBaseCreation' },
+ config,
+ catalog
+ )
+ expect(CAPABILITY_RULES['knowledge.create'].deniedBy(delta.config)).toBe(false)
+ expect(CAPABILITY_RULES['knowledge.export'].deniedBy(delta.config)).toBe(true)
+ expect(delta.changes.map((change) => change.configKey)).toEqual([
+ 'hideKnowledgeBaseTab',
+ 'disableKnowledgeBaseCreation',
+ ])
+ })
+
+ it('lifts both the connector allowlist and the module restriction', () => {
+ const delta = buildAccessRequestPolicyDelta(
+ { kind: 'knowledge_connector', id: 'google_drive' },
+ {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ hideKnowledgeBaseTab: true,
+ allowedKnowledgeConnectors: [],
+ },
+ catalog
+ )
+ expect(CAPABILITY_RULES['knowledge.use'].deniedBy(delta.config)).toBe(false)
+ expect(CAPABILITY_RULES['knowledge.connectors'].deniedBy(delta.config, 'google_drive')).toBe(
+ false
+ )
+ expect(delta.config.allowedKnowledgeConnectors).toEqual(['google_drive'])
+ })
+
+ it('includes parent sharing/module restrictions when allowing one authentication mode', () => {
+ const delta = buildAccessRequestPolicyDelta(
+ { kind: 'file_share_auth', id: 'sso' },
+ {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ hideFilesTab: true,
+ disablePublicFileSharing: true,
+ allowedFileShareAuthTypes: ['password'],
+ },
+ catalog
+ )
+ expect(delta.config.allowedFileShareAuthTypes).toEqual(['password', 'sso'])
+ expect(delta.changes.map((change) => change.configKey)).toEqual([
+ 'hideFilesTab',
+ 'disablePublicFileSharing',
+ 'allowedFileShareAuthTypes',
+ ])
+ })
+
+ it('identifies organization-only targets and keeps billing out of policy mutation', () => {
+ expect(
+ isAccessRequestTargetInScope(
+ { kind: 'feature', configKey: 'disableWorkspaceCreation' },
+ { kind: 'workspace', workspaceId: 'ws' },
+ catalog
+ )
+ ).toBe(false)
+ expect(
+ isAccessRequestTargetInScope(
+ { kind: 'feature', configKey: 'disableCliAccess' },
+ { kind: 'organization', organizationId: 'org' },
+ catalog
+ )
+ ).toBe(true)
+ expect(describeAccessRequestTarget({ kind: 'usage_limit', id: 'member' }, catalog)?.scope).toBe(
+ 'workspace-or-organization'
+ )
+ for (const scope of [
+ { kind: 'workspace', workspaceId: 'ws' },
+ { kind: 'organization', organizationId: 'org' },
+ ] as const) {
+ expect(
+ isAccessRequestTargetInScope({ kind: 'usage_limit', id: 'member' }, scope, catalog)
+ ).toBe(true)
+ }
+ expect(() =>
+ buildAccessRequestPolicyDelta(
+ { kind: 'usage_limit', id: 'member' },
+ DEFAULT_PERMISSION_GROUP_CONFIG,
+ catalog
+ )
+ ).toThrow('billing limit change')
+ })
+
+ it('includes module and upload blockers for built-in tool requests', () => {
+ const moduleCatalog = createAccessRequestCatalog({
+ integrations: [
+ { id: 'mcp', label: 'MCP' },
+ { id: 'knowledge', label: 'Knowledge' },
+ { id: 'table_v2', label: 'Tables' },
+ ],
+ providers: [],
+ models: [],
+ knowledgeConnectors: [],
+ tools: [
+ { id: 'mcp_run_operation', label: 'Run MCP operation', integrationId: 'mcp' },
+ { id: 'knowledge_create_document', label: 'Create document', integrationId: 'knowledge' },
+ ],
+ })
+ const config = {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ disableMcpTools: true,
+ hideKnowledgeBaseTab: true,
+ disableKnowledgeBaseFileUpload: true,
+ hideTablesTab: true,
+ }
+ const mcp = buildAccessRequestPolicyDelta(
+ { kind: 'tool', id: 'mcp_run_operation' },
+ config,
+ moduleCatalog
+ )
+ expect(mcp.changes.map((change) => change.configKey)).toEqual(['disableMcpTools'])
+ const upload = buildAccessRequestPolicyDelta(
+ { kind: 'tool', id: 'knowledge_create_document' },
+ config,
+ moduleCatalog
+ )
+ expect(upload.changes.map((change) => change.configKey)).toEqual([
+ 'hideKnowledgeBaseTab',
+ 'disableKnowledgeBaseFileUpload',
+ ])
+ const table = buildAccessRequestPolicyDelta(
+ { kind: 'integration', id: 'table_v2' },
+ config,
+ moduleCatalog
+ )
+ expect(table.changes.map((change) => change.configKey)).toEqual(['hideTablesTab'])
+ for (const delta of [mcp, upload, table]) {
+ expect(isAccessRequestTargetDenied(delta.target, config, moduleCatalog)).toBe(true)
+ expect(isAccessRequestTargetDenied(delta.target, delta.config, moduleCatalog)).toBe(false)
+ }
+ })
+
+ it('keeps cheap discovery denial in parity with full policy deltas', () => {
+ const targets: AccessRequestTarget[] = [
+ { kind: 'feature', configKey: 'disableKnowledgeBaseCreation' },
+ { kind: 'integration', id: 'slack' },
+ { kind: 'provider', id: 'openai' },
+ { kind: 'model', id: 'GPT-EXAMPLE' },
+ { kind: 'tool', id: 'slack_send_message_v2' },
+ { kind: 'knowledge_connector', id: 'google_drive' },
+ { kind: 'file_share_auth', id: 'public' },
+ { kind: 'chat_deploy_auth', id: 'sso' },
+ ]
+ const configs = [
+ DEFAULT_PERMISSION_GROUP_CONFIG,
+ {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ allowedIntegrations: ['SLACK'],
+ allowedModelProviders: ['openai'],
+ deniedModels: ['OTHER-GPT'],
+ },
+ {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ hideKnowledgeBaseTab: true,
+ hideFilesTab: true,
+ hideDeployChatbot: true,
+ },
+ {
+ ...DEFAULT_PERMISSION_GROUP_CONFIG,
+ allowedIntegrations: [],
+ allowedModelProviders: [],
+ deniedModels: ['GPT-EXAMPLE'],
+ deniedTools: ['slack_send_message_v2'],
+ allowedKnowledgeConnectors: [],
+ allowedFileShareAuthTypes: [],
+ allowedChatDeployAuthTypes: [],
+ },
+ ]
+ for (const config of configs) {
+ for (const target of targets) {
+ expect(isAccessRequestTargetDenied(target, config, catalog)).toBe(
+ buildAccessRequestPolicyDelta(target, config, catalog).changes.length > 0
+ )
+ }
+ }
+ })
+
+ it('permits read-level module requests for secrets and API-key visibility', () => {
+ expect(
+ describeAccessRequestTarget({ kind: 'feature', configKey: 'hideSecretsTab' }, catalog)
+ ?.minimumRole
+ ).toBe('read')
+ expect(
+ describeAccessRequestTarget({ kind: 'feature', configKey: 'hideApiKeysTab' }, catalog)
+ ?.minimumRole
+ ).toBe('read')
+ })
+})
diff --git a/apps/sim/lib/permission-groups/access-requests/targets.ts b/apps/sim/lib/permission-groups/access-requests/targets.ts
new file mode 100644
index 00000000000..80ad601af85
--- /dev/null
+++ b/apps/sim/lib/permission-groups/access-requests/targets.ts
@@ -0,0 +1,446 @@
+import {
+ type BooleanPermissionGroupConfigKey,
+ PLATFORM_FEATURES,
+} from '@/lib/permission-groups/features'
+import {
+ FILE_SHARE_AUTH_TYPES,
+ PERMISSION_GROUP_FIELDS,
+ type PermissionGroupCapabilityScope,
+ type PermissionGroupConfig,
+ type PermissionGroupConfigKey,
+} from '@/lib/permission-groups/fields'
+import {
+ resolveAccessControlBlockType,
+ toAccessControlAllowlist,
+} from '@/lib/permission-groups/integration-allowlist'
+
+export type AccessRequestScope =
+ | { kind: 'workspace'; workspaceId: string }
+ | { kind: 'organization'; organizationId: string }
+
+export type AccessRequestTarget =
+ | { kind: 'feature'; configKey: BooleanPermissionGroupConfigKey }
+ | { kind: 'integration' | 'provider' | 'model' | 'tool' | 'knowledge_connector'; id: string }
+ | { kind: 'file_share_auth' | 'chat_deploy_auth'; id: (typeof FILE_SHARE_AUTH_TYPES)[number] }
+ | { kind: 'usage_limit'; id: 'member' }
+
+export const ACCESS_REQUEST_TARGET_KINDS = [
+ 'feature',
+ 'integration',
+ 'provider',
+ 'model',
+ 'tool',
+ 'knowledge_connector',
+ 'file_share_auth',
+ 'chat_deploy_auth',
+ 'usage_limit',
+] as const satisfies readonly AccessRequestTarget['kind'][]
+
+export interface AccessRequestCatalogItem {
+ id: string
+ label: string
+}
+
+export interface AccessRequestModelItem extends AccessRequestCatalogItem {
+ providerId: string | null
+}
+
+export interface AccessRequestToolItem extends AccessRequestCatalogItem {
+ integrationId: string | null
+}
+
+export interface AccessRequestCatalogInput {
+ integrations: readonly AccessRequestCatalogItem[]
+ providers: readonly AccessRequestCatalogItem[]
+ models: readonly AccessRequestModelItem[]
+ tools: readonly AccessRequestToolItem[]
+ knowledgeConnectors: readonly AccessRequestCatalogItem[]
+}
+
+/** Catalogs come from authorized discovery; executable registries stay out of this module. */
+export interface AccessRequestCatalog {
+ integrations: ReadonlyMap
+ providers: ReadonlyMap
+ models: ReadonlyMap
+ tools: ReadonlyMap
+ knowledgeConnectors: ReadonlyMap
+}
+
+export interface AccessRequestTargetDescription {
+ label: string
+ scope: PermissionGroupCapabilityScope
+ minimumRole: 'read' | 'write'
+}
+
+export type AccessRequestPolicyValue = boolean | string[] | null
+
+export interface AccessRequestPolicyChange {
+ configKey: PermissionGroupConfigKey
+ label: string
+ before: AccessRequestPolicyValue
+ after: AccessRequestPolicyValue
+}
+
+export interface AccessRequestPolicyDelta {
+ target: AccessRequestTarget
+ targetLabel: string
+ config: PermissionGroupConfig
+ changes: AccessRequestPolicyChange[]
+}
+
+const FEATURES_BY_KEY = new Map(PLATFORM_FEATURES.map((feature) => [feature.configKey, feature]))
+
+/** The parent module must also be available for these actions to become usable. */
+const FEATURE_PARENTS: Partial<
+ Record
+> = {
+ disableKnowledgeBaseCreation: ['hideKnowledgeBaseTab'],
+ disableKnowledgeBaseFileUpload: ['hideKnowledgeBaseTab'],
+ disableKnowledgeBaseExport: ['hideKnowledgeBaseTab'],
+ disableTableCreation: ['hideTablesTab'],
+ disableTableExport: ['hideTablesTab'],
+ disableBulkFileDownload: ['hideFilesTab'],
+ disablePublicFileSharing: ['hideFilesTab'],
+ disablePersonalCredentials: ['hideIntegrationsTab'],
+}
+
+const WRITE_FEATURES = new Set([
+ 'hideDeployApi',
+ 'hideDeployMcp',
+ 'hideDeployChatbot',
+ 'disableKnowledgeBaseCreation',
+ 'disableKnowledgeBaseFileUpload',
+ 'disableTableCreation',
+ 'disableInvitations',
+ 'disablePublicFileSharing',
+ 'disableWebhookTriggers',
+])
+
+/** Built-in blocks whose operations also enter a governed platform module. */
+const INTEGRATION_FEATURES = new Map([
+ ['mcp', 'disableMcpTools'],
+ ['knowledge', 'hideKnowledgeBaseTab'],
+ ['table_v2', 'hideTablesTab'],
+ ['file_v5', 'hideFilesTab'],
+])
+
+const TOOL_FEATURES = new Map([
+ ['knowledge_create_document', 'disableKnowledgeBaseFileUpload'],
+ ['knowledge_upsert_document', 'disableKnowledgeBaseFileUpload'],
+])
+
+const LIST_FIELD_LABELS = {
+ allowedIntegrations: 'Allowed integrations and blocks',
+ allowedModelProviders: 'Allowed model providers',
+ deniedModels: 'Blocked models',
+ deniedTools: 'Blocked tools',
+ allowedKnowledgeConnectors: 'Allowed knowledge base connectors',
+ allowedFileShareAuthTypes: 'Allowed file sharing authentication',
+ allowedChatDeployAuthTypes: 'Allowed chat authentication',
+} as const
+
+const AUTH_LABELS = {
+ public: 'Public',
+ password: 'Password',
+ email: 'Email',
+ sso: 'SSO',
+} as const
+
+function indexItems(
+ items: readonly T[],
+ normalize: (id: string) => string = (id) => id
+): ReadonlyMap {
+ return new Map(items.map((item) => [normalize(item.id), item]))
+}
+
+function normalizeIntegration(id: string): string {
+ return resolveAccessControlBlockType(id.toLowerCase()).toLowerCase()
+}
+
+/** Index once per discovery, so evaluating every target does not scan every catalog repeatedly. */
+export function createAccessRequestCatalog(input: AccessRequestCatalogInput): AccessRequestCatalog {
+ return {
+ integrations: indexItems(input.integrations, normalizeIntegration),
+ providers: indexItems(input.providers),
+ models: indexItems(input.models, (id) => id.toLowerCase()),
+ tools: indexItems(input.tools),
+ knowledgeConnectors: indexItems(input.knowledgeConnectors),
+ }
+}
+
+/** Rejects unknown IDs and returns the vocabulary the existing permission gates compare. */
+export function validateAccessRequestTarget(
+ target: AccessRequestTarget,
+ catalog: AccessRequestCatalog
+): AccessRequestTarget | null {
+ switch (target.kind) {
+ case 'feature':
+ return FEATURES_BY_KEY.has(target.configKey) ? { ...target } : null
+ case 'integration': {
+ const id = normalizeIntegration(target.id)
+ return catalog.integrations.has(id) ? { kind: target.kind, id } : null
+ }
+ case 'provider':
+ return catalog.providers.has(target.id) ? { ...target } : null
+ case 'model': {
+ const model = catalog.models.get(target.id.toLowerCase())
+ if (!model || (model.providerId !== null && !catalog.providers.has(model.providerId))) {
+ return null
+ }
+ return { kind: target.kind, id: model.id }
+ }
+ case 'tool': {
+ const tool = catalog.tools.get(target.id)
+ if (
+ !tool ||
+ (tool.integrationId !== null &&
+ !catalog.integrations.has(normalizeIntegration(tool.integrationId)))
+ ) {
+ return null
+ }
+ return { kind: target.kind, id: tool.id }
+ }
+ case 'knowledge_connector':
+ return catalog.knowledgeConnectors.has(target.id) ? { ...target } : null
+ case 'file_share_auth':
+ case 'chat_deploy_auth':
+ return FILE_SHARE_AUTH_TYPES.some((authType) => authType === target.id) ? { ...target } : null
+ case 'usage_limit':
+ return target.id === 'member' ? { ...target } : null
+ }
+}
+
+/** Stable key for a target already canonicalized by validateAccessRequestTarget. */
+export function getAccessRequestTargetKey(target: AccessRequestTarget): string {
+ return `${target.kind}:${encodeURIComponent(target.kind === 'feature' ? target.configKey : target.id)}`
+}
+
+export function describeAccessRequestTarget(
+ target: AccessRequestTarget,
+ catalog: AccessRequestCatalog
+): AccessRequestTargetDescription | null {
+ const canonical = validateAccessRequestTarget(target, catalog)
+ if (!canonical) return null
+ if (canonical.kind === 'feature') {
+ const feature = FEATURES_BY_KEY.get(canonical.configKey)
+ if (!feature) return null
+ return {
+ label: feature.label,
+ scope: feature.scope,
+ minimumRole: WRITE_FEATURES.has(canonical.configKey) ? 'write' : 'read',
+ }
+ }
+ if (canonical.kind === 'usage_limit') {
+ return { label: 'Member usage limit', scope: 'workspace-or-organization', minimumRole: 'read' }
+ }
+ if (canonical.kind === 'file_share_auth' || canonical.kind === 'chat_deploy_auth') {
+ const subject = canonical.kind === 'file_share_auth' ? 'file sharing' : 'chat deployment'
+ return {
+ label: `${AUTH_LABELS[canonical.id]} ${subject}`,
+ scope: 'workspace',
+ minimumRole: 'write',
+ }
+ }
+ const items = {
+ integration: catalog.integrations,
+ provider: catalog.providers,
+ model: catalog.models,
+ tool: catalog.tools,
+ knowledge_connector: catalog.knowledgeConnectors,
+ }
+ const item = items[canonical.kind].get(
+ canonical.kind === 'model' ? canonical.id.toLowerCase() : canonical.id
+ )
+ if (!item) return null
+ return {
+ label: item.label,
+ scope: 'workspace',
+ minimumRole: canonical.kind === 'knowledge_connector' ? 'write' : 'read',
+ }
+}
+
+export function isAccessRequestTargetInScope(
+ target: AccessRequestTarget,
+ scope: AccessRequestScope,
+ catalog: AccessRequestCatalog
+): boolean {
+ const description = describeAccessRequestTarget(target, catalog)
+ return Boolean(
+ description &&
+ (description.scope === 'workspace-or-organization' || description.scope === scope.kind)
+ )
+}
+
+function allowMember(allowed: T[] | null, member: T): T[] | null {
+ return allowed === null || allowed.includes(member) ? allowed : [...allowed, member]
+}
+
+function requiredFeatures(
+ target: AccessRequestTarget,
+ catalog: AccessRequestCatalog
+): BooleanPermissionGroupConfigKey[] {
+ const keys: BooleanPermissionGroupConfigKey[] = []
+ if (target.kind === 'feature') keys.push(target.configKey)
+ if (target.kind === 'integration') {
+ const feature = INTEGRATION_FEATURES.get(target.id)
+ if (feature) keys.push(feature)
+ }
+ if (target.kind === 'tool') {
+ const integrationId = catalog.tools.get(target.id)?.integrationId
+ const integrationFeature = integrationId && INTEGRATION_FEATURES.get(integrationId)
+ if (integrationFeature) keys.push(integrationFeature)
+ const feature = TOOL_FEATURES.get(target.id)
+ if (feature) keys.push(feature)
+ }
+ if (target.kind === 'knowledge_connector') keys.push('hideKnowledgeBaseTab')
+ if (target.kind === 'file_share_auth') keys.push('disablePublicFileSharing')
+ if (target.kind === 'chat_deploy_auth') keys.push('hideDeployChatbot')
+ return [...new Set(keys.flatMap((key) => [key, ...(FEATURE_PARENTS[key] ?? [])]))]
+}
+
+function integrationDenied(config: PermissionGroupConfig, integrationId: string): boolean {
+ return (
+ config.allowedIntegrations !== null &&
+ !config.allowedIntegrations.some(
+ (id) => normalizeIntegration(id) === normalizeIntegration(integrationId)
+ )
+ )
+}
+
+/** Tests denial without copying full policies or their potentially large denylists. */
+export function isAccessRequestTargetDenied(
+ target: AccessRequestTarget,
+ config: PermissionGroupConfig,
+ catalog: AccessRequestCatalog
+): boolean {
+ const canonical = validateAccessRequestTarget(target, catalog)
+ if (!canonical) throw new Error('Unknown access request target')
+ if (requiredFeatures(canonical, catalog).some((key) => config[key])) return true
+ switch (canonical.kind) {
+ case 'feature':
+ return false
+ case 'integration':
+ return integrationDenied(config, canonical.id)
+ case 'provider':
+ return (
+ config.allowedModelProviders !== null &&
+ !config.allowedModelProviders.includes(canonical.id)
+ )
+ case 'model': {
+ const providerId = catalog.models.get(canonical.id.toLowerCase())?.providerId
+ return (
+ config.deniedModels.some((id) => id.toLowerCase() === canonical.id.toLowerCase()) ||
+ Boolean(
+ providerId &&
+ config.allowedModelProviders !== null &&
+ !config.allowedModelProviders.includes(providerId)
+ )
+ )
+ }
+ case 'tool': {
+ const integrationId = catalog.tools.get(canonical.id)?.integrationId
+ return (
+ config.deniedTools.includes(canonical.id) ||
+ Boolean(integrationId && integrationDenied(config, integrationId))
+ )
+ }
+ case 'knowledge_connector':
+ return (
+ config.allowedKnowledgeConnectors !== null &&
+ !config.allowedKnowledgeConnectors.includes(canonical.id)
+ )
+ case 'file_share_auth':
+ return (
+ config.allowedFileShareAuthTypes !== null &&
+ !config.allowedFileShareAuthTypes.includes(canonical.id)
+ )
+ case 'chat_deploy_auth':
+ return (
+ config.allowedChatDeployAuthTypes !== null &&
+ !config.allowedChatDeployAuthTypes.includes(canonical.id)
+ )
+ case 'usage_limit':
+ throw new Error('Usage limit requests require a billing limit change')
+ }
+}
+
+function allowIntegration(config: PermissionGroupConfig, id: string) {
+ const allowed = toAccessControlAllowlist(config.allowedIntegrations)
+ const canonical = normalizeIntegration(id)
+ if (allowed !== null && !allowed.has(canonical)) {
+ config.allowedIntegrations = [...allowed, canonical]
+ }
+}
+
+/**
+ * Computes the complete group-policy change. Callers must display every change before applying it;
+ * enabling a model's provider, for example, also admits other models from that provider.
+ * Usage limits belong to billing and must never be fulfilled through a permission-group mutation.
+ */
+export function buildAccessRequestPolicyDelta(
+ target: AccessRequestTarget,
+ config: PermissionGroupConfig,
+ catalog: AccessRequestCatalog
+): AccessRequestPolicyDelta {
+ const canonical = validateAccessRequestTarget(target, catalog)
+ const description = canonical && describeAccessRequestTarget(canonical, catalog)
+ if (!canonical || !description) throw new Error('Unknown access request target')
+ if (canonical.kind === 'usage_limit') {
+ throw new Error('Usage limit requests require a billing limit change')
+ }
+ const next = structuredClone(config)
+ for (const configKey of requiredFeatures(canonical, catalog)) next[configKey] = false
+ switch (canonical.kind) {
+ case 'feature':
+ break
+ case 'integration':
+ allowIntegration(next, canonical.id)
+ break
+ case 'provider':
+ next.allowedModelProviders = allowMember(next.allowedModelProviders, canonical.id)
+ break
+ case 'model': {
+ const model = catalog.models.get(canonical.id.toLowerCase())
+ next.deniedModels = next.deniedModels.filter(
+ (id) => id.toLowerCase() !== canonical.id.toLowerCase()
+ )
+ if (model?.providerId) {
+ next.allowedModelProviders = allowMember(next.allowedModelProviders, model.providerId)
+ }
+ break
+ }
+ case 'tool': {
+ const tool = catalog.tools.get(canonical.id)
+ next.deniedTools = next.deniedTools.filter((id) => id !== canonical.id)
+ if (tool?.integrationId) allowIntegration(next, tool.integrationId)
+ break
+ }
+ case 'knowledge_connector':
+ next.allowedKnowledgeConnectors = allowMember(next.allowedKnowledgeConnectors, canonical.id)
+ break
+ case 'file_share_auth':
+ next.allowedFileShareAuthTypes = allowMember(next.allowedFileShareAuthTypes, canonical.id)
+ break
+ case 'chat_deploy_auth':
+ next.allowedChatDeployAuthTypes = allowMember(next.allowedChatDeployAuthTypes, canonical.id)
+ break
+ }
+ const changes: AccessRequestPolicyChange[] = []
+ for (const configKey of Object.keys(PERMISSION_GROUP_FIELDS) as PermissionGroupConfigKey[]) {
+ const before = config[configKey]
+ const after = next[configKey]
+ if (JSON.stringify(before) === JSON.stringify(after)) continue
+ const field = PERMISSION_GROUP_FIELDS[configKey]
+ const label =
+ field.kind === 'boolean-restriction'
+ ? field.feature.label
+ : LIST_FIELD_LABELS[configKey as keyof typeof LIST_FIELD_LABELS]
+ changes.push({
+ configKey,
+ label,
+ before: structuredClone(before),
+ after: structuredClone(after),
+ })
+ }
+ return { target: canonical, targetLabel: description.label, config: next, changes }
+}
diff --git a/apps/sim/lib/permission-groups/resolve.server.ts b/apps/sim/lib/permission-groups/resolve.server.ts
index c3844bf1c77..0190a94b0ca 100644
--- a/apps/sim/lib/permission-groups/resolve.server.ts
+++ b/apps/sim/lib/permission-groups/resolve.server.ts
@@ -99,7 +99,7 @@ function inactiveUserAccessControlContext(organizationId: string | null): UserAc
* connection, and a default would let that caller silently check out a second
* pooled connection while advisory locks are held.
*/
-async function resolveDefaultGroup(
+export async function resolveDefaultGroup(
organizationId: string,
executor: DbOrTx
): Promise {
@@ -155,9 +155,10 @@ async function resolveDefaultGroup(
export async function resolveWorkspaceGroup(
userId: string,
organizationId: string,
- workspaceId: string
+ workspaceId: string,
+ executor: DbOrTx = db
): Promise {
- const rows = await db
+ const rows = await executor
.select({
id: permissionGroup.id,
name: permissionGroup.name,
@@ -199,7 +200,7 @@ export async function resolveWorkspaceGroup(
}
}
- return resolveDefaultGroup(organizationId, db)
+ return resolveDefaultGroup(organizationId, executor)
}
/**
diff --git a/apps/sim/lib/settings/application/workspace-section-access.test.ts b/apps/sim/lib/settings/application/workspace-section-access.test.ts
index a8ca619c801..cb9724ac59e 100644
--- a/apps/sim/lib/settings/application/workspace-section-access.test.ts
+++ b/apps/sim/lib/settings/application/workspace-section-access.test.ts
@@ -34,6 +34,7 @@ const mocks = vi.hoisted(() => ({
isScopedCredentialGroupsAvailable: vi.fn(),
isKnowledgeMemberAccessAvailable: vi.fn(),
isPlatformAdmin: vi.fn(),
+ isAccessRequestEnabled: vi.fn(),
resolveVerifiedUserAccessControlContext: vi.fn(),
resolveWorkspaceNavigation: vi.fn(),
}))
@@ -56,6 +57,10 @@ vi.mock('@/components/settings/navigation', () => ({
workspaceSectionUsesPermissionConfig: vi.fn((section: string) =>
['secrets', 'api-keys', 'inbox', 'mcp', 'custom-tools'].includes(section)
),
+ WORKSPACE_PERMISSION_CONFIG_KEYS: { secrets: 'hideSecretsTab' },
+}))
+vi.mock('@/lib/permission-access-requests/settings', () => ({
+ isAccessRequestEnabled: mocks.isAccessRequestEnabled,
}))
vi.mock('@/lib/billing/core/subscription', () => ({
isOrganizationOnEnterprisePlan: mocks.isOrganizationOnEnterprisePlan,
@@ -127,6 +132,7 @@ describe('authorizeWorkspaceSettingsSection', () => {
mocks.isScopedCredentialGroupsAvailable.mockResolvedValue(true)
mocks.isKnowledgeMemberAccessAvailable.mockResolvedValue(false)
mocks.isPlatformAdmin.mockResolvedValue(true)
+ mocks.isAccessRequestEnabled.mockResolvedValue(false)
mocks.canOpenOrganizationSettingsSection.mockResolvedValue(true)
mocks.resolveVerifiedUserAccessControlContext.mockResolvedValue({ config: {} })
mocks.resolveWorkspaceNavigation.mockReturnValue([{ id: 'secrets' }])
@@ -196,6 +202,56 @@ describe('authorizeWorkspaceSettingsSection', () => {
)
})
+ it.each([true, false])(
+ 'offers a request-only page when requests are enabled=%s',
+ async (enabled) => {
+ mocks.checkWorkspaceAccess.mockResolvedValue(ORGANIZATION_ACCESS)
+ mocks.resolveVerifiedUserAccessControlContext.mockResolvedValue({
+ config: { hideSecretsTab: true },
+ })
+ mocks.resolveWorkspaceNavigation.mockImplementation(({ permissionConfig }) =>
+ permissionConfig.hideSecretsTab ? [] : [{ id: 'secrets' }]
+ )
+ mocks.isAccessRequestEnabled.mockResolvedValue(enabled)
+
+ await expect(authorize('secrets')).resolves.toEqual(
+ enabled
+ ? { allowed: false, disposition: 'request-access', configKey: 'hideSecretsTab' }
+ : { allowed: false, disposition: 'redirect-general' }
+ )
+ expect(mocks.isAccessRequestEnabled).toHaveBeenCalledWith('organization-1')
+ }
+ )
+
+ it('keeps deployment and role exclusions when considering a permission request', async () => {
+ mocks.checkWorkspaceAccess.mockResolvedValue(ORGANIZATION_ACCESS)
+ mocks.resolveVerifiedUserAccessControlContext.mockResolvedValue({
+ config: { hideSecretsTab: true },
+ })
+ mocks.resolveWorkspaceNavigation.mockReturnValue([])
+ mocks.isAccessRequestEnabled.mockResolvedValue(true)
+
+ await expect(authorize('secrets')).resolves.toEqual({
+ allowed: false,
+ disposition: 'redirect-general',
+ })
+ expect(mocks.isAccessRequestEnabled).not.toHaveBeenCalled()
+ })
+
+ it('does not offer organization requests for personal workspace restrictions', async () => {
+ mocks.resolveVerifiedUserAccessControlContext.mockResolvedValue({
+ config: { hideSecretsTab: true },
+ })
+ mocks.resolveWorkspaceNavigation.mockImplementation(({ permissionConfig }) =>
+ permissionConfig.hideSecretsTab ? [] : [{ id: 'secrets' }]
+ )
+ await expect(authorize('secrets')).resolves.toEqual({
+ allowed: false,
+ disposition: 'redirect-general',
+ })
+ expect(mocks.isAccessRequestEnabled).not.toHaveBeenCalled()
+ })
+
it('enforces canonical permission config independently of billing subscription state', async () => {
mocks.checkWorkspaceAccess.mockResolvedValue(ORGANIZATION_ACCESS)
mocks.resolveVerifiedUserAccessControlContext.mockResolvedValue({
diff --git a/apps/sim/lib/settings/application/workspace-section-access.ts b/apps/sim/lib/settings/application/workspace-section-access.ts
index daa8201117b..2f441121f74 100644
--- a/apps/sim/lib/settings/application/workspace-section-access.ts
+++ b/apps/sim/lib/settings/application/workspace-section-access.ts
@@ -5,12 +5,15 @@ import {
UNIFIED_TO_ORGANIZATION_SECTION,
UNIFIED_TO_WORKSPACE_SECTION,
type UnifiedSettingsSection,
+ WORKSPACE_PERMISSION_CONFIG_KEYS,
type WorkspaceSettingsSection,
workspaceSectionUsesPermissionConfig,
} from '@/components/settings/navigation'
import { isOrganizationOnEnterprisePlan } from '@/lib/billing/core/subscription'
import { getDeploymentShape } from '@/lib/core/config/deployment-shape'
import { canOpenOrganizationSettingsSection } from '@/lib/organizations/settings-access'
+import { isAccessRequestEnabled } from '@/lib/permission-access-requests/settings'
+import type { BooleanPermissionGroupConfigKey } from '@/lib/permission-groups/features'
import { isPlatformAdmin } from '@/lib/permissions/super-user'
import { authorizeOrganizationSettingsSection } from '@/lib/settings/application/organization-section-access'
import { isCustomBlocksEligibleForOrganization } from '@/lib/workflows/custom-blocks/operations'
@@ -21,6 +24,7 @@ import { isForkingAvailableForWorkspace } from '@/ee/workspace-forking/lib/linea
export type WorkspaceSettingsSectionAccess =
| { allowed: true }
| { allowed: false; disposition: 'not-found' | 'redirect-general' }
+ | { allowed: false; disposition: 'request-access'; configKey: BooleanPermissionGroupConfigKey }
interface AuthorizeWorkspaceSettingsSectionInput {
workspaceId: string
@@ -28,14 +32,14 @@ interface AuthorizeWorkspaceSettingsSectionInput {
section: UnifiedSettingsSection
}
-async function canOpenWorkspaceSection(
+async function authorizeWorkspaceSection(
section: WorkspaceSettingsSection,
input: AuthorizeWorkspaceSettingsSectionInput,
workspace: {
organizationId: string | null
},
permission: NonNullable>['permission']>
-): Promise {
+): Promise {
const [accessControl, forksAvailable, customBlocksAvailable] = await Promise.all([
workspaceSectionUsesPermissionConfig(section)
? resolveVerifiedUserAccessControlContext(
@@ -53,7 +57,7 @@ async function canOpenWorkspaceSection(
])
const deployment = getDeploymentShape()
- const navigation = resolveWorkspaceNavigation({
+ const navigationOptions = {
permission,
permissionConfig: accessControl?.config ?? {},
deployment,
@@ -63,8 +67,25 @@ async function canOpenWorkspaceSection(
forks: forksAvailable,
sandboxes: true,
},
- })
- return navigation.some((item) => item.id === section)
+ }
+ if (resolveWorkspaceNavigation(navigationOptions).some((item) => item.id === section)) {
+ return { allowed: true }
+ }
+
+ const configKey = WORKSPACE_PERMISSION_CONFIG_KEYS[section]
+ if (
+ configKey &&
+ accessControl?.config?.[configKey] &&
+ workspace.organizationId &&
+ resolveWorkspaceNavigation({
+ ...navigationOptions,
+ permissionConfig: { ...navigationOptions.permissionConfig, [configKey]: false },
+ }).some((item) => item.id === section) &&
+ (await isAccessRequestEnabled(workspace.organizationId))
+ ) {
+ return { allowed: false, disposition: 'request-access', configKey }
+ }
+ return { allowed: false, disposition: 'redirect-general' }
}
async function canOpenOrganizationSection(
@@ -124,11 +145,14 @@ export async function authorizeWorkspaceSettingsSection(
}
const workspaceSection = UNIFIED_TO_WORKSPACE_SECTION[input.section]
- if (
- workspaceSection &&
- !(await canOpenWorkspaceSection(workspaceSection, input, access.workspace, access.permission))
- ) {
- return { allowed: false, disposition: 'redirect-general' }
+ if (workspaceSection) {
+ const sectionAccess = await authorizeWorkspaceSection(
+ workspaceSection,
+ input,
+ access.workspace,
+ access.permission
+ )
+ if (!sectionAccess.allowed) return sectionAccess
}
if (!(await canOpenOrganizationSection(input, access.workspace))) {
return { allowed: false, disposition: 'redirect-general' }
diff --git a/apps/sim/lib/table/application/context.test.ts b/apps/sim/lib/table/application/context.test.ts
index f5f6ee94b8c..aca566fbbad 100644
--- a/apps/sim/lib/table/application/context.test.ts
+++ b/apps/sim/lib/table/application/context.test.ts
@@ -9,7 +9,7 @@ const { getTableById, loadWorkspace } = vi.hoisted(() => ({
loadWorkspace: vi.fn(),
}))
-vi.mock('@/lib/table', () => ({ getTableById }))
+vi.mock('@/lib/table/service', () => ({ getTableById }))
vi.mock('@/lib/workspaces/application/workspace-context', () => ({
loadActiveWorkspaceApplicationContext: loadWorkspace,
}))
diff --git a/apps/sim/lib/table/application/context.ts b/apps/sim/lib/table/application/context.ts
index 9ad2abd3247..08132dcb5e6 100644
--- a/apps/sim/lib/table/application/context.ts
+++ b/apps/sim/lib/table/application/context.ts
@@ -1,6 +1,7 @@
import { OrchestrationError } from '@/lib/core/orchestration/types'
-import { getTableById, type TableDefinition } from '@/lib/table'
import type { TableAuthorizationContext } from '@/lib/table/application/authorization'
+import { getTableById } from '@/lib/table/service'
+import type { TableDefinition } from '@/lib/table/types'
import { loadActiveWorkspaceApplicationContext } from '@/lib/workspaces/application/workspace-context'
export type TableWorkspaceContext = TableAuthorizationContext
diff --git a/apps/sim/lib/table/application/tables.test.ts b/apps/sim/lib/table/application/tables.test.ts
index 405b1c73056..3af1fea3d4c 100644
--- a/apps/sim/lib/table/application/tables.test.ts
+++ b/apps/sim/lib/table/application/tables.test.ts
@@ -44,11 +44,11 @@ vi.mock('@/lib/folders/queries', () => ({
resolveFolderPathFilter: mocks.resolveFolderPathFilter,
}))
-vi.mock('@/lib/table', () => ({
+vi.mock('@/lib/table/billing', () => ({ getWorkspaceTableLimits: mocks.getLimits }))
+vi.mock('@/lib/table/service', () => ({
createTable: vi.fn(),
deleteTable: vi.fn(),
getTableById: mocks.getTableById,
- getWorkspaceTableLimits: mocks.getLimits,
listTables: mocks.listDefinitions,
moveTableToFolder: vi.fn(),
queryTables: mocks.queryTables,
diff --git a/apps/sim/lib/table/application/tables.ts b/apps/sim/lib/table/application/tables.ts
index 52974c43c4a..26b23b59ea2 100644
--- a/apps/sim/lib/table/application/tables.ts
+++ b/apps/sim/lib/table/application/tables.ts
@@ -10,21 +10,6 @@ import {
loadActiveFolderPathIndex,
resolveFolderPathFilter,
} from '@/lib/folders/queries'
-import {
- createTable,
- deleteTable,
- getTableById,
- getWorkspaceTableLimits,
- listTables as listTableDefinitions,
- moveTableToFolder,
- queryTables,
- renameTable,
- restoreTable,
- type TableDefinition,
- type TableSchema,
- type TableScope,
- updateTableDescription,
-} from '@/lib/table'
import { defineAuthorizedTableUseCase } from '@/lib/table/application/authorized-table-use-case'
import {
resolveActiveTableContext,
@@ -37,7 +22,21 @@ import {
tableFolderPathForId,
} from '@/lib/table/application/folder-paths'
import { tableOperations } from '@/lib/table/application/operations'
+import { getWorkspaceTableLimits } from '@/lib/table/billing'
import { signalTableSchemaChanged } from '@/lib/table/events'
+import {
+ createTable,
+ deleteTable,
+ getTableById,
+ listTables as listTableDefinitions,
+ moveTableToFolder,
+ queryTables,
+ renameTable,
+ restoreTable,
+ type TableScope,
+ updateTableDescription,
+} from '@/lib/table/service'
+import type { TableDefinition, TableSchema } from '@/lib/table/types'
export interface ListTablesInput {
workspaceId: string
diff --git a/apps/sim/providers/models.test.ts b/apps/sim/providers/models.test.ts
index bcb1d103709..b638b56a7cc 100644
--- a/apps/sim/providers/models.test.ts
+++ b/apps/sim/providers/models.test.ts
@@ -11,6 +11,7 @@ import {
getModelsWithPromptCaching,
getPromptCachingMinimumTokens,
getProviderModels,
+ getStaticProviderModels,
getThinkingStreamVisibility,
isCustomModelId,
isKnownModelId,
@@ -632,6 +633,37 @@ describe('fireworks static catalog (the sim-auto pool)', () => {
})
})
+describe('getStaticProviderModels', () => {
+ it('retains public built-in models after private models are discovered', () => {
+ const originalModels = PROVIDER_DEFINITIONS.fireworks.models
+ const publicModels = getStaticProviderModels('fireworks')
+ try {
+ updateFireworksModels(['fireworks/private-test-model'])
+
+ expect(publicModels.length).toBeGreaterThan(0)
+ expect(getProviderModels('fireworks')).toContain('fireworks/private-test-model')
+ expect(getStaticProviderModels('fireworks')).toEqual(publicModels)
+ } finally {
+ PROVIDER_DEFINITIONS.fireworks.models = originalModels
+ }
+ })
+
+ it("excludes discovered names even when they match another provider's public model", () => {
+ const originalModels = PROVIDER_DEFINITIONS.ollama.models
+ try {
+ updateOllamaModels(['private-local-model', 'fireworks/glm-5.2'])
+
+ expect(getStaticProviderModels('ollama')).toEqual([])
+ } finally {
+ PROVIDER_DEFINITIONS.ollama.models = originalModels
+ }
+ })
+
+ it('returns no models for an unknown provider', () => {
+ expect(getStaticProviderModels('unknown-provider')).toEqual([])
+ })
+})
+
describe('isModelDeprecated', () => {
it('returns true for a catalogued deprecated model (case-insensitive)', () => {
const id = firstDeprecatedModelId()
diff --git a/apps/sim/providers/models.ts b/apps/sim/providers/models.ts
index edd140d3b28..21d4203639d 100644
--- a/apps/sim/providers/models.ts
+++ b/apps/sim/providers/models.ts
@@ -4989,9 +4989,8 @@ interface ModelCatalogEntry {
/**
* Lowercased model ID → catalog position metadata, built once from the static
- * provider catalog. Dynamic providers contribute nothing here because their model
- * lists are populated at runtime (not at module load), and only catalog models are
- * ever reordered by release date.
+ * provider catalog, including built-in models of dynamic providers. Models added
+ * by runtime discovery are excluded.
*/
const MODEL_CATALOG_INDEX: Map = new Map(
Object.entries(PROVIDER_DEFINITIONS).flatMap(([providerId, provider]) =>
@@ -5009,6 +5008,13 @@ const MODEL_CATALOG_INDEX: Map = new Map(
)
)
+/** Returns built-in public models, excluding names added by runtime discovery. */
+export function getStaticProviderModels(providerId: string): ModelDefinition[] {
+ return (PROVIDER_DEFINITIONS[providerId]?.models ?? []).filter(
+ (model) => MODEL_CATALOG_INDEX.get(model.id.toLowerCase())?.providerId === providerId
+ )
+}
+
/**
* Reorders model IDs so that, within each provider, newer models (by release date)
* come first — while preserving the caller's existing provider grouping order. The
diff --git a/packages/audit/src/types.ts b/packages/audit/src/types.ts
index 049bdec5b44..c690c562bfd 100644
--- a/packages/audit/src/types.ts
+++ b/packages/audit/src/types.ts
@@ -184,6 +184,12 @@ export const AuditAction = {
PERMISSION_GROUP_DELETED: 'permission_group.deleted',
PERMISSION_GROUP_MEMBER_ADDED: 'permission_group_member.added',
PERMISSION_GROUP_MEMBER_REMOVED: 'permission_group_member.removed',
+ PERMISSION_ACCESS_REQUEST_CREATED: 'permission_access_request.created',
+ PERMISSION_ACCESS_REQUEST_FULFILLED: 'permission_access_request.fulfilled',
+ PERMISSION_ACCESS_REQUEST_DECLINED: 'permission_access_request.declined',
+ PERMISSION_ACCESS_REQUEST_CANCELLED: 'permission_access_request.cancelled',
+ PERMISSION_ACCESS_REQUEST_CLOSED: 'permission_access_request.closed',
+ PERMISSION_ACCESS_REQUEST_SETTINGS_CHANGED: 'permission_access_request.settings_changed',
// Sandboxes
SANDBOX_CREATED: 'sandbox.created',
@@ -288,6 +294,7 @@ export const AuditResourceType = {
ORGANIZATION: 'organization',
PASSWORD: 'password',
PERMISSION_GROUP: 'permission_group',
+ PERMISSION_ACCESS_REQUEST: 'permission_access_request',
SANDBOX: 'sandbox',
SCHEDULE: 'schedule',
SCIM_CONNECTION: 'scim_connection',
diff --git a/packages/db/migrations/0349_permission_access_requests.sql b/packages/db/migrations/0349_permission_access_requests.sql
new file mode 100644
index 00000000000..f3831ff4bf5
--- /dev/null
+++ b/packages/db/migrations/0349_permission_access_requests.sql
@@ -0,0 +1,38 @@
+CREATE TABLE "organization_access_request_settings" (
+ "organization_id" text PRIMARY KEY NOT NULL,
+ "allow_requests" boolean DEFAULT true NOT NULL,
+ "updated_at" timestamp DEFAULT now() NOT NULL,
+ "updated_by" text
+);
+--> statement-breakpoint
+CREATE TABLE "permission_access_request" (
+ "id" text PRIMARY KEY NOT NULL,
+ "organization_id" text NOT NULL,
+ "requester_id" text NOT NULL,
+ "workspace_id" text,
+ "scope_key" text NOT NULL,
+ "target_key" text NOT NULL,
+ "target" jsonb NOT NULL,
+ "target_label" text NOT NULL,
+ "membership_id" text NOT NULL,
+ "group_id" text,
+ "group_name" text,
+ "reason" text DEFAULT '' NOT NULL,
+ "status" text DEFAULT 'pending' NOT NULL,
+ "decision_reason" text,
+ "decided_by" text,
+ "decision" jsonb,
+ "created_at" timestamp DEFAULT now() NOT NULL,
+ "updated_at" timestamp DEFAULT now() NOT NULL,
+ "decided_at" timestamp,
+ CONSTRAINT "permission_access_request_status_check" CHECK ("permission_access_request"."status" in ('pending', 'fulfilled', 'declined', 'cancelled', 'closed'))
+);
+--> statement-breakpoint
+ALTER TABLE "organization_access_request_settings" ADD CONSTRAINT "organization_access_request_settings_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
+ALTER TABLE "organization_access_request_settings" ADD CONSTRAINT "organization_access_request_settings_updated_by_user_id_fk" FOREIGN KEY ("updated_by") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
+ALTER TABLE "permission_access_request" ADD CONSTRAINT "permission_access_request_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
+ALTER TABLE "permission_access_request" ADD CONSTRAINT "permission_access_request_requester_id_user_id_fk" FOREIGN KEY ("requester_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
+ALTER TABLE "permission_access_request" ADD CONSTRAINT "permission_access_request_decided_by_user_id_fk" FOREIGN KEY ("decided_by") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
+CREATE UNIQUE INDEX "permission_access_request_pending_unique" ON "permission_access_request" USING btree ("organization_id","requester_id","scope_key","target_key") WHERE "permission_access_request"."status" = 'pending';--> statement-breakpoint
+CREATE INDEX "permission_access_request_org_queue_idx" ON "permission_access_request" USING btree ("organization_id","status","created_at","id");--> statement-breakpoint
+CREATE INDEX "permission_access_request_requester_idx" ON "permission_access_request" USING btree ("organization_id","requester_id","scope_key","created_at","id");
\ No newline at end of file
diff --git a/packages/db/migrations/meta/0349_snapshot.json b/packages/db/migrations/meta/0349_snapshot.json
new file mode 100644
index 00000000000..c52c305984c
--- /dev/null
+++ b/packages/db/migrations/meta/0349_snapshot.json
@@ -0,0 +1,27023 @@
+{
+ "id": "1136b3de-1a5d-4bff-bc91-988f2458d002",
+ "prevId": "7f02eafd-2b34-42e0-a89e-8a205c612f13",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.academy_certificate": {
+ "name": "academy_certificate",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "course_id": {
+ "name": "course_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "academy_cert_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "issued_at": {
+ "name": "issued_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "certificate_number": {
+ "name": "certificate_number",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "academy_certificate_user_id_idx": {
+ "name": "academy_certificate_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "academy_certificate_course_id_idx": {
+ "name": "academy_certificate_course_id_idx",
+ "columns": [
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "academy_certificate_user_course_unique": {
+ "name": "academy_certificate_user_course_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "course_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "academy_certificate_status_idx": {
+ "name": "academy_certificate_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "academy_certificate_user_id_user_id_fk": {
+ "name": "academy_certificate_user_id_user_id_fk",
+ "tableFrom": "academy_certificate",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "academy_certificate_certificate_number_unique": {
+ "name": "academy_certificate_certificate_number_unique",
+ "nullsNotDistinct": false,
+ "columns": ["certificate_number"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "oauth_config": {
+ "name": "oauth_config",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "account_user_id_idx": {
+ "name": "account_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "idx_account_on_account_id_provider_id": {
+ "name": "idx_account_on_account_id_provider_id",
+ "columns": [
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "account_user_id_user_id_fk": {
+ "name": "account_user_id_user_id_fk",
+ "tableFrom": "account",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.api_key": {
+ "name": "api_key",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key_hash": {
+ "name": "key_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'personal'"
+ },
+ "last_used": {
+ "name": "last_used",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "api_key_workspace_type_idx": {
+ "name": "api_key_workspace_type_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "api_key_user_type_idx": {
+ "name": "api_key_user_type_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "api_key_key_hash_idx": {
+ "name": "api_key_key_hash_idx",
+ "columns": [
+ {
+ "expression": "key_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "api_key_user_id_user_id_fk": {
+ "name": "api_key_user_id_user_id_fk",
+ "tableFrom": "api_key",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "api_key_workspace_id_workspace_id_fk": {
+ "name": "api_key_workspace_id_workspace_id_fk",
+ "tableFrom": "api_key",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "api_key_created_by_user_id_fk": {
+ "name": "api_key_created_by_user_id_fk",
+ "tableFrom": "api_key",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "api_key_key_unique": {
+ "name": "api_key_key_unique",
+ "nullsNotDistinct": false,
+ "columns": ["key"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "workspace_type_check": {
+ "name": "workspace_type_check",
+ "value": "(type = 'workspace' AND workspace_id IS NOT NULL) OR (type = 'personal' AND workspace_id IS NULL)"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.async_jobs": {
+ "name": "async_jobs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_at": {
+ "name": "run_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "max_attempts": {
+ "name": "max_attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 3
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "output": {
+ "name": "output",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "async_jobs_status_started_at_idx": {
+ "name": "async_jobs_status_started_at_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "async_jobs_status_completed_at_idx": {
+ "name": "async_jobs_status_completed_at_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "completed_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "async_jobs_schedule_pending_run_at_idx": {
+ "name": "async_jobs_schedule_pending_run_at_idx",
+ "columns": [
+ {
+ "expression": "run_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"async_jobs\".\"type\" = 'schedule-execution' AND \"async_jobs\".\"status\" = 'pending'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "async_jobs_schedule_processing_started_at_idx": {
+ "name": "async_jobs_schedule_processing_started_at_idx",
+ "columns": [
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"async_jobs\".\"type\" = 'schedule-execution' AND \"async_jobs\".\"status\" = 'processing'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "async_jobs_schedule_unreconciled_terminal_idx": {
+ "name": "async_jobs_schedule_unreconciled_terminal_idx",
+ "columns": [
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"async_jobs\".\"type\" = 'schedule-execution' AND \"async_jobs\".\"status\" IN ('completed', 'failed', 'cancelled') AND COALESCE(\"async_jobs\".\"metadata\" ->> 'scheduleReconciled', 'false') <> 'true'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.audit_log": {
+ "name": "audit_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_name": {
+ "name": "actor_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "actor_email": {
+ "name": "actor_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_name": {
+ "name": "resource_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'"
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "surface": {
+ "name": "surface",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "audit_log_workspace_created_idx": {
+ "name": "audit_log_workspace_created_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "audit_log_workspace_created_at_id_idx": {
+ "name": "audit_log_workspace_created_at_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date_trunc('milliseconds', \"created_at\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "audit_log_actor_created_idx": {
+ "name": "audit_log_actor_created_idx",
+ "columns": [
+ {
+ "expression": "actor_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "audit_log_resource_idx": {
+ "name": "audit_log_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "audit_log_action_idx": {
+ "name": "audit_log_action_idx",
+ "columns": [
+ {
+ "expression": "action",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "audit_log_workspace_id_workspace_id_fk": {
+ "name": "audit_log_workspace_id_workspace_id_fk",
+ "tableFrom": "audit_log",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "audit_log_actor_id_user_id_fk": {
+ "name": "audit_log_actor_id_user_id_fk",
+ "tableFrom": "audit_log",
+ "tableTo": "user",
+ "columnsFrom": ["actor_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.background_work_status": {
+ "name": "background_work_status",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "background_work_kind",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "background_work_status_value",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "message": {
+ "name": "message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "background_work_status_workspace_status_idx": {
+ "name": "background_work_status_workspace_status_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "background_work_status_workflow_status_idx": {
+ "name": "background_work_status_workflow_status_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "background_work_status_meta_child_ws_idx": {
+ "name": "background_work_status_meta_child_ws_idx",
+ "columns": [
+ {
+ "expression": "(\"metadata\" ->> 'childWorkspaceId')",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "background_work_status_meta_other_ws_idx": {
+ "name": "background_work_status_meta_other_ws_idx",
+ "columns": [
+ {
+ "expression": "(\"metadata\" ->> 'otherWorkspaceId')",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "background_work_status_workspace_id_workspace_id_fk": {
+ "name": "background_work_status_workspace_id_workspace_id_fk",
+ "tableFrom": "background_work_status",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "background_work_status_workflow_id_workflow_id_fk": {
+ "name": "background_work_status_workflow_id_workflow_id_fk",
+ "tableFrom": "background_work_status",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.chat": {
+ "name": "chat",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "customizations": {
+ "name": "customizations",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'"
+ },
+ "auth_type": {
+ "name": "auth_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'public'"
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "allowed_emails": {
+ "name": "allowed_emails",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'[]'"
+ },
+ "output_configs": {
+ "name": "output_configs",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'[]'"
+ },
+ "include_thinking": {
+ "name": "include_thinking",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "include_tool_calls": {
+ "name": "include_tool_calls",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "identifier_idx": {
+ "name": "identifier_idx",
+ "columns": [
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"chat\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "chat_archived_at_partial_idx": {
+ "name": "chat_archived_at_partial_idx",
+ "columns": [
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"chat\".\"archived_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "idx_chat_on_workflow_id_archived_at": {
+ "name": "idx_chat_on_workflow_id_archived_at",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "chat_workflow_id_workflow_id_fk": {
+ "name": "chat_workflow_id_workflow_id_fk",
+ "tableFrom": "chat",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "chat_user_id_user_id_fk": {
+ "name": "chat_user_id_user_id_fk",
+ "tableFrom": "chat",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.copilot_async_tool_calls": {
+ "name": "copilot_async_tool_calls",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "checkpoint_id": {
+ "name": "checkpoint_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tool_call_id": {
+ "name": "tool_call_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tool_name": {
+ "name": "tool_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "args": {
+ "name": "args",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "status": {
+ "name": "status",
+ "type": "copilot_async_tool_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "result": {
+ "name": "result",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "permission_decision": {
+ "name": "permission_decision",
+ "type": "copilot_tool_permission_decision",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "permission_decided_at": {
+ "name": "permission_decided_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "claimed_at": {
+ "name": "claimed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "claimed_by": {
+ "name": "claimed_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "copilot_async_tool_calls_run_id_idx": {
+ "name": "copilot_async_tool_calls_run_id_idx",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_async_tool_calls_checkpoint_id_idx": {
+ "name": "copilot_async_tool_calls_checkpoint_id_idx",
+ "columns": [
+ {
+ "expression": "checkpoint_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_async_tool_calls_status_idx": {
+ "name": "copilot_async_tool_calls_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_async_tool_calls_run_status_idx": {
+ "name": "copilot_async_tool_calls_run_status_idx",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_async_tool_calls_tool_call_id_unique": {
+ "name": "copilot_async_tool_calls_tool_call_id_unique",
+ "columns": [
+ {
+ "expression": "tool_call_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "copilot_async_tool_calls_run_id_copilot_runs_id_fk": {
+ "name": "copilot_async_tool_calls_run_id_copilot_runs_id_fk",
+ "tableFrom": "copilot_async_tool_calls",
+ "tableTo": "copilot_runs",
+ "columnsFrom": ["run_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_async_tool_calls_checkpoint_id_copilot_run_checkpoints_id_fk": {
+ "name": "copilot_async_tool_calls_checkpoint_id_copilot_run_checkpoints_id_fk",
+ "tableFrom": "copilot_async_tool_calls",
+ "tableTo": "copilot_run_checkpoints",
+ "columnsFrom": ["checkpoint_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.copilot_chats": {
+ "name": "copilot_chats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "chat_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'copilot'"
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'claude-3-7-sonnet-latest'"
+ },
+ "conversation_id": {
+ "name": "conversation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_conversation_key": {
+ "name": "external_conversation_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_conversation_metadata": {
+ "name": "external_conversation_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "preview_yaml": {
+ "name": "preview_yaml",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "plan_artifact": {
+ "name": "plan_artifact",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resources": {
+ "name": "resources",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'"
+ },
+ "auto_allowed_tools": {
+ "name": "auto_allowed_tools",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'"
+ },
+ "last_seen_at": {
+ "name": "last_seen_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pinned": {
+ "name": "pinned",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "copilot_chats_organization_id_idx": {
+ "name": "copilot_chats_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_external_conversation_unique": {
+ "name": "copilot_chats_external_conversation_unique",
+ "columns": [
+ {
+ "expression": "external_conversation_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"copilot_chats\".\"external_conversation_key\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_user_org_created_idx": {
+ "name": "copilot_chats_user_org_created_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_user_id_idx": {
+ "name": "copilot_chats_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_workflow_id_idx": {
+ "name": "copilot_chats_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_user_workflow_idx": {
+ "name": "copilot_chats_user_workflow_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_user_workspace_idx": {
+ "name": "copilot_chats_user_workspace_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_created_at_idx": {
+ "name": "copilot_chats_created_at_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_updated_at_idx": {
+ "name": "copilot_chats_updated_at_idx",
+ "columns": [
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_workspace_created_at_id_idx": {
+ "name": "copilot_chats_workspace_created_at_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date_trunc('milliseconds', \"created_at\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_chats_user_workspace_deleted_partial_idx": {
+ "name": "copilot_chats_user_workspace_deleted_partial_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"copilot_chats\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "copilot_chats_user_id_user_id_fk": {
+ "name": "copilot_chats_user_id_user_id_fk",
+ "tableFrom": "copilot_chats",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_chats_workflow_id_workflow_id_fk": {
+ "name": "copilot_chats_workflow_id_workflow_id_fk",
+ "tableFrom": "copilot_chats",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_chats_workspace_id_workspace_id_fk": {
+ "name": "copilot_chats_workspace_id_workspace_id_fk",
+ "tableFrom": "copilot_chats",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_chats_organization_id_organization_id_fk": {
+ "name": "copilot_chats_organization_id_organization_id_fk",
+ "tableFrom": "copilot_chats",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "copilot_chats_owner_check": {
+ "name": "copilot_chats_owner_check",
+ "value": "num_nonnulls(\"copilot_chats\".\"workspace_id\", \"copilot_chats\".\"organization_id\") <= 1"
+ },
+ "copilot_chats_organization_workflow_check": {
+ "name": "copilot_chats_organization_workflow_check",
+ "value": "\"copilot_chats\".\"organization_id\" IS NULL OR \"copilot_chats\".\"workflow_id\" IS NULL"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.copilot_feedback": {
+ "name": "copilot_feedback",
+ "schema": "",
+ "columns": {
+ "feedback_id": {
+ "name": "feedback_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chat_id": {
+ "name": "chat_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_query": {
+ "name": "user_query",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent_response": {
+ "name": "agent_response",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_positive": {
+ "name": "is_positive",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "feedback": {
+ "name": "feedback",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_yaml": {
+ "name": "workflow_yaml",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "copilot_feedback_user_id_idx": {
+ "name": "copilot_feedback_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_feedback_chat_id_idx": {
+ "name": "copilot_feedback_chat_id_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_feedback_user_chat_idx": {
+ "name": "copilot_feedback_user_chat_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_feedback_is_positive_idx": {
+ "name": "copilot_feedback_is_positive_idx",
+ "columns": [
+ {
+ "expression": "is_positive",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_feedback_created_at_idx": {
+ "name": "copilot_feedback_created_at_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "copilot_feedback_user_id_user_id_fk": {
+ "name": "copilot_feedback_user_id_user_id_fk",
+ "tableFrom": "copilot_feedback",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_feedback_chat_id_copilot_chats_id_fk": {
+ "name": "copilot_feedback_chat_id_copilot_chats_id_fk",
+ "tableFrom": "copilot_feedback",
+ "tableTo": "copilot_chats",
+ "columnsFrom": ["chat_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.copilot_messages": {
+ "name": "copilot_messages",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "chat_id": {
+ "name": "chat_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "message_id": {
+ "name": "message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stream_id": {
+ "name": "stream_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "parent_message_id": {
+ "name": "parent_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tokens_in": {
+ "name": "tokens_in",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tokens_out": {
+ "name": "tokens_out",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "seq": {
+ "name": "seq",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "copilot_messages_chat_message_unique": {
+ "name": "copilot_messages_chat_message_unique",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_messages_chat_created_at_idx": {
+ "name": "copilot_messages_chat_created_at_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"copilot_messages\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_messages_chat_seq_idx": {
+ "name": "copilot_messages_chat_seq_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "seq",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"copilot_messages\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_messages_chat_stream_idx": {
+ "name": "copilot_messages_chat_stream_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "stream_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"copilot_messages\".\"stream_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_messages_user_created_at_idx": {
+ "name": "copilot_messages_user_created_at_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"copilot_messages\".\"role\" = 'user' AND \"copilot_messages\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "copilot_messages_chat_id_copilot_chats_id_fk": {
+ "name": "copilot_messages_chat_id_copilot_chats_id_fk",
+ "tableFrom": "copilot_messages",
+ "tableTo": "copilot_chats",
+ "columnsFrom": ["chat_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.copilot_run_checkpoints": {
+ "name": "copilot_run_checkpoints",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pending_tool_call_id": {
+ "name": "pending_tool_call_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_snapshot": {
+ "name": "conversation_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "agent_state": {
+ "name": "agent_state",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "provider_request": {
+ "name": "provider_request",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "copilot_run_checkpoints_run_id_idx": {
+ "name": "copilot_run_checkpoints_run_id_idx",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_run_checkpoints_pending_tool_call_id_idx": {
+ "name": "copilot_run_checkpoints_pending_tool_call_id_idx",
+ "columns": [
+ {
+ "expression": "pending_tool_call_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_run_checkpoints_run_pending_tool_unique": {
+ "name": "copilot_run_checkpoints_run_pending_tool_unique",
+ "columns": [
+ {
+ "expression": "run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "pending_tool_call_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "copilot_run_checkpoints_run_id_copilot_runs_id_fk": {
+ "name": "copilot_run_checkpoints_run_id_copilot_runs_id_fk",
+ "tableFrom": "copilot_run_checkpoints",
+ "tableTo": "copilot_runs",
+ "columnsFrom": ["run_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.copilot_runs": {
+ "name": "copilot_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "execution_id": {
+ "name": "execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_run_id": {
+ "name": "parent_run_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "chat_id": {
+ "name": "chat_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stream_id": {
+ "name": "stream_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "agent": {
+ "name": "agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "model": {
+ "name": "model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "copilot_run_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "request_context": {
+ "name": "request_context",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "copilot_runs_execution_id_idx": {
+ "name": "copilot_runs_execution_id_idx",
+ "columns": [
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_parent_run_id_idx": {
+ "name": "copilot_runs_parent_run_id_idx",
+ "columns": [
+ {
+ "expression": "parent_run_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_chat_id_idx": {
+ "name": "copilot_runs_chat_id_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_user_id_idx": {
+ "name": "copilot_runs_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_workflow_id_idx": {
+ "name": "copilot_runs_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_workspace_id_idx": {
+ "name": "copilot_runs_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_status_idx": {
+ "name": "copilot_runs_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_chat_execution_idx": {
+ "name": "copilot_runs_chat_execution_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_execution_started_at_idx": {
+ "name": "copilot_runs_execution_started_at_idx",
+ "columns": [
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_workspace_completed_at_id_idx": {
+ "name": "copilot_runs_workspace_completed_at_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date_trunc('milliseconds', \"completed_at\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_runs_stream_id_unique": {
+ "name": "copilot_runs_stream_id_unique",
+ "columns": [
+ {
+ "expression": "stream_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "copilot_runs_chat_id_copilot_chats_id_fk": {
+ "name": "copilot_runs_chat_id_copilot_chats_id_fk",
+ "tableFrom": "copilot_runs",
+ "tableTo": "copilot_chats",
+ "columnsFrom": ["chat_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_runs_user_id_user_id_fk": {
+ "name": "copilot_runs_user_id_user_id_fk",
+ "tableFrom": "copilot_runs",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_runs_workflow_id_workflow_id_fk": {
+ "name": "copilot_runs_workflow_id_workflow_id_fk",
+ "tableFrom": "copilot_runs",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_runs_workspace_id_workspace_id_fk": {
+ "name": "copilot_runs_workspace_id_workspace_id_fk",
+ "tableFrom": "copilot_runs",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.copilot_workflow_read_hashes": {
+ "name": "copilot_workflow_read_hashes",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "chat_id": {
+ "name": "chat_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hash": {
+ "name": "hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "copilot_workflow_read_hashes_chat_id_idx": {
+ "name": "copilot_workflow_read_hashes_chat_id_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_workflow_read_hashes_workflow_id_idx": {
+ "name": "copilot_workflow_read_hashes_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "copilot_workflow_read_hashes_chat_workflow_unique": {
+ "name": "copilot_workflow_read_hashes_chat_workflow_unique",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "copilot_workflow_read_hashes_chat_id_copilot_chats_id_fk": {
+ "name": "copilot_workflow_read_hashes_chat_id_copilot_chats_id_fk",
+ "tableFrom": "copilot_workflow_read_hashes",
+ "tableTo": "copilot_chats",
+ "columnsFrom": ["chat_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "copilot_workflow_read_hashes_workflow_id_workflow_id_fk": {
+ "name": "copilot_workflow_read_hashes_workflow_id_workflow_id_fk",
+ "tableFrom": "copilot_workflow_read_hashes",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.credential": {
+ "name": "credential",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "slack_app_id": {
+ "name": "slack_app_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "credential_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "unredacted": {
+ "name": "unredacted",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env_key": {
+ "name": "env_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "env_owner_user_id": {
+ "name": "env_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "encrypted_service_account_key": {
+ "name": "encrypted_service_account_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "encrypted_personal_token": {
+ "name": "encrypted_personal_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "authorization_app_id": {
+ "name": "authorization_app_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_group_enrollment_id": {
+ "name": "credential_group_enrollment_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_group_option_id": {
+ "name": "credential_group_option_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mcp_server_id": {
+ "name": "mcp_server_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mcp_oauth_config_version": {
+ "name": "mcp_oauth_config_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "managed_oauth_scope_version": {
+ "name": "managed_oauth_scope_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_subject_id": {
+ "name": "provider_subject_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_tenant_id": {
+ "name": "provider_tenant_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "managed_oauth_status": {
+ "name": "managed_oauth_status",
+ "type": "managed_oauth_credential_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "granted_scopes": {
+ "name": "granted_scopes",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_metadata": {
+ "name": "provider_metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "encrypted_oauth_token_set": {
+ "name": "encrypted_oauth_token_set",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mcp_tools": {
+ "name": "mcp_tools",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mcp_tools_refreshed_at": {
+ "name": "mcp_tools_refreshed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "granted_at": {
+ "name": "granted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_refreshed_at": {
+ "name": "last_refreshed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "credential_organization_id_idx": {
+ "name": "credential_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_organization_account_unique": {
+ "name": "credential_organization_account_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"credential\".\"account_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_org_personal_token_unique": {
+ "name": "credential_org_personal_token_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_by",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"credential\".\"type\" = 'personal_token'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_workspace_id_idx": {
+ "name": "credential_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_type_idx": {
+ "name": "credential_type_idx",
+ "columns": [
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_provider_id_idx": {
+ "name": "credential_provider_id_idx",
+ "columns": [
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_account_id_idx": {
+ "name": "credential_account_id_idx",
+ "columns": [
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_env_owner_user_id_idx": {
+ "name": "credential_env_owner_user_id_idx",
+ "columns": [
+ {
+ "expression": "env_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_enrollment_idx": {
+ "name": "credential_group_enrollment_idx",
+ "columns": [
+ {
+ "expression": "credential_group_enrollment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_mcp_server_idx": {
+ "name": "credential_mcp_server_idx",
+ "columns": [
+ {
+ "expression": "mcp_server_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_option_unique": {
+ "name": "credential_group_option_unique",
+ "columns": [
+ {
+ "expression": "credential_group_enrollment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "credential_group_option_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"credential\".\"type\" = 'managed_oauth'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_managed_mcp_enrollment_server_unique": {
+ "name": "credential_managed_mcp_enrollment_server_unique",
+ "columns": [
+ {
+ "expression": "credential_group_enrollment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "mcp_server_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"credential\".\"type\" = 'managed_mcp'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_workspace_account_unique": {
+ "name": "credential_workspace_account_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "account_id IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_workspace_env_unique": {
+ "name": "credential_workspace_env_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "env_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "type = 'env_workspace'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_workspace_personal_env_unique": {
+ "name": "credential_workspace_personal_env_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "env_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "env_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "type = 'env_personal'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_personal_token_identity_unique": {
+ "name": "credential_personal_token_identity_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_by",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_subject_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "type = 'personal_token'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "credential_workspace_id_workspace_id_fk": {
+ "name": "credential_workspace_id_workspace_id_fk",
+ "tableFrom": "credential",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_organization_id_organization_id_fk": {
+ "name": "credential_organization_id_organization_id_fk",
+ "tableFrom": "credential",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_slack_app_id_slack_app_id_fk": {
+ "name": "credential_slack_app_id_slack_app_id_fk",
+ "tableFrom": "credential",
+ "tableTo": "slack_app",
+ "columnsFrom": ["slack_app_id"],
+ "columnsTo": ["id"],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "credential_account_id_account_id_fk": {
+ "name": "credential_account_id_account_id_fk",
+ "tableFrom": "credential",
+ "tableTo": "account",
+ "columnsFrom": ["account_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_env_owner_user_id_user_id_fk": {
+ "name": "credential_env_owner_user_id_user_id_fk",
+ "tableFrom": "credential",
+ "tableTo": "user",
+ "columnsFrom": ["env_owner_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_credential_group_enrollment_id_credential_group_enrollment_id_fk": {
+ "name": "credential_credential_group_enrollment_id_credential_group_enrollment_id_fk",
+ "tableFrom": "credential",
+ "tableTo": "credential_group_enrollment",
+ "columnsFrom": ["credential_group_enrollment_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_mcp_server_id_mcp_servers_id_fk": {
+ "name": "credential_mcp_server_id_mcp_servers_id_fk",
+ "tableFrom": "credential",
+ "tableTo": "mcp_servers",
+ "columnsFrom": ["mcp_server_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_created_by_user_id_fk": {
+ "name": "credential_created_by_user_id_fk",
+ "tableFrom": "credential",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "credential_owner_check": {
+ "name": "credential_owner_check",
+ "value": "num_nonnulls(\"credential\".\"workspace_id\", \"credential\".\"organization_id\") = 1"
+ },
+ "credential_organization_type_check": {
+ "name": "credential_organization_type_check",
+ "value": "\"credential\".\"organization_id\" IS NULL OR \"credential\".\"type\" IN ('oauth', 'managed_oauth', 'managed_mcp', 'service_account', 'personal_token')"
+ },
+ "credential_personal_token_source_check": {
+ "name": "credential_personal_token_source_check",
+ "value": "(type::text <> 'personal_token') OR (\n created_by IS NOT NULL\n AND provider_id IS NOT NULL\n AND provider_id = 'gitlab'\n AND provider_subject_id IS NOT NULL\n AND provider_tenant_id IS NOT NULL\n AND encrypted_personal_token IS NOT NULL\n AND granted_scopes IS NOT NULL\n AND cardinality(granted_scopes) > 0\n AND account_id IS NULL\n AND env_key IS NULL\n AND env_owner_user_id IS NULL\n AND authorization_app_id IS NULL\n AND encrypted_oauth_token_set IS NULL\n AND encrypted_service_account_key IS NULL\n AND unredacted = false\n )"
+ },
+ "credential_oauth_source_check": {
+ "name": "credential_oauth_source_check",
+ "value": "(type <> 'oauth') OR (account_id IS NOT NULL AND provider_id IS NOT NULL)"
+ },
+ "credential_managed_oauth_source_check": {
+ "name": "credential_managed_oauth_source_check",
+ "value": "(type::text <> 'managed_oauth') OR (\n account_id IS NULL\n AND provider_id IS NOT NULL\n AND authorization_app_id IS NOT NULL\n AND provider_subject_id IS NOT NULL\n AND managed_oauth_status IS NOT NULL\n AND granted_scopes IS NOT NULL\n AND encrypted_oauth_token_set IS NOT NULL\n AND granted_at IS NOT NULL\n )"
+ },
+ "credential_managed_oauth_group_binding_check": {
+ "name": "credential_managed_oauth_group_binding_check",
+ "value": "(type::text <> 'managed_oauth') OR (\n credential_group_enrollment_id IS NOT NULL\n AND credential_group_option_id IS NOT NULL\n AND managed_oauth_scope_version IS NOT NULL\n AND managed_oauth_scope_version > 0\n )"
+ },
+ "credential_managed_mcp_source_check": {
+ "name": "credential_managed_mcp_source_check",
+ "value": "(type::text <> 'managed_mcp') OR (\n id LIKE 'mcp-cg-%'\n AND account_id IS NULL\n AND provider_id IS NULL\n AND authorization_app_id IS NULL\n AND credential_group_enrollment_id IS NOT NULL\n AND credential_group_option_id IS NULL\n AND mcp_server_id IS NOT NULL\n AND managed_oauth_status IS NOT NULL\n AND (managed_oauth_status <> 'active' OR (\n encrypted_oauth_token_set IS NOT NULL\n AND mcp_tools IS NOT NULL\n ))\n AND granted_at IS NOT NULL\n AND managed_oauth_scope_version IS NULL\n AND provider_subject_id IS NULL\n AND provider_tenant_id IS NULL\n AND granted_scopes IS NULL\n AND provider_metadata IS NULL\n AND created_by IS NULL\n AND env_key IS NULL\n AND env_owner_user_id IS NULL\n AND encrypted_service_account_key IS NULL\n AND unredacted = false\n )"
+ },
+ "credential_creator_source_check": {
+ "name": "credential_creator_source_check",
+ "value": "(type::text = 'managed_mcp') OR created_by IS NOT NULL"
+ },
+ "credential_workspace_env_source_check": {
+ "name": "credential_workspace_env_source_check",
+ "value": "(type <> 'env_workspace') OR (env_key IS NOT NULL AND env_owner_user_id IS NULL)"
+ },
+ "credential_personal_env_source_check": {
+ "name": "credential_personal_env_source_check",
+ "value": "(type <> 'env_personal') OR (env_key IS NOT NULL AND env_owner_user_id IS NOT NULL)"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.credential_group": {
+ "name": "credential_group",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "public_id": {
+ "name": "public_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "options": {
+ "name": "options",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_provider_configuration": {
+ "name": "encrypted_provider_configuration",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "credential_group_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "credential_group_organization_id_idx": {
+ "name": "credential_group_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_organization_unique": {
+ "name": "credential_group_organization_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_public_id_unique": {
+ "name": "credential_group_public_id_unique",
+ "columns": [
+ {
+ "expression": "public_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_workspace_unique": {
+ "name": "credential_group_workspace_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "credential_group_workspace_id_workspace_id_fk": {
+ "name": "credential_group_workspace_id_workspace_id_fk",
+ "tableFrom": "credential_group",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_group_organization_id_organization_id_fk": {
+ "name": "credential_group_organization_id_organization_id_fk",
+ "tableFrom": "credential_group",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_group_created_by_user_id_fk": {
+ "name": "credential_group_created_by_user_id_fk",
+ "tableFrom": "credential_group",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "credential_group_owner_check": {
+ "name": "credential_group_owner_check",
+ "value": "num_nonnulls(\"credential_group\".\"workspace_id\", \"credential_group\".\"organization_id\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.credential_group_enrollment": {
+ "name": "credential_group_enrollment",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "credential_group_id": {
+ "name": "credential_group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "credential_group_enrollment_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'invited'"
+ },
+ "invitation_token_hash": {
+ "name": "invitation_token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invitation_expires_at": {
+ "name": "invitation_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invited_at": {
+ "name": "invited_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sent_at": {
+ "name": "sent_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_delivery_error": {
+ "name": "last_delivery_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "credential_group_enrollment_group_user_unique": {
+ "name": "credential_group_enrollment_group_user_unique",
+ "columns": [
+ {
+ "expression": "credential_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"credential_group_enrollment\".\"user_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_enrollment_user_id_idx": {
+ "name": "credential_group_enrollment_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_enrollment_group_email_unique": {
+ "name": "credential_group_enrollment_group_email_unique",
+ "columns": [
+ {
+ "expression": "credential_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_enrollment_invitation_token_hash_unique": {
+ "name": "credential_group_enrollment_invitation_token_hash_unique",
+ "columns": [
+ {
+ "expression": "invitation_token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_enrollment_group_status_idx": {
+ "name": "credential_group_enrollment_group_status_idx",
+ "columns": [
+ {
+ "expression": "credential_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_group_enrollment_group_invited_at_id_idx": {
+ "name": "credential_group_enrollment_group_invited_at_id_idx",
+ "columns": [
+ {
+ "expression": "credential_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "invited_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "credential_group_enrollment_credential_group_id_credential_group_id_fk": {
+ "name": "credential_group_enrollment_credential_group_id_credential_group_id_fk",
+ "tableFrom": "credential_group_enrollment",
+ "tableTo": "credential_group",
+ "columnsFrom": ["credential_group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_group_enrollment_user_id_user_id_fk": {
+ "name": "credential_group_enrollment_user_id_user_id_fk",
+ "tableFrom": "credential_group_enrollment",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_group_enrollment_created_by_user_id_fk": {
+ "name": "credential_group_enrollment_created_by_user_id_fk",
+ "tableFrom": "credential_group_enrollment",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "credential_group_enrollment_normalized_email_check": {
+ "name": "credential_group_enrollment_normalized_email_check",
+ "value": "\"credential_group_enrollment\".\"email\" = lower(btrim(\"credential_group_enrollment\".\"email\")) AND length(\"credential_group_enrollment\".\"email\") BETWEEN 3 AND 320"
+ },
+ "credential_group_enrollment_invitation_token_hash_length_check": {
+ "name": "credential_group_enrollment_invitation_token_hash_length_check",
+ "value": "length(\"credential_group_enrollment\".\"invitation_token_hash\") = 64"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.credential_member": {
+ "name": "credential_member",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "credential_id": {
+ "name": "credential_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "credential_member_role",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'member'"
+ },
+ "status": {
+ "name": "status",
+ "type": "credential_member_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "joined_at": {
+ "name": "joined_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "invited_by": {
+ "name": "invited_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "credential_member_user_id_idx": {
+ "name": "credential_member_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_member_role_idx": {
+ "name": "credential_member_role_idx",
+ "columns": [
+ {
+ "expression": "role",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_member_status_idx": {
+ "name": "credential_member_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "credential_member_unique": {
+ "name": "credential_member_unique",
+ "columns": [
+ {
+ "expression": "credential_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "credential_member_credential_id_credential_id_fk": {
+ "name": "credential_member_credential_id_credential_id_fk",
+ "tableFrom": "credential_member",
+ "tableTo": "credential",
+ "columnsFrom": ["credential_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_member_user_id_user_id_fk": {
+ "name": "credential_member_user_id_user_id_fk",
+ "tableFrom": "credential_member",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "credential_member_invited_by_user_id_fk": {
+ "name": "credential_member_invited_by_user_id_fk",
+ "tableFrom": "credential_member",
+ "tableTo": "user",
+ "columnsFrom": ["invited_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.custom_block": {
+ "name": "custom_block",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "icon_url": {
+ "name": "icon_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "inputs": {
+ "name": "inputs",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outputs": {
+ "name": "outputs",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "trace_child_runs": {
+ "name": "trace_child_runs",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "custom_block_organization_id_idx": {
+ "name": "custom_block_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "custom_block_workflow_id_idx": {
+ "name": "custom_block_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "custom_block_organization_type_unique": {
+ "name": "custom_block_organization_type_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "custom_block_organization_id_organization_id_fk": {
+ "name": "custom_block_organization_id_organization_id_fk",
+ "tableFrom": "custom_block",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "custom_block_workflow_id_workflow_id_fk": {
+ "name": "custom_block_workflow_id_workflow_id_fk",
+ "tableFrom": "custom_block",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "custom_block_created_by_user_id_fk": {
+ "name": "custom_block_created_by_user_id_fk",
+ "tableFrom": "custom_block",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.custom_tools": {
+ "name": "custom_tools",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "schema": {
+ "name": "schema",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "custom_tools_workspace_id_idx": {
+ "name": "custom_tools_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "custom_tools_workspace_title_unique": {
+ "name": "custom_tools_workspace_title_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "title",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "custom_tools_workspace_id_workspace_id_fk": {
+ "name": "custom_tools_workspace_id_workspace_id_fk",
+ "tableFrom": "custom_tools",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "custom_tools_user_id_user_id_fk": {
+ "name": "custom_tools_user_id_user_id_fk",
+ "tableFrom": "custom_tools",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.data_drain_runs": {
+ "name": "data_drain_runs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "drain_id": {
+ "name": "drain_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "data_drain_run_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "trigger": {
+ "name": "trigger",
+ "type": "data_drain_run_trigger",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "finished_at": {
+ "name": "finished_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rows_exported": {
+ "name": "rows_exported",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "bytes_written": {
+ "name": "bytes_written",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "cursor_before": {
+ "name": "cursor_before",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cursor_after": {
+ "name": "cursor_after",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "locators": {
+ "name": "locators",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ }
+ },
+ "indexes": {
+ "data_drain_runs_drain_started_idx": {
+ "name": "data_drain_runs_drain_started_idx",
+ "columns": [
+ {
+ "expression": "drain_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "data_drain_runs_drain_id_data_drains_id_fk": {
+ "name": "data_drain_runs_drain_id_data_drains_id_fk",
+ "tableFrom": "data_drain_runs",
+ "tableTo": "data_drains",
+ "columnsFrom": ["drain_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.data_drains": {
+ "name": "data_drains",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "data_drain_source",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "destination_type": {
+ "name": "destination_type",
+ "type": "data_drain_destination",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "destination_config": {
+ "name": "destination_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "destination_credentials": {
+ "name": "destination_credentials",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "schedule_cadence": {
+ "name": "schedule_cadence",
+ "type": "data_drain_cadence",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "cursor": {
+ "name": "cursor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_run_at": {
+ "name": "last_run_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_success_at": {
+ "name": "last_success_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "data_drains_org_idx": {
+ "name": "data_drains_org_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "data_drains_due_idx": {
+ "name": "data_drains_due_idx",
+ "columns": [
+ {
+ "expression": "enabled",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_run_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "data_drains_org_name_unique": {
+ "name": "data_drains_org_name_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "data_drains_organization_id_organization_id_fk": {
+ "name": "data_drains_organization_id_organization_id_fk",
+ "tableFrom": "data_drains",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "data_drains_created_by_user_id_fk": {
+ "name": "data_drains_created_by_user_id_fk",
+ "tableFrom": "data_drains",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.docs_embeddings": {
+ "name": "docs_embeddings",
+ "schema": "",
+ "columns": {
+ "chunk_id": {
+ "name": "chunk_id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "chunk_text": {
+ "name": "chunk_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_document": {
+ "name": "source_document",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_link": {
+ "name": "source_link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "header_text": {
+ "name": "header_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "header_level": {
+ "name": "header_level",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_count": {
+ "name": "token_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "embedding": {
+ "name": "embedding",
+ "type": "vector(1536)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "embedding_model": {
+ "name": "embedding_model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'text-embedding-3-small'"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "chunk_text_tsv": {
+ "name": "chunk_text_tsv",
+ "type": "tsvector",
+ "primaryKey": false,
+ "notNull": false,
+ "generated": {
+ "as": "to_tsvector('english', \"docs_embeddings\".\"chunk_text\")",
+ "type": "stored"
+ }
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "docs_emb_source_document_idx": {
+ "name": "docs_emb_source_document_idx",
+ "columns": [
+ {
+ "expression": "source_document",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "docs_emb_header_level_idx": {
+ "name": "docs_emb_header_level_idx",
+ "columns": [
+ {
+ "expression": "header_level",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "docs_emb_source_header_idx": {
+ "name": "docs_emb_source_header_idx",
+ "columns": [
+ {
+ "expression": "source_document",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "header_level",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "docs_emb_model_idx": {
+ "name": "docs_emb_model_idx",
+ "columns": [
+ {
+ "expression": "embedding_model",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "docs_emb_created_at_idx": {
+ "name": "docs_emb_created_at_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "docs_embedding_vector_hnsw_idx": {
+ "name": "docs_embedding_vector_hnsw_idx",
+ "columns": [
+ {
+ "expression": "embedding",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "vector_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "docs_emb_metadata_gin_idx": {
+ "name": "docs_emb_metadata_gin_idx",
+ "columns": [
+ {
+ "expression": "metadata",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ },
+ "docs_emb_chunk_text_fts_idx": {
+ "name": "docs_emb_chunk_text_fts_idx",
+ "columns": [
+ {
+ "expression": "chunk_text_tsv",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "docs_embedding_not_null_check": {
+ "name": "docs_embedding_not_null_check",
+ "value": "\"embedding\" IS NOT NULL"
+ },
+ "docs_header_level_check": {
+ "name": "docs_header_level_check",
+ "value": "\"header_level\" >= 1 AND \"header_level\" <= 6"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.document": {
+ "name": "document",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "knowledge_base_id": {
+ "name": "knowledge_base_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "filename": {
+ "name": "filename",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_url": {
+ "name": "file_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_key": {
+ "name": "storage_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mime_type": {
+ "name": "mime_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chunk_count": {
+ "name": "chunk_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "token_count": {
+ "name": "token_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "character_count": {
+ "name": "character_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "processing_status": {
+ "name": "processing_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "processing_attempts": {
+ "name": "processing_attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "processing_queued_at": {
+ "name": "processing_queued_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processing_queue_token": {
+ "name": "processing_queue_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processing_started_at": {
+ "name": "processing_started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processing_deferred_until": {
+ "name": "processing_deferred_until",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processing_completed_at": {
+ "name": "processing_completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processing_error": {
+ "name": "processing_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processing_recovery_after": {
+ "name": "processing_recovery_after",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_excluded": {
+ "name": "user_excluded",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "tag1": {
+ "name": "tag1",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag2": {
+ "name": "tag2",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag3": {
+ "name": "tag3",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag4": {
+ "name": "tag4",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag5": {
+ "name": "tag5",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag6": {
+ "name": "tag6",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag7": {
+ "name": "tag7",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number1": {
+ "name": "number1",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number2": {
+ "name": "number2",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number3": {
+ "name": "number3",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number4": {
+ "name": "number4",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number5": {
+ "name": "number5",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "date1": {
+ "name": "date1",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "date2": {
+ "name": "date2",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "boolean1": {
+ "name": "boolean1",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "boolean2": {
+ "name": "boolean2",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "boolean3": {
+ "name": "boolean3",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connector_id": {
+ "name": "connector_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content_hash": {
+ "name": "content_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_url": {
+ "name": "source_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret_provenance_version": {
+ "name": "secret_provenance_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uploaded_by": {
+ "name": "uploaded_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "acl": {
+ "name": "acl",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{ws}'::text[]"
+ },
+ "acl_requirements": {
+ "name": "acl_requirements",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "acl_verified_at": {
+ "name": "acl_verified_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_modified_at": {
+ "name": "source_modified_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_seen_at": {
+ "name": "source_seen_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uploaded_at": {
+ "name": "uploaded_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "doc_kb_id_idx": {
+ "name": "doc_kb_id_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_acl_gin_idx": {
+ "name": "doc_acl_gin_idx",
+ "columns": [
+ {
+ "expression": "acl",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "array_ops"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"document\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ },
+ "doc_filename_idx": {
+ "name": "doc_filename_idx",
+ "columns": [
+ {
+ "expression": "filename",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_processing_status_idx": {
+ "name": "doc_processing_status_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "processing_status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_processing_recovery_idx": {
+ "name": "doc_processing_recovery_idx",
+ "columns": [
+ {
+ "expression": "uploaded_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"document\".\"processing_status\" IN ('pending', 'processing', 'failed') AND \"document\".\"connector_id\" IS NOT NULL AND \"document\".\"content_hash\" IS NOT NULL AND \"document\".\"storage_key\" IS NOT NULL AND \"document\".\"user_excluded\" = false AND \"document\".\"archived_at\" IS NULL AND \"document\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_connector_processing_status_idx": {
+ "name": "doc_connector_processing_status_idx",
+ "columns": [
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "processing_status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"document\".\"processing_status\" IN ('pending', 'processing', 'failed') AND \"document\".\"connector_id\" IS NOT NULL AND \"document\".\"user_excluded\" = false AND \"document\".\"archived_at\" IS NULL AND \"document\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_connector_external_id_idx": {
+ "name": "doc_connector_external_id_idx",
+ "columns": [
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"document\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_connector_source_lookup_idx": {
+ "name": "doc_connector_source_lookup_idx",
+ "columns": [
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_connector_reconciliation_idx": {
+ "name": "doc_connector_reconciliation_idx",
+ "columns": [
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "COALESCE(\"source_seen_at\", '-infinity'::timestamp)",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"document\".\"user_excluded\" = false AND \"document\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_active_kb_token_count_idx": {
+ "name": "doc_active_kb_token_count_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "token_count",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"document\".\"user_excluded\" = false AND \"document\".\"archived_at\" IS NULL AND \"document\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_storage_key_idx": {
+ "name": "doc_storage_key_idx",
+ "columns": [
+ {
+ "expression": "storage_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"document\".\"storage_key\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_archived_at_partial_idx": {
+ "name": "doc_archived_at_partial_idx",
+ "columns": [
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"document\".\"archived_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_deleted_at_partial_idx": {
+ "name": "doc_deleted_at_partial_idx",
+ "columns": [
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"document\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_kb_tag1_lower_idx": {
+ "name": "doc_kb_tag1_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag1\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_kb_tag2_lower_idx": {
+ "name": "doc_kb_tag2_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag2\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_kb_tag3_lower_idx": {
+ "name": "doc_kb_tag3_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag3\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_kb_tag4_lower_idx": {
+ "name": "doc_kb_tag4_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag4\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_kb_tag5_lower_idx": {
+ "name": "doc_kb_tag5_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag5\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_kb_tag6_lower_idx": {
+ "name": "doc_kb_tag6_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag6\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_kb_tag7_lower_idx": {
+ "name": "doc_kb_tag7_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag7\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_number1_idx": {
+ "name": "doc_number1_idx",
+ "columns": [
+ {
+ "expression": "number1",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_number2_idx": {
+ "name": "doc_number2_idx",
+ "columns": [
+ {
+ "expression": "number2",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_number3_idx": {
+ "name": "doc_number3_idx",
+ "columns": [
+ {
+ "expression": "number3",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_number4_idx": {
+ "name": "doc_number4_idx",
+ "columns": [
+ {
+ "expression": "number4",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_number5_idx": {
+ "name": "doc_number5_idx",
+ "columns": [
+ {
+ "expression": "number5",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_date1_idx": {
+ "name": "doc_date1_idx",
+ "columns": [
+ {
+ "expression": "date1",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_date2_idx": {
+ "name": "doc_date2_idx",
+ "columns": [
+ {
+ "expression": "date2",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_boolean1_idx": {
+ "name": "doc_boolean1_idx",
+ "columns": [
+ {
+ "expression": "boolean1",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_boolean2_idx": {
+ "name": "doc_boolean2_idx",
+ "columns": [
+ {
+ "expression": "boolean2",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "doc_boolean3_idx": {
+ "name": "doc_boolean3_idx",
+ "columns": [
+ {
+ "expression": "boolean3",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "document_knowledge_base_id_knowledge_base_id_fk": {
+ "name": "document_knowledge_base_id_knowledge_base_id_fk",
+ "tableFrom": "document",
+ "tableTo": "knowledge_base",
+ "columnsFrom": ["knowledge_base_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "document_connector_id_knowledge_connector_id_fk": {
+ "name": "document_connector_id_knowledge_connector_id_fk",
+ "tableFrom": "document",
+ "tableTo": "knowledge_connector",
+ "columnsFrom": ["connector_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "document_uploaded_by_user_id_fk": {
+ "name": "document_uploaded_by_user_id_fk",
+ "tableFrom": "document",
+ "tableTo": "user",
+ "columnsFrom": ["uploaded_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "doc_acl_token_shape_check": {
+ "name": "doc_acl_token_shape_check",
+ "value": "array_position(\"document\".\"acl\", NULL) IS NULL AND (cardinality(\"document\".\"acl\") = 0 OR (cardinality(\"document\".\"acl\") = array_length(string_to_array(array_to_string(\"document\".\"acl\", E'\\n'), E'\\n'), 1) AND array_to_string(\"document\".\"acl\", E'\\n') ~ '^((ws|pub|link|u:[^\\nA-Z]+@[^\\nA-Z]+|[gs]:[^\\n:]+:[^\\n:]+:[^\\n]+)(\\n(ws|pub|link|u:[^\\nA-Z]+@[^\\nA-Z]+|[gs]:[^\\n:]+:[^\\n:]+:[^\\n]+))*)$'))"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.document_secret_provenance": {
+ "name": "document_secret_provenance",
+ "schema": "",
+ "columns": {
+ "document_id": {
+ "name": "document_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "source_hash": {
+ "name": "source_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entries": {
+ "name": "entries",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "document_secret_provenance_document_id_document_id_fk": {
+ "name": "document_secret_provenance_document_id_document_id_fk",
+ "tableFrom": "document_secret_provenance",
+ "tableTo": "document",
+ "columnsFrom": ["document_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "document_secret_provenance_status_check": {
+ "name": "document_secret_provenance_status_check",
+ "value": "\"document_secret_provenance\".\"status\" IN ('exact', 'unknown')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.embedding": {
+ "name": "embedding",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "knowledge_base_id": {
+ "name": "knowledge_base_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chunk_index": {
+ "name": "chunk_index",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chunk_hash": {
+ "name": "chunk_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret_provenance_version": {
+ "name": "secret_provenance_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content_length": {
+ "name": "content_length",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_count": {
+ "name": "token_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "embedding": {
+ "name": "embedding",
+ "type": "vector(1536)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "embedding_384": {
+ "name": "embedding_384",
+ "type": "vector(384)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "embedding_768": {
+ "name": "embedding_768",
+ "type": "vector(768)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "embedding_1024": {
+ "name": "embedding_1024",
+ "type": "vector(1024)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "embedding_3072": {
+ "name": "embedding_3072",
+ "type": "vector(3072)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "embedding_model": {
+ "name": "embedding_model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'text-embedding-3-small'"
+ },
+ "start_offset": {
+ "name": "start_offset",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "end_offset": {
+ "name": "end_offset",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tag1": {
+ "name": "tag1",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag2": {
+ "name": "tag2",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag3": {
+ "name": "tag3",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag4": {
+ "name": "tag4",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag5": {
+ "name": "tag5",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag6": {
+ "name": "tag6",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tag7": {
+ "name": "tag7",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number1": {
+ "name": "number1",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number2": {
+ "name": "number2",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number3": {
+ "name": "number3",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number4": {
+ "name": "number4",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number5": {
+ "name": "number5",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "date1": {
+ "name": "date1",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "date2": {
+ "name": "date2",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "boolean1": {
+ "name": "boolean1",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "boolean2": {
+ "name": "boolean2",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "boolean3": {
+ "name": "boolean3",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "content_tsv": {
+ "name": "content_tsv",
+ "type": "tsvector",
+ "primaryKey": false,
+ "notNull": false,
+ "generated": {
+ "as": "to_tsvector('english', \"embedding\".\"content\")",
+ "type": "stored"
+ }
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "emb_kb_id_idx": {
+ "name": "emb_kb_id_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_doc_id_idx": {
+ "name": "emb_doc_id_idx",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_doc_chunk_idx": {
+ "name": "emb_doc_chunk_idx",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "chunk_index",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_kb_model_idx": {
+ "name": "emb_kb_model_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "embedding_model",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_kb_enabled_idx": {
+ "name": "emb_kb_enabled_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "enabled",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_doc_enabled_idx": {
+ "name": "emb_doc_enabled_idx",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "enabled",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "embedding_vector_hnsw_idx": {
+ "name": "embedding_vector_hnsw_idx",
+ "columns": [
+ {
+ "expression": "embedding",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "vector_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_384_vector_hnsw_idx": {
+ "name": "embedding_384_vector_hnsw_idx",
+ "columns": [
+ {
+ "expression": "embedding_384",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "vector_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_768_vector_hnsw_idx": {
+ "name": "embedding_768_vector_hnsw_idx",
+ "columns": [
+ {
+ "expression": "embedding_768",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "vector_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_1024_vector_hnsw_idx": {
+ "name": "embedding_1024_vector_hnsw_idx",
+ "columns": [
+ {
+ "expression": "embedding_1024",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "vector_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_3072_vector_hnsw_idx": {
+ "name": "embedding_3072_vector_hnsw_idx",
+ "columns": [
+ {
+ "expression": "(\"embedding_3072\"::halfvec(3072)) halfvec_cosine_ops",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_binary_hnsw_idx": {
+ "name": "embedding_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "(binary_quantize(\"embedding\")::bit(1536)) bit_hamming_ops",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_384_binary_hnsw_idx": {
+ "name": "embedding_384_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "(binary_quantize(\"embedding_384\")::bit(384)) bit_hamming_ops",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_768_binary_hnsw_idx": {
+ "name": "embedding_768_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "(binary_quantize(\"embedding_768\")::bit(768)) bit_hamming_ops",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_1024_binary_hnsw_idx": {
+ "name": "embedding_1024_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "(binary_quantize(\"embedding_1024\")::bit(1024)) bit_hamming_ops",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_3072_binary_hnsw_idx": {
+ "name": "embedding_3072_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "(binary_quantize(\"embedding_3072\")::bit(3072)) bit_hamming_ops",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "emb_kb_tag1_lower_idx": {
+ "name": "emb_kb_tag1_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag1\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_kb_tag2_lower_idx": {
+ "name": "emb_kb_tag2_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag2\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_kb_tag3_lower_idx": {
+ "name": "emb_kb_tag3_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag3\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_kb_tag4_lower_idx": {
+ "name": "emb_kb_tag4_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag4\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_kb_tag5_lower_idx": {
+ "name": "emb_kb_tag5_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag5\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_kb_tag6_lower_idx": {
+ "name": "emb_kb_tag6_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag6\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_kb_tag7_lower_idx": {
+ "name": "emb_kb_tag7_lower_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"tag7\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_number1_idx": {
+ "name": "emb_number1_idx",
+ "columns": [
+ {
+ "expression": "number1",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_number2_idx": {
+ "name": "emb_number2_idx",
+ "columns": [
+ {
+ "expression": "number2",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_number3_idx": {
+ "name": "emb_number3_idx",
+ "columns": [
+ {
+ "expression": "number3",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_number4_idx": {
+ "name": "emb_number4_idx",
+ "columns": [
+ {
+ "expression": "number4",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_number5_idx": {
+ "name": "emb_number5_idx",
+ "columns": [
+ {
+ "expression": "number5",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_date1_idx": {
+ "name": "emb_date1_idx",
+ "columns": [
+ {
+ "expression": "date1",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_date2_idx": {
+ "name": "emb_date2_idx",
+ "columns": [
+ {
+ "expression": "date2",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_boolean1_idx": {
+ "name": "emb_boolean1_idx",
+ "columns": [
+ {
+ "expression": "boolean1",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_boolean2_idx": {
+ "name": "emb_boolean2_idx",
+ "columns": [
+ {
+ "expression": "boolean2",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_boolean3_idx": {
+ "name": "emb_boolean3_idx",
+ "columns": [
+ {
+ "expression": "boolean3",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "emb_content_fts_idx": {
+ "name": "emb_content_fts_idx",
+ "columns": [
+ {
+ "expression": "content_tsv",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "embedding_knowledge_base_id_knowledge_base_id_fk": {
+ "name": "embedding_knowledge_base_id_knowledge_base_id_fk",
+ "tableFrom": "embedding",
+ "tableTo": "knowledge_base",
+ "columnsFrom": ["knowledge_base_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "embedding_document_id_document_id_fk": {
+ "name": "embedding_document_id_document_id_fk",
+ "tableFrom": "embedding",
+ "tableTo": "document",
+ "columnsFrom": ["document_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "embedding_width_check": {
+ "name": "embedding_width_check",
+ "value": "num_nonnulls(\"embedding\", \"embedding_384\", \"embedding_768\", \"embedding_1024\", \"embedding_3072\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.embedding_keyword_search": {
+ "name": "embedding_keyword_search",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "knowledge_base_id": {
+ "name": "knowledge_base_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_tsv": {
+ "name": "content_tsv",
+ "type": "tsvector",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "embedding_keyword_search_kb_idx": {
+ "name": "embedding_keyword_search_kb_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "embedding_keyword_search_document_idx": {
+ "name": "embedding_keyword_search_document_idx",
+ "columns": [
+ {
+ "expression": "document_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "embedding_keyword_search_content_idx": {
+ "name": "embedding_keyword_search_content_idx",
+ "columns": [
+ {
+ "expression": "content_tsv",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "embedding_keyword_search_id_embedding_id_fk": {
+ "name": "embedding_keyword_search_id_embedding_id_fk",
+ "tableFrom": "embedding_keyword_search",
+ "tableTo": "embedding",
+ "columnsFrom": ["id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.embedding_search": {
+ "name": "embedding_search",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "knowledge_base_id": {
+ "name": "knowledge_base_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_id": {
+ "name": "document_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "binary": {
+ "name": "binary",
+ "type": "bit(1536)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "binary_384": {
+ "name": "binary_384",
+ "type": "bit(384)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "binary_768": {
+ "name": "binary_768",
+ "type": "bit(768)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "binary_1024": {
+ "name": "binary_1024",
+ "type": "bit(1024)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "binary_3072": {
+ "name": "binary_3072",
+ "type": "bit(3072)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "vector": {
+ "name": "vector",
+ "type": "halfvec(1536)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "vector_384": {
+ "name": "vector_384",
+ "type": "halfvec(384)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "vector_512": {
+ "name": "vector_512",
+ "type": "halfvec(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "vector_768": {
+ "name": "vector_768",
+ "type": "halfvec(768)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "vector_1024": {
+ "name": "vector_1024",
+ "type": "halfvec(1024)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "vector_3072": {
+ "name": "vector_3072",
+ "type": "halfvec(3072)",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "embedding_search_kb_idx": {
+ "name": "embedding_search_kb_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "embedding_search_binary_hnsw_idx": {
+ "name": "embedding_search_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "binary",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "bit_hamming_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_384_binary_hnsw_idx": {
+ "name": "embedding_search_384_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "binary_384",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "bit_hamming_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_768_binary_hnsw_idx": {
+ "name": "embedding_search_768_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "binary_768",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "bit_hamming_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_1024_binary_hnsw_idx": {
+ "name": "embedding_search_1024_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "binary_1024",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "bit_hamming_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_3072_binary_hnsw_idx": {
+ "name": "embedding_search_3072_binary_hnsw_idx",
+ "columns": [
+ {
+ "expression": "binary_3072",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "bit_hamming_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_cosine_hnsw_idx": {
+ "name": "embedding_search_cosine_hnsw_idx",
+ "columns": [
+ {
+ "expression": "vector",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "halfvec_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_512_cosine_hnsw_idx": {
+ "name": "embedding_search_512_cosine_hnsw_idx",
+ "columns": [
+ {
+ "expression": "vector_512",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "halfvec_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_384_cosine_hnsw_idx": {
+ "name": "embedding_search_384_cosine_hnsw_idx",
+ "columns": [
+ {
+ "expression": "vector_384",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "halfvec_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_768_cosine_hnsw_idx": {
+ "name": "embedding_search_768_cosine_hnsw_idx",
+ "columns": [
+ {
+ "expression": "vector_768",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "halfvec_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_1024_cosine_hnsw_idx": {
+ "name": "embedding_search_1024_cosine_hnsw_idx",
+ "columns": [
+ {
+ "expression": "vector_1024",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "halfvec_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ },
+ "embedding_search_3072_cosine_hnsw_idx": {
+ "name": "embedding_search_3072_cosine_hnsw_idx",
+ "columns": [
+ {
+ "expression": "vector_3072",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "halfvec_cosine_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "hnsw",
+ "with": {
+ "m": 16,
+ "ef_construction": 64
+ }
+ }
+ },
+ "foreignKeys": {
+ "embedding_search_id_embedding_id_fk": {
+ "name": "embedding_search_id_embedding_id_fk",
+ "tableFrom": "embedding_search",
+ "tableTo": "embedding",
+ "columnsFrom": ["id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "embedding_search_width_check": {
+ "name": "embedding_search_width_check",
+ "value": "num_nonnulls(\"binary\", \"binary_384\", \"binary_768\", \"binary_1024\", \"binary_3072\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.embedding_secret_provenance": {
+ "name": "embedding_secret_provenance",
+ "schema": "",
+ "columns": {
+ "embedding_id": {
+ "name": "embedding_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "content_hash": {
+ "name": "content_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entries": {
+ "name": "entries",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "embedding_secret_provenance_embedding_id_embedding_id_fk": {
+ "name": "embedding_secret_provenance_embedding_id_embedding_id_fk",
+ "tableFrom": "embedding_secret_provenance",
+ "tableTo": "embedding",
+ "columnsFrom": ["embedding_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "embedding_secret_provenance_status_check": {
+ "name": "embedding_secret_provenance_status_check",
+ "value": "\"embedding_secret_provenance\".\"status\" IN ('exact', 'unknown')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.environment": {
+ "name": "environment",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "variables": {
+ "name": "variables",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "environment_user_id_user_id_fk": {
+ "name": "environment_user_id_user_id_fk",
+ "tableFrom": "environment",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "environment_user_id_unique": {
+ "name": "environment_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": ["user_id"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.execution_large_value_dependencies": {
+ "name": "execution_large_value_dependencies",
+ "schema": "",
+ "columns": {
+ "parent_key": {
+ "name": "parent_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "child_key": {
+ "name": "child_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "execution_large_value_dependencies_workspace_parent_key_idx": {
+ "name": "execution_large_value_dependencies_workspace_parent_key_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "execution_large_value_dependencies_workspace_child_key_idx": {
+ "name": "execution_large_value_dependencies_workspace_child_key_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "child_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "execution_large_value_dependencies_workspace_id_workspace_id_fk": {
+ "name": "execution_large_value_dependencies_workspace_id_workspace_id_fk",
+ "tableFrom": "execution_large_value_dependencies",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "execution_large_value_dependencies_parent_key_child_key_pk": {
+ "name": "execution_large_value_dependencies_parent_key_child_key_pk",
+ "columns": ["parent_key", "child_key"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.execution_large_value_references": {
+ "name": "execution_large_value_references",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_id": {
+ "name": "execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "execution_large_value_reference_source",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "execution_large_value_references_workspace_execution_source_idx": {
+ "name": "execution_large_value_references_workspace_execution_source_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "execution_large_value_references_workflow_id_idx": {
+ "name": "execution_large_value_references_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "execution_large_value_references_workspace_id_workspace_id_fk": {
+ "name": "execution_large_value_references_workspace_id_workspace_id_fk",
+ "tableFrom": "execution_large_value_references",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "execution_large_value_references_workflow_id_workflow_id_fk": {
+ "name": "execution_large_value_references_workflow_id_workflow_id_fk",
+ "tableFrom": "execution_large_value_references",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "execution_large_value_references_key_execution_id_source_pk": {
+ "name": "execution_large_value_references_key_execution_id_source_pk",
+ "columns": ["key", "execution_id", "source"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.execution_large_values": {
+ "name": "execution_large_values",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_execution_id": {
+ "name": "owner_execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "size": {
+ "name": "size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "execution_large_values_owner_execution_id_idx": {
+ "name": "execution_large_values_owner_execution_id_idx",
+ "columns": [
+ {
+ "expression": "owner_execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "execution_large_values_cleanup_idx": {
+ "name": "execution_large_values_cleanup_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"execution_large_values\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "execution_large_values_tombstone_cleanup_idx": {
+ "name": "execution_large_values_tombstone_cleanup_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"execution_large_values\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "execution_large_values_workflow_id_idx": {
+ "name": "execution_large_values_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "execution_large_values_workspace_id_workspace_id_fk": {
+ "name": "execution_large_values_workspace_id_workspace_id_fk",
+ "tableFrom": "execution_large_values",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "execution_large_values_workflow_id_workflow_id_fk": {
+ "name": "execution_large_values_workflow_id_workflow_id_fk",
+ "tableFrom": "execution_large_values",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.folder": {
+ "name": "folder",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "folder_resource_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_id": {
+ "name": "parent_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "locked": {
+ "name": "locked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "folder_user_idx": {
+ "name": "folder_user_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "folder_workspace_resource_parent_idx": {
+ "name": "folder_workspace_resource_parent_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "folder_parent_sort_idx": {
+ "name": "folder_parent_sort_idx",
+ "columns": [
+ {
+ "expression": "parent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sort_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "folder_deleted_at_idx": {
+ "name": "folder_deleted_at_idx",
+ "columns": [
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "folder_workspace_deleted_partial_idx": {
+ "name": "folder_workspace_deleted_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"folder\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "folder_workspace_resource_parent_name_active_unique": {
+ "name": "folder_workspace_resource_parent_name_active_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "coalesce(\"parent_id\", '')",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"folder\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "folder_user_id_user_id_fk": {
+ "name": "folder_user_id_user_id_fk",
+ "tableFrom": "folder",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "folder_workspace_id_workspace_id_fk": {
+ "name": "folder_workspace_id_workspace_id_fk",
+ "tableFrom": "folder",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "folder_parent_id_folder_id_fk": {
+ "name": "folder_parent_id_folder_id_fk",
+ "tableFrom": "folder",
+ "tableTo": "folder",
+ "columnsFrom": ["parent_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.idempotency_key": {
+ "name": "idempotency_key",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "result": {
+ "name": "result",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "idempotency_key_created_at_idx": {
+ "name": "idempotency_key_created_at_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.invitation": {
+ "name": "invitation",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "invitation_kind",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'organization'"
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "inviter_id": {
+ "name": "inviter_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "membership_intent": {
+ "name": "membership_intent",
+ "type": "invitation_membership_intent",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'internal'"
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "invitation_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "invitation_email_idx": {
+ "name": "invitation_email_idx",
+ "columns": [
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "invitation_organization_id_idx": {
+ "name": "invitation_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "invitation_status_idx": {
+ "name": "invitation_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "invitation_pending_email_org_unique": {
+ "name": "invitation_pending_email_org_unique",
+ "columns": [
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"invitation\".\"status\" = 'pending' AND \"invitation\".\"organization_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "invitation_inviter_id_user_id_fk": {
+ "name": "invitation_inviter_id_user_id_fk",
+ "tableFrom": "invitation",
+ "tableTo": "user",
+ "columnsFrom": ["inviter_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "invitation_organization_id_organization_id_fk": {
+ "name": "invitation_organization_id_organization_id_fk",
+ "tableFrom": "invitation",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "invitation_token_unique": {
+ "name": "invitation_token_unique",
+ "nullsNotDistinct": false,
+ "columns": ["token"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.invitation_workspace_grant": {
+ "name": "invitation_workspace_grant",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "invitation_id": {
+ "name": "invitation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission": {
+ "name": "permission",
+ "type": "permission_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "invitation_workspace_grant_unique": {
+ "name": "invitation_workspace_grant_unique",
+ "columns": [
+ {
+ "expression": "invitation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "invitation_workspace_grant_workspace_id_idx": {
+ "name": "invitation_workspace_grant_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "invitation_workspace_grant_invitation_id_invitation_id_fk": {
+ "name": "invitation_workspace_grant_invitation_id_invitation_id_fk",
+ "tableFrom": "invitation_workspace_grant",
+ "tableTo": "invitation",
+ "columnsFrom": ["invitation_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "invitation_workspace_grant_workspace_id_workspace_id_fk": {
+ "name": "invitation_workspace_grant_workspace_id_workspace_id_fk",
+ "tableFrom": "invitation_workspace_grant",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.job_execution_logs": {
+ "name": "job_execution_logs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "schedule_id": {
+ "name": "schedule_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_id": {
+ "name": "execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "level": {
+ "name": "level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'running'"
+ },
+ "trigger": {
+ "name": "trigger",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ended_at": {
+ "name": "ended_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_duration_ms": {
+ "name": "total_duration_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_data": {
+ "name": "execution_data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "cost": {
+ "name": "cost",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "job_execution_logs_schedule_id_idx": {
+ "name": "job_execution_logs_schedule_id_idx",
+ "columns": [
+ {
+ "expression": "schedule_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "job_execution_logs_workspace_started_at_idx": {
+ "name": "job_execution_logs_workspace_started_at_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "job_execution_logs_workspace_ended_at_id_idx": {
+ "name": "job_execution_logs_workspace_ended_at_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date_trunc('milliseconds', \"ended_at\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "job_execution_logs_execution_id_unique": {
+ "name": "job_execution_logs_execution_id_unique",
+ "columns": [
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "job_execution_logs_trigger_idx": {
+ "name": "job_execution_logs_trigger_idx",
+ "columns": [
+ {
+ "expression": "trigger",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "job_execution_logs_schedule_id_workflow_schedule_id_fk": {
+ "name": "job_execution_logs_schedule_id_workflow_schedule_id_fk",
+ "tableFrom": "job_execution_logs",
+ "tableTo": "workflow_schedule",
+ "columnsFrom": ["schedule_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "job_execution_logs_workspace_id_workspace_id_fk": {
+ "name": "job_execution_logs_workspace_id_workspace_id_fk",
+ "tableFrom": "job_execution_logs",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.knowledge_base": {
+ "name": "knowledge_base",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "folder_id": {
+ "name": "folder_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_search_index": {
+ "name": "is_search_index",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "token_count": {
+ "name": "token_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "embedding_model": {
+ "name": "embedding_model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'text-embedding-3-small'"
+ },
+ "embedding_dimension": {
+ "name": "embedding_dimension",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1536
+ },
+ "chunking_config": {
+ "name": "chunking_config",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{\"maxSize\": 1024, \"minSize\": 1, \"overlap\": 200}'"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "kb_organization_id_idx": {
+ "name": "kb_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_organization_search_index_unique": {
+ "name": "kb_organization_search_index_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"knowledge_base\".\"is_search_index\" = true AND \"knowledge_base\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_organization_name_active_unique": {
+ "name": "kb_organization_name_active_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"knowledge_base\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_user_id_idx": {
+ "name": "kb_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_workspace_id_idx": {
+ "name": "kb_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_user_workspace_idx": {
+ "name": "kb_user_workspace_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_folder_id_idx": {
+ "name": "kb_folder_id_idx",
+ "columns": [
+ {
+ "expression": "folder_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_deleted_at_idx": {
+ "name": "kb_deleted_at_idx",
+ "columns": [
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_workspace_deleted_partial_idx": {
+ "name": "kb_workspace_deleted_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"knowledge_base\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_workspace_name_active_unique": {
+ "name": "kb_workspace_name_active_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"knowledge_base\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_workspace_search_index_unique": {
+ "name": "kb_workspace_search_index_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"knowledge_base\".\"is_search_index\" = true AND \"knowledge_base\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_base_user_id_user_id_fk": {
+ "name": "knowledge_base_user_id_user_id_fk",
+ "tableFrom": "knowledge_base",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_base_workspace_id_workspace_id_fk": {
+ "name": "knowledge_base_workspace_id_workspace_id_fk",
+ "tableFrom": "knowledge_base",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_base_organization_id_organization_id_fk": {
+ "name": "knowledge_base_organization_id_organization_id_fk",
+ "tableFrom": "knowledge_base",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_base_folder_id_folder_id_fk": {
+ "name": "knowledge_base_folder_id_folder_id_fk",
+ "tableFrom": "knowledge_base",
+ "tableTo": "folder",
+ "columnsFrom": ["folder_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "kb_owner_check": {
+ "name": "kb_owner_check",
+ "value": "num_nonnulls(\"knowledge_base\".\"workspace_id\", \"knowledge_base\".\"organization_id\") = 1"
+ },
+ "kb_organization_search_index_check": {
+ "name": "kb_organization_search_index_check",
+ "value": "\"knowledge_base\".\"organization_id\" IS NULL OR \"knowledge_base\".\"is_search_index\""
+ },
+ "kb_organization_folder_check": {
+ "name": "kb_organization_folder_check",
+ "value": "\"knowledge_base\".\"organization_id\" IS NULL OR \"knowledge_base\".\"folder_id\" IS NULL"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.knowledge_base_tag_definitions": {
+ "name": "knowledge_base_tag_definitions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "knowledge_base_id": {
+ "name": "knowledge_base_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tag_slot": {
+ "name": "tag_slot",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "field_type": {
+ "name": "field_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'text'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "kb_tag_definitions_kb_slot_idx": {
+ "name": "kb_tag_definitions_kb_slot_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "tag_slot",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_tag_definitions_kb_display_name_idx": {
+ "name": "kb_tag_definitions_kb_display_name_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kb_tag_definitions_kb_id_idx": {
+ "name": "kb_tag_definitions_kb_id_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_base_tag_definitions_knowledge_base_id_knowledge_base_id_fk": {
+ "name": "knowledge_base_tag_definitions_knowledge_base_id_knowledge_base_id_fk",
+ "tableFrom": "knowledge_base_tag_definitions",
+ "tableTo": "knowledge_base",
+ "columnsFrom": ["knowledge_base_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.knowledge_connector": {
+ "name": "knowledge_connector",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "knowledge_base_id": {
+ "name": "knowledge_base_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connector_type": {
+ "name": "connector_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "credential_id": {
+ "name": "credential_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "encrypted_api_key": {
+ "name": "encrypted_api_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_config": {
+ "name": "source_config",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sync_mode": {
+ "name": "sync_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'full'"
+ },
+ "sync_interval_minutes": {
+ "name": "sync_interval_minutes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1440
+ },
+ "access_mode": {
+ "name": "access_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'workspace'"
+ },
+ "credential_group_id": {
+ "name": "credential_group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_group_option_id": {
+ "name": "credential_group_option_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "member_sync_status": {
+ "name": "member_sync_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "member_sync_lock_token": {
+ "name": "member_sync_lock_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "member_sync_lock_lease_at": {
+ "name": "member_sync_lock_lease_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_member_sync_at": {
+ "name": "next_member_sync_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_member_sync_at": {
+ "name": "last_member_sync_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_member_sync_error": {
+ "name": "last_member_sync_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "member_sync_consecutive_failures": {
+ "name": "member_sync_consecutive_failures",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "access_rewrite_pending": {
+ "name": "access_rewrite_pending",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_sync_at": {
+ "name": "last_sync_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_sync_error": {
+ "name": "last_sync_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_sync_doc_count": {
+ "name": "last_sync_doc_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "listing_checkpoint": {
+ "name": "listing_checkpoint",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "directory_checkpoint": {
+ "name": "directory_checkpoint",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_sync_at": {
+ "name": "next_sync_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_directory_sync_at": {
+ "name": "next_directory_sync_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "consecutive_failures": {
+ "name": "consecutive_failures",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "sync_lock_token": {
+ "name": "sync_lock_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_lock_lease_at": {
+ "name": "sync_lock_lease_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "kc_knowledge_base_id_idx": {
+ "name": "kc_knowledge_base_id_idx",
+ "columns": [
+ {
+ "expression": "knowledge_base_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kc_status_next_sync_idx": {
+ "name": "kc_status_next_sync_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_sync_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kc_archived_at_partial_idx": {
+ "name": "kc_archived_at_partial_idx",
+ "columns": [
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"knowledge_connector\".\"archived_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kc_deleted_at_partial_idx": {
+ "name": "kc_deleted_at_partial_idx",
+ "columns": [
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"knowledge_connector\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kc_member_sync_due_idx": {
+ "name": "kc_member_sync_due_idx",
+ "columns": [
+ {
+ "expression": "member_sync_status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_member_sync_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"knowledge_connector\".\"access_mode\" = 'members' AND \"knowledge_connector\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kc_directory_sync_due_idx": {
+ "name": "kc_directory_sync_due_idx",
+ "columns": [
+ {
+ "expression": "next_directory_sync_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"knowledge_connector\".\"access_mode\" = 'admin' AND \"knowledge_connector\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_connector_knowledge_base_id_knowledge_base_id_fk": {
+ "name": "knowledge_connector_knowledge_base_id_knowledge_base_id_fk",
+ "tableFrom": "knowledge_connector",
+ "tableTo": "knowledge_base",
+ "columnsFrom": ["knowledge_base_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_connector_credential_group_id_credential_group_id_fk": {
+ "name": "knowledge_connector_credential_group_id_credential_group_id_fk",
+ "tableFrom": "knowledge_connector",
+ "tableTo": "credential_group",
+ "columnsFrom": ["credential_group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "kc_access_mode_check": {
+ "name": "kc_access_mode_check",
+ "value": "\"knowledge_connector\".\"access_mode\" IN ('workspace', 'members', 'admin')"
+ },
+ "kc_member_sync_status_check": {
+ "name": "kc_member_sync_status_check",
+ "value": "\"knowledge_connector\".\"member_sync_status\" IN ('idle', 'pending', 'running', 'error', 'disabled')"
+ },
+ "kc_sync_lock_exclusive_check": {
+ "name": "kc_sync_lock_exclusive_check",
+ "value": "NOT (\"knowledge_connector\".\"sync_lock_token\" IS NOT NULL AND \"knowledge_connector\".\"member_sync_lock_token\" IS NOT NULL)"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.knowledge_connector_member": {
+ "name": "knowledge_connector_member",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connector_id": {
+ "name": "connector_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "credential_id": {
+ "name": "credential_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_token": {
+ "name": "subject_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "consecutive_failures": {
+ "name": "consecutive_failures",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "next_attempt_at": {
+ "name": "next_attempt_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_started_at": {
+ "name": "last_started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_complete_listing_at": {
+ "name": "last_complete_listing_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_listed_count": {
+ "name": "last_listed_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "member_synced_through": {
+ "name": "member_synced_through",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "change_cursor": {
+ "name": "change_cursor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "listing_checkpoint": {
+ "name": "listing_checkpoint",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "suspended_at": {
+ "name": "suspended_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "kcm_organization_id_idx": {
+ "name": "kcm_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kcm_connector_credential_unique": {
+ "name": "kcm_connector_credential_unique",
+ "columns": [
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "credential_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kcm_connector_queue_idx": {
+ "name": "kcm_connector_queue_idx",
+ "columns": [
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "next_attempt_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "first"
+ },
+ {
+ "expression": "last_started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "first"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kcm_credential_idx": {
+ "name": "kcm_credential_idx",
+ "columns": [
+ {
+ "expression": "credential_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_connector_member_workspace_id_workspace_id_fk": {
+ "name": "knowledge_connector_member_workspace_id_workspace_id_fk",
+ "tableFrom": "knowledge_connector_member",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_connector_member_organization_id_organization_id_fk": {
+ "name": "knowledge_connector_member_organization_id_organization_id_fk",
+ "tableFrom": "knowledge_connector_member",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_connector_member_connector_id_knowledge_connector_id_fk": {
+ "name": "knowledge_connector_member_connector_id_knowledge_connector_id_fk",
+ "tableFrom": "knowledge_connector_member",
+ "tableTo": "knowledge_connector",
+ "columnsFrom": ["connector_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_connector_member_credential_id_credential_id_fk": {
+ "name": "knowledge_connector_member_credential_id_credential_id_fk",
+ "tableFrom": "knowledge_connector_member",
+ "tableTo": "credential",
+ "columnsFrom": ["credential_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "kcm_owner_check": {
+ "name": "kcm_owner_check",
+ "value": "num_nonnulls(\"knowledge_connector_member\".\"workspace_id\", \"knowledge_connector_member\".\"organization_id\") = 1"
+ },
+ "kcm_status_check": {
+ "name": "kcm_status_check",
+ "value": "\"knowledge_connector_member\".\"status\" IN ('active', 'suspended', 'disabled')"
+ },
+ "kcm_subject_token_shape_check": {
+ "name": "kcm_subject_token_shape_check",
+ "value": "\"knowledge_connector_member\".\"subject_token\" ~ '^s:[^:]+:[^:]+:.+$'"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.knowledge_connector_member_sync_log": {
+ "name": "knowledge_connector_member_sync_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connector_id": {
+ "name": "connector_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "members_claimed": {
+ "name": "members_claimed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "members_completed": {
+ "name": "members_completed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "members_incomplete": {
+ "name": "members_incomplete",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "members_failed": {
+ "name": "members_failed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_listed": {
+ "name": "docs_listed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_added": {
+ "name": "docs_added",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_updated": {
+ "name": "docs_updated",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_unchanged": {
+ "name": "docs_unchanged",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_hydrated_once": {
+ "name": "docs_hydrated_once",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "observations_added": {
+ "name": "observations_added",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "observations_removed": {
+ "name": "observations_removed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_tombstoned": {
+ "name": "docs_tombstoned",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_resurrected": {
+ "name": "docs_resurrected",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_purged": {
+ "name": "docs_purged",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "credentials_audited": {
+ "name": "credentials_audited",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "kcmsl_connector_started_at_idx": {
+ "name": "kcmsl_connector_started_at_idx",
+ "columns": [
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "\"started_at\" DESC",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kcmsl_started_at_partial_idx": {
+ "name": "kcmsl_started_at_partial_idx",
+ "columns": [
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"knowledge_connector_member_sync_log\".\"status\" = 'started'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_connector_member_sync_log_connector_id_knowledge_connector_id_fk": {
+ "name": "knowledge_connector_member_sync_log_connector_id_knowledge_connector_id_fk",
+ "tableFrom": "knowledge_connector_member_sync_log",
+ "tableTo": "knowledge_connector",
+ "columnsFrom": ["connector_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "kcmsl_status_check": {
+ "name": "kcmsl_status_check",
+ "value": "\"knowledge_connector_member_sync_log\".\"status\" IN ('started', 'partial', 'completed', 'failed')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.knowledge_connector_permission_grant": {
+ "name": "knowledge_connector_permission_grant",
+ "schema": "",
+ "columns": {
+ "connector_id": {
+ "name": "connector_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_key": {
+ "name": "group_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_token": {
+ "name": "subject_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "kcpg_subject_idx": {
+ "name": "kcpg_subject_idx",
+ "columns": [
+ {
+ "expression": "subject_token",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "group_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "kcpg_snapshot_fk": {
+ "name": "kcpg_snapshot_fk",
+ "tableFrom": "knowledge_connector_permission_grant",
+ "tableTo": "knowledge_connector_permission_snapshot",
+ "columnsFrom": ["connector_id"],
+ "columnsTo": ["connector_id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "kcpg_pk": {
+ "name": "kcpg_pk",
+ "columns": ["connector_id", "group_key", "subject_token"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "kcpg_group_check": {
+ "name": "kcpg_group_check",
+ "value": "length(\"knowledge_connector_permission_grant\".\"group_key\") BETWEEN 1 AND 255"
+ },
+ "kcpg_subject_check": {
+ "name": "kcpg_subject_check",
+ "value": "\"knowledge_connector_permission_grant\".\"subject_token\" ~ '^u:[^[:space:]A-Z]+@[^[:space:]A-Z]+$'"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.knowledge_connector_permission_snapshot": {
+ "name": "knowledge_connector_permission_snapshot",
+ "schema": "",
+ "columns": {
+ "connector_id": {
+ "name": "connector_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "kcps_connector_fk": {
+ "name": "kcps_connector_fk",
+ "tableFrom": "knowledge_connector_permission_snapshot",
+ "tableTo": "knowledge_connector",
+ "columnsFrom": ["connector_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "kcps_revision_check": {
+ "name": "kcps_revision_check",
+ "value": "\"knowledge_connector_permission_snapshot\".\"revision\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.knowledge_connector_sync_log": {
+ "name": "knowledge_connector_sync_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connector_id": {
+ "name": "connector_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "docs_added": {
+ "name": "docs_added",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_updated": {
+ "name": "docs_updated",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_deleted": {
+ "name": "docs_deleted",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_unchanged": {
+ "name": "docs_unchanged",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_skipped": {
+ "name": "docs_skipped",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "docs_failed": {
+ "name": "docs_failed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "listed_count": {
+ "name": "listed_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "kcsl_connector_started_at_idx": {
+ "name": "kcsl_connector_started_at_idx",
+ "columns": [
+ {
+ "expression": "connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "\"started_at\" DESC",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "kcsl_started_at_partial_idx": {
+ "name": "kcsl_started_at_partial_idx",
+ "columns": [
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"knowledge_connector_sync_log\".\"status\" = 'started'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_connector_sync_log_connector_id_knowledge_connector_id_fk": {
+ "name": "knowledge_connector_sync_log_connector_id_knowledge_connector_id_fk",
+ "tableFrom": "knowledge_connector_sync_log",
+ "tableTo": "knowledge_connector",
+ "columnsFrom": ["connector_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.knowledge_document_observation": {
+ "name": "knowledge_document_observation",
+ "schema": "",
+ "columns": {
+ "document_id": {
+ "name": "document_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "member_id": {
+ "name": "member_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_seen_at": {
+ "name": "last_seen_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "run_id": {
+ "name": "run_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "kdo_member_idx": {
+ "name": "kdo_member_idx",
+ "columns": [
+ {
+ "expression": "member_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_document_observation_document_id_document_id_fk": {
+ "name": "knowledge_document_observation_document_id_document_id_fk",
+ "tableFrom": "knowledge_document_observation",
+ "tableTo": "document",
+ "columnsFrom": ["document_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_document_observation_member_id_knowledge_connector_member_id_fk": {
+ "name": "knowledge_document_observation_member_id_knowledge_connector_member_id_fk",
+ "tableFrom": "knowledge_document_observation",
+ "tableTo": "knowledge_connector_member",
+ "columnsFrom": ["member_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "knowledge_document_observation_document_id_member_id_pk": {
+ "name": "knowledge_document_observation_document_id_member_id_pk",
+ "columns": ["document_id", "member_id"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.knowledge_external_directory": {
+ "name": "knowledge_external_directory",
+ "schema": "",
+ "columns": {
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sync_lock_token": {
+ "name": "sync_lock_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sync_lock_lease_at": {
+ "name": "sync_lock_lease_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_started_at": {
+ "name": "last_started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_complete_sync_at": {
+ "name": "last_complete_sync_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "ked_organization_id_idx": {
+ "name": "ked_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ked_workspace_identity_unique": {
+ "name": "ked_workspace_identity_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "ked_organization_identity_unique": {
+ "name": "ked_organization_identity_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_external_directory_workspace_id_workspace_id_fk": {
+ "name": "knowledge_external_directory_workspace_id_workspace_id_fk",
+ "tableFrom": "knowledge_external_directory",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "knowledge_external_directory_organization_id_organization_id_fk": {
+ "name": "knowledge_external_directory_organization_id_organization_id_fk",
+ "tableFrom": "knowledge_external_directory",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "ked_owner_check": {
+ "name": "ked_owner_check",
+ "value": "num_nonnulls(\"knowledge_external_directory\".\"workspace_id\", \"knowledge_external_directory\".\"organization_id\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.knowledge_external_group": {
+ "name": "knowledge_external_group",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenant_id": {
+ "name": "tenant_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_group_id": {
+ "name": "external_group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "keg_organization_id_idx": {
+ "name": "keg_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "keg_organization_identity_unique": {
+ "name": "keg_organization_identity_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "keg_organization_synced_idx": {
+ "name": "keg_organization_synced_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_synced_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "first"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "keg_identity_unique": {
+ "name": "keg_identity_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "tenant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "keg_workspace_synced_idx": {
+ "name": "keg_workspace_synced_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_synced_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "first"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "knowledge_external_group_organization_id_organization_id_fk": {
+ "name": "knowledge_external_group_organization_id_organization_id_fk",
+ "tableFrom": "knowledge_external_group",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "keg_workspace_fk": {
+ "name": "keg_workspace_fk",
+ "tableFrom": "knowledge_external_group",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "keg_owner_check": {
+ "name": "keg_owner_check",
+ "value": "num_nonnulls(\"knowledge_external_group\".\"workspace_id\", \"knowledge_external_group\".\"organization_id\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.knowledge_external_group_member": {
+ "name": "knowledge_external_group_member",
+ "schema": "",
+ "columns": {
+ "group_id": {
+ "name": "group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "subject_token": {
+ "name": "subject_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "kegm_subject_token_idx": {
+ "name": "kegm_subject_token_idx",
+ "columns": [
+ {
+ "expression": "subject_token",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "kegm_group_fk": {
+ "name": "kegm_group_fk",
+ "tableFrom": "knowledge_external_group_member",
+ "tableTo": "knowledge_external_group",
+ "columnsFrom": ["group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "knowledge_external_group_member_group_id_subject_token_pk": {
+ "name": "knowledge_external_group_member_group_id_subject_token_pk",
+ "columns": ["group_id", "subject_token"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mcp_server_oauth": {
+ "name": "mcp_server_oauth",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "mcp_server_id": {
+ "name": "mcp_server_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "client_information": {
+ "name": "client_information",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tokens": {
+ "name": "tokens",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "code_verifier": {
+ "name": "code_verifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "state": {
+ "name": "state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "state_created_at": {
+ "name": "state_created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_refreshed_at": {
+ "name": "last_refreshed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_server_oauth_server_unique": {
+ "name": "mcp_server_oauth_server_unique",
+ "columns": [
+ {
+ "expression": "mcp_server_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_server_oauth_state_idx": {
+ "name": "mcp_server_oauth_state_idx",
+ "columns": [
+ {
+ "expression": "state",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mcp_server_oauth_mcp_server_id_mcp_servers_id_fk": {
+ "name": "mcp_server_oauth_mcp_server_id_mcp_servers_id_fk",
+ "tableFrom": "mcp_server_oauth",
+ "tableTo": "mcp_servers",
+ "columnsFrom": ["mcp_server_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_server_oauth_user_id_user_id_fk": {
+ "name": "mcp_server_oauth_user_id_user_id_fk",
+ "tableFrom": "mcp_server_oauth",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "mcp_server_oauth_workspace_id_workspace_id_fk": {
+ "name": "mcp_server_oauth_workspace_id_workspace_id_fk",
+ "tableFrom": "mcp_server_oauth",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_server_oauth_organization_id_organization_id_fk": {
+ "name": "mcp_server_oauth_organization_id_organization_id_fk",
+ "tableFrom": "mcp_server_oauth",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "mcp_server_oauth_owner_check": {
+ "name": "mcp_server_oauth_owner_check",
+ "value": "num_nonnulls(\"mcp_server_oauth\".\"workspace_id\", \"mcp_server_oauth\".\"organization_id\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.mcp_servers": {
+ "name": "mcp_servers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_group_id": {
+ "name": "credential_group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "managed_connector_id": {
+ "name": "managed_connector_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "oauth_config_version": {
+ "name": "oauth_config_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "transport": {
+ "name": "transport",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "auth_type": {
+ "name": "auth_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'headers'"
+ },
+ "oauth_client_id": {
+ "name": "oauth_client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "oauth_client_secret": {
+ "name": "oauth_client_secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "headers": {
+ "name": "headers",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'"
+ },
+ "timeout": {
+ "name": "timeout",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 30000
+ },
+ "retries": {
+ "name": "retries",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 3
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "last_connected": {
+ "name": "last_connected",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "connection_status": {
+ "name": "connection_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'disconnected'"
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status_config": {
+ "name": "status_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'"
+ },
+ "tool_count": {
+ "name": "tool_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 0
+ },
+ "last_tools_refresh": {
+ "name": "last_tools_refresh",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_requests": {
+ "name": "total_requests",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 0
+ },
+ "last_used": {
+ "name": "last_used",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "mcp_servers_organization_id_idx": {
+ "name": "mcp_servers_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_servers_workspace_enabled_idx": {
+ "name": "mcp_servers_workspace_enabled_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "enabled",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_servers_credential_group_idx": {
+ "name": "mcp_servers_credential_group_idx",
+ "columns": [
+ {
+ "expression": "credential_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_servers_credential_group_managed_connector_unique": {
+ "name": "mcp_servers_credential_group_managed_connector_unique",
+ "columns": [
+ {
+ "expression": "credential_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "managed_connector_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"mcp_servers\".\"credential_group_id\" IS NOT NULL AND \"mcp_servers\".\"managed_connector_id\" IS NOT NULL AND \"mcp_servers\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "mcp_servers_workspace_deleted_partial_idx": {
+ "name": "mcp_servers_workspace_deleted_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"mcp_servers\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mcp_servers_workspace_id_workspace_id_fk": {
+ "name": "mcp_servers_workspace_id_workspace_id_fk",
+ "tableFrom": "mcp_servers",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_servers_organization_id_organization_id_fk": {
+ "name": "mcp_servers_organization_id_organization_id_fk",
+ "tableFrom": "mcp_servers",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mcp_servers_credential_group_id_credential_group_id_fk": {
+ "name": "mcp_servers_credential_group_id_credential_group_id_fk",
+ "tableFrom": "mcp_servers",
+ "tableTo": "credential_group",
+ "columnsFrom": ["credential_group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "mcp_servers_created_by_user_id_fk": {
+ "name": "mcp_servers_created_by_user_id_fk",
+ "tableFrom": "mcp_servers",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "mcp_servers_owner_check": {
+ "name": "mcp_servers_owner_check",
+ "value": "num_nonnulls(\"mcp_servers\".\"workspace_id\", \"mcp_servers\".\"organization_id\") = 1"
+ },
+ "mcp_servers_organization_managed_check": {
+ "name": "mcp_servers_organization_managed_check",
+ "value": "\"mcp_servers\".\"organization_id\" IS NULL OR \"mcp_servers\".\"credential_group_id\" IS NOT NULL"
+ },
+ "mcp_servers_credential_group_managed_connector_check": {
+ "name": "mcp_servers_credential_group_managed_connector_check",
+ "value": "\"mcp_servers\".\"credential_group_id\" IS NULL OR \"mcp_servers\".\"managed_connector_id\" IS NOT NULL"
+ },
+ "mcp_servers_managed_connector_oauth_check": {
+ "name": "mcp_servers_managed_connector_oauth_check",
+ "value": "\"mcp_servers\".\"managed_connector_id\" IS NULL OR \"mcp_servers\".\"auth_type\" = 'oauth'"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.member": {
+ "name": "member",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "member_user_id_unique": {
+ "name": "member_user_id_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "member_organization_id_idx": {
+ "name": "member_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "member_user_id_user_id_fk": {
+ "name": "member_user_id_user_id_fk",
+ "tableFrom": "member",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "member_organization_id_organization_id_fk": {
+ "name": "member_organization_id_organization_id_fk",
+ "tableFrom": "member",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.memory": {
+ "name": "memory",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "data": {
+ "name": "data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret_provenance_version": {
+ "name": "secret_provenance_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "memory_key_idx": {
+ "name": "memory_key_idx",
+ "columns": [
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "memory_workspace_idx": {
+ "name": "memory_workspace_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "memory_workspace_key_idx": {
+ "name": "memory_workspace_key_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "memory_workspace_deleted_partial_idx": {
+ "name": "memory_workspace_deleted_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"memory\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "memory_workspace_id_workspace_id_fk": {
+ "name": "memory_workspace_id_workspace_id_fk",
+ "tableFrom": "memory",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.memory_secret_provenance": {
+ "name": "memory_secret_provenance",
+ "schema": "",
+ "columns": {
+ "memory_id": {
+ "name": "memory_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "content_hash": {
+ "name": "content_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entries": {
+ "name": "entries",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "memory_secret_provenance_memory_id_memory_id_fk": {
+ "name": "memory_secret_provenance_memory_id_memory_id_fk",
+ "tableFrom": "memory_secret_provenance",
+ "tableTo": "memory",
+ "columnsFrom": ["memory_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "memory_secret_provenance_status_check": {
+ "name": "memory_secret_provenance_status_check",
+ "value": "\"memory_secret_provenance\".\"status\" IN ('exact', 'unknown')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.mothership_inbox_allowed_sender": {
+ "name": "mothership_inbox_allowed_sender",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "label": {
+ "name": "label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "added_by": {
+ "name": "added_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "inbox_sender_ws_email_idx": {
+ "name": "inbox_sender_ws_email_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "email",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mothership_inbox_allowed_sender_workspace_id_workspace_id_fk": {
+ "name": "mothership_inbox_allowed_sender_workspace_id_workspace_id_fk",
+ "tableFrom": "mothership_inbox_allowed_sender",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mothership_inbox_allowed_sender_added_by_user_id_fk": {
+ "name": "mothership_inbox_allowed_sender_added_by_user_id_fk",
+ "tableFrom": "mothership_inbox_allowed_sender",
+ "tableTo": "user",
+ "columnsFrom": ["added_by"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mothership_inbox_task": {
+ "name": "mothership_inbox_task",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "from_email": {
+ "name": "from_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "from_name": {
+ "name": "from_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subject": {
+ "name": "subject",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "body_preview": {
+ "name": "body_preview",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "body_text": {
+ "name": "body_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "body_html": {
+ "name": "body_html",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email_message_id": {
+ "name": "email_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "in_reply_to": {
+ "name": "in_reply_to",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "response_message_id": {
+ "name": "response_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "agentmail_message_id": {
+ "name": "agentmail_message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'received'"
+ },
+ "chat_id": {
+ "name": "chat_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trigger_job_id": {
+ "name": "trigger_job_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "result_summary": {
+ "name": "result_summary",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rejection_reason": {
+ "name": "rejection_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "has_attachments": {
+ "name": "has_attachments",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "cc_recipients": {
+ "name": "cc_recipients",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "processing_started_at": {
+ "name": "processing_started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "inbox_task_ws_created_at_idx": {
+ "name": "inbox_task_ws_created_at_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "inbox_task_ws_status_idx": {
+ "name": "inbox_task_ws_status_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "inbox_task_response_msg_id_idx": {
+ "name": "inbox_task_response_msg_id_idx",
+ "columns": [
+ {
+ "expression": "response_message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "inbox_task_email_msg_id_idx": {
+ "name": "inbox_task_email_msg_id_idx",
+ "columns": [
+ {
+ "expression": "email_message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "mothership_inbox_task_workspace_id_workspace_id_fk": {
+ "name": "mothership_inbox_task_workspace_id_workspace_id_fk",
+ "tableFrom": "mothership_inbox_task",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "mothership_inbox_task_chat_id_copilot_chats_id_fk": {
+ "name": "mothership_inbox_task_chat_id_copilot_chats_id_fk",
+ "tableFrom": "mothership_inbox_task",
+ "tableTo": "copilot_chats",
+ "columnsFrom": ["chat_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mothership_inbox_webhook": {
+ "name": "mothership_inbox_webhook",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "webhook_id": {
+ "name": "webhook_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret": {
+ "name": "secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "mothership_inbox_webhook_workspace_id_workspace_id_fk": {
+ "name": "mothership_inbox_webhook_workspace_id_workspace_id_fk",
+ "tableFrom": "mothership_inbox_webhook",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "mothership_inbox_webhook_workspace_id_unique": {
+ "name": "mothership_inbox_webhook_workspace_id_unique",
+ "nullsNotDistinct": false,
+ "columns": ["workspace_id"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.mothership_settings": {
+ "name": "mothership_settings",
+ "schema": "",
+ "columns": {
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "mcp_tool_refs": {
+ "name": "mcp_tool_refs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "custom_tool_refs": {
+ "name": "custom_tool_refs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "skill_refs": {
+ "name": "skill_refs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "mothership_settings_workspace_id_workspace_id_fk": {
+ "name": "mothership_settings_workspace_id_workspace_id_fk",
+ "tableFrom": "mothership_settings",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.oauth_access_token": {
+ "name": "oauth_access_token",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_id": {
+ "name": "session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reference_id": {
+ "name": "reference_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_id": {
+ "name": "refresh_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource": {
+ "name": "resource",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "oauth_access_token_client_id_idx": {
+ "name": "oauth_access_token_client_id_idx",
+ "columns": [
+ {
+ "expression": "client_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_access_token_session_id_idx": {
+ "name": "oauth_access_token_session_id_idx",
+ "columns": [
+ {
+ "expression": "session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_access_token_refresh_id_idx": {
+ "name": "oauth_access_token_refresh_id_idx",
+ "columns": [
+ {
+ "expression": "refresh_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_access_token_user_client_idx": {
+ "name": "oauth_access_token_user_client_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "client_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_access_token_expires_at_idx": {
+ "name": "oauth_access_token_expires_at_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "oauth_access_token_client_id_oauth_client_client_id_fk": {
+ "name": "oauth_access_token_client_id_oauth_client_client_id_fk",
+ "tableFrom": "oauth_access_token",
+ "tableTo": "oauth_client",
+ "columnsFrom": ["client_id"],
+ "columnsTo": ["client_id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "oauth_access_token_session_id_session_id_fk": {
+ "name": "oauth_access_token_session_id_session_id_fk",
+ "tableFrom": "oauth_access_token",
+ "tableTo": "session",
+ "columnsFrom": ["session_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "oauth_access_token_user_id_user_id_fk": {
+ "name": "oauth_access_token_user_id_user_id_fk",
+ "tableFrom": "oauth_access_token",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "oauth_access_token_refresh_id_oauth_refresh_token_id_fk": {
+ "name": "oauth_access_token_refresh_id_oauth_refresh_token_id_fk",
+ "tableFrom": "oauth_access_token",
+ "tableTo": "oauth_refresh_token",
+ "columnsFrom": ["refresh_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "oauth_access_token_token_unique": {
+ "name": "oauth_access_token_token_unique",
+ "nullsNotDistinct": false,
+ "columns": ["token"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "oauth_access_token_search_resource_check": {
+ "name": "oauth_access_token_search_resource_check",
+ "value": "NOT ('search:read' = ANY(\"oauth_access_token\".\"scopes\")) OR \"oauth_access_token\".\"resource\" IS NOT NULL"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.oauth_client": {
+ "name": "oauth_client",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "client_secret": {
+ "name": "client_secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "disabled": {
+ "name": "disabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "skip_consent": {
+ "name": "skip_consent",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enable_end_session": {
+ "name": "enable_end_session",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "subject_type": {
+ "name": "subject_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uri": {
+ "name": "uri",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contacts": {
+ "name": "contacts",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tos": {
+ "name": "tos",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "policy": {
+ "name": "policy",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "software_id": {
+ "name": "software_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "software_version": {
+ "name": "software_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "software_statement": {
+ "name": "software_statement",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "redirect_uris": {
+ "name": "redirect_uris",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "post_logout_redirect_uris": {
+ "name": "post_logout_redirect_uris",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token_endpoint_auth_method": {
+ "name": "token_endpoint_auth_method",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "grant_types": {
+ "name": "grant_types",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "response_types": {
+ "name": "response_types",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "public": {
+ "name": "public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "require_pkce": {
+ "name": "require_pkce",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reference_id": {
+ "name": "reference_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "oauth_client_user_id_idx": {
+ "name": "oauth_client_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "oauth_client_user_id_user_id_fk": {
+ "name": "oauth_client_user_id_user_id_fk",
+ "tableFrom": "oauth_client",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "oauth_client_client_id_unique": {
+ "name": "oauth_client_client_id_unique",
+ "nullsNotDistinct": false,
+ "columns": ["client_id"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.oauth_consent": {
+ "name": "oauth_consent",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reference_id": {
+ "name": "reference_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "oauth_consent_client_id_idx": {
+ "name": "oauth_consent_client_id_idx",
+ "columns": [
+ {
+ "expression": "client_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "oauth_consent_client_id_oauth_client_client_id_fk": {
+ "name": "oauth_consent_client_id_oauth_client_client_id_fk",
+ "tableFrom": "oauth_consent",
+ "tableTo": "oauth_client",
+ "columnsFrom": ["client_id"],
+ "columnsTo": ["client_id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "oauth_consent_user_id_user_id_fk": {
+ "name": "oauth_consent_user_id_user_id_fk",
+ "tableFrom": "oauth_consent",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "oauth_consent_user_client_reference_unique": {
+ "name": "oauth_consent_user_client_reference_unique",
+ "nullsNotDistinct": true,
+ "columns": ["user_id", "client_id", "reference_id"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.oauth_refresh_token": {
+ "name": "oauth_refresh_token",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_id": {
+ "name": "session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reference_id": {
+ "name": "reference_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revoked": {
+ "name": "revoked",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "auth_time": {
+ "name": "auth_time",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource": {
+ "name": "resource",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "family_id": {
+ "name": "family_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "generation": {
+ "name": "generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "oauth_refresh_token_client_id_idx": {
+ "name": "oauth_refresh_token_client_id_idx",
+ "columns": [
+ {
+ "expression": "client_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_refresh_token_session_id_idx": {
+ "name": "oauth_refresh_token_session_id_idx",
+ "columns": [
+ {
+ "expression": "session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_refresh_token_user_client_idx": {
+ "name": "oauth_refresh_token_user_client_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "client_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_refresh_token_expires_at_idx": {
+ "name": "oauth_refresh_token_expires_at_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "oauth_refresh_token_client_id_oauth_client_client_id_fk": {
+ "name": "oauth_refresh_token_client_id_oauth_client_client_id_fk",
+ "tableFrom": "oauth_refresh_token",
+ "tableTo": "oauth_client",
+ "columnsFrom": ["client_id"],
+ "columnsTo": ["client_id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "oauth_refresh_token_session_id_session_id_fk": {
+ "name": "oauth_refresh_token_session_id_session_id_fk",
+ "tableFrom": "oauth_refresh_token",
+ "tableTo": "session",
+ "columnsFrom": ["session_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "oauth_refresh_token_user_id_user_id_fk": {
+ "name": "oauth_refresh_token_user_id_user_id_fk",
+ "tableFrom": "oauth_refresh_token",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "oauth_refresh_token_family_id_oauth_token_family_id_fk": {
+ "name": "oauth_refresh_token_family_id_oauth_token_family_id_fk",
+ "tableFrom": "oauth_refresh_token",
+ "tableTo": "oauth_token_family",
+ "columnsFrom": ["family_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "oauth_refresh_token_token_unique": {
+ "name": "oauth_refresh_token_token_unique",
+ "nullsNotDistinct": false,
+ "columns": ["token"]
+ },
+ "oauth_refresh_token_family_generation_unique": {
+ "name": "oauth_refresh_token_family_generation_unique",
+ "nullsNotDistinct": false,
+ "columns": ["family_id", "generation"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {
+ "oauth_refresh_token_generation_check": {
+ "name": "oauth_refresh_token_generation_check",
+ "value": "\"oauth_refresh_token\".\"generation\" BETWEEN 0 AND 1000"
+ },
+ "oauth_refresh_token_search_resource_check": {
+ "name": "oauth_refresh_token_search_resource_check",
+ "value": "NOT ('search:read' = ANY(\"oauth_refresh_token\".\"scopes\")) OR \"oauth_refresh_token\".\"resource\" IS NOT NULL"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.oauth_token_family": {
+ "name": "oauth_token_family",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "session_id": {
+ "name": "session_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reference_id": {
+ "name": "reference_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "consent_id": {
+ "name": "consent_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "current_generation": {
+ "name": "current_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "oauth_token_family_client_id_idx": {
+ "name": "oauth_token_family_client_id_idx",
+ "columns": [
+ {
+ "expression": "client_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_token_family_session_id_idx": {
+ "name": "oauth_token_family_session_id_idx",
+ "columns": [
+ {
+ "expression": "session_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_token_family_user_client_idx": {
+ "name": "oauth_token_family_user_client_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "client_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_token_family_consent_id_idx": {
+ "name": "oauth_token_family_consent_id_idx",
+ "columns": [
+ {
+ "expression": "consent_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "oauth_token_family_expires_at_idx": {
+ "name": "oauth_token_family_expires_at_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "oauth_token_family_client_id_oauth_client_client_id_fk": {
+ "name": "oauth_token_family_client_id_oauth_client_client_id_fk",
+ "tableFrom": "oauth_token_family",
+ "tableTo": "oauth_client",
+ "columnsFrom": ["client_id"],
+ "columnsTo": ["client_id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "oauth_token_family_session_id_session_id_fk": {
+ "name": "oauth_token_family_session_id_session_id_fk",
+ "tableFrom": "oauth_token_family",
+ "tableTo": "session",
+ "columnsFrom": ["session_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "oauth_token_family_user_id_user_id_fk": {
+ "name": "oauth_token_family_user_id_user_id_fk",
+ "tableFrom": "oauth_token_family",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "oauth_token_family_consent_id_oauth_consent_id_fk": {
+ "name": "oauth_token_family_consent_id_oauth_consent_id_fk",
+ "tableFrom": "oauth_token_family",
+ "tableTo": "oauth_consent",
+ "columnsFrom": ["consent_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "oauth_token_family_generation_check": {
+ "name": "oauth_token_family_generation_check",
+ "value": "\"oauth_token_family\".\"current_generation\" BETWEEN 0 AND 1000"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.organization": {
+ "name": "organization",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "logo": {
+ "name": "logo",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_policy_settings": {
+ "name": "session_policy_settings",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "security_policy_version": {
+ "name": "security_policy_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "whitelabel_settings": {
+ "name": "whitelabel_settings",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "data_retention_settings": {
+ "name": "data_retention_settings",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "org_usage_limit": {
+ "name": "org_usage_limit",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "storage_used_bytes": {
+ "name": "storage_used_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "limit_notifications": {
+ "name": "limit_notifications",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "credit_balance": {
+ "name": "credit_balance",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.organization_access_request_settings": {
+ "name": "organization_access_request_settings",
+ "schema": "",
+ "columns": {
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "allow_requests": {
+ "name": "allow_requests",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "organization_access_request_settings_organization_id_organization_id_fk": {
+ "name": "organization_access_request_settings_organization_id_organization_id_fk",
+ "tableFrom": "organization_access_request_settings",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "organization_access_request_settings_updated_by_user_id_fk": {
+ "name": "organization_access_request_settings_updated_by_user_id_fk",
+ "tableFrom": "organization_access_request_settings",
+ "tableTo": "user",
+ "columnsFrom": ["updated_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.organization_byok_keys": {
+ "name": "organization_byok_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_api_key": {
+ "name": "encrypted_api_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "organization_byok_organization_provider_idx": {
+ "name": "organization_byok_organization_provider_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "organization_byok_keys_organization_id_organization_id_fk": {
+ "name": "organization_byok_keys_organization_id_organization_id_fk",
+ "tableFrom": "organization_byok_keys",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "organization_byok_keys_created_by_user_id_fk": {
+ "name": "organization_byok_keys_created_by_user_id_fk",
+ "tableFrom": "organization_byok_keys",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.organization_member_usage_limit": {
+ "name": "organization_member_usage_limit",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "usage_limit": {
+ "name": "usage_limit",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "set_by": {
+ "name": "set_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "org_member_usage_limit_org_user_unique": {
+ "name": "org_member_usage_limit_org_user_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "org_member_usage_limit_organization_id_idx": {
+ "name": "org_member_usage_limit_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "organization_member_usage_limit_organization_id_organization_id_fk": {
+ "name": "organization_member_usage_limit_organization_id_organization_id_fk",
+ "tableFrom": "organization_member_usage_limit",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "organization_member_usage_limit_user_id_user_id_fk": {
+ "name": "organization_member_usage_limit_user_id_user_id_fk",
+ "tableFrom": "organization_member_usage_limit",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "organization_member_usage_limit_set_by_user_id_fk": {
+ "name": "organization_member_usage_limit_set_by_user_id_fk",
+ "tableFrom": "organization_member_usage_limit",
+ "tableTo": "user",
+ "columnsFrom": ["set_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.organization_search_integration": {
+ "name": "organization_search_integration",
+ "schema": "",
+ "columns": {
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "connector_type": {
+ "name": "connector_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "approved": {
+ "name": "approved",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "organization_search_integration_organization_id_organization_id_fk": {
+ "name": "organization_search_integration_organization_id_organization_id_fk",
+ "tableFrom": "organization_search_integration",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "organization_search_integration_organization_id_connector_type_pk": {
+ "name": "organization_search_integration_organization_id_connector_type_pk",
+ "columns": ["organization_id", "connector_type"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.organization_search_invocation": {
+ "name": "organization_search_invocation",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "surface": {
+ "name": "surface",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_types": {
+ "name": "source_types",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "result_count": {
+ "name": "result_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "organization_search_invocation_org_created_idx": {
+ "name": "organization_search_invocation_org_created_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "organization_search_invocation_user_idx": {
+ "name": "organization_search_invocation_user_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "organization_search_invocation_organization_id_organization_id_fk": {
+ "name": "organization_search_invocation_organization_id_organization_id_fk",
+ "tableFrom": "organization_search_invocation",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "organization_search_invocation_user_id_user_id_fk": {
+ "name": "organization_search_invocation_user_id_user_id_fk",
+ "tableFrom": "organization_search_invocation",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "organization_search_invocation_result_count_bounds": {
+ "name": "organization_search_invocation_result_count_bounds",
+ "value": "\"organization_search_invocation\".\"result_count\" BETWEEN 0 AND 100"
+ },
+ "organization_search_invocation_source_types_bounds": {
+ "name": "organization_search_invocation_source_types_bounds",
+ "value": "cardinality(\"organization_search_invocation\".\"source_types\") <= 100"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.outbox_event": {
+ "name": "outbox_event",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "attempts": {
+ "name": "attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "max_attempts": {
+ "name": "max_attempts",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 10
+ },
+ "available_at": {
+ "name": "available_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "locked_at": {
+ "name": "locked_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_error": {
+ "name": "last_error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "processed_at": {
+ "name": "processed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "outbox_event_status_available_idx": {
+ "name": "outbox_event_status_available_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "available_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "outbox_event_pending_type_available_idx": {
+ "name": "outbox_event_pending_type_available_idx",
+ "columns": [
+ {
+ "expression": "event_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "available_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"outbox_event\".\"status\" = 'pending'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "outbox_event_locked_at_idx": {
+ "name": "outbox_event_locked_at_idx",
+ "columns": [
+ {
+ "expression": "locked_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "outbox_event_type_created_idx": {
+ "name": "outbox_event_type_created_idx",
+ "columns": [
+ {
+ "expression": "event_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.paused_executions": {
+ "name": "paused_executions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_id": {
+ "name": "execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_snapshot": {
+ "name": "execution_snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pause_points": {
+ "name": "pause_points",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_pause_count": {
+ "name": "total_pause_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resumed_count": {
+ "name": "resumed_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "automatic_resume_retry_count": {
+ "name": "automatic_resume_retry_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'paused'"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "paused_at": {
+ "name": "paused_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_resume_at": {
+ "name": "next_resume_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "paused_executions_workflow_id_idx": {
+ "name": "paused_executions_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "paused_executions_status_idx": {
+ "name": "paused_executions_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "paused_executions_execution_id_unique": {
+ "name": "paused_executions_execution_id_unique",
+ "columns": [
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "paused_executions_next_resume_at_idx": {
+ "name": "paused_executions_next_resume_at_idx",
+ "columns": [
+ {
+ "expression": "next_resume_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "status = 'paused' AND next_resume_at IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "paused_executions_workflow_id_workflow_id_fk": {
+ "name": "paused_executions_workflow_id_workflow_id_fk",
+ "tableFrom": "paused_executions",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.pending_credential_draft": {
+ "name": "pending_credential_draft",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "credential_id": {
+ "name": "credential_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "oauth_config": {
+ "name": "oauth_config",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pending_draft_organization_id_idx": {
+ "name": "pending_draft_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "pending_draft_user_provider_org": {
+ "name": "pending_draft_user_provider_org",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "pending_draft_user_provider_ws": {
+ "name": "pending_draft_user_provider_ws",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "pending_credential_draft_user_id_user_id_fk": {
+ "name": "pending_credential_draft_user_id_user_id_fk",
+ "tableFrom": "pending_credential_draft",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "pending_credential_draft_workspace_id_workspace_id_fk": {
+ "name": "pending_credential_draft_workspace_id_workspace_id_fk",
+ "tableFrom": "pending_credential_draft",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "pending_credential_draft_organization_id_organization_id_fk": {
+ "name": "pending_credential_draft_organization_id_organization_id_fk",
+ "tableFrom": "pending_credential_draft",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "pending_credential_draft_credential_id_credential_id_fk": {
+ "name": "pending_credential_draft_credential_id_credential_id_fk",
+ "tableFrom": "pending_credential_draft",
+ "tableTo": "credential",
+ "columnsFrom": ["credential_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "pending_draft_owner_check": {
+ "name": "pending_draft_owner_check",
+ "value": "num_nonnulls(\"pending_credential_draft\".\"workspace_id\", \"pending_credential_draft\".\"organization_id\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.permission_access_request": {
+ "name": "permission_access_request",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "requester_id": {
+ "name": "requester_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope_key": {
+ "name": "scope_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_key": {
+ "name": "target_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target": {
+ "name": "target",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_label": {
+ "name": "target_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "membership_id": {
+ "name": "membership_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "group_name": {
+ "name": "group_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reason": {
+ "name": "reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "decision_reason": {
+ "name": "decision_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decided_by": {
+ "name": "decided_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "decision": {
+ "name": "decision",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "decided_at": {
+ "name": "decided_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "permission_access_request_pending_unique": {
+ "name": "permission_access_request_pending_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "requester_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"permission_access_request\".\"status\" = 'pending'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_access_request_org_queue_idx": {
+ "name": "permission_access_request_org_queue_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_access_request_requester_idx": {
+ "name": "permission_access_request_requester_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "requester_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scope_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_access_request_organization_id_organization_id_fk": {
+ "name": "permission_access_request_organization_id_organization_id_fk",
+ "tableFrom": "permission_access_request",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_access_request_requester_id_user_id_fk": {
+ "name": "permission_access_request_requester_id_user_id_fk",
+ "tableFrom": "permission_access_request",
+ "tableTo": "user",
+ "columnsFrom": ["requester_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_access_request_decided_by_user_id_fk": {
+ "name": "permission_access_request_decided_by_user_id_fk",
+ "tableFrom": "permission_access_request",
+ "tableTo": "user",
+ "columnsFrom": ["decided_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "permission_access_request_status_check": {
+ "name": "permission_access_request_status_check",
+ "value": "\"permission_access_request\".\"status\" in ('pending', 'fulfilled', 'declined', 'cancelled', 'closed')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.permission_group": {
+ "name": "permission_group",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "membership_mode": {
+ "name": "membership_mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'inherit'"
+ }
+ },
+ "indexes": {
+ "permission_group_created_by_idx": {
+ "name": "permission_group_created_by_idx",
+ "columns": [
+ {
+ "expression": "created_by",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_group_organization_name_unique": {
+ "name": "permission_group_organization_name_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_group_organization_default_unique": {
+ "name": "permission_group_organization_default_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "is_default = true",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_group_organization_id_organization_id_fk": {
+ "name": "permission_group_organization_id_organization_id_fk",
+ "tableFrom": "permission_group",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_group_created_by_user_id_fk": {
+ "name": "permission_group_created_by_user_id_fk",
+ "tableFrom": "permission_group",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.permission_group_member": {
+ "name": "permission_group_member",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "permission_group_id": {
+ "name": "permission_group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "assigned_by": {
+ "name": "assigned_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "assigned_at": {
+ "name": "assigned_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "permission_group_member_group_id_idx": {
+ "name": "permission_group_member_group_id_idx",
+ "columns": [
+ {
+ "expression": "permission_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_group_member_group_user_unique": {
+ "name": "permission_group_member_group_user_unique",
+ "columns": [
+ {
+ "expression": "permission_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_group_member_organization_user_idx": {
+ "name": "permission_group_member_organization_user_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_group_member_permission_group_id_permission_group_id_fk": {
+ "name": "permission_group_member_permission_group_id_permission_group_id_fk",
+ "tableFrom": "permission_group_member",
+ "tableTo": "permission_group",
+ "columnsFrom": ["permission_group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_group_member_organization_id_organization_id_fk": {
+ "name": "permission_group_member_organization_id_organization_id_fk",
+ "tableFrom": "permission_group_member",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_group_member_user_id_user_id_fk": {
+ "name": "permission_group_member_user_id_user_id_fk",
+ "tableFrom": "permission_group_member",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_group_member_assigned_by_user_id_fk": {
+ "name": "permission_group_member_assigned_by_user_id_fk",
+ "tableFrom": "permission_group_member",
+ "tableTo": "user",
+ "columnsFrom": ["assigned_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.permission_group_workspace": {
+ "name": "permission_group_workspace",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "permission_group_id": {
+ "name": "permission_group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "permission_group_workspace_workspace_id_idx": {
+ "name": "permission_group_workspace_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permission_group_workspace_group_workspace_unique": {
+ "name": "permission_group_workspace_group_workspace_unique",
+ "columns": [
+ {
+ "expression": "permission_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permission_group_workspace_permission_group_id_permission_group_id_fk": {
+ "name": "permission_group_workspace_permission_group_id_permission_group_id_fk",
+ "tableFrom": "permission_group_workspace",
+ "tableTo": "permission_group",
+ "columnsFrom": ["permission_group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_group_workspace_workspace_id_workspace_id_fk": {
+ "name": "permission_group_workspace_workspace_id_workspace_id_fk",
+ "tableFrom": "permission_group_workspace",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "permission_group_workspace_organization_id_organization_id_fk": {
+ "name": "permission_group_workspace_organization_id_organization_id_fk",
+ "tableFrom": "permission_group_workspace",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.permissions": {
+ "name": "permissions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_type": {
+ "name": "entity_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entity_id": {
+ "name": "entity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission_type": {
+ "name": "permission_type",
+ "type": "permission_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "permissions_user_id_idx": {
+ "name": "permissions_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permissions_entity_idx": {
+ "name": "permissions_entity_idx",
+ "columns": [
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permissions_user_entity_type_idx": {
+ "name": "permissions_user_entity_type_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permissions_user_entity_permission_idx": {
+ "name": "permissions_user_entity_permission_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "permission_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "permissions_unique_constraint": {
+ "name": "permissions_unique_constraint",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "permissions_user_id_user_id_fk": {
+ "name": "permissions_user_id_user_id_fk",
+ "tableFrom": "permissions",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.pinned_item": {
+ "name": "pinned_item",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pinned_at": {
+ "name": "pinned_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "pinned_item_user_workspace_idx": {
+ "name": "pinned_item_user_workspace_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "pinned_item_resource_idx": {
+ "name": "pinned_item_resource_idx",
+ "columns": [
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "pinned_item_user_resource_unique": {
+ "name": "pinned_item_user_resource_unique",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "pinned_item_user_id_user_id_fk": {
+ "name": "pinned_item_user_id_user_id_fk",
+ "tableFrom": "pinned_item",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "pinned_item_workspace_id_workspace_id_fk": {
+ "name": "pinned_item_workspace_id_workspace_id_fk",
+ "tableFrom": "pinned_item",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.public_share": {
+ "name": "public_share",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "auth_type": {
+ "name": "auth_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'public'"
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "allowed_emails": {
+ "name": "allowed_emails",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'[]'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "public_share_token_unique": {
+ "name": "public_share_token_unique",
+ "columns": [
+ {
+ "expression": "token",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "public_share_resource_unique": {
+ "name": "public_share_resource_unique",
+ "columns": [
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "public_share_resource_id_idx": {
+ "name": "public_share_resource_id_idx",
+ "columns": [
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "public_share_workspace_id_idx": {
+ "name": "public_share_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "public_share_workspace_id_workspace_id_fk": {
+ "name": "public_share_workspace_id_workspace_id_fk",
+ "tableFrom": "public_share",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "public_share_created_by_user_id_fk": {
+ "name": "public_share_created_by_user_id_fk",
+ "tableFrom": "public_share",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.rate_limit_bucket": {
+ "name": "rate_limit_bucket",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "tokens": {
+ "name": "tokens",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_refill_at": {
+ "name": "last_refill_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "blocked_until": {
+ "name": "blocked_until",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "capacity_state": {
+ "name": "capacity_state",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.resource_policy": {
+ "name": "resource_policy",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_id": {
+ "name": "resource_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "document": {
+ "name": "document",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_by": {
+ "name": "updated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "resource_policy_organization_id_idx": {
+ "name": "resource_policy_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resource_policy_resource_unique": {
+ "name": "resource_policy_resource_unique",
+ "columns": [
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resource_policy_workspace_id_idx": {
+ "name": "resource_policy_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "resource_policy_workspace_id_workspace_id_fk": {
+ "name": "resource_policy_workspace_id_workspace_id_fk",
+ "tableFrom": "resource_policy",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "resource_policy_organization_id_organization_id_fk": {
+ "name": "resource_policy_organization_id_organization_id_fk",
+ "tableFrom": "resource_policy",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "resource_policy_created_by_user_id_fk": {
+ "name": "resource_policy_created_by_user_id_fk",
+ "tableFrom": "resource_policy",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "resource_policy_updated_by_user_id_fk": {
+ "name": "resource_policy_updated_by_user_id_fk",
+ "tableFrom": "resource_policy",
+ "tableTo": "user",
+ "columnsFrom": ["updated_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "resource_policy_owner_check": {
+ "name": "resource_policy_owner_check",
+ "value": "num_nonnulls(\"resource_policy\".\"workspace_id\", \"resource_policy\".\"organization_id\") = 1"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.resume_queue": {
+ "name": "resume_queue",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "paused_execution_id": {
+ "name": "paused_execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_execution_id": {
+ "name": "parent_execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "new_execution_id": {
+ "name": "new_execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "context_id": {
+ "name": "context_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resume_input": {
+ "name": "resume_input",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "queued_at": {
+ "name": "queued_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "claimed_at": {
+ "name": "claimed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "resume_queue_parent_status_idx": {
+ "name": "resume_queue_parent_status_idx",
+ "columns": [
+ {
+ "expression": "parent_execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "queued_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "resume_queue_new_execution_idx": {
+ "name": "resume_queue_new_execution_idx",
+ "columns": [
+ {
+ "expression": "new_execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "resume_queue_paused_execution_id_paused_executions_id_fk": {
+ "name": "resume_queue_paused_execution_id_paused_executions_id_fk",
+ "tableFrom": "resume_queue",
+ "tableTo": "paused_executions",
+ "columnsFrom": ["paused_execution_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sandbox_image": {
+ "name": "sandbox_image",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "spec_hash": {
+ "name": "spec_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "spec": {
+ "name": "spec",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "sandbox_image_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "image_ref": {
+ "name": "image_ref",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_image_id": {
+ "name": "provider_image_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "build_id": {
+ "name": "build_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "materialization_generation": {
+ "name": "materialization_generation",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_detail": {
+ "name": "error_detail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "sandbox_image_provider_spec_unique": {
+ "name": "sandbox_image_provider_spec_unique",
+ "columns": [
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "spec_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sandbox_image_status_idx": {
+ "name": "sandbox_image_status_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sandbox_image_last_used_idx": {
+ "name": "sandbox_image_last_used_idx",
+ "columns": [
+ {
+ "expression": "last_used_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scim_connection": {
+ "name": "scim_connection",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "settings": {
+ "name": "settings",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "last_request_at": {
+ "name": "last_request_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reconcile_lock_token": {
+ "name": "reconcile_lock_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reconcile_lease_at": {
+ "name": "reconcile_lease_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "reconciled_at": {
+ "name": "reconciled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_connection_organization_unique": {
+ "name": "scim_connection_organization_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_connection_reconcile_due_idx": {
+ "name": "scim_connection_reconcile_due_idx",
+ "columns": [
+ {
+ "expression": "reconciled_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_connection_organization_id_organization_id_fk": {
+ "name": "scim_connection_organization_id_organization_id_fk",
+ "tableFrom": "scim_connection",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_connection_created_by_user_id_fk": {
+ "name": "scim_connection_created_by_user_id_fk",
+ "tableFrom": "scim_connection",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scim_credential": {
+ "name": "scim_credential",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token_prefix": {
+ "name": "token_prefix",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scopes": {
+ "name": "scopes",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_at": {
+ "name": "revoked_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revoked_by": {
+ "name": "revoked_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_credential_token_hash_unique": {
+ "name": "scim_credential_token_hash_unique",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_credential_connection_idx": {
+ "name": "scim_credential_connection_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_credential_connection_id_scim_connection_id_fk": {
+ "name": "scim_credential_connection_id_scim_connection_id_fk",
+ "tableFrom": "scim_credential",
+ "tableTo": "scim_connection",
+ "columnsFrom": ["connection_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_credential_revoked_by_user_id_fk": {
+ "name": "scim_credential_revoked_by_user_id_fk",
+ "tableFrom": "scim_credential",
+ "tableTo": "user",
+ "columnsFrom": ["revoked_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "scim_credential_created_by_user_id_fk": {
+ "name": "scim_credential_created_by_user_id_fk",
+ "tableFrom": "scim_credential",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scim_group": {
+ "name": "scim_group",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_name_key": {
+ "name": "display_name_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "order_key": {
+ "name": "order_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_group_connection_display_name_unique": {
+ "name": "scim_group_connection_display_name_unique",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_name_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_group_connection_external_id_unique": {
+ "name": "scim_group_connection_external_id_unique",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "external_id is not null",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_group_connection_order_idx": {
+ "name": "scim_group_connection_order_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "order_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_group_connection_id_scim_connection_id_fk": {
+ "name": "scim_group_connection_id_scim_connection_id_fk",
+ "tableFrom": "scim_group",
+ "tableTo": "scim_connection",
+ "columnsFrom": ["connection_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scim_group_mapping": {
+ "name": "scim_group_mapping",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_kind": {
+ "name": "target_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission_group_id": {
+ "name": "permission_group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "permission_type": {
+ "name": "permission_type",
+ "type": "permission_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source": {
+ "name": "source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'manual'"
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_group_mapping_group_idx": {
+ "name": "scim_group_mapping_group_idx",
+ "columns": [
+ {
+ "expression": "group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_group_mapping_permission_group_idx": {
+ "name": "scim_group_mapping_permission_group_idx",
+ "columns": [
+ {
+ "expression": "permission_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_group_mapping_workspace_idx": {
+ "name": "scim_group_mapping_workspace_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_group_mapping_group_target_unique": {
+ "name": "scim_group_mapping_group_target_unique",
+ "columns": [
+ {
+ "expression": "group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "coalesce(\"permission_group_id\", \"workspace_id\", \"role\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_group_mapping_group_id_scim_group_id_fk": {
+ "name": "scim_group_mapping_group_id_scim_group_id_fk",
+ "tableFrom": "scim_group_mapping",
+ "tableTo": "scim_group",
+ "columnsFrom": ["group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_group_mapping_permission_group_id_permission_group_id_fk": {
+ "name": "scim_group_mapping_permission_group_id_permission_group_id_fk",
+ "tableFrom": "scim_group_mapping",
+ "tableTo": "permission_group",
+ "columnsFrom": ["permission_group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_group_mapping_workspace_id_workspace_id_fk": {
+ "name": "scim_group_mapping_workspace_id_workspace_id_fk",
+ "tableFrom": "scim_group_mapping",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_group_mapping_created_by_user_id_fk": {
+ "name": "scim_group_mapping_created_by_user_id_fk",
+ "tableFrom": "scim_group_mapping",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "scim_group_mapping_target_shape": {
+ "name": "scim_group_mapping_target_shape",
+ "value": "(\n (\"scim_group_mapping\".\"target_kind\" = 'permission_group' AND \"scim_group_mapping\".\"permission_group_id\" IS NOT NULL AND \"scim_group_mapping\".\"workspace_id\" IS NULL AND \"scim_group_mapping\".\"permission_type\" IS NULL AND \"scim_group_mapping\".\"role\" IS NULL)\n OR (\"scim_group_mapping\".\"target_kind\" = 'workspace' AND \"scim_group_mapping\".\"workspace_id\" IS NOT NULL AND \"scim_group_mapping\".\"permission_type\" IS NOT NULL AND \"scim_group_mapping\".\"permission_group_id\" IS NULL AND \"scim_group_mapping\".\"role\" IS NULL)\n OR (\"scim_group_mapping\".\"target_kind\" = 'org_role' AND \"scim_group_mapping\".\"role\" IS NOT NULL AND \"scim_group_mapping\".\"permission_group_id\" IS NULL AND \"scim_group_mapping\".\"workspace_id\" IS NULL AND \"scim_group_mapping\".\"permission_type\" IS NULL)\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.scim_group_member": {
+ "name": "scim_group_member",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scim_user_id": {
+ "name": "scim_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_group_member_group_user_unique": {
+ "name": "scim_group_member_group_user_unique",
+ "columns": [
+ {
+ "expression": "group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scim_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_group_member_scim_user_idx": {
+ "name": "scim_group_member_scim_user_idx",
+ "columns": [
+ {
+ "expression": "scim_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_group_member_group_id_scim_group_id_fk": {
+ "name": "scim_group_member_group_id_scim_group_id_fk",
+ "tableFrom": "scim_group_member",
+ "tableTo": "scim_group",
+ "columnsFrom": ["group_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_group_member_scim_user_id_scim_user_id_fk": {
+ "name": "scim_group_member_scim_user_id_scim_user_id_fk",
+ "tableFrom": "scim_group_member",
+ "tableTo": "scim_user",
+ "columnsFrom": ["scim_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scim_projection_grant": {
+ "name": "scim_projection_grant",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scim_user_id": {
+ "name": "scim_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_kind": {
+ "name": "target_kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_id": {
+ "name": "target_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "permission_type": {
+ "name": "permission_type",
+ "type": "permission_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "baseline_permission": {
+ "name": "baseline_permission",
+ "type": "permission_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "origin": {
+ "name": "origin",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'directory'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_projection_grant_user_target_unique": {
+ "name": "scim_projection_grant_user_target_unique",
+ "columns": [
+ {
+ "expression": "scim_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_kind",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_projection_grant_connection_idx": {
+ "name": "scim_projection_grant_connection_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_projection_grant_connection_id_scim_connection_id_fk": {
+ "name": "scim_projection_grant_connection_id_scim_connection_id_fk",
+ "tableFrom": "scim_projection_grant",
+ "tableTo": "scim_connection",
+ "columnsFrom": ["connection_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_projection_grant_scim_user_id_scim_user_id_fk": {
+ "name": "scim_projection_grant_scim_user_id_scim_user_id_fk",
+ "tableFrom": "scim_projection_grant",
+ "tableTo": "scim_user",
+ "columnsFrom": ["scim_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scim_request_log": {
+ "name": "scim_request_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "credential_id": {
+ "name": "credential_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "method": {
+ "name": "method",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scim_type": {
+ "name": "scim_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "detail": {
+ "name": "detail",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "duration_ms": {
+ "name": "duration_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_request_log_connection_created_idx": {
+ "name": "scim_request_log_connection_created_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_request_log_connection_id_scim_connection_id_fk": {
+ "name": "scim_request_log_connection_id_scim_connection_id_fk",
+ "tableFrom": "scim_request_log",
+ "tableTo": "scim_connection",
+ "columnsFrom": ["connection_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scim_user": {
+ "name": "scim_user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_name": {
+ "name": "user_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "active": {
+ "name": "active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "attributes": {
+ "name": "attributes",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "order_key": {
+ "name": "order_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_user_connection_user_unique": {
+ "name": "scim_user_connection_user_unique",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_user_connection_user_name_unique": {
+ "name": "scim_user_connection_user_name_unique",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_user_connection_external_id_unique": {
+ "name": "scim_user_connection_external_id_unique",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "external_id is not null",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_user_connection_order_idx": {
+ "name": "scim_user_connection_order_idx",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "order_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_user_user_idx": {
+ "name": "scim_user_user_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_user_connection_id_scim_connection_id_fk": {
+ "name": "scim_user_connection_id_scim_connection_id_fk",
+ "tableFrom": "scim_user",
+ "tableTo": "scim_connection",
+ "columnsFrom": ["connection_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_user_user_id_user_id_fk": {
+ "name": "scim_user_user_id_user_id_fk",
+ "tableFrom": "scim_user",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scim_user_tombstone": {
+ "name": "scim_user_tombstone",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "connection_id": {
+ "name": "connection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "scim_user_tombstone_connection_external_id_unique": {
+ "name": "scim_user_tombstone_connection_external_id_unique",
+ "columns": [
+ {
+ "expression": "connection_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "scim_user_tombstone_user_idx": {
+ "name": "scim_user_tombstone_user_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "scim_user_tombstone_connection_id_scim_connection_id_fk": {
+ "name": "scim_user_tombstone_connection_id_scim_connection_id_fk",
+ "tableFrom": "scim_user_tombstone",
+ "tableTo": "scim_connection",
+ "columnsFrom": ["connection_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scim_user_tombstone_user_id_user_id_fk": {
+ "name": "scim_user_tombstone_user_id_user_id_fk",
+ "tableFrom": "scim_user_tombstone",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.secret_usage": {
+ "name": "secret_usage",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret_name": {
+ "name": "secret_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret_scope": {
+ "name": "secret_scope",
+ "type": "secret_usage_scope",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "secret_owner_user_id": {
+ "name": "secret_owner_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "source": {
+ "name": "source",
+ "type": "secret_usage_source",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "usage_date": {
+ "name": "usage_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "use_count": {
+ "name": "use_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_used_at": {
+ "name": "last_used_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_execution_id": {
+ "name": "last_execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_trigger": {
+ "name": "last_trigger",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "secret_usage_bucket_unique": {
+ "name": "secret_usage_bucket_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_scope",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "actor_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "usage_date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "secret_usage_secret_recent_idx": {
+ "name": "secret_usage_secret_recent_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_scope",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "secret_owner_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_used_at",
+ "isExpression": false,
+ "asc": false,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "secret_usage_workspace_id_workspace_id_fk": {
+ "name": "secret_usage_workspace_id_workspace_id_fk",
+ "tableFrom": "secret_usage",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "active_organization_id": {
+ "name": "active_organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "impersonated_by": {
+ "name": "impersonated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "session_user_id_idx": {
+ "name": "session_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "session_user_id_user_id_fk": {
+ "name": "session_user_id_user_id_fk",
+ "tableFrom": "session",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "session_active_organization_id_organization_id_fk": {
+ "name": "session_active_organization_id_organization_id_fk",
+ "tableFrom": "session",
+ "tableTo": "organization",
+ "columnsFrom": ["active_organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "session_token_unique": {
+ "name": "session_token_unique",
+ "nullsNotDistinct": false,
+ "columns": ["token"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.settings": {
+ "name": "settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "theme": {
+ "name": "theme",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'system'"
+ },
+ "auto_connect": {
+ "name": "auto_connect",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "telemetry_enabled": {
+ "name": "telemetry_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "email_preferences": {
+ "name": "email_preferences",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "billing_usage_notifications_enabled": {
+ "name": "billing_usage_notifications_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "show_training_controls": {
+ "name": "show_training_controls",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "super_user_mode_enabled": {
+ "name": "super_user_mode_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "mothership_environment": {
+ "name": "mothership_environment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'default'"
+ },
+ "error_notifications_enabled": {
+ "name": "error_notifications_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "snap_to_grid_size": {
+ "name": "snap_to_grid_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "show_action_bar": {
+ "name": "show_action_bar",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "auto_focus_on_click": {
+ "name": "auto_focus_on_click",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "copilot_enabled_models": {
+ "name": "copilot_enabled_models",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "copilot_auto_allowed_tools": {
+ "name": "copilot_auto_allowed_tools",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'"
+ },
+ "last_active_workspace_id": {
+ "name": "last_active_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "settings_user_id_user_id_fk": {
+ "name": "settings_user_id_user_id_fk",
+ "tableFrom": "settings",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "settings_user_id_unique": {
+ "name": "settings_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": ["user_id"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sim_trigger_state": {
+ "name": "sim_trigger_state",
+ "schema": "",
+ "columns": {
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "block_id": {
+ "name": "block_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope_key": {
+ "name": "scope_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "last_fired_at": {
+ "name": "last_fired_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sim_trigger_state_workflow_id_workflow_id_fk": {
+ "name": "sim_trigger_state_workflow_id_workflow_id_fk",
+ "tableFrom": "sim_trigger_state",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "sim_trigger_state_workflow_id_block_id_scope_key_pk": {
+ "name": "sim_trigger_state_workflow_id_block_id_scope_key_pk",
+ "columns": ["workflow_id", "block_id", "scope_key"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.skill": {
+ "name": "skill",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "skill_workspace_name_unique": {
+ "name": "skill_workspace_name_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "skill_workspace_id_workspace_id_fk": {
+ "name": "skill_workspace_id_workspace_id_fk",
+ "tableFrom": "skill",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "skill_user_id_user_id_fk": {
+ "name": "skill_user_id_user_id_fk",
+ "tableFrom": "skill",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.skill_member": {
+ "name": "skill_member",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "skill_id": {
+ "name": "skill_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "invited_by": {
+ "name": "invited_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "skill_member_user_id_idx": {
+ "name": "skill_member_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "skill_member_unique": {
+ "name": "skill_member_unique",
+ "columns": [
+ {
+ "expression": "skill_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "skill_member_skill_id_skill_id_fk": {
+ "name": "skill_member_skill_id_skill_id_fk",
+ "tableFrom": "skill_member",
+ "tableTo": "skill",
+ "columnsFrom": ["skill_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "skill_member_user_id_user_id_fk": {
+ "name": "skill_member_user_id_user_id_fk",
+ "tableFrom": "skill_member",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "skill_member_invited_by_user_id_fk": {
+ "name": "skill_member_invited_by_user_id_fk",
+ "tableFrom": "skill_member",
+ "tableTo": "user",
+ "columnsFrom": ["invited_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.slack_app": {
+ "name": "slack_app",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "client_id": {
+ "name": "client_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "encrypted_client_secret": {
+ "name": "encrypted_client_secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "encrypted_signing_secret": {
+ "name": "encrypted_signing_secret",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "revision": {
+ "name": "revision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "slack_app_organization_id_organization_id_fk": {
+ "name": "slack_app_organization_id_organization_id_fk",
+ "tableFrom": "slack_app",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "slack_app_owner_check": {
+ "name": "slack_app_owner_check",
+ "value": "(\"slack_app\".\"kind\" = 'custom' AND \"slack_app\".\"organization_id\" IS NOT NULL) OR (\"slack_app\".\"kind\" = 'shared' AND \"slack_app\".\"organization_id\" IS NULL)"
+ },
+ "slack_app_custom_credentials_check": {
+ "name": "slack_app_custom_credentials_check",
+ "value": "\"slack_app\".\"kind\" = 'shared' OR (\"slack_app\".\"client_id\" IS NOT NULL AND \"slack_app\".\"encrypted_client_secret\" IS NOT NULL AND \"slack_app\".\"encrypted_signing_secret\" IS NOT NULL)"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.slack_search_installation": {
+ "name": "slack_search_installation",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "credential_id": {
+ "name": "credential_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "app_id": {
+ "name": "app_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slack_app_id": {
+ "name": "slack_app_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_name": {
+ "name": "team_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "bot_user_id": {
+ "name": "bot_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enterprise_id": {
+ "name": "enterprise_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "credential_version": {
+ "name": "credential_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "revision": {
+ "name": "revision",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_outcome": {
+ "name": "last_outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_event_at": {
+ "name": "last_event_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "slack_search_installation_organization_idx": {
+ "name": "slack_search_installation_organization_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "slack_search_installation_credential_unique": {
+ "name": "slack_search_installation_credential_unique",
+ "columns": [
+ {
+ "expression": "credential_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "slack_search_installation_app_team_unique": {
+ "name": "slack_search_installation_app_team_unique",
+ "columns": [
+ {
+ "expression": "app_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "slack_search_installation_active_team_unique": {
+ "name": "slack_search_installation_active_team_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"slack_search_installation\".\"enabled\" = true",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "slack_search_installation_organization_id_organization_id_fk": {
+ "name": "slack_search_installation_organization_id_organization_id_fk",
+ "tableFrom": "slack_search_installation",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "slack_search_installation_credential_id_credential_id_fk": {
+ "name": "slack_search_installation_credential_id_credential_id_fk",
+ "tableFrom": "slack_search_installation",
+ "tableTo": "credential",
+ "columnsFrom": ["credential_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "slack_search_installation_slack_app_id_slack_app_id_fk": {
+ "name": "slack_search_installation_slack_app_id_slack_app_id_fk",
+ "tableFrom": "slack_search_installation",
+ "tableTo": "slack_app",
+ "columnsFrom": ["slack_app_id"],
+ "columnsTo": ["id"],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.slack_search_turn": {
+ "name": "slack_search_turn",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "ordinal": {
+ "name": "ordinal",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "identity": {
+ "type": "always",
+ "name": "slack_search_turn_ordinal_seq",
+ "schema": "public",
+ "increment": "1",
+ "startWith": "1",
+ "minValue": "1",
+ "maxValue": "2147483647",
+ "cache": "1",
+ "cycle": false
+ }
+ },
+ "installation_id": {
+ "name": "installation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "conversation_key": {
+ "name": "conversation_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_id": {
+ "name": "event_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "lease_id": {
+ "name": "lease_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lease_expires_at": {
+ "name": "lease_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "outcome": {
+ "name": "outcome",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "slack_search_turn_event_unique": {
+ "name": "slack_search_turn_event_unique",
+ "columns": [
+ {
+ "expression": "installation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "slack_search_turn_pending_idx": {
+ "name": "slack_search_turn_pending_idx",
+ "columns": [
+ {
+ "expression": "installation_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "slack_search_turn_thread_idx": {
+ "name": "slack_search_turn_thread_idx",
+ "columns": [
+ {
+ "expression": "conversation_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "slack_search_turn_active_thread_unique": {
+ "name": "slack_search_turn_active_thread_unique",
+ "columns": [
+ {
+ "expression": "conversation_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"slack_search_turn\".\"status\" = 'running'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "slack_search_turn_installation_id_slack_search_installation_id_fk": {
+ "name": "slack_search_turn_installation_id_slack_search_installation_id_fk",
+ "tableFrom": "slack_search_turn",
+ "tableTo": "slack_search_installation",
+ "columnsFrom": ["installation_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sso_domain": {
+ "name": "sso_domain",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "domain": {
+ "name": "domain",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "verification_token": {
+ "name": "verification_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "verified_at": {
+ "name": "verified_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "primary_provider_id": {
+ "name": "primary_provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "sso_domain_organization_id_idx": {
+ "name": "sso_domain_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sso_domain_domain_idx": {
+ "name": "sso_domain_domain_idx",
+ "columns": [
+ {
+ "expression": "domain",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sso_domain_org_domain_unique": {
+ "name": "sso_domain_org_domain_unique",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "domain",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sso_domain_verified_unique": {
+ "name": "sso_domain_verified_unique",
+ "columns": [
+ {
+ "expression": "domain",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "status = 'verified'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "sso_domain_organization_id_organization_id_fk": {
+ "name": "sso_domain_organization_id_organization_id_fk",
+ "tableFrom": "sso_domain",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "sso_domain_created_by_user_id_fk": {
+ "name": "sso_domain_created_by_user_id_fk",
+ "tableFrom": "sso_domain",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sso_provider": {
+ "name": "sso_provider",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "issuer": {
+ "name": "issuer",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "domain": {
+ "name": "domain",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "oidc_config": {
+ "name": "oidc_config",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "saml_config": {
+ "name": "saml_config",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "domain_verified": {
+ "name": "domain_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "jit_provisioning_enabled": {
+ "name": "jit_provisioning_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ }
+ },
+ "indexes": {
+ "sso_provider_provider_id_unique": {
+ "name": "sso_provider_provider_id_unique",
+ "columns": [
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sso_provider_domain_idx": {
+ "name": "sso_provider_domain_idx",
+ "columns": [
+ {
+ "expression": "domain",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sso_provider_user_id_idx": {
+ "name": "sso_provider_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sso_provider_organization_id_idx": {
+ "name": "sso_provider_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "sso_provider_user_id_user_id_fk": {
+ "name": "sso_provider_user_id_user_id_fk",
+ "tableFrom": "sso_provider",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "sso_provider_organization_id_organization_id_fk": {
+ "name": "sso_provider_organization_id_organization_id_fk",
+ "tableFrom": "sso_provider",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.subscription": {
+ "name": "subscription",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "plan": {
+ "name": "plan",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "reference_id": {
+ "name": "reference_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stripe_customer_id": {
+ "name": "stripe_customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stripe_subscription_id": {
+ "name": "stripe_subscription_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "period_start": {
+ "name": "period_start",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "period_end": {
+ "name": "period_end",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cancel_at_period_end": {
+ "name": "cancel_at_period_end",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cancel_at": {
+ "name": "cancel_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "canceled_at": {
+ "name": "canceled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_at": {
+ "name": "ended_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "seats": {
+ "name": "seats",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trial_start": {
+ "name": "trial_start",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trial_end": {
+ "name": "trial_end",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "billing_interval": {
+ "name": "billing_interval",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stripe_schedule_id": {
+ "name": "stripe_schedule_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_closed_period_start": {
+ "name": "last_closed_period_start",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "subscription_reference_status_idx": {
+ "name": "subscription_reference_status_idx",
+ "columns": [
+ {
+ "expression": "reference_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "subscription_cycle_close_lagging_idx": {
+ "name": "subscription_cycle_close_lagging_idx",
+ "columns": [
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"subscription\".\"status\" in ('active', 'past_due') and \"subscription\".\"period_start\" is not null and (\"subscription\".\"last_closed_period_start\" is null or \"subscription\".\"last_closed_period_start\" < \"subscription\".\"period_start\")",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "check_enterprise_metadata": {
+ "name": "check_enterprise_metadata",
+ "value": "plan != 'enterprise' OR metadata IS NOT NULL"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.table_jobs": {
+ "name": "table_jobs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "table_id": {
+ "name": "table_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'running'"
+ },
+ "payload": {
+ "name": "payload",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rows_processed": {
+ "name": "rows_processed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "table_jobs_one_active_per_table": {
+ "name": "table_jobs_one_active_per_table",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"table_jobs\".\"status\" = 'running' AND \"table_jobs\".\"type\" <> 'export'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "table_jobs_watchdog_idx": {
+ "name": "table_jobs_watchdog_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "table_jobs_table_started_idx": {
+ "name": "table_jobs_table_started_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "table_jobs_table_id_user_table_definitions_id_fk": {
+ "name": "table_jobs_table_id_user_table_definitions_id_fk",
+ "tableFrom": "table_jobs",
+ "tableTo": "user_table_definitions",
+ "columnsFrom": ["table_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "table_jobs_workspace_id_workspace_id_fk": {
+ "name": "table_jobs_workspace_id_workspace_id_fk",
+ "tableFrom": "table_jobs",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.table_row_executions": {
+ "name": "table_row_executions",
+ "schema": "",
+ "columns": {
+ "table_id": {
+ "name": "table_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "row_id": {
+ "name": "row_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_id": {
+ "name": "group_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_id": {
+ "name": "execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "job_id": {
+ "name": "job_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "running_block_ids": {
+ "name": "running_block_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::text[]"
+ },
+ "block_errors": {
+ "name": "block_errors",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "cancelled_at": {
+ "name": "cancelled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "capability_governed_user_id": {
+ "name": "capability_governed_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "enrichment_details": {
+ "name": "enrichment_details",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "table_row_executions_table_status_idx": {
+ "name": "table_row_executions_table_status_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"table_row_executions\".\"status\" IN ('queued', 'running', 'pending')",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "table_row_executions_execution_id_idx": {
+ "name": "table_row_executions_execution_id_idx",
+ "columns": [
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"table_row_executions\".\"execution_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "table_row_executions_table_group_idx": {
+ "name": "table_row_executions_table_group_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "table_row_executions_table_id_user_table_definitions_id_fk": {
+ "name": "table_row_executions_table_id_user_table_definitions_id_fk",
+ "tableFrom": "table_row_executions",
+ "tableTo": "user_table_definitions",
+ "columnsFrom": ["table_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "table_row_executions_row_id_user_table_rows_id_fk": {
+ "name": "table_row_executions_row_id_user_table_rows_id_fk",
+ "tableFrom": "table_row_executions",
+ "tableTo": "user_table_rows",
+ "columnsFrom": ["row_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "table_row_executions_capability_governed_user_id_user_id_fk": {
+ "name": "table_row_executions_capability_governed_user_id_user_id_fk",
+ "tableFrom": "table_row_executions",
+ "tableTo": "user",
+ "columnsFrom": ["capability_governed_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "table_row_executions_row_id_group_id_pk": {
+ "name": "table_row_executions_row_id_group_id_pk",
+ "columns": ["row_id", "group_id"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.table_run_dispatches": {
+ "name": "table_run_dispatches",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "table_id": {
+ "name": "table_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mode": {
+ "name": "mode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scope": {
+ "name": "scope",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "cursor": {
+ "name": "cursor",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "limit": {
+ "name": "limit",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processed_count": {
+ "name": "processed_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "is_manual_run": {
+ "name": "is_manual_run",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "triggered_by_user_id": {
+ "name": "triggered_by_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "capability_governed_user_id": {
+ "name": "capability_governed_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "requested_at": {
+ "name": "requested_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "heartbeat_at": {
+ "name": "heartbeat_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cancelled_at": {
+ "name": "cancelled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "table_run_dispatches_active_idx": {
+ "name": "table_run_dispatches_active_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "table_run_dispatches_watchdog_idx": {
+ "name": "table_run_dispatches_watchdog_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "requested_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "table_run_dispatches_governed_active_idx": {
+ "name": "table_run_dispatches_governed_active_idx",
+ "columns": [
+ {
+ "expression": "capability_governed_user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"table_run_dispatches\".\"status\" IN ('pending', 'dispatching')",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "table_run_dispatches_table_id_user_table_definitions_id_fk": {
+ "name": "table_run_dispatches_table_id_user_table_definitions_id_fk",
+ "tableFrom": "table_run_dispatches",
+ "tableTo": "user_table_definitions",
+ "columnsFrom": ["table_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "table_run_dispatches_workspace_id_workspace_id_fk": {
+ "name": "table_run_dispatches_workspace_id_workspace_id_fk",
+ "tableFrom": "table_run_dispatches",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "table_run_dispatches_triggered_by_user_id_user_id_fk": {
+ "name": "table_run_dispatches_triggered_by_user_id_user_id_fk",
+ "tableFrom": "table_run_dispatches",
+ "tableTo": "user",
+ "columnsFrom": ["triggered_by_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "table_run_dispatches_capability_governed_user_id_user_id_fk": {
+ "name": "table_run_dispatches_capability_governed_user_id_user_id_fk",
+ "tableFrom": "table_run_dispatches",
+ "tableTo": "user",
+ "columnsFrom": ["capability_governed_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.table_views": {
+ "name": "table_views",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "table_id": {
+ "name": "table_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "table_views_table_created_idx": {
+ "name": "table_views_table_created_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "table_views_workspace_created_idx": {
+ "name": "table_views_workspace_created_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "table_views_table_default_unique": {
+ "name": "table_views_table_default_unique",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "is_default = true",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "table_views_table_id_user_table_definitions_id_fk": {
+ "name": "table_views_table_id_user_table_definitions_id_fk",
+ "tableFrom": "table_views",
+ "tableTo": "user_table_definitions",
+ "columnsFrom": ["table_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "table_views_workspace_id_workspace_id_fk": {
+ "name": "table_views_workspace_id_workspace_id_fk",
+ "tableFrom": "table_views",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "table_views_created_by_user_id_fk": {
+ "name": "table_views_created_by_user_id_fk",
+ "tableFrom": "table_views",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.upload_session": {
+ "name": "upload_session",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "token_hash": {
+ "name": "token_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "knowledge_base_id": {
+ "name": "knowledge_base_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_id": {
+ "name": "execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "purpose": {
+ "name": "purpose",
+ "type": "upload_session_purpose",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "method": {
+ "name": "method",
+ "type": "upload_session_method",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_context": {
+ "name": "storage_context",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "final_key": {
+ "name": "final_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_provider": {
+ "name": "storage_provider",
+ "type": "upload_session_provider",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_upload_id": {
+ "name": "provider_upload_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_object_version": {
+ "name": "provider_object_version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "file_name": {
+ "name": "file_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_size": {
+ "name": "file_size",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "part_size": {
+ "name": "part_size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "part_count": {
+ "name": "part_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "upload_session_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'uploading'"
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "processing_lease_id": {
+ "name": "processing_lease_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "processing_lease_expires_at": {
+ "name": "processing_lease_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_file_id": {
+ "name": "completed_file_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error": {
+ "name": "error",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "upload_session_token_hash_unique": {
+ "name": "upload_session_token_hash_unique",
+ "columns": [
+ {
+ "expression": "token_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "upload_session_final_key_unique": {
+ "name": "upload_session_final_key_unique",
+ "columns": [
+ {
+ "expression": "final_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "upload_session_status_expires_at_idx": {
+ "name": "upload_session_status_expires_at_idx",
+ "columns": [
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.usage_log": {
+ "name": "usage_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "category": {
+ "name": "category",
+ "type": "usage_log_category",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source": {
+ "name": "source",
+ "type": "usage_log_source",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost": {
+ "name": "cost",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_key": {
+ "name": "event_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "billing_entity_type": {
+ "name": "billing_entity_type",
+ "type": "billing_entity_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "billing_entity_id": {
+ "name": "billing_entity_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "billing_period_start": {
+ "name": "billing_period_start",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "billing_period_end": {
+ "name": "billing_period_end",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_id": {
+ "name": "execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "usage_log_user_created_at_idx": {
+ "name": "usage_log_user_created_at_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_source_idx": {
+ "name": "usage_log_source_idx",
+ "columns": [
+ {
+ "expression": "source",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_workspace_id_idx": {
+ "name": "usage_log_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_workflow_id_idx": {
+ "name": "usage_log_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_event_key_unique": {
+ "name": "usage_log_event_key_unique",
+ "columns": [
+ {
+ "expression": "event_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"usage_log\".\"event_key\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_billing_entity_period_idx": {
+ "name": "usage_log_billing_entity_period_idx",
+ "columns": [
+ {
+ "expression": "billing_entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "billing_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "billing_period_start",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "billing_period_end",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"usage_log\".\"billing_entity_type\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_billing_period_cost_idx": {
+ "name": "usage_log_billing_period_cost_idx",
+ "columns": [
+ {
+ "expression": "billing_entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "billing_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "billing_period_start",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "billing_period_end",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"usage_log\".\"billing_entity_type\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_billing_entity_created_at_cost_idx": {
+ "name": "usage_log_billing_entity_created_at_cost_idx",
+ "columns": [
+ {
+ "expression": "billing_entity_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "billing_entity_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"usage_log\".\"billing_entity_type\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_workspace_created_at_idx": {
+ "name": "usage_log_workspace_created_at_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "usage_log_execution_id_idx": {
+ "name": "usage_log_execution_id_idx",
+ "columns": [
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "usage_log_user_id_user_id_fk": {
+ "name": "usage_log_user_id_user_id_fk",
+ "tableFrom": "usage_log",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "usage_log_workspace_id_workspace_id_fk": {
+ "name": "usage_log_workspace_id_workspace_id_fk",
+ "tableFrom": "usage_log",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "usage_log_workflow_id_workflow_id_fk": {
+ "name": "usage_log_workflow_id_workflow_id_fk",
+ "tableFrom": "usage_log",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "usage_log_billing_scope_all_or_none": {
+ "name": "usage_log_billing_scope_all_or_none",
+ "value": "(\n (\"usage_log\".\"billing_entity_type\" IS NULL AND \"usage_log\".\"billing_entity_id\" IS NULL AND \"usage_log\".\"billing_period_start\" IS NULL AND \"usage_log\".\"billing_period_end\" IS NULL)\n OR\n (\"usage_log\".\"billing_entity_type\" IS NOT NULL AND \"usage_log\".\"billing_entity_id\" IS NOT NULL AND \"usage_log\".\"billing_period_start\" IS NOT NULL AND \"usage_log\".\"billing_period_end\" IS NOT NULL AND \"usage_log\".\"billing_period_start\" < \"usage_log\".\"billing_period_end\")\n )"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "normalized_email": {
+ "name": "normalized_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stripe_customer_id": {
+ "name": "stripe_customer_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'user'"
+ },
+ "banned": {
+ "name": "banned",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "ban_reason": {
+ "name": "ban_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ban_expires": {
+ "name": "ban_expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "suspended_at": {
+ "name": "suspended_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "suspension_source": {
+ "name": "suspension_source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "user_email_lower_idx": {
+ "name": "user_email_lower_idx",
+ "columns": [
+ {
+ "expression": "lower(btrim(\"email\"))",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "nullsNotDistinct": false,
+ "columns": ["email"]
+ },
+ "user_normalized_email_unique": {
+ "name": "user_normalized_email_unique",
+ "nullsNotDistinct": false,
+ "columns": ["normalized_email"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_stats": {
+ "name": "user_stats",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_usage_limit": {
+ "name": "current_usage_limit",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'5'"
+ },
+ "usage_limit_updated_at": {
+ "name": "usage_limit_updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "last_period_cost": {
+ "name": "last_period_cost",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'0'"
+ },
+ "billed_overage_this_period": {
+ "name": "billed_overage_this_period",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "credit_balance": {
+ "name": "credit_balance",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "last_period_copilot_cost": {
+ "name": "last_period_copilot_cost",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'0'"
+ },
+ "storage_used_bytes": {
+ "name": "storage_used_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "billing_blocked": {
+ "name": "billing_blocked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "billing_blocked_reason": {
+ "name": "billing_blocked_reason",
+ "type": "billing_blocked_reason",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "limit_notifications": {
+ "name": "limit_notifications",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "user_stats_user_id_user_id_fk": {
+ "name": "user_stats_user_id_user_id_fk",
+ "tableFrom": "user_stats",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_stats_user_id_unique": {
+ "name": "user_stats_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": ["user_id"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_table_definitions": {
+ "name": "user_table_definitions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "folder_id": {
+ "name": "folder_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "schema": {
+ "name": "schema",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_rows": {
+ "name": "max_rows",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 10000
+ },
+ "row_count": {
+ "name": "row_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "rows_version": {
+ "name": "rows_version",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "schema_locked": {
+ "name": "schema_locked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "insert_locked": {
+ "name": "insert_locked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "update_locked": {
+ "name": "update_locked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "delete_locked": {
+ "name": "delete_locked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "user_table_def_workspace_id_idx": {
+ "name": "user_table_def_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_table_def_folder_id_idx": {
+ "name": "user_table_def_folder_id_idx",
+ "columns": [
+ {
+ "expression": "folder_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_table_def_workspace_name_unique": {
+ "name": "user_table_def_workspace_name_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"user_table_definitions\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_table_def_archived_at_idx": {
+ "name": "user_table_def_archived_at_idx",
+ "columns": [
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_table_def_workspace_archived_partial_idx": {
+ "name": "user_table_def_workspace_archived_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"user_table_definitions\".\"archived_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_table_definitions_workspace_id_workspace_id_fk": {
+ "name": "user_table_definitions_workspace_id_workspace_id_fk",
+ "tableFrom": "user_table_definitions",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_table_definitions_folder_id_folder_id_fk": {
+ "name": "user_table_definitions_folder_id_folder_id_fk",
+ "tableFrom": "user_table_definitions",
+ "tableTo": "folder",
+ "columnsFrom": ["folder_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "user_table_definitions_created_by_user_id_fk": {
+ "name": "user_table_definitions_created_by_user_id_fk",
+ "tableFrom": "user_table_definitions",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_table_row_secret_provenance": {
+ "name": "user_table_row_secret_provenance",
+ "schema": "",
+ "columns": {
+ "row_id": {
+ "name": "row_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "content_updated_at": {
+ "name": "content_updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entries": {
+ "name": "entries",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "user_table_row_secret_provenance_row_id_user_table_rows_id_fk": {
+ "name": "user_table_row_secret_provenance_row_id_user_table_rows_id_fk",
+ "tableFrom": "user_table_row_secret_provenance",
+ "tableTo": "user_table_rows",
+ "columnsFrom": ["row_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "user_table_row_secret_provenance_status_check": {
+ "name": "user_table_row_secret_provenance_status_check",
+ "value": "\"user_table_row_secret_provenance\".\"status\" IN ('exact', 'unknown')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.user_table_rows": {
+ "name": "user_table_rows",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "table_id": {
+ "name": "table_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "data": {
+ "name": "data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "position": {
+ "name": "position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "order_key": {
+ "name": "order_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret_provenance_version": {
+ "name": "secret_provenance_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "user_table_rows_tenant_data_gin_idx": {
+ "name": "user_table_rows_tenant_data_gin_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "\"data\" jsonb_path_ops",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ },
+ "user_table_rows_workspace_table_idx": {
+ "name": "user_table_rows_workspace_table_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_table_rows_table_position_idx": {
+ "name": "user_table_rows_table_position_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "position",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_table_rows_table_order_key_idx": {
+ "name": "user_table_rows_table_order_key_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "order_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_table_rows_table_created_id_idx": {
+ "name": "user_table_rows_table_created_id_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "user_table_rows_table_id_id_idx": {
+ "name": "user_table_rows_table_id_id_idx",
+ "columns": [
+ {
+ "expression": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "user_table_rows_table_id_user_table_definitions_id_fk": {
+ "name": "user_table_rows_table_id_user_table_definitions_id_fk",
+ "tableFrom": "user_table_rows",
+ "tableTo": "user_table_definitions",
+ "columnsFrom": ["table_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_table_rows_workspace_id_workspace_id_fk": {
+ "name": "user_table_rows_workspace_id_workspace_id_fk",
+ "tableFrom": "user_table_rows",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "user_table_rows_created_by_user_id_fk": {
+ "name": "user_table_rows_created_by_user_id_fk",
+ "tableFrom": "user_table_rows",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.verification": {
+ "name": "verification",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "verification_identifier_idx": {
+ "name": "verification_identifier_idx",
+ "columns": [
+ {
+ "expression": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "verification_expires_at_idx": {
+ "name": "verification_expires_at_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.waitlist": {
+ "name": "waitlist",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "waitlist_email_unique": {
+ "name": "waitlist_email_unique",
+ "nullsNotDistinct": false,
+ "columns": ["email"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.webhook": {
+ "name": "webhook",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deployment_version_id": {
+ "name": "deployment_version_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "registration_status": {
+ "name": "registration_status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "registration_generation": {
+ "name": "registration_generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "config_fingerprint": {
+ "name": "config_fingerprint",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "prepared_at": {
+ "name": "prepared_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "block_id": {
+ "name": "block_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "routing_key": {
+ "name": "routing_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "provider_config": {
+ "name": "provider_config",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "failed_count": {
+ "name": "failed_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 0
+ },
+ "last_failed_at": {
+ "name": "last_failed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "path_deployment_unique": {
+ "name": "path_deployment_unique",
+ "columns": [
+ {
+ "expression": "path",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"webhook\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "webhook_workflow_deployment_idx": {
+ "name": "webhook_workflow_deployment_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "webhook_routing_key_active_idx": {
+ "name": "webhook_routing_key_active_idx",
+ "columns": [
+ {
+ "expression": "routing_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"webhook\".\"archived_at\" IS NULL AND \"webhook\".\"routing_key\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "webhook_archived_at_partial_idx": {
+ "name": "webhook_archived_at_partial_idx",
+ "columns": [
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"webhook\".\"archived_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "idx_webhook_on_provider_is_active_workflow_id_deploym_bdeed5468": {
+ "name": "idx_webhook_on_provider_is_active_workflow_id_deploym_bdeed5468",
+ "columns": [
+ {
+ "expression": "provider",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "is_active",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "idx_webhook_on_workflow_id_block_id_updated_at_desc": {
+ "name": "idx_webhook_on_workflow_id_block_id_updated_at_desc",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": false,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "webhook_active_registration_unique": {
+ "name": "webhook_active_registration_unique",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"webhook\".\"registration_status\" = 'active' AND \"webhook\".\"block_id\" IS NOT NULL AND \"webhook\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "webhook_candidate_registration_unique": {
+ "name": "webhook_candidate_registration_unique",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"webhook\".\"registration_status\" = 'candidate' AND \"webhook\".\"block_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "webhook_registration_status_generation_idx": {
+ "name": "webhook_registration_status_generation_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "registration_status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "registration_generation",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "webhook_workflow_id_workflow_id_fk": {
+ "name": "webhook_workflow_id_workflow_id_fk",
+ "tableFrom": "webhook",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "webhook_deployment_version_id_workflow_deployment_version_id_fk": {
+ "name": "webhook_deployment_version_id_workflow_deployment_version_id_fk",
+ "tableFrom": "webhook",
+ "tableTo": "workflow_deployment_version",
+ "columnsFrom": ["deployment_version_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "webhook_registration_status_check": {
+ "name": "webhook_registration_status_check",
+ "value": "\"webhook\".\"registration_status\" IS NULL OR \"webhook\".\"registration_status\" IN ('active', 'candidate', 'retired', 'orphaned')"
+ },
+ "webhook_registration_generation_check": {
+ "name": "webhook_registration_generation_check",
+ "value": "\"webhook\".\"registration_generation\" IS NULL OR \"webhook\".\"registration_generation\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.webhook_path_claim": {
+ "name": "webhook_path_claim",
+ "schema": "",
+ "columns": {
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "generation": {
+ "name": "generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "webhook_path_claim_workflow_idx": {
+ "name": "webhook_path_claim_workflow_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "webhook_path_claim_workflow_id_workflow_id_fk": {
+ "name": "webhook_path_claim_workflow_id_workflow_id_fk",
+ "tableFrom": "webhook_path_claim",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "webhook_path_claim_generation_check": {
+ "name": "webhook_path_claim_generation_check",
+ "value": "\"webhook_path_claim\".\"generation\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.workflow": {
+ "name": "workflow",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "folder_id": {
+ "name": "folder_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sort_order": {
+ "name": "sort_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_synced": {
+ "name": "last_synced",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_deployed": {
+ "name": "is_deployed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "deployed_at": {
+ "name": "deployed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_public_api": {
+ "name": "is_public_api",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "locked": {
+ "name": "locked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "fork_sync_excluded": {
+ "name": "fork_sync_excluded",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "run_count": {
+ "name": "run_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "last_run_at": {
+ "name": "last_run_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "variables": {
+ "name": "variables",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'"
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "workflow_user_id_idx": {
+ "name": "workflow_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_workspace_id_idx": {
+ "name": "workflow_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_user_workspace_idx": {
+ "name": "workflow_user_workspace_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_workspace_folder_name_active_unique": {
+ "name": "workflow_workspace_folder_name_active_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "coalesce(\"folder_id\", '')",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workflow\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_folder_sort_idx": {
+ "name": "workflow_folder_sort_idx",
+ "columns": [
+ {
+ "expression": "folder_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sort_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_active_workspace_sort_idx": {
+ "name": "workflow_active_workspace_sort_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sort_order",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_archived_at_idx": {
+ "name": "workflow_archived_at_idx",
+ "columns": [
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_workspace_archived_partial_idx": {
+ "name": "workflow_workspace_archived_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow\".\"archived_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_user_id_user_id_fk": {
+ "name": "workflow_user_id_user_id_fk",
+ "tableFrom": "workflow",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_workspace_id_workspace_id_fk": {
+ "name": "workflow_workspace_id_workspace_id_fk",
+ "tableFrom": "workflow",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_folder_id_folder_id_fk": {
+ "name": "workflow_folder_id_folder_id_fk",
+ "tableFrom": "workflow",
+ "tableTo": "folder",
+ "columnsFrom": ["folder_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_blocks": {
+ "name": "workflow_blocks",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "position_x": {
+ "name": "position_x",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "position_y": {
+ "name": "position_y",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "horizontal_handles": {
+ "name": "horizontal_handles",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "is_wide": {
+ "name": "is_wide",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "advanced_mode": {
+ "name": "advanced_mode",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "trigger_mode": {
+ "name": "trigger_mode",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "error_enabled": {
+ "name": "error_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "retry": {
+ "name": "retry",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "locked": {
+ "name": "locked",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "height": {
+ "name": "height",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "sub_blocks": {
+ "name": "sub_blocks",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "outputs": {
+ "name": "outputs",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "data": {
+ "name": "data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'{}'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_blocks_workflow_id_idx": {
+ "name": "workflow_blocks_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_blocks_type_idx": {
+ "name": "workflow_blocks_type_idx",
+ "columns": [
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_blocks_workflow_id_workflow_id_fk": {
+ "name": "workflow_blocks_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_blocks",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_checkpoints": {
+ "name": "workflow_checkpoints",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chat_id": {
+ "name": "chat_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "message_id": {
+ "name": "message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workflow_state": {
+ "name": "workflow_state",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_checkpoints_user_id_idx": {
+ "name": "workflow_checkpoints_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_checkpoints_workflow_id_idx": {
+ "name": "workflow_checkpoints_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_checkpoints_chat_id_idx": {
+ "name": "workflow_checkpoints_chat_id_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_checkpoints_message_id_idx": {
+ "name": "workflow_checkpoints_message_id_idx",
+ "columns": [
+ {
+ "expression": "message_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_checkpoints_user_workflow_idx": {
+ "name": "workflow_checkpoints_user_workflow_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_checkpoints_workflow_chat_idx": {
+ "name": "workflow_checkpoints_workflow_chat_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_checkpoints_created_at_idx": {
+ "name": "workflow_checkpoints_created_at_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_checkpoints_chat_created_at_idx": {
+ "name": "workflow_checkpoints_chat_created_at_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_checkpoints_user_id_user_id_fk": {
+ "name": "workflow_checkpoints_user_id_user_id_fk",
+ "tableFrom": "workflow_checkpoints",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_checkpoints_workflow_id_workflow_id_fk": {
+ "name": "workflow_checkpoints_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_checkpoints",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_checkpoints_chat_id_copilot_chats_id_fk": {
+ "name": "workflow_checkpoints_chat_id_copilot_chats_id_fk",
+ "tableFrom": "workflow_checkpoints",
+ "tableTo": "copilot_chats",
+ "columnsFrom": ["chat_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_deployment_operation": {
+ "name": "workflow_deployment_operation",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deployment_version_id": {
+ "name": "deployment_version_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_active_version_id": {
+ "name": "previous_active_version_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action": {
+ "name": "action",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "protocol_version": {
+ "name": "protocol_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "generation": {
+ "name": "generation",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'preparing'"
+ },
+ "component_readiness": {
+ "name": "component_readiness",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "error_code": {
+ "name": "error_code",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "error_message": {
+ "name": "error_message",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "idempotency_key": {
+ "name": "idempotency_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "request_hash": {
+ "name": "request_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_id": {
+ "name": "actor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_deployment_operation_workflow_generation_unique": {
+ "name": "workflow_deployment_operation_workflow_generation_unique",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "generation",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_deployment_operation_workflow_idempotency_unique": {
+ "name": "workflow_deployment_operation_workflow_idempotency_unique",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "idempotency_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workflow_deployment_operation\".\"idempotency_key\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_deployment_operation_workflow_in_flight_unique": {
+ "name": "workflow_deployment_operation_workflow_in_flight_unique",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workflow_deployment_operation\".\"status\" IN ('preparing', 'activating')",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_deployment_operation_workflow_status_idx": {
+ "name": "workflow_deployment_operation_workflow_status_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_deployment_operation_deployment_version_idx": {
+ "name": "workflow_deployment_operation_deployment_version_idx",
+ "columns": [
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_deployment_operation_workflow_version_generation_idx": {
+ "name": "workflow_deployment_operation_workflow_version_generation_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "generation",
+ "isExpression": false,
+ "asc": false,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_deployment_operation_workflow_id_workflow_id_fk": {
+ "name": "workflow_deployment_operation_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_deployment_operation",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_deployment_operation_deployment_version_id_workflow_deployment_version_id_fk": {
+ "name": "workflow_deployment_operation_deployment_version_id_workflow_deployment_version_id_fk",
+ "tableFrom": "workflow_deployment_operation",
+ "tableTo": "workflow_deployment_version",
+ "columnsFrom": ["deployment_version_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_deployment_operation_previous_active_version_id_workflow_deployment_version_id_fk": {
+ "name": "workflow_deployment_operation_previous_active_version_id_workflow_deployment_version_id_fk",
+ "tableFrom": "workflow_deployment_operation",
+ "tableTo": "workflow_deployment_version",
+ "columnsFrom": ["previous_active_version_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "workflow_deployment_operation_action_check": {
+ "name": "workflow_deployment_operation_action_check",
+ "value": "\"workflow_deployment_operation\".\"action\" IN ('deploy', 'activate')"
+ },
+ "workflow_deployment_operation_status_check": {
+ "name": "workflow_deployment_operation_status_check",
+ "value": "\"workflow_deployment_operation\".\"status\" IN ('preparing', 'activating', 'active', 'failed', 'superseded')"
+ },
+ "workflow_deployment_operation_generation_check": {
+ "name": "workflow_deployment_operation_generation_check",
+ "value": "\"workflow_deployment_operation\".\"generation\" > 0"
+ },
+ "workflow_deployment_operation_protocol_version_check": {
+ "name": "workflow_deployment_operation_protocol_version_check",
+ "value": "\"workflow_deployment_operation\".\"protocol_version\" > 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.workflow_deployment_version": {
+ "name": "workflow_deployment_version",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "version": {
+ "name": "version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "state": {
+ "name": "state",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "workflow_deployment_version_workflow_version_unique": {
+ "name": "workflow_deployment_version_workflow_version_unique",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "version",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_deployment_version_workflow_active_idx": {
+ "name": "workflow_deployment_version_workflow_active_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "is_active",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_deployment_version_created_at_idx": {
+ "name": "workflow_deployment_version_created_at_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_deployment_version_workflow_id_workflow_id_fk": {
+ "name": "workflow_deployment_version_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_deployment_version",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_edges": {
+ "name": "workflow_edges",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_block_id": {
+ "name": "source_block_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_block_id": {
+ "name": "target_block_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_handle": {
+ "name": "source_handle",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "target_handle": {
+ "name": "target_handle",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_edges_workflow_id_idx": {
+ "name": "workflow_edges_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_edges_workflow_source_idx": {
+ "name": "workflow_edges_workflow_source_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_edges_workflow_target_idx": {
+ "name": "workflow_edges_workflow_target_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_edges_workflow_id_workflow_id_fk": {
+ "name": "workflow_edges_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_edges",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_edges_source_block_id_workflow_blocks_id_fk": {
+ "name": "workflow_edges_source_block_id_workflow_blocks_id_fk",
+ "tableFrom": "workflow_edges",
+ "tableTo": "workflow_blocks",
+ "columnsFrom": ["source_block_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_edges_target_block_id_workflow_blocks_id_fk": {
+ "name": "workflow_edges_target_block_id_workflow_blocks_id_fk",
+ "tableFrom": "workflow_edges",
+ "tableTo": "workflow_blocks",
+ "columnsFrom": ["target_block_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_execution_logs": {
+ "name": "workflow_execution_logs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_id": {
+ "name": "execution_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state_snapshot_id": {
+ "name": "state_snapshot_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deployment_version_id": {
+ "name": "deployment_version_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "level": {
+ "name": "level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'running'"
+ },
+ "trigger": {
+ "name": "trigger",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "execution_deadline_at": {
+ "name": "execution_deadline_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ended_at": {
+ "name": "ended_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_duration_ms": {
+ "name": "total_duration_ms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "execution_data": {
+ "name": "execution_data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "cost_total": {
+ "name": "cost_total",
+ "type": "numeric",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "models_used": {
+ "name": "models_used",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "files": {
+ "name": "files",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_execution_logs_workflow_id_idx": {
+ "name": "workflow_execution_logs_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_state_snapshot_id_idx": {
+ "name": "workflow_execution_logs_state_snapshot_id_idx",
+ "columns": [
+ {
+ "expression": "state_snapshot_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_deployment_version_id_idx": {
+ "name": "workflow_execution_logs_deployment_version_id_idx",
+ "columns": [
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_trigger_idx": {
+ "name": "workflow_execution_logs_trigger_idx",
+ "columns": [
+ {
+ "expression": "trigger",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_level_idx": {
+ "name": "workflow_execution_logs_level_idx",
+ "columns": [
+ {
+ "expression": "level",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_started_at_idx": {
+ "name": "workflow_execution_logs_started_at_idx",
+ "columns": [
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_execution_id_unique": {
+ "name": "workflow_execution_logs_execution_id_unique",
+ "columns": [
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_workflow_started_at_idx": {
+ "name": "workflow_execution_logs_workflow_started_at_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_workspace_started_at_idx": {
+ "name": "workflow_execution_logs_workspace_started_at_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_workspace_started_at_id_desc_idx": {
+ "name": "workflow_execution_logs_workspace_started_at_id_desc_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "\"started_at\" DESC NULLS LAST",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "\"id\" DESC",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_workspace_cost_total_idx": {
+ "name": "workflow_execution_logs_workspace_cost_total_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "cost_total",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_models_used_idx": {
+ "name": "workflow_execution_logs_models_used_idx",
+ "columns": [
+ {
+ "expression": "models_used",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ },
+ "workflow_execution_logs_workspace_ended_at_id_idx": {
+ "name": "workflow_execution_logs_workspace_ended_at_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "date_trunc('milliseconds', \"ended_at\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_running_started_at_idx": {
+ "name": "workflow_execution_logs_running_started_at_idx",
+ "columns": [
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "status = 'running'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_running_deadline_idx": {
+ "name": "workflow_execution_logs_running_deadline_idx",
+ "columns": [
+ {
+ "expression": "execution_deadline_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow_execution_logs\".\"status\" = 'running' AND \"workflow_execution_logs\".\"execution_deadline_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_redacting_started_at_idx": {
+ "name": "workflow_execution_logs_redacting_started_at_idx",
+ "columns": [
+ {
+ "expression": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "status = 'redacting'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_redacting_deadline_idx": {
+ "name": "workflow_execution_logs_redacting_deadline_idx",
+ "columns": [
+ {
+ "expression": "execution_deadline_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow_execution_logs\".\"status\" = 'redacting' AND \"workflow_execution_logs\".\"execution_deadline_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_execution_logs_completed_ended_at_idx": {
+ "name": "workflow_execution_logs_completed_ended_at_idx",
+ "columns": [
+ {
+ "expression": "ended_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "execution_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow_execution_logs\".\"status\" = 'completed' AND \"workflow_execution_logs\".\"level\" = 'info' AND \"workflow_execution_logs\".\"ended_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_execution_logs_workflow_id_workflow_id_fk": {
+ "name": "workflow_execution_logs_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_execution_logs",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "workflow_execution_logs_workspace_id_workspace_id_fk": {
+ "name": "workflow_execution_logs_workspace_id_workspace_id_fk",
+ "tableFrom": "workflow_execution_logs",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_execution_logs_state_snapshot_id_workflow_execution_snapshots_id_fk": {
+ "name": "workflow_execution_logs_state_snapshot_id_workflow_execution_snapshots_id_fk",
+ "tableFrom": "workflow_execution_logs",
+ "tableTo": "workflow_execution_snapshots",
+ "columnsFrom": ["state_snapshot_id"],
+ "columnsTo": ["id"],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "workflow_execution_logs_deployment_version_id_workflow_deployment_version_id_fk": {
+ "name": "workflow_execution_logs_deployment_version_id_workflow_deployment_version_id_fk",
+ "tableFrom": "workflow_execution_logs",
+ "tableTo": "workflow_deployment_version",
+ "columnsFrom": ["deployment_version_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_execution_snapshots": {
+ "name": "workflow_execution_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "state_hash": {
+ "name": "state_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "state_data": {
+ "name": "state_data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_snapshots_workflow_id_idx": {
+ "name": "workflow_snapshots_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_snapshots_hash_idx": {
+ "name": "workflow_snapshots_hash_idx",
+ "columns": [
+ {
+ "expression": "state_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_snapshots_workflow_hash_idx": {
+ "name": "workflow_snapshots_workflow_hash_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "state_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_snapshots_created_at_idx": {
+ "name": "workflow_snapshots_created_at_idx",
+ "columns": [
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_execution_snapshots_workflow_id_workflow_id_fk": {
+ "name": "workflow_execution_snapshots_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_execution_snapshots",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_mcp_server": {
+ "name": "workflow_mcp_server",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_public": {
+ "name": "is_public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_mcp_server_workspace_id_idx": {
+ "name": "workflow_mcp_server_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_mcp_server_created_by_idx": {
+ "name": "workflow_mcp_server_created_by_idx",
+ "columns": [
+ {
+ "expression": "created_by",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_mcp_server_deleted_at_idx": {
+ "name": "workflow_mcp_server_deleted_at_idx",
+ "columns": [
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_mcp_server_workspace_deleted_partial_idx": {
+ "name": "workflow_mcp_server_workspace_deleted_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow_mcp_server\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_mcp_server_workspace_id_workspace_id_fk": {
+ "name": "workflow_mcp_server_workspace_id_workspace_id_fk",
+ "tableFrom": "workflow_mcp_server",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_mcp_server_created_by_user_id_fk": {
+ "name": "workflow_mcp_server_created_by_user_id_fk",
+ "tableFrom": "workflow_mcp_server",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_mcp_tool": {
+ "name": "workflow_mcp_tool",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "server_id": {
+ "name": "server_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tool_name": {
+ "name": "tool_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tool_description": {
+ "name": "tool_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "parameter_schema": {
+ "name": "parameter_schema",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "parameter_description_overrides": {
+ "name": "parameter_description_overrides",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::json"
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_mcp_tool_server_id_idx": {
+ "name": "workflow_mcp_tool_server_id_idx",
+ "columns": [
+ {
+ "expression": "server_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_mcp_tool_workflow_id_idx": {
+ "name": "workflow_mcp_tool_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_mcp_tool_server_workflow_unique": {
+ "name": "workflow_mcp_tool_server_workflow_unique",
+ "columns": [
+ {
+ "expression": "server_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workflow_mcp_tool\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_mcp_tool_archived_at_partial_idx": {
+ "name": "workflow_mcp_tool_archived_at_partial_idx",
+ "columns": [
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow_mcp_tool\".\"archived_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_mcp_tool_server_id_workflow_mcp_server_id_fk": {
+ "name": "workflow_mcp_tool_server_id_workflow_mcp_server_id_fk",
+ "tableFrom": "workflow_mcp_tool",
+ "tableTo": "workflow_mcp_server",
+ "columnsFrom": ["server_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_mcp_tool_workflow_id_workflow_id_fk": {
+ "name": "workflow_mcp_tool_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_mcp_tool",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_schedule": {
+ "name": "workflow_schedule",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deployment_version_id": {
+ "name": "deployment_version_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deployment_operation_id": {
+ "name": "deployment_operation_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "block_id": {
+ "name": "block_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cron_expression": {
+ "name": "cron_expression",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "next_run_at": {
+ "name": "next_run_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_ran_at": {
+ "name": "last_ran_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_queued_at": {
+ "name": "last_queued_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "trigger_type": {
+ "name": "trigger_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'UTC'"
+ },
+ "failed_count": {
+ "name": "failed_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "infra_retry_count": {
+ "name": "infra_retry_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'active'"
+ },
+ "last_failed_at": {
+ "name": "last_failed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_type": {
+ "name": "source_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'workflow'"
+ },
+ "job_title": {
+ "name": "job_title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "prompt": {
+ "name": "prompt",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lifecycle": {
+ "name": "lifecycle",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'persistent'"
+ },
+ "success_condition": {
+ "name": "success_condition",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_runs": {
+ "name": "max_runs",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "run_count": {
+ "name": "run_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "source_chat_id": {
+ "name": "source_chat_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_task_name": {
+ "name": "source_task_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_user_id": {
+ "name": "source_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_workspace_id": {
+ "name": "source_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secret_scope": {
+ "name": "secret_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'all'"
+ },
+ "mounted_secrets": {
+ "name": "mounted_secrets",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "job_history": {
+ "name": "job_history",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contexts": {
+ "name": "contexts",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "excluded_dates": {
+ "name": "excluded_dates",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ends_at": {
+ "name": "ends_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_schedule_workflow_block_deployment_unique": {
+ "name": "workflow_schedule_workflow_block_deployment_unique",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workflow_schedule\".\"archived_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_schedule_workflow_deployment_idx": {
+ "name": "workflow_schedule_workflow_deployment_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_schedule_archived_at_partial_idx": {
+ "name": "workflow_schedule_archived_at_partial_idx",
+ "columns": [
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow_schedule\".\"archived_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "idx_workflow_schedule_on_source_workspace_id_source_t_c07f3bba6": {
+ "name": "idx_workflow_schedule_on_source_workspace_id_source_t_c07f3bba6",
+ "columns": [
+ {
+ "expression": "source_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "archived_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_schedule_due_workflow_idx": {
+ "name": "workflow_schedule_due_workflow_idx",
+ "columns": [
+ {
+ "expression": "next_run_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_queued_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deployment_version_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow_schedule\".\"archived_at\" IS NULL AND \"workflow_schedule\".\"status\" NOT IN ('disabled', 'completed') AND (\"workflow_schedule\".\"source_type\" = 'workflow' OR \"workflow_schedule\".\"source_type\" IS NULL)",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_schedule_due_job_idx": {
+ "name": "workflow_schedule_due_job_idx",
+ "columns": [
+ {
+ "expression": "next_run_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "last_queued_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workflow_schedule\".\"archived_at\" IS NULL AND \"workflow_schedule\".\"status\" NOT IN ('disabled', 'completed') AND \"workflow_schedule\".\"source_type\" = 'job'",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_schedule_workflow_id_workflow_id_fk": {
+ "name": "workflow_schedule_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_schedule",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_schedule_deployment_version_id_workflow_deployment_version_id_fk": {
+ "name": "workflow_schedule_deployment_version_id_workflow_deployment_version_id_fk",
+ "tableFrom": "workflow_schedule",
+ "tableTo": "workflow_deployment_version",
+ "columnsFrom": ["deployment_version_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_schedule_deployment_operation_id_workflow_deployment_operation_id_fk": {
+ "name": "workflow_schedule_deployment_operation_id_workflow_deployment_operation_id_fk",
+ "tableFrom": "workflow_schedule",
+ "tableTo": "workflow_deployment_operation",
+ "columnsFrom": ["deployment_operation_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "workflow_schedule_source_user_id_user_id_fk": {
+ "name": "workflow_schedule_source_user_id_user_id_fk",
+ "tableFrom": "workflow_schedule",
+ "tableTo": "user",
+ "columnsFrom": ["source_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workflow_schedule_source_workspace_id_workspace_id_fk": {
+ "name": "workflow_schedule_source_workspace_id_workspace_id_fk",
+ "tableFrom": "workflow_schedule",
+ "tableTo": "workspace",
+ "columnsFrom": ["source_workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workflow_subflows": {
+ "name": "workflow_subflows",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workflow_id": {
+ "name": "workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workflow_subflows_workflow_id_idx": {
+ "name": "workflow_subflows_workflow_id_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workflow_subflows_workflow_type_idx": {
+ "name": "workflow_subflows_workflow_type_idx",
+ "columns": [
+ {
+ "expression": "workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workflow_subflows_workflow_id_workflow_id_fk": {
+ "name": "workflow_subflows_workflow_id_workflow_id_fk",
+ "tableFrom": "workflow_subflows",
+ "tableTo": "workflow",
+ "columnsFrom": ["workflow_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace": {
+ "name": "workspace",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "color": {
+ "name": "color",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'#33C482'"
+ },
+ "logo_url": {
+ "name": "logo_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "owner_id": {
+ "name": "owner_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "workspace_mode": {
+ "name": "workspace_mode",
+ "type": "workspace_mode",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'grandfathered_shared'"
+ },
+ "billed_account_user_id": {
+ "name": "billed_account_user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "storage_used_bytes": {
+ "name": "storage_used_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "allow_personal_api_keys": {
+ "name": "allow_personal_api_keys",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "inbox_enabled": {
+ "name": "inbox_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "inbox_address": {
+ "name": "inbox_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "inbox_provider_id": {
+ "name": "inbox_provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "inbox_secret_scope": {
+ "name": "inbox_secret_scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'all'"
+ },
+ "inbox_mounted_secrets": {
+ "name": "inbox_mounted_secrets",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_assigned_at": {
+ "name": "organization_assigned_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "forked_from_workspace_id": {
+ "name": "forked_from_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_owner_id_idx": {
+ "name": "workspace_owner_id_idx",
+ "columns": [
+ {
+ "expression": "owner_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_organization_id_idx": {
+ "name": "workspace_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_mode_idx": {
+ "name": "workspace_mode_idx",
+ "columns": [
+ {
+ "expression": "workspace_mode",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_forked_from_workspace_id_idx": {
+ "name": "workspace_forked_from_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "forked_from_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_inbox_provider_id_idx": {
+ "name": "workspace_inbox_provider_id_idx",
+ "columns": [
+ {
+ "expression": "inbox_provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workspace\".\"inbox_provider_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_owner_id_user_id_fk": {
+ "name": "workspace_owner_id_user_id_fk",
+ "tableFrom": "workspace",
+ "tableTo": "user",
+ "columnsFrom": ["owner_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_organization_id_organization_id_fk": {
+ "name": "workspace_organization_id_organization_id_fk",
+ "tableFrom": "workspace",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "workspace_billed_account_user_id_user_id_fk": {
+ "name": "workspace_billed_account_user_id_user_id_fk",
+ "tableFrom": "workspace",
+ "tableTo": "user",
+ "columnsFrom": ["billed_account_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "workspace_forked_from_workspace_id_workspace_id_fk": {
+ "name": "workspace_forked_from_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace",
+ "tableTo": "workspace",
+ "columnsFrom": ["forked_from_workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "workspace_storage_used_bytes_non_negative": {
+ "name": "workspace_storage_used_bytes_non_negative",
+ "value": "\"workspace\".\"storage_used_bytes\" >= 0"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.workspace_byok_keys": {
+ "name": "workspace_byok_keys",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "encrypted_api_key": {
+ "name": "encrypted_api_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_byok_workspace_provider_idx": {
+ "name": "workspace_byok_workspace_provider_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "provider_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_byok_keys_workspace_id_workspace_id_fk": {
+ "name": "workspace_byok_keys_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_byok_keys",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_byok_keys_created_by_user_id_fk": {
+ "name": "workspace_byok_keys_created_by_user_id_fk",
+ "tableFrom": "workspace_byok_keys",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_environment": {
+ "name": "workspace_environment",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "variables": {
+ "name": "variables",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_environment_workspace_unique": {
+ "name": "workspace_environment_workspace_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_environment_workspace_id_workspace_id_fk": {
+ "name": "workspace_environment_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_environment",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_file": {
+ "name": "workspace_file",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "size": {
+ "name": "size",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "uploaded_by": {
+ "name": "uploaded_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uploaded_at": {
+ "name": "uploaded_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_file_workspace_id_idx": {
+ "name": "workspace_file_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_file_deleted_at_idx": {
+ "name": "workspace_file_deleted_at_idx",
+ "columns": [
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_file_workspace_deleted_partial_idx": {
+ "name": "workspace_file_workspace_deleted_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workspace_file\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_file_workspace_id_workspace_id_fk": {
+ "name": "workspace_file_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_file",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_file_uploaded_by_user_id_fk": {
+ "name": "workspace_file_uploaded_by_user_id_fk",
+ "tableFrom": "workspace_file",
+ "tableTo": "user",
+ "columnsFrom": ["uploaded_by"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "workspace_file_key_unique": {
+ "name": "workspace_file_key_unique",
+ "nullsNotDistinct": false,
+ "columns": ["key"]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_file_collab_state": {
+ "name": "workspace_file_collab_state",
+ "schema": "",
+ "columns": {
+ "file_id": {
+ "name": "file_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "doc_state": {
+ "name": "doc_state",
+ "type": "bytea",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_hash": {
+ "name": "source_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "workspace_file_collab_state_file_id_workspace_files_id_fk": {
+ "name": "workspace_file_collab_state_file_id_workspace_files_id_fk",
+ "tableFrom": "workspace_file_collab_state",
+ "tableTo": "workspace_files",
+ "columnsFrom": ["file_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_file_search_backfill": {
+ "name": "workspace_file_search_backfill",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "after_workspace_id": {
+ "name": "after_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "after_file_id": {
+ "name": "after_file_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_file_search_dispatch_queue": {
+ "name": "workspace_file_search_dispatch_queue",
+ "schema": "",
+ "columns": {
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "enqueued_at": {
+ "name": "enqueued_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "last_dispatched_at": {
+ "name": "last_dispatched_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_file_search_dispatch_queue_schedule_idx": {
+ "name": "workspace_file_search_dispatch_queue_schedule_idx",
+ "columns": [
+ {
+ "expression": "last_dispatched_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "first"
+ },
+ {
+ "expression": "enqueued_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_file_search_queue_workspace_fk": {
+ "name": "workspace_file_search_queue_workspace_fk",
+ "tableFrom": "workspace_file_search_dispatch_queue",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_file_search_index": {
+ "name": "workspace_file_search_index",
+ "schema": "",
+ "columns": {
+ "file_id": {
+ "name": "file_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_content_updated_at": {
+ "name": "source_content_updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "workspace_file_search_index_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pending'"
+ },
+ "partial": {
+ "name": "partial",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "failure_reason": {
+ "name": "failure_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "line_count": {
+ "name": "line_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "indexed_bytes": {
+ "name": "indexed_bytes",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "dispatched_at": {
+ "name": "dispatched_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_file_search_index_workspace_status_idx": {
+ "name": "workspace_file_search_index_workspace_status_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_content_updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_file_search_index_pending_dispatch_idx": {
+ "name": "workspace_file_search_index_pending_dispatch_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "file_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_content_updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workspace_file_search_index\".\"status\" = 'pending' AND \"workspace_file_search_index\".\"dispatched_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_file_search_index_active_dispatch_idx": {
+ "name": "workspace_file_search_index_active_dispatch_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "dispatched_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workspace_file_search_index\".\"status\" = 'pending' AND \"workspace_file_search_index\".\"dispatched_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_file_search_index_file_fk": {
+ "name": "workspace_file_search_index_file_fk",
+ "tableFrom": "workspace_file_search_index",
+ "tableTo": "workspace_files",
+ "columnsFrom": ["file_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_file_search_index_workspace_fk": {
+ "name": "workspace_file_search_index_workspace_fk",
+ "tableFrom": "workspace_file_search_index",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "workspace_file_search_index_pk": {
+ "name": "workspace_file_search_index_pk",
+ "columns": ["file_id", "source_content_updated_at"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_file_search_segment": {
+ "name": "workspace_file_search_segment",
+ "schema": "",
+ "columns": {
+ "file_id": {
+ "name": "file_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_content_updated_at": {
+ "name": "source_content_updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "line_number": {
+ "name": "line_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "segment_number": {
+ "name": "segment_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "segment_start": {
+ "name": "segment_start",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "line_length": {
+ "name": "line_length",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "workspace_file_search_segment_workspace_revision_idx": {
+ "name": "workspace_file_search_segment_workspace_revision_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "file_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "source_content_updated_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_file_search_segment_workspace_content_trgm_idx": {
+ "name": "workspace_file_search_segment_workspace_content_trgm_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "text_ops"
+ },
+ {
+ "expression": "content",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last",
+ "opclass": "gin_trgm_ops"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gin",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_file_search_segment_file_fk": {
+ "name": "workspace_file_search_segment_file_fk",
+ "tableFrom": "workspace_file_search_segment",
+ "tableTo": "workspace_files",
+ "columnsFrom": ["file_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_file_search_segment_workspace_fk": {
+ "name": "workspace_file_search_segment_workspace_fk",
+ "tableFrom": "workspace_file_search_segment",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "workspace_file_search_segment_pk": {
+ "name": "workspace_file_search_segment_pk",
+ "columns": ["file_id", "source_content_updated_at", "line_number", "segment_number"]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_file_secret_provenance": {
+ "name": "workspace_file_secret_provenance",
+ "schema": "",
+ "columns": {
+ "file_id": {
+ "name": "file_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "content_updated_at": {
+ "name": "content_updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "entries": {
+ "name": "entries",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "workspace_file_secret_provenance_file_id_workspace_files_id_fk": {
+ "name": "workspace_file_secret_provenance_file_id_workspace_files_id_fk",
+ "tableFrom": "workspace_file_secret_provenance",
+ "tableTo": "workspace_files",
+ "columnsFrom": ["file_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "workspace_file_secret_provenance_status_check": {
+ "name": "workspace_file_secret_provenance_status_check",
+ "value": "\"workspace_file_secret_provenance\".\"status\" IN ('exact', 'unknown', 'unrecorded')"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.workspace_files": {
+ "name": "workspace_files",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "folder_id": {
+ "name": "folder_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "context": {
+ "name": "context",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "chat_id": {
+ "name": "chat_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "message_id": {
+ "name": "message_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "original_name": {
+ "name": "original_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "size_bytes": {
+ "name": "size_bytes",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "width": {
+ "name": "width",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "height": {
+ "name": "height",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uploaded_at": {
+ "name": "uploaded_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "content_updated_at": {
+ "name": "content_updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "secret_provenance_version": {
+ "name": "secret_provenance_version",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {
+ "workspace_files_key_active_unique": {
+ "name": "workspace_files_key_active_unique",
+ "columns": [
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workspace_files\".\"deleted_at\" IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_workspace_folder_name_active_unique": {
+ "name": "workspace_files_workspace_folder_name_active_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "coalesce(\"folder_id\", '')",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "original_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workspace_files\".\"deleted_at\" IS NULL AND \"workspace_files\".\"context\" = 'workspace' AND \"workspace_files\".\"workspace_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_chat_display_name_unique": {
+ "name": "workspace_files_chat_display_name_unique",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "display_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"workspace_files\".\"context\" = 'mothership' AND \"workspace_files\".\"chat_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_organization_id_idx": {
+ "name": "workspace_files_organization_id_idx",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_key_idx": {
+ "name": "workspace_files_key_idx",
+ "columns": [
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_user_id_idx": {
+ "name": "workspace_files_user_id_idx",
+ "columns": [
+ {
+ "expression": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_workspace_id_idx": {
+ "name": "workspace_files_workspace_id_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_folder_id_idx": {
+ "name": "workspace_files_folder_id_idx",
+ "columns": [
+ {
+ "expression": "folder_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_context_idx": {
+ "name": "workspace_files_context_idx",
+ "columns": [
+ {
+ "expression": "context",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_chat_id_idx": {
+ "name": "workspace_files_chat_id_idx",
+ "columns": [
+ {
+ "expression": "chat_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_deleted_at_idx": {
+ "name": "workspace_files_deleted_at_idx",
+ "columns": [
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_files_workspace_deleted_partial_idx": {
+ "name": "workspace_files_workspace_deleted_partial_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deleted_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "where": "\"workspace_files\".\"deleted_at\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_files_user_id_user_id_fk": {
+ "name": "workspace_files_user_id_user_id_fk",
+ "tableFrom": "workspace_files",
+ "tableTo": "user",
+ "columnsFrom": ["user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_files_workspace_id_workspace_id_fk": {
+ "name": "workspace_files_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_files",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_files_organization_id_organization_id_fk": {
+ "name": "workspace_files_organization_id_organization_id_fk",
+ "tableFrom": "workspace_files",
+ "tableTo": "organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_files_folder_id_folder_id_fk": {
+ "name": "workspace_files_folder_id_folder_id_fk",
+ "tableFrom": "workspace_files",
+ "tableTo": "folder",
+ "columnsFrom": ["folder_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "workspace_files_chat_id_copilot_chats_id_fk": {
+ "name": "workspace_files_chat_id_copilot_chats_id_fk",
+ "tableFrom": "workspace_files",
+ "tableTo": "copilot_chats",
+ "columnsFrom": ["chat_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "workspace_files_organization_binding_check": {
+ "name": "workspace_files_organization_binding_check",
+ "value": "\"workspace_files\".\"organization_id\" IS NULL OR (\"workspace_files\".\"workspace_id\" IS NULL AND \"workspace_files\".\"context\" = 'knowledge-base' AND \"workspace_files\".\"folder_id\" IS NULL AND \"workspace_files\".\"chat_id\" IS NULL)"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.workspace_fork_block_map": {
+ "name": "workspace_fork_block_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "child_workspace_id": {
+ "name": "child_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_workflow_id": {
+ "name": "parent_workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_block_id": {
+ "name": "parent_block_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "child_workflow_id": {
+ "name": "child_workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "child_block_id": {
+ "name": "child_block_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_fork_block_map_child_ws_parent_unique": {
+ "name": "workspace_fork_block_map_child_ws_parent_unique",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_fork_block_map_child_ws_child_unique": {
+ "name": "workspace_fork_block_map_child_ws_child_unique",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "child_block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_fork_block_map_child_ws_parent_wf_idx": {
+ "name": "workspace_fork_block_map_child_ws_parent_wf_idx",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_fork_block_map_child_ws_child_wf_idx": {
+ "name": "workspace_fork_block_map_child_ws_child_wf_idx",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "child_workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_fork_block_map_child_workspace_id_workspace_id_fk": {
+ "name": "workspace_fork_block_map_child_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_fork_block_map",
+ "tableTo": "workspace",
+ "columnsFrom": ["child_workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_fork_dependent_value": {
+ "name": "workspace_fork_dependent_value",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "child_workspace_id": {
+ "name": "child_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_workflow_id": {
+ "name": "target_workflow_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_block_id": {
+ "name": "target_block_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sub_block_key": {
+ "name": "sub_block_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_fork_dependent_value_child_ws_wf_idx": {
+ "name": "workspace_fork_dependent_value_child_ws_wf_idx",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_fork_dependent_value_field_unique": {
+ "name": "workspace_fork_dependent_value_field_unique",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_workflow_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_block_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sub_block_key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_fork_dependent_value_child_workspace_id_workspace_id_fk": {
+ "name": "workspace_fork_dependent_value_child_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_fork_dependent_value",
+ "tableTo": "workspace",
+ "columnsFrom": ["child_workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_fork_promote_run": {
+ "name": "workspace_fork_promote_run",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "child_workspace_id": {
+ "name": "child_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_workspace_id": {
+ "name": "source_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_workspace_id": {
+ "name": "target_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "direction": {
+ "name": "direction",
+ "type": "workspace_fork_promote_direction",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snapshot": {
+ "name": "snapshot",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_fork_promote_run_child_ws_target_unique": {
+ "name": "workspace_fork_promote_run_child_ws_target_unique",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_fork_promote_run_target_ws_idx": {
+ "name": "workspace_fork_promote_run_target_ws_idx",
+ "columns": [
+ {
+ "expression": "target_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_fork_promote_run_child_workspace_id_workspace_id_fk": {
+ "name": "workspace_fork_promote_run_child_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_fork_promote_run",
+ "tableTo": "workspace",
+ "columnsFrom": ["child_workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_fork_promote_run_created_by_user_id_fk": {
+ "name": "workspace_fork_promote_run_created_by_user_id_fk",
+ "tableFrom": "workspace_fork_promote_run",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_fork_resource_map": {
+ "name": "workspace_fork_resource_map",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "child_workspace_id": {
+ "name": "child_workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "resource_type": {
+ "name": "resource_type",
+ "type": "workspace_fork_resource_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parent_resource_id": {
+ "name": "parent_resource_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "child_resource_id": {
+ "name": "child_resource_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_fork_resource_map_child_ws_idx": {
+ "name": "workspace_fork_resource_map_child_ws_idx",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_fork_resource_map_child_ws_type_idx": {
+ "name": "workspace_fork_resource_map_child_ws_type_idx",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_fork_resource_map_child_type_parent_unique": {
+ "name": "workspace_fork_resource_map_child_type_parent_unique",
+ "columns": [
+ {
+ "expression": "child_workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "resource_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "parent_resource_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_fork_resource_map_child_workspace_id_workspace_id_fk": {
+ "name": "workspace_fork_resource_map_child_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_fork_resource_map",
+ "tableTo": "workspace",
+ "columnsFrom": ["child_workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_fork_resource_map_created_by_user_id_fk": {
+ "name": "workspace_fork_resource_map_created_by_user_id_fk",
+ "tableFrom": "workspace_fork_resource_map",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_operation_receipt": {
+ "name": "workspace_operation_receipt",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "request_hash": {
+ "name": "request_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "kind": {
+ "name": "kind",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "report": {
+ "name": "report",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_operation_receipt_request_unique": {
+ "name": "workspace_operation_receipt_request_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "request_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_operation_receipt_workspace_created_idx": {
+ "name": "workspace_operation_receipt_workspace_created_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_operation_receipt_workspace_id_workspace_id_fk": {
+ "name": "workspace_operation_receipt_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_operation_receipt",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.workspace_sandbox": {
+ "name": "workspace_sandbox",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "language": {
+ "name": "language",
+ "type": "sandbox_language",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dependencies": {
+ "name": "dependencies",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "cli_tools": {
+ "name": "cli_tools",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "system_packages": {
+ "name": "system_packages",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'[]'::jsonb"
+ },
+ "spec_hash": {
+ "name": "spec_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "workspace_sandbox_workspace_name_unique": {
+ "name": "workspace_sandbox_workspace_name_unique",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_sandbox_workspace_idx": {
+ "name": "workspace_sandbox_workspace_idx",
+ "columns": [
+ {
+ "expression": "workspace_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "workspace_sandbox_spec_hash_idx": {
+ "name": "workspace_sandbox_spec_hash_idx",
+ "columns": [
+ {
+ "expression": "spec_hash",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "workspace_sandbox_workspace_id_workspace_id_fk": {
+ "name": "workspace_sandbox_workspace_id_workspace_id_fk",
+ "tableFrom": "workspace_sandbox",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "workspace_sandbox_created_by_user_id_fk": {
+ "name": "workspace_sandbox_created_by_user_id_fk",
+ "tableFrom": "workspace_sandbox",
+ "tableTo": "user",
+ "columnsFrom": ["created_by"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {
+ "public.academy_cert_status": {
+ "name": "academy_cert_status",
+ "schema": "public",
+ "values": ["active", "revoked", "expired"]
+ },
+ "public.background_work_kind": {
+ "name": "background_work_kind",
+ "schema": "public",
+ "values": ["deployment_side_effects", "fork_content_copy", "fork_sync", "fork_rollback"]
+ },
+ "public.background_work_status_value": {
+ "name": "background_work_status_value",
+ "schema": "public",
+ "values": ["pending", "processing", "completed", "completed_with_warnings", "failed"]
+ },
+ "public.billing_blocked_reason": {
+ "name": "billing_blocked_reason",
+ "schema": "public",
+ "values": ["payment_failed", "dispute"]
+ },
+ "public.billing_entity_type": {
+ "name": "billing_entity_type",
+ "schema": "public",
+ "values": ["user", "organization"]
+ },
+ "public.chat_type": {
+ "name": "chat_type",
+ "schema": "public",
+ "values": ["mothership", "copilot"]
+ },
+ "public.copilot_async_tool_status": {
+ "name": "copilot_async_tool_status",
+ "schema": "public",
+ "values": ["pending", "running", "completed", "failed", "cancelled", "delivered"]
+ },
+ "public.copilot_run_status": {
+ "name": "copilot_run_status",
+ "schema": "public",
+ "values": ["active", "paused_waiting_for_tool", "resuming", "complete", "error", "cancelled"]
+ },
+ "public.copilot_tool_permission_decision": {
+ "name": "copilot_tool_permission_decision",
+ "schema": "public",
+ "values": ["allow", "allow_chat", "always_allow", "skip"]
+ },
+ "public.credential_group_enrollment_status": {
+ "name": "credential_group_enrollment_status",
+ "schema": "public",
+ "values": ["invited", "delivery_failed", "in_progress", "completed", "revoked"]
+ },
+ "public.credential_group_status": {
+ "name": "credential_group_status",
+ "schema": "public",
+ "values": ["active", "disabled"]
+ },
+ "public.credential_member_role": {
+ "name": "credential_member_role",
+ "schema": "public",
+ "values": ["admin", "member"]
+ },
+ "public.credential_member_status": {
+ "name": "credential_member_status",
+ "schema": "public",
+ "values": ["active", "pending", "revoked"]
+ },
+ "public.credential_type": {
+ "name": "credential_type",
+ "schema": "public",
+ "values": [
+ "oauth",
+ "managed_oauth",
+ "managed_mcp",
+ "env_workspace",
+ "env_personal",
+ "service_account",
+ "personal_token"
+ ]
+ },
+ "public.data_drain_cadence": {
+ "name": "data_drain_cadence",
+ "schema": "public",
+ "values": ["hourly", "daily"]
+ },
+ "public.data_drain_destination": {
+ "name": "data_drain_destination",
+ "schema": "public",
+ "values": ["s3", "gcs", "azure_blob", "datadog", "bigquery", "snowflake", "webhook"]
+ },
+ "public.data_drain_run_status": {
+ "name": "data_drain_run_status",
+ "schema": "public",
+ "values": ["running", "success", "failed"]
+ },
+ "public.data_drain_run_trigger": {
+ "name": "data_drain_run_trigger",
+ "schema": "public",
+ "values": ["cron", "manual"]
+ },
+ "public.data_drain_source": {
+ "name": "data_drain_source",
+ "schema": "public",
+ "values": ["workflow_logs", "job_logs", "audit_logs", "copilot_chats", "copilot_runs"]
+ },
+ "public.execution_large_value_reference_source": {
+ "name": "execution_large_value_reference_source",
+ "schema": "public",
+ "values": ["execution_log", "paused_snapshot"]
+ },
+ "public.folder_resource_type": {
+ "name": "folder_resource_type",
+ "schema": "public",
+ "values": ["workflow", "file", "knowledge_base", "table"]
+ },
+ "public.invitation_kind": {
+ "name": "invitation_kind",
+ "schema": "public",
+ "values": ["organization", "workspace"]
+ },
+ "public.invitation_membership_intent": {
+ "name": "invitation_membership_intent",
+ "schema": "public",
+ "values": ["internal", "external"]
+ },
+ "public.invitation_status": {
+ "name": "invitation_status",
+ "schema": "public",
+ "values": ["pending", "accepted", "rejected", "cancelled", "expired"]
+ },
+ "public.managed_oauth_credential_status": {
+ "name": "managed_oauth_credential_status",
+ "schema": "public",
+ "values": ["active", "needs_reauth", "revoked"]
+ },
+ "public.permission_type": {
+ "name": "permission_type",
+ "schema": "public",
+ "values": ["admin", "write", "read"]
+ },
+ "public.sandbox_image_status": {
+ "name": "sandbox_image_status",
+ "schema": "public",
+ "values": ["pending", "building", "ready", "failed"]
+ },
+ "public.sandbox_language": {
+ "name": "sandbox_language",
+ "schema": "public",
+ "values": ["javascript", "python"]
+ },
+ "public.secret_usage_scope": {
+ "name": "secret_usage_scope",
+ "schema": "public",
+ "values": ["workspace", "personal"]
+ },
+ "public.secret_usage_source": {
+ "name": "secret_usage_source",
+ "schema": "public",
+ "values": ["workflow", "copilot", "mcp"]
+ },
+ "public.upload_session_method": {
+ "name": "upload_session_method",
+ "schema": "public",
+ "values": ["put", "multipart"]
+ },
+ "public.upload_session_provider": {
+ "name": "upload_session_provider",
+ "schema": "public",
+ "values": ["local", "s3", "blob", "gcs"]
+ },
+ "public.upload_session_purpose": {
+ "name": "upload_session_purpose",
+ "schema": "public",
+ "values": [
+ "workspace_file",
+ "table_import",
+ "knowledge_document",
+ "profile_picture",
+ "workspace_logo",
+ "organization_logo",
+ "mothership_attachment",
+ "execution_attachment"
+ ]
+ },
+ "public.upload_session_status": {
+ "name": "upload_session_status",
+ "schema": "public",
+ "values": [
+ "uploading",
+ "completing",
+ "finalizing",
+ "completed",
+ "aborting",
+ "aborted",
+ "failed",
+ "expired"
+ ]
+ },
+ "public.usage_log_category": {
+ "name": "usage_log_category",
+ "schema": "public",
+ "values": ["model", "fixed", "tool", "model_unbilled"]
+ },
+ "public.usage_log_source": {
+ "name": "usage_log_source",
+ "schema": "public",
+ "values": [
+ "workflow",
+ "wand",
+ "copilot",
+ "workspace-chat",
+ "mcp_copilot",
+ "mothership_block",
+ "knowledge-base",
+ "voice-input",
+ "enrichment",
+ "voice-output",
+ "api-tool"
+ ]
+ },
+ "public.workspace_file_search_index_status": {
+ "name": "workspace_file_search_index_status",
+ "schema": "public",
+ "values": ["pending", "ready", "skipped", "failed"]
+ },
+ "public.workspace_fork_promote_direction": {
+ "name": "workspace_fork_promote_direction",
+ "schema": "public",
+ "values": ["push", "pull"]
+ },
+ "public.workspace_fork_resource_type": {
+ "name": "workspace_fork_resource_type",
+ "schema": "public",
+ "values": [
+ "workflow",
+ "oauth_credential",
+ "service_account_credential",
+ "env_var",
+ "table",
+ "knowledge_base",
+ "knowledge_document",
+ "file",
+ "file_folder",
+ "mcp_server",
+ "workflow_mcp_server",
+ "custom_block",
+ "custom_tool",
+ "skill",
+ "sandbox"
+ ]
+ },
+ "public.workspace_mode": {
+ "name": "workspace_mode",
+ "schema": "public",
+ "values": ["personal", "organization", "grandfathered_shared"]
+ }
+ },
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json
index 90f19ecc792..46100733dd1 100644
--- a/packages/db/migrations/meta/_journal.json
+++ b/packages/db/migrations/meta/_journal.json
@@ -2437,6 +2437,13 @@
"when": 1789514921671,
"tag": "0348_drop_retired_usage_columns",
"breakpoints": true
+ },
+ {
+ "idx": 349,
+ "version": "7",
+ "when": 1789518532535,
+ "tag": "0349_permission_access_requests",
+ "breakpoints": true
}
]
}
diff --git a/packages/db/permission-access-requests-migration.postgres.test.ts b/packages/db/permission-access-requests-migration.postgres.test.ts
new file mode 100644
index 00000000000..d171919d82f
--- /dev/null
+++ b/packages/db/permission-access-requests-migration.postgres.test.ts
@@ -0,0 +1,115 @@
+/**
+ * @vitest-environment node
+ */
+import { readFile } from 'node:fs/promises'
+import { generateId } from '@sim/utils/id'
+import postgres from 'postgres'
+import { describe, expect, it } from 'vitest'
+
+const databaseUrl = process.env.ACCESS_REQUESTS_TEST_DATABASE_URL
+
+async function createFixture() {
+ const url = new URL(databaseUrl ?? '')
+ if (
+ !['localhost', '127.0.0.1'].includes(url.hostname) ||
+ url.pathname !== '/sim_access_requests_test'
+ ) {
+ throw new Error('Use a disposable local sim_access_requests_test database')
+ }
+ const schema = `access_requests_${generateId().replaceAll('-', '')}`
+ const client = postgres(url.toString(), { max: 2, onnotice: () => undefined })
+ const sql = await client.reserve()
+ const migration = await readFile(
+ new URL('./migrations/0349_permission_access_requests.sql', import.meta.url),
+ 'utf8'
+ )
+ await sql.unsafe(`CREATE SCHEMA "${schema}"`)
+ await sql.unsafe(`SET search_path TO "${schema}"`)
+ await sql.unsafe(`
+ CREATE TABLE organization (id text PRIMARY KEY);
+ CREATE TABLE "user" (id text PRIMARY KEY);
+ CREATE TABLE workspace (id text PRIMARY KEY);
+ INSERT INTO organization VALUES ('org');
+ INSERT INTO "user" VALUES ('requester'), ('admin');
+ INSERT INTO workspace VALUES ('workspace');
+ `)
+ for (const statement of migration
+ .replaceAll('"public".', `"${schema}".`)
+ .split('--> statement-breakpoint')) {
+ if (statement.trim()) await sql.unsafe(statement)
+ }
+ return {
+ sql,
+ client,
+ schema,
+ async cleanup() {
+ try {
+ await sql.unsafe('ROLLBACK')
+ await sql.unsafe(`DROP SCHEMA "${schema}" CASCADE`)
+ } finally {
+ sql.release()
+ await client.end()
+ }
+ },
+ }
+}
+
+const insertRequest = `INSERT INTO permission_access_request
+ (id, organization_id, requester_id, workspace_id, scope_key, target_key, target, target_label, membership_id)
+ VALUES ($1, 'org', 'requester', 'workspace', 'workspace:workspace', 'feature:hideTablesTab',
+ '{"kind":"feature","configKey":"hideTablesTab"}', 'Tables', '["member",null]')`
+
+describe.skipIf(!databaseUrl)('permission access request migration on PostgreSQL', () => {
+ it('preserves history, enforces lifecycle states, and allows a fresh request after a decision', async () => {
+ const fixture = await createFixture()
+ try {
+ const { sql } = fixture
+ const [settings] =
+ await sql`INSERT INTO organization_access_request_settings (organization_id) VALUES ('org') RETURNING allow_requests`
+ expect(settings.allow_requests).toBe(true)
+ await sql.unsafe(insertRequest, ['first'])
+ await expect(sql.unsafe(insertRequest, ['duplicate'])).rejects.toMatchObject({
+ code: '23505',
+ })
+ await expect(
+ sql`UPDATE permission_access_request SET status='unknown' WHERE id='first'`
+ ).rejects.toMatchObject({ code: '23514' })
+ await sql`UPDATE permission_access_request SET status='fulfilled', decided_by='admin', decided_at=now() WHERE id='first'`
+ await sql.unsafe(insertRequest, ['second'])
+ await sql`DELETE FROM "user" WHERE id='admin'`
+ const [history] =
+ await sql`SELECT status, decided_by FROM permission_access_request WHERE id='first'`
+ expect(history).toMatchObject({ status: 'fulfilled', decided_by: null })
+ await sql`DELETE FROM workspace WHERE id='workspace'`
+ expect(
+ await sql`SELECT status, workspace_id FROM permission_access_request ORDER BY id`
+ ).toEqual([
+ { status: 'fulfilled', workspace_id: 'workspace' },
+ { status: 'pending', workspace_id: 'workspace' },
+ ])
+ expect(await sql`SELECT id FROM permission_access_request`).toHaveLength(2)
+ } finally {
+ await fixture.cleanup()
+ }
+ })
+
+ it('permits only one pending request when independent transactions submit concurrently', async () => {
+ const fixture = await createFixture()
+ try {
+ await fixture.sql.unsafe('BEGIN')
+ await fixture.sql.unsafe(insertRequest, ['first'])
+ const competing = fixture.client.begin(async (transaction) => {
+ await transaction.unsafe(`SET LOCAL search_path TO "${fixture.schema}"`)
+ await transaction.unsafe(insertRequest, ['second'])
+ })
+ const rejected = expect(competing).rejects.toMatchObject({ code: '23505' })
+ await fixture.sql.unsafe('COMMIT')
+ await rejected
+ expect(
+ await fixture.sql`SELECT id FROM permission_access_request WHERE status='pending'`
+ ).toHaveLength(1)
+ } finally {
+ await fixture.cleanup()
+ }
+ })
+})
diff --git a/packages/db/schema.ts b/packages/db/schema.ts
index 2a1922ef0e5..d9d9292dbd0 100644
--- a/packages/db/schema.ts
+++ b/packages/db/schema.ts
@@ -1693,6 +1693,70 @@ export const organizationMemberUsageLimit = pgTable(
})
)
+/** Organization opt-out; an absent row keeps access requests enabled. */
+export const organizationAccessRequestSettings = pgTable('organization_access_request_settings', {
+ organizationId: text('organization_id')
+ .primaryKey()
+ .references(() => organization.id, { onDelete: 'cascade' }),
+ allowRequests: boolean('allow_requests').default(true).notNull(),
+ updatedAt: timestamp('updated_at').defaultNow().notNull(),
+ updatedBy: text('updated_by').references(() => user.id, { onDelete: 'set null' }),
+})
+
+/** Durable review history, scoped to the organization that owned the request at creation. */
+export const permissionAccessRequest = pgTable(
+ 'permission_access_request',
+ {
+ id: text('id').primaryKey(),
+ organizationId: text('organization_id')
+ .notNull()
+ .references(() => organization.id, { onDelete: 'cascade' }),
+ requesterId: text('requester_id')
+ .notNull()
+ .references(() => user.id, { onDelete: 'cascade' }),
+ workspaceId: text('workspace_id'),
+ scopeKey: text('scope_key').notNull(),
+ targetKey: text('target_key').notNull(),
+ target: jsonb('target').notNull(),
+ targetLabel: text('target_label').notNull(),
+ membershipId: text('membership_id').notNull(),
+ groupId: text('group_id'),
+ groupName: text('group_name'),
+ reason: text('reason').default('').notNull(),
+ status: text('status', { enum: ['pending', 'fulfilled', 'declined', 'cancelled', 'closed'] })
+ .default('pending')
+ .notNull(),
+ decisionReason: text('decision_reason'),
+ decidedBy: text('decided_by').references(() => user.id, { onDelete: 'set null' }),
+ decision: jsonb('decision'),
+ createdAt: timestamp('created_at').defaultNow().notNull(),
+ updatedAt: timestamp('updated_at').defaultNow().notNull(),
+ decidedAt: timestamp('decided_at'),
+ },
+ (table) => ({
+ pendingUnique: uniqueIndex('permission_access_request_pending_unique')
+ .on(table.organizationId, table.requesterId, table.scopeKey, table.targetKey)
+ .where(sql`${table.status} = 'pending'`),
+ organizationQueue: index('permission_access_request_org_queue_idx').on(
+ table.organizationId,
+ table.status,
+ table.createdAt,
+ table.id
+ ),
+ requesterHistory: index('permission_access_request_requester_idx').on(
+ table.organizationId,
+ table.requesterId,
+ table.scopeKey,
+ table.createdAt,
+ table.id
+ ),
+ statusCheck: check(
+ 'permission_access_request_status_check',
+ sql`${table.status} in ('pending', 'fulfilled', 'declined', 'cancelled', 'closed')`
+ ),
+ })
+)
+
export const invitationKindEnum = pgEnum('invitation_kind', ['organization', 'workspace'])
export type InvitationKind = (typeof invitationKindEnum.enumValues)[number]
diff --git a/packages/testing/src/mocks/audit.mock.ts b/packages/testing/src/mocks/audit.mock.ts
index 11bb2266864..0279abe0a40 100644
--- a/packages/testing/src/mocks/audit.mock.ts
+++ b/packages/testing/src/mocks/audit.mock.ts
@@ -141,6 +141,12 @@ export const auditMock = {
PERMISSION_GROUP_DELETED: 'permission_group.deleted',
PERMISSION_GROUP_MEMBER_ADDED: 'permission_group_member.added',
PERMISSION_GROUP_MEMBER_REMOVED: 'permission_group_member.removed',
+ PERMISSION_ACCESS_REQUEST_CREATED: 'permission_access_request.created',
+ PERMISSION_ACCESS_REQUEST_FULFILLED: 'permission_access_request.fulfilled',
+ PERMISSION_ACCESS_REQUEST_DECLINED: 'permission_access_request.declined',
+ PERMISSION_ACCESS_REQUEST_CANCELLED: 'permission_access_request.cancelled',
+ PERMISSION_ACCESS_REQUEST_CLOSED: 'permission_access_request.closed',
+ PERMISSION_ACCESS_REQUEST_SETTINGS_CHANGED: 'permission_access_request.settings_changed',
SCHEDULE_CREATED: 'schedule.created',
SCHEDULE_UPDATED: 'schedule.updated',
SCHEDULE_DELETED: 'schedule.deleted',
@@ -239,6 +245,7 @@ export const auditMock = {
ORGANIZATION: 'organization',
PASSWORD: 'password',
PERMISSION_GROUP: 'permission_group',
+ PERMISSION_ACCESS_REQUEST: 'permission_access_request',
SANDBOX: 'sandbox',
SCHEDULE: 'schedule',
SCIM_CONNECTION: 'scim_connection',
diff --git a/packages/testing/src/mocks/schema.mock.ts b/packages/testing/src/mocks/schema.mock.ts
index f8da60c8e58..cdd6f68e5ea 100644
--- a/packages/testing/src/mocks/schema.mock.ts
+++ b/packages/testing/src/mocks/schema.mock.ts
@@ -118,6 +118,43 @@ const workspaceFileSearchSegmentMock = {
}
export const schemaMock = {
+ permissionAccessRequest: {
+ id: 'permissionAccessRequest.id',
+ organizationId: 'permissionAccessRequest.organizationId',
+ requesterId: 'permissionAccessRequest.requesterId',
+ workspaceId: 'permissionAccessRequest.workspaceId',
+ scopeKey: 'permissionAccessRequest.scopeKey',
+ targetKey: 'permissionAccessRequest.targetKey',
+ target: 'permissionAccessRequest.target',
+ targetLabel: 'permissionAccessRequest.targetLabel',
+ membershipId: 'permissionAccessRequest.membershipId',
+ groupId: 'permissionAccessRequest.groupId',
+ groupName: 'permissionAccessRequest.groupName',
+ reason: 'permissionAccessRequest.reason',
+ status: 'permissionAccessRequest.status',
+ decisionReason: 'permissionAccessRequest.decisionReason',
+ decidedBy: 'permissionAccessRequest.decidedBy',
+ decision: 'permissionAccessRequest.decision',
+ createdAt: 'permissionAccessRequest.createdAt',
+ updatedAt: 'permissionAccessRequest.updatedAt',
+ decidedAt: 'permissionAccessRequest.decidedAt',
+ },
+ organizationMemberUsageLimit: {
+ id: 'organizationMemberUsageLimit.id',
+ organizationId: 'organizationMemberUsageLimit.organizationId',
+ userId: 'organizationMemberUsageLimit.userId',
+ usageLimit: 'organizationMemberUsageLimit.usageLimit',
+ setBy: 'organizationMemberUsageLimit.setBy',
+ createdAt: 'organizationMemberUsageLimit.createdAt',
+ updatedAt: 'organizationMemberUsageLimit.updatedAt',
+ },
+ organizationAccessRequestSettings: {
+ organizationId: 'organizationAccessRequestSettings.organizationId',
+ allowRequests: 'organizationAccessRequestSettings.allowRequests',
+ updatedAt: 'organizationAccessRequestSettings.updatedAt',
+ updatedBy: 'organizationAccessRequestSettings.updatedBy',
+ },
+
/**
* The schema's folded-address expression. Returns the column it wraps so a
* predicate built on it still names the column, and assertions on condition
diff --git a/scripts/check-tool-registry-boundary.baseline.json b/scripts/check-tool-registry-boundary.baseline.json
index 66d5fe7185f..93b812d2985 100644
--- a/scripts/check-tool-registry-boundary.baseline.json
+++ b/scripts/check-tool-registry-boundary.baseline.json
@@ -70,6 +70,18 @@
"apps/sim/lib/webhooks/providers/registry.ts": 116
}
},
+ "app/workspace/[workspaceId]/access-requests/loading.tsx": {
+ "modules": 2,
+ "gateways": {}
+ },
+ "app/workspace/[workspaceId]/access-requests/page.tsx": {
+ "modules": 113,
+ "gateways": {
+ "apps/sim/components/access-requests/my-access-requests.tsx": 111,
+ "apps/sim/hooks/queries/access-requests.ts": 95,
+ "apps/sim/ee/access-control/hooks/permission-groups.ts": 74
+ }
+ },
"app/workspace/[workspaceId]/chat/[chatId]/error.tsx": {
"modules": 157,
"gateways": {
@@ -112,16 +124,16 @@
}
},
"app/workspace/[workspaceId]/files/[fileId]/page.tsx": {
- "modules": 2074,
+ "modules": 2176,
"gateways": {
"apps/sim/triggers/registry.ts": 485,
- "apps/sim/app/workspace/[workspaceId]/files/files.tsx": 391,
- "apps/sim/blocks/registry.ts": 354,
- "apps/sim/lib/auth/index.ts": 281,
- "apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/index.ts": 212,
- "apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx": 179,
- "apps/sim/lib/webhooks/providers/index.ts": 118,
- "apps/sim/lib/webhooks/providers/registry.ts": 116
+ "apps/sim/app/workspace/[workspaceId]/files/files.tsx": 411,
+ "apps/sim/blocks/registry.ts": 355,
+ "apps/sim/lib/auth/index.ts": 274,
+ "apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/index.ts": 214,
+ "apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx": 183,
+ "apps/sim/lib/webhooks/providers/index.ts": 117,
+ "apps/sim/lib/webhooks/providers/registry.ts": 115
}
},
"app/workspace/[workspaceId]/files/[fileId]/view/page.tsx": {
@@ -148,16 +160,16 @@
}
},
"app/workspace/[workspaceId]/files/page.tsx": {
- "modules": 2073,
+ "modules": 2175,
"gateways": {
"apps/sim/triggers/registry.ts": 485,
- "apps/sim/app/workspace/[workspaceId]/files/files.tsx": 392,
- "apps/sim/blocks/registry.ts": 354,
- "apps/sim/lib/auth/index.ts": 281,
- "apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/index.ts": 212,
- "apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx": 179,
- "apps/sim/lib/webhooks/providers/index.ts": 118,
- "apps/sim/lib/webhooks/providers/registry.ts": 116
+ "apps/sim/app/workspace/[workspaceId]/files/files.tsx": 412,
+ "apps/sim/blocks/registry.ts": 355,
+ "apps/sim/lib/auth/index.ts": 274,
+ "apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/index.ts": 214,
+ "apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx": 183,
+ "apps/sim/lib/webhooks/providers/index.ts": 117,
+ "apps/sim/lib/webhooks/providers/registry.ts": 115
}
},
"app/workspace/[workspaceId]/home/error.tsx": {
@@ -199,16 +211,16 @@
}
},
"app/workspace/[workspaceId]/integrations/connected/[credentialId]/page.tsx": {
- "modules": 1185,
+ "modules": 1213,
"gateways": {
- "apps/sim/app/workspace/[workspaceId]/integrations/connected/[credentialId]/connected-credential-detail.tsx": 1184,
+ "apps/sim/app/workspace/[workspaceId]/integrations/connected/[credentialId]/connected-credential-detail.tsx": 1103,
"apps/sim/triggers/registry.ts": 522,
"apps/sim/blocks/registry.ts": 373,
- "apps/sim/app/workspace/[workspaceId]/components/credential-detail/index.ts": 98,
- "apps/sim/components/permissions/index.ts": 85,
- "apps/sim/components/permissions/add-people-modal.tsx": 76,
- "apps/sim/app/workspace/[workspaceId]/providers/workspace-permissions-provider.tsx": 74,
- "apps/sim/lib/api/contracts/index.ts": 41
+ "apps/sim/app/workspace/[workspaceId]/components/credential-detail/index.ts": 102,
+ "apps/sim/components/permissions/index.ts": 89,
+ "apps/sim/components/permissions/add-people-modal.tsx": 80,
+ "apps/sim/app/workspace/[workspaceId]/providers/workspace-permissions-provider.tsx": 78,
+ "apps/sim/lib/api/contracts/index.ts": 40
}
},
"app/workspace/[workspaceId]/integrations/error.tsx": {
@@ -298,29 +310,29 @@
}
},
"app/workspace/[workspaceId]/knowledge/page.tsx": {
- "modules": 2328,
+ "modules": 2376,
"gateways": {
"apps/sim/triggers/registry.ts": 485,
- "apps/sim/app/workspace/[workspaceId]/knowledge/prefetch.ts": 397,
- "apps/sim/blocks/registry.ts": 354,
- "apps/sim/lib/knowledge/application/knowledge-bases.ts": 338,
- "apps/sim/lib/auth/index.ts": 224,
- "apps/sim/lib/knowledge/orchestration/index.ts": 201,
- "apps/sim/lib/knowledge/orchestration/connectors.ts": 197,
- "apps/sim/app/workspace/[workspaceId]/knowledge/knowledge.tsx": 189
+ "apps/sim/app/workspace/[workspaceId]/knowledge/prefetch.ts": 408,
+ "apps/sim/blocks/registry.ts": 355,
+ "apps/sim/lib/knowledge/application/knowledge-bases.ts": 347,
+ "apps/sim/lib/auth/index.ts": 226,
+ "apps/sim/lib/knowledge/orchestration/index.ts": 211,
+ "apps/sim/lib/knowledge/orchestration/connectors.ts": 207,
+ "apps/sim/app/workspace/[workspaceId]/knowledge/knowledge.tsx": 203
}
},
"app/workspace/[workspaceId]/layout.tsx": {
- "modules": 2155,
+ "modules": 2205,
"gateways": {
"apps/sim/triggers/registry.ts": 485,
- "apps/sim/lib/auth/index.ts": 393,
- "apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx": 362,
+ "apps/sim/lib/auth/index.ts": 413,
+ "apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx": 384,
"apps/sim/blocks/registry.ts": 353,
- "apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/index.ts": 252,
- "apps/sim/lib/webhooks/providers/index.ts": 118,
- "apps/sim/lib/webhooks/providers/registry.ts": 116,
- "apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-sidebar/index.ts": 93
+ "apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/index.ts": 256,
+ "apps/sim/lib/webhooks/providers/index.ts": 117,
+ "apps/sim/lib/webhooks/providers/registry.ts": 115,
+ "apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-sidebar/index.ts": 92
}
},
"app/workspace/[workspaceId]/logs/error.tsx": {
@@ -591,16 +603,16 @@
}
},
"app/workspace/[workspaceId]/tables/page.tsx": {
- "modules": 1871,
+ "modules": 1971,
"gateways": {
"apps/sim/triggers/registry.ts": 485,
- "apps/sim/lib/auth/index.ts": 427,
- "apps/sim/blocks/registry.ts": 353,
- "apps/sim/app/workspace/[workspaceId]/tables/tables.tsx": 176,
- "apps/sim/lib/webhooks/providers/index.ts": 118,
- "apps/sim/lib/webhooks/providers/registry.ts": 116,
- "apps/sim/app/workspace/[workspaceId]/components/index.ts": 61,
- "apps/sim/lib/workflows/lifecycle.ts": 50
+ "apps/sim/lib/auth/index.ts": 416,
+ "apps/sim/blocks/registry.ts": 354,
+ "apps/sim/app/workspace/[workspaceId]/tables/tables.tsx": 192,
+ "apps/sim/lib/webhooks/providers/index.ts": 117,
+ "apps/sim/lib/webhooks/providers/registry.ts": 115,
+ "apps/sim/app/workspace/[workspaceId]/tables/prefetch.ts": 98,
+ "apps/sim/app/workspace/[workspaceId]/components/index.ts": 60
}
},
"app/workspace/[workspaceId]/upgrade/page.tsx": {
@@ -624,29 +636,29 @@
}
},
"app/workspace/[workspaceId]/w/[workflowId]/page.tsx": {
- "modules": 2111,
+ "modules": 2155,
"gateways": {
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx": 2110,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx": 2154,
"apps/sim/triggers/registry.ts": 522,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/index.ts": 361,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/index.ts": 371,
"apps/sim/blocks/registry.ts": 350,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/index.ts": 324,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/index.ts": 262,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/index.ts": 164,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx": 156
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/index.ts": 334,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/index.ts": 268,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/index.ts": 168,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx": 149
}
},
"app/workspace/[workspaceId]/w/page.tsx": {
- "modules": 2090,
+ "modules": 2136,
"gateways": {
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/index.ts": 912,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/index.ts": 594,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/index.ts": 950,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/index.ts": 624,
"apps/sim/triggers/registry.ts": 522,
"apps/sim/blocks/registry.ts": 350,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/index.ts": 342,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/index.ts": 171,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx": 163,
- "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/index.ts": 157
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/index.ts": 347,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/index.ts": 175,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/sub-block.tsx": 155,
+ "apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/index.ts": 150
}
},
"app/workspace/layout.tsx": {