import { sql, } from "drizzle-orm"; import { boolean, check, foreignKey, index, integer, jsonb, pgTable, text, timestamp, unique, uniqueIndex, uuid, } from "drizzle-orm/pg-core"; import type { ConnectionAgentInstructions, ConnectionTokenIssuanceOutcome, ConnectionTokenIssuancePath, McpConnectionCredentialRef, ToolActionRequestStatus, ToolApplicationStatus, ToolApplicationType, ToolAuditEventType, ToolAuditOutcome, ToolCatalogEntryKind, ToolCatalogEntryStatus, ToolConnectionHealthStatus, ToolConnectionAuthKind, ToolConnectionCredentialSource, ToolConnectionKind, ToolConnectionCredentialPolicy, ToolConnectionOwnership, ToolConnectionPurpose, ToolConnectionInstallTargetType, ToolConnectionStatus, ToolConnectionTransport, ConnectionGrantKind, ConnectionGrantMemberSubjectType, ConnectionGrantStatus, ToolCredentialSecretRef, ToolInvocationApprovalState, ToolInvocationStatus, ToolMcpGatewayAuthConfig, ToolMcpGatewayContextScopeType, ToolMcpGatewayDefaultProfileMode, ToolMcpGatewayHeaderPolicy, ToolMcpGatewayMetadataPolicy, ToolMcpGatewayOnDemandToolsConfig, ToolMcpGatewayStatus, ToolMcpGatewayTokenAction, ToolMcpGatewayTokenSubjectType, ToolPolicyDecision, ToolPolicyType, ToolProfileBindingTargetType, ToolProfileDefaultAction, ToolProfileEntryEffect, ToolProfileEntrySelectorType, ToolProfileStatus, ToolRateLimitWindowKind, ToolRedactedValueSummary, ToolRiskLevel, ToolRuntimeKind, ToolRuntimeSlotStatus, VercelConnectCredentialReference, VercelConnectGrantReference, } from "@paperclipai/shared"; import { agents } from "./agents.js"; import { approvals } from "./approvals.js"; import { companies } from "./companies.js"; import { executionWorkspaces } from "./execution_workspaces.js"; import { heartbeatRuns } from "./heartbeat_runs.js"; import { issueThreadInteractions } from "./issue_thread_interactions.js"; import { issues } from "./issues.js"; import { plugins } from "./plugins.js"; import { projects } from "./projects.js"; import { projectWorkspaces } from "./project_workspaces.js"; export const toolApplications = pgTable( "tool_applications", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), applicationKey: text("application_key"), name: text("name").notNull(), description: text("description"), type: text("type").$type().notNull(), status: text("status").$type().notNull().default("active"), pluginId: uuid("plugin_id").references(() => plugins.id, { onDelete: "set null" }), ownerAgentId: uuid("owner_agent_id").references(() => agents.id, { onDelete: "set null" }), ownerUserId: text("owner_user_id"), metadata: jsonb("metadata").$type>().notNull().default({}), archivedAt: timestamp("archived_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_applications_company_idx").on(table.companyId), index("tool_applications_company_status_idx").on(table.companyId, table.status), uniqueIndex("tool_applications_company_name_uq").on(table.companyId, table.name), uniqueIndex("tool_applications_company_key_uq").on(table.companyId, table.applicationKey), ], ); export const toolConnections = pgTable( "tool_connections", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), // NO ACTION (not CASCADE) so the database itself refuses to delete an application that still // has connections. This closes the delete-vs-create race in DELETE // /tool-applications/:applicationId: a connection inserted concurrently takes a FOR KEY SHARE // lock on the parent row, so the delete fails closed with a foreign-key violation instead of // silently cascading the new connection away. NO ACTION (checked at end-of-statement) rather // than RESTRICT (checked immediately) is deliberate: it lets a company delete still cascade — // companies → tool_applications and companies → tool_connections both fire in one statement, // and the connections are gone by the time this constraint is checked. applicationId: uuid("application_id").notNull().references(() => toolApplications.id, { onDelete: "no action" }), name: text("name").notNull(), uid: text("uid").notNull(), connectionKind: text("connection_kind").$type().notNull().default("managed"), connectionPurpose: text("connection_purpose").$type().notNull().default("tool"), ownership: text("ownership").$type().notNull().default("customer"), transport: text("transport").$type().notNull(), authKind: text("auth_kind").$type().notNull().default("none"), credentialSource: text("credential_source").$type().notNull().default("paperclip_vault"), externalCredential: jsonb("external_credential").$type(), credentialPolicy: text("credential_policy").$type().notNull().default("shared"), status: text("status").$type().notNull().default("draft"), enabled: boolean("enabled").notNull().default(false), agentInstructions: jsonb("agent_instructions").$type(), config: jsonb("config").$type>().notNull().default({}), transportConfig: jsonb("transport_config").$type>().notNull().default({}), credentialRefs: jsonb("credential_refs").$type().notNull().default([]), credentialSecretRefs: jsonb("credential_secret_refs").$type().notNull().default([]), healthStatus: text("health_status").$type().notNull().default("unchecked"), healthMessage: text("health_message"), healthCheckedAt: timestamp("health_checked_at", { withTimezone: true }), lastHealthAt: timestamp("last_health_at", { withTimezone: true }), lastCatalogRefreshAt: timestamp("last_catalog_refresh_at", { withTimezone: true }), lastError: text("last_error"), createdByAgentId: uuid("created_by_agent_id").references(() => agents.id, { onDelete: "set null" }), createdByUserId: text("created_by_user_id"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ check("tool_connections_ownership_check", sql`${table.ownership} in ('platform_shared', 'platform_provisioned', 'customer', 'dcr')`), check("tool_connections_transport_check", sql`${table.transport} in ('mcp_remote', 'rest_api', 'local_stdio', 'chat_sdk', 'runtime_auth')`), check("tool_connections_purpose_check", sql`${table.connectionPurpose} in ('tool', 'channel', 'ai')`), check("tool_connections_channel_transport_check", sql`( (${table.connectionPurpose} = 'tool' and ${table.transport} not in ('chat_sdk', 'runtime_auth')) or (${table.connectionPurpose} = 'channel' and (${table.transport} = 'chat_sdk' or (${table.transport} = 'rest_api' and ${table.config}->>'provider' = 'agentmail'))) or (${table.connectionPurpose} = 'ai' and ${table.transport} = 'runtime_auth') )`), check("tool_connections_auth_kind_check", sql`${table.authKind} in ('oauth', 'api_key', 'none')`), check("tool_connections_credential_source_check", sql`${table.credentialSource} in ('paperclip_vault', 'vercel_connect')`), check("tool_connections_credential_source_one_of_check", sql`( (${table.credentialSource} = 'paperclip_vault' and ${table.externalCredential} is null) or (${table.credentialSource} = 'vercel_connect' and ${table.externalCredential} is not null and jsonb_array_length(${table.credentialRefs}) = 0 and jsonb_array_length(${table.credentialSecretRefs}) = 0) )`), check("tool_connections_credential_policy_check", sql`${table.credentialPolicy} in ('shared', 'per_user', 'per_user_with_fallback', 'per_agent')`), index("tool_connections_company_idx").on(table.companyId), index("tool_connections_application_idx").on(table.applicationId), index("tool_connections_company_enabled_idx").on(table.companyId, table.enabled), uniqueIndex("tool_connections_company_uid_uq").on(table.companyId, table.uid), unique("tool_connections_company_id_uq").on(table.companyId, table.id), ], ); export const connectionGrants = pgTable( "connection_grants", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), connectionId: uuid("connection_id").notNull(), kind: text("kind").$type().notNull(), subjectUserId: text("subject_user_id"), subjectAgentId: uuid("subject_agent_id").references(() => agents.id, { onDelete: "cascade" }), providerTenant: jsonb("provider_tenant").$type<{ name?: string; externalId?: string; oauth?: { strategy?: string; accessTokenExpiresAt?: string | null; scopes?: string[]; /** * Whether `scopes` is what the provider asserted, or only what we requested. * A provider may omit `scope` from the token response, and RFC 6749 §5.1 reads that * omission as "the grant matches the request" — but a provider that over-grants and * omits it turns our own request into a false record of the grant. */ scopeSource?: "provider" | "requested_fallback"; /** Scopes the provider asserted that we never asked for. Empty unless it over-granted. */ unrequestedScopes?: string[]; /** * The scopes the authorization URL sent for *this* grant. A refresh carries no fresh * request, so this is the baseline it judges the provider's response against. It is * per-grant because two users can authorize the same connection with different scopes. */ requestedScopes?: string[]; tokenType?: string; refreshedAt?: string; refreshTokenExpiresAt?: string; refreshLease?: { id?: string; expiresAt?: string; }; }; slackSearch?: { endpointId: string; workspaceId: string; slackUserId: string; clientRevision: string }; github?: { userId: string; login: string; avatarUrl?: string; installationCount: number; repositoryCount: number; repositorySelection: "all" | "selected" | "mixed" | "none"; installationIds: string[]; installationOwnerLogins: string[]; /** Repository metadata visible to this credential; refreshed from GitHub. */ repositories?: Array<{ id: string; fullName: string; installationId: string; private?: boolean }>; installationUrl?: string; managementUrl?: string; appSlug?: string; accessRevision?: string; lastAccessRefreshAt?: string; lastWebhookAt?: string; webhookHealth?: "pending" | "healthy" | "unhealthy"; }; }>(), credentialSecretRefs: jsonb("credential_secret_refs").$type().notNull().default([]), externalCredential: jsonb("external_credential").$type(), status: text("status").$type().notNull().default("active"), isDefault: boolean("is_default").notNull().default(false), createdByAgentId: uuid("created_by_agent_id").references(() => agents.id, { onDelete: "set null" }), createdByUserId: text("created_by_user_id"), revokedAt: timestamp("revoked_at", { withTimezone: true }), revokedByAgentId: uuid("revoked_by_agent_id").references(() => agents.id, { onDelete: "set null" }), revokedByUserId: text("revoked_by_user_id"), lastUsedAt: timestamp("last_used_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ check("connection_grants_kind_check", sql`${table.kind} in ('organization', 'user', 'agent')`), check("connection_grants_status_check", sql`${table.status} in ('active', 'revoked', 'expired', 'needs_reauthorization')`), check("connection_grants_credential_source_one_of_check", sql`${table.externalCredential} is null or jsonb_array_length(${table.credentialSecretRefs}) = 0`), check("connection_grants_subject_check", sql`(${table.kind} = 'user' and ${table.subjectUserId} is not null and ${table.subjectAgentId} is null) or (${table.kind} = 'agent' and ${table.subjectAgentId} is not null and ${table.subjectUserId} is null) or (${table.kind} = 'organization' and ${table.subjectUserId} is null and ${table.subjectAgentId} is null)`), check("connection_grants_default_check", sql`${table.isDefault} = false or ${table.kind} = 'organization'`), foreignKey({ columns: [table.companyId, table.connectionId], foreignColumns: [toolConnections.companyId, toolConnections.id], name: "connection_grants_company_connection_fk", }).onDelete("cascade"), index("connection_grants_company_connection_idx").on(table.companyId, table.connectionId), index("connection_grants_subject_user_idx").on(table.companyId, table.subjectUserId), index("connection_grants_subject_agent_idx").on(table.companyId, table.subjectAgentId), unique("connection_grants_company_id_uq").on(table.companyId, table.id), uniqueIndex("connection_grants_user_uq").on(table.connectionId, table.subjectUserId), uniqueIndex("connection_grants_agent_uq").on(table.connectionId, table.subjectAgentId), uniqueIndex("connection_grants_default_uq").on(table.connectionId).where(sql`${table.isDefault} = true and ${table.kind} = 'organization'`), ], ); export const connectionGrantMembers = pgTable( "connection_grant_members", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), grantId: uuid("grant_id").notNull(), subjectType: text("subject_type").$type().notNull(), subjectId: text("subject_id").notNull(), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ check("connection_grant_members_subject_type_check", sql`${table.subjectType} in ('user')`), foreignKey({ columns: [table.companyId, table.grantId], foreignColumns: [connectionGrants.companyId, connectionGrants.id], name: "connection_grant_members_company_grant_fk", }).onDelete("cascade"), index("connection_grant_members_company_subject_idx").on(table.companyId, table.subjectType, table.subjectId), uniqueIndex("connection_grant_members_grant_subject_uq").on(table.grantId, table.subjectType, table.subjectId), ], ); export const connectionGrantDelegations = pgTable( "connection_grant_delegations", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), grantId: uuid("grant_id").notNull(), agentId: uuid("agent_id").notNull().references(() => agents.id, { onDelete: "cascade" }), createdByUserId: text("created_by_user_id").notNull(), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ foreignKey({ columns: [table.companyId, table.grantId], foreignColumns: [connectionGrants.companyId, connectionGrants.id], name: "connection_grant_delegations_company_grant_fk", }).onDelete("cascade"), index("connection_grant_delegations_company_agent_idx").on(table.companyId, table.agentId), uniqueIndex("connection_grant_delegations_grant_agent_uq").on(table.grantId, table.agentId), ], ); export const toolConnectionInstalls = pgTable( "tool_connection_installs", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), connectionId: uuid("connection_id").notNull().references(() => toolConnections.id, { onDelete: "cascade" }), targetType: text("target_type").$type().notNull(), targetId: text("target_id").notNull(), createdByAgentId: uuid("created_by_agent_id").references(() => agents.id, { onDelete: "set null" }), createdByUserId: text("created_by_user_id"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ check("tool_connection_installs_target_type_check", sql`${table.targetType} in ('company', 'agent')`), index("tool_connection_installs_company_target_idx").on(table.companyId, table.targetType, table.targetId), index("tool_connection_installs_connection_idx").on(table.companyId, table.connectionId), uniqueIndex("tool_connection_installs_target_uq").on( table.companyId, table.connectionId, table.targetType, table.targetId, ), ], ); export const toolOauthStates = pgTable( "tool_oauth_states", { state: text("state").primaryKey(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), connectionId: uuid("connection_id").notNull().references(() => toolConnections.id, { onDelete: "cascade" }), codeVerifier: text("code_verifier").notNull(), createdByActorType: text("created_by_actor_type"), createdByActorId: text("created_by_actor_id"), createdBySessionId: text("created_by_session_id"), subjectUserId: text("subject_user_id"), subjectAgentId: uuid("subject_agent_id").references(() => agents.id, { onDelete: "cascade" }), requestedScopes: jsonb("requested_scopes").$type(), returnTo: text("return_to"), issueId: uuid("issue_id"), interactionId: uuid("interaction_id"), expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_oauth_states_company_idx").on(table.companyId), index("tool_oauth_states_connection_idx").on(table.connectionId), index("tool_oauth_states_actor_idx").on(table.createdByActorType, table.createdByActorId), index("tool_oauth_states_subject_agent_idx").on(table.companyId, table.subjectAgentId), index("tool_oauth_states_expires_at_idx").on(table.expiresAt), ], ); export const toolCatalogEntries = pgTable( "tool_catalog_entries", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), applicationId: uuid("application_id").references(() => toolApplications.id, { onDelete: "cascade" }), connectionId: uuid("connection_id").notNull().references(() => toolConnections.id, { onDelete: "cascade" }), entryKind: text("entry_kind").$type().notNull().default("tool"), name: text("name").notNull(), toolName: text("tool_name").notNull(), title: text("title"), description: text("description"), inputSchema: jsonb("input_schema").$type>().notNull().default({}), outputSchema: jsonb("output_schema").$type>(), annotations: jsonb("annotations").$type>().notNull().default({}), riskLevel: text("risk_level").$type().notNull().default("read"), isReadOnly: boolean("is_read_only").notNull().default(true), isWrite: boolean("is_write").notNull().default(false), isDestructive: boolean("is_destructive").notNull().default(false), status: text("status").$type().notNull().default("active"), version: text("version"), versionHash: text("version_hash").notNull(), schemaHash: text("schema_hash"), firstSeenAt: timestamp("first_seen_at", { withTimezone: true }).notNull().defaultNow(), lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).notNull().defaultNow(), reviewedAt: timestamp("reviewed_at", { withTimezone: true }), reviewedByAgentId: uuid("reviewed_by_agent_id").references(() => agents.id, { onDelete: "set null" }), reviewedByUserId: text("reviewed_by_user_id"), quarantinedAt: timestamp("quarantined_at", { withTimezone: true }), quarantineReason: text("quarantine_reason"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_catalog_entries_company_idx").on(table.companyId), index("tool_catalog_entries_application_idx").on(table.applicationId), index("tool_catalog_entries_connection_idx").on(table.connectionId), index("tool_catalog_entries_company_status_idx").on(table.companyId, table.status), uniqueIndex("tool_catalog_entries_connection_name_uq").on(table.connectionId, table.name), ], ); export const toolProfiles = pgTable( "tool_profiles", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), profileKey: text("profile_key").notNull(), name: text("name").notNull(), description: text("description"), status: text("status").$type().notNull().default("active"), defaultAction: text("default_action").$type().notNull().default("deny"), newToolsReviewedAt: timestamp("new_tools_reviewed_at", { withTimezone: true }), metadata: jsonb("metadata").$type>().notNull().default({}), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_profiles_company_status_idx").on(table.companyId, table.status), uniqueIndex("tool_profiles_company_key_uq").on(table.companyId, table.profileKey), uniqueIndex("tool_profiles_company_name_uq").on(table.companyId, table.name), ], ); export const toolProfileEntries = pgTable( "tool_profile_entries", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), profileId: uuid("profile_id").notNull().references(() => toolProfiles.id, { onDelete: "cascade" }), selectorType: text("selector_type").$type().notNull(), effect: text("effect").$type().notNull().default("include"), applicationId: uuid("application_id").references(() => toolApplications.id, { onDelete: "cascade" }), connectionId: uuid("connection_id").references(() => toolConnections.id, { onDelete: "cascade" }), catalogEntryId: uuid("catalog_entry_id").references(() => toolCatalogEntries.id, { onDelete: "cascade" }), toolName: text("tool_name"), riskLevel: text("risk_level").$type(), conditions: jsonb("conditions").$type>(), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_profile_entries_company_profile_idx").on(table.companyId, table.profileId), index("tool_profile_entries_application_idx").on(table.companyId, table.applicationId), index("tool_profile_entries_connection_idx").on(table.companyId, table.connectionId), index("tool_profile_entries_catalog_entry_idx").on(table.companyId, table.catalogEntryId), ], ); export const toolProfileBindings = pgTable( "tool_profile_bindings", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), profileId: uuid("profile_id").notNull().references(() => toolProfiles.id, { onDelete: "cascade" }), targetType: text("target_type").$type().notNull(), targetId: text("target_id").notNull(), priority: integer("priority").notNull().default(100), metadata: jsonb("metadata").$type>().notNull().default({}), createdByAgentId: uuid("created_by_agent_id").references(() => agents.id, { onDelete: "set null" }), createdByUserId: text("created_by_user_id"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_profile_bindings_company_target_idx").on(table.companyId, table.targetType, table.targetId), uniqueIndex("tool_profile_bindings_target_profile_uq").on( table.companyId, table.targetType, table.targetId, table.profileId, ), ], ); export const toolMcpGateways = pgTable( "tool_mcp_gateways", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), gatewayPublicId: text("gateway_public_id").notNull().default(sql`'gw_' || replace(gen_random_uuid()::text, '-', '')`), name: text("name").notNull(), slug: text("slug").notNull(), displaySlug: text("display_slug").notNull().default(""), description: text("description"), status: text("status").$type().notNull().default("active"), profileId: uuid("profile_id").notNull().references(() => toolProfiles.id, { onDelete: "restrict" }), defaultProfileMode: text("default_profile_mode").$type().notNull().default("gateway_only"), contextScopeType: text("context_scope_type").$type().notNull().default("none"), contextScopeId: text("context_scope_id"), agentId: uuid("agent_id").references(() => agents.id, { onDelete: "set null" }), projectId: uuid("project_id").references(() => projects.id, { onDelete: "set null" }), issueId: uuid("issue_id").references(() => issues.id, { onDelete: "set null" }), approvalIssueId: uuid("approval_issue_id").references(() => issues.id, { onDelete: "set null" }), authConfig: jsonb("auth_config").$type().notNull().default({ version: 1, bearer: { enabled: true, tokenPrefix: "pcgw", defaultTtlSeconds: 7_776_000, requireFiniteExpiry: true, longLivedTokenRequiresOverride: true, }, oauth: { enabled: false, reservedFor: "v1_5", dynamicClientRegistration: false, authorizationCodePkce: false, }, }), headerPolicy: jsonb("header_policy").$type().notNull().default({ version: 1, callerPassthrough: { enabled: false, allowedHeaders: [] }, staticHeaders: [], generatedMetadata: { enabled: false, allowedHeaders: [] }, responseHeaders: { forwardMcpRequiredHeaders: true, forwardSafeCacheHeaders: true }, }), metadataPolicy: jsonb("metadata_policy").$type().notNull().default({ version: 1, forwardCompanyId: false, forwardGatewayId: false, forwardProjectId: false, forwardIssueId: false, forwardAgentId: false, forwardRunId: false, forwardCorrelationId: true, }), onDemandToolsConfig: jsonb("on_demand_tools_config").$type().notNull().default({ enabled: false, searchToolName: "search_tools", runToolName: "run_tool", }), metadata: jsonb("metadata").$type>().notNull().default({}), createdByAgentId: uuid("created_by_agent_id").references(() => agents.id, { onDelete: "set null" }), createdByUserId: text("created_by_user_id"), archivedAt: timestamp("archived_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_mcp_gateways_company_idx").on(table.companyId), index("tool_mcp_gateways_company_status_idx").on(table.companyId, table.status), index("tool_mcp_gateways_profile_idx").on(table.companyId, table.profileId), uniqueIndex("tool_mcp_gateways_public_id_uq").on(table.gatewayPublicId), uniqueIndex("tool_mcp_gateways_company_slug_uq").on(table.companyId, table.slug), uniqueIndex("tool_mcp_gateways_company_name_uq").on(table.companyId, table.name), ], ); export const toolMcpGatewayTokens = pgTable( "tool_mcp_gateway_tokens", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), gatewayId: uuid("gateway_id").notNull().references(() => toolMcpGateways.id, { onDelete: "cascade" }), name: text("name").notNull(), tokenHash: text("token_hash").notNull(), tokenPrefix: text("token_prefix").notNull().default(""), subjectType: text("subject_type").$type().notNull().default("gateway_client"), subjectId: text("subject_id"), clientLabel: text("client_label").notNull().default(""), ownerNote: text("owner_note").notNull().default(""), allowedActions: jsonb("allowed_actions").$type().notNull().default(["tools/list", "tools/call"]), expiresAt: timestamp("expires_at", { withTimezone: true }), expiryOverrideReason: text("expiry_override_reason"), expiryOverrideByUserId: text("expiry_override_by_user_id"), expiryOverrideByAgentId: uuid("expiry_override_by_agent_id").references(() => agents.id, { onDelete: "set null" }), expiryOverrideAt: timestamp("expiry_override_at", { withTimezone: true }), lastUsedAt: timestamp("last_used_at", { withTimezone: true }), revokedAt: timestamp("revoked_at", { withTimezone: true }), createdByAgentId: uuid("created_by_agent_id").references(() => agents.id, { onDelete: "set null" }), createdByUserId: text("created_by_user_id"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ uniqueIndex("tool_mcp_gateway_tokens_token_hash_uq").on(table.tokenHash), index("tool_mcp_gateway_tokens_expiry_idx").on(table.expiresAt, table.id), index("tool_mcp_gateway_tokens_gateway_idx").on(table.companyId, table.gatewayId), index("tool_mcp_gateway_tokens_subject_idx").on(table.companyId, table.subjectType, table.subjectId), index("tool_mcp_gateway_tokens_company_expires_idx").on(table.companyId, table.expiresAt), ], ); export const toolPolicies = pgTable( "tool_policies", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), name: text("name").notNull(), description: text("description"), policyType: text("policy_type").$type().notNull(), priority: integer("priority").notNull().default(100), enabled: boolean("enabled").notNull().default(true), selectors: jsonb("selectors").$type>().notNull().default({}), conditions: jsonb("conditions").$type>(), config: jsonb("config").$type>(), createdByAgentId: uuid("created_by_agent_id").references(() => agents.id, { onDelete: "set null" }), createdByUserId: text("created_by_user_id"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_policies_company_enabled_idx").on(table.companyId, table.enabled), index("tool_policies_company_type_idx").on(table.companyId, table.policyType), uniqueIndex("tool_policies_company_name_uq").on(table.companyId, table.name), ], ); export const toolRuntimeSlots = pgTable( "tool_runtime_slots", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), applicationId: uuid("application_id").references(() => toolApplications.id, { onDelete: "set null" }), connectionId: uuid("connection_id").references(() => toolConnections.id, { onDelete: "cascade" }), projectWorkspaceId: uuid("project_workspace_id").references(() => projectWorkspaces.id, { onDelete: "set null" }), executionWorkspaceId: uuid("execution_workspace_id").references(() => executionWorkspaces.id, { onDelete: "set null" }), issueId: uuid("issue_id").references(() => issues.id, { onDelete: "set null" }), ownerScopeType: text("owner_scope_type").notNull().default("connection"), ownerScopeId: text("owner_scope_id"), runtimeKind: text("runtime_kind").$type().notNull().default("local_stdio"), slotKey: text("slot_key").notNull(), status: text("status").$type().notNull().default("stopped"), reuseKey: text("reuse_key"), workspaceScope: text("workspace_scope"), credentialScopeHash: text("credential_scope_hash"), provider: text("provider"), providerRef: text("provider_ref"), processId: integer("process_id"), commandTemplateKey: text("command_template_key"), healthStatus: text("health_status").$type().notNull().default("unchecked"), healthMessage: text("health_message"), lastHealthCheckAt: timestamp("last_health_check_at", { withTimezone: true }), lastStartedAt: timestamp("last_started_at", { withTimezone: true }), startedAt: timestamp("started_at", { withTimezone: true }), stoppedAt: timestamp("stopped_at", { withTimezone: true }), lastUsedAt: timestamp("last_used_at", { withTimezone: true }), idleExpiresAt: timestamp("idle_expires_at", { withTimezone: true }), idleDeadlineAt: timestamp("idle_deadline_at", { withTimezone: true }), lastError: text("last_error"), metadata: jsonb("metadata").$type>().notNull().default({}), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_runtime_slots_company_idx").on(table.companyId), index("tool_runtime_slots_connection_idx").on(table.connectionId), index("tool_runtime_slots_execution_workspace_idx").on(table.companyId, table.executionWorkspaceId), uniqueIndex("tool_runtime_slots_slot_key_uq").on(table.companyId, table.slotKey), ], ); export const toolStdioCommandTemplates = pgTable( "tool_stdio_command_templates", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), templateKey: text("template_key").notNull(), name: text("name").notNull(), description: text("description"), status: text("status").$type<"active" | "disabled">().notNull().default("active"), command: text("command").notNull(), args: jsonb("args").$type().notNull().default([]), envKeys: jsonb("env_keys").$type().notNull().default([]), tools: jsonb("tools").$type>>().notNull().default([]), createdByAgentId: uuid("created_by_agent_id").references(() => agents.id, { onDelete: "set null" }), createdByUserId: text("created_by_user_id"), disabledAt: timestamp("disabled_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_stdio_command_templates_company_idx").on(table.companyId), index("tool_stdio_command_templates_company_status_idx").on(table.companyId, table.status), uniqueIndex("tool_stdio_command_templates_company_key_uq").on(table.companyId, table.templateKey), ], ); export const toolGatewaySessions = pgTable( "tool_gateway_sessions", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), agentId: uuid("agent_id").notNull().references(() => agents.id, { onDelete: "cascade" }), runId: uuid("run_id").notNull().references(() => heartbeatRuns.id, { onDelete: "cascade" }), issueId: uuid("issue_id").references(() => issues.id, { onDelete: "set null" }), projectId: uuid("project_id").references(() => projects.id, { onDelete: "set null" }), gatewayId: uuid("gateway_id").references(() => toolMcpGateways.id, { onDelete: "set null" }), gatewayTokenId: uuid("gateway_token_id").references(() => toolMcpGatewayTokens.id, { onDelete: "set null" }), gatewayPublicId: text("gateway_public_id"), clientSubjectType: text("client_subject_type").$type(), clientSubjectId: text("client_subject_id"), clientName: text("client_name"), mcpSessionId: text("mcp_session_id"), correlationId: text("correlation_id"), tokenHash: text("token_hash").notNull(), expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(), lastUsedAt: timestamp("last_used_at", { withTimezone: true }), revokedAt: timestamp("revoked_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ uniqueIndex("tool_gateway_sessions_token_hash_uq").on(table.tokenHash), index("tool_gateway_sessions_company_agent_idx").on(table.companyId, table.agentId), index("tool_gateway_sessions_company_expires_idx").on(table.companyId, table.expiresAt), index("tool_gateway_sessions_run_idx").on(table.companyId, table.runId), index("tool_gateway_sessions_issue_idx").on(table.companyId, table.issueId), index("tool_gateway_sessions_gateway_idx").on(table.companyId, table.gatewayId), ], ); export const toolGatewayRateLimitCounters = pgTable( "tool_gateway_rate_limit_counters", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), counterKey: text("counter_key").notNull(), windowStartAt: timestamp("window_start_at", { withTimezone: true }).notNull(), windowMs: integer("window_ms").notNull(), limit: integer("limit").notNull(), count: integer("count").notNull().default(0), resetAt: timestamp("reset_at", { withTimezone: true }).notNull(), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_gateway_rate_limit_counters_company_idx").on(table.companyId), uniqueIndex("tool_gateway_rate_limit_counters_window_uq").on( table.companyId, table.counterKey, table.windowStartAt, ), ], ); export const toolInvocations = pgTable( "tool_invocations", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), idempotencyKey: text("idempotency_key"), actorType: text("actor_type").notNull().default("system"), actorId: text("actor_id"), agentId: uuid("agent_id").references(() => agents.id, { onDelete: "set null" }), issueId: uuid("issue_id").references(() => issues.id, { onDelete: "set null" }), runId: uuid("run_id").references(() => heartbeatRuns.id, { onDelete: "set null" }), gatewayId: uuid("gateway_id").references(() => toolMcpGateways.id, { onDelete: "set null" }), gatewayTokenId: uuid("gateway_token_id").references(() => toolMcpGatewayTokens.id, { onDelete: "set null" }), gatewayPublicId: text("gateway_public_id"), clientSubjectType: text("client_subject_type").$type(), clientSubjectId: text("client_subject_id"), clientName: text("client_name"), mcpSessionId: text("mcp_session_id"), correlationId: text("correlation_id"), applicationId: uuid("application_id").references(() => toolApplications.id, { onDelete: "set null" }), connectionId: uuid("connection_id").references(() => toolConnections.id, { onDelete: "set null" }), catalogEntryId: uuid("catalog_entry_id").references(() => toolCatalogEntries.id, { onDelete: "set null" }), catalogVersionHash: text("catalog_version_hash"), catalogSchemaHash: text("catalog_schema_hash"), providerType: text("provider_type"), applicationKey: text("application_key"), upstreamToolName: text("upstream_tool_name"), riskLevel: text("risk_level").$type(), toolName: text("tool_name").notNull(), argumentsHash: text("arguments_hash"), argumentsSummary: jsonb("arguments_summary").$type(), policyDecision: text("policy_decision").$type(), matchedPolicyIds: jsonb("matched_policy_ids").$type().notNull().default([]), policyExplanation: jsonb("policy_explanation").$type>(), credentialScopeSummary: jsonb("credential_scope_summary").$type>(), headerPolicySummary: jsonb("header_policy_summary").$type>(), approvalState: text("approval_state").$type().notNull().default("not_required"), status: text("status").$type().notNull().default("pending"), upstreamRequestId: text("upstream_request_id"), resultHash: text("result_hash"), resultSummary: jsonb("result_summary").$type(), resultSizeBytes: integer("result_size_bytes"), resultArtifactId: uuid("result_artifact_id"), errorCode: text("error_code"), errorMessage: text("error_message"), startedAt: timestamp("started_at", { withTimezone: true }), completedAt: timestamp("completed_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_invocations_company_created_idx").on(table.companyId, table.createdAt), index("tool_invocations_run_idx").on(table.companyId, table.runId), index("tool_invocations_issue_idx").on(table.companyId, table.issueId), index("tool_invocations_gateway_idx").on(table.companyId, table.gatewayId), uniqueIndex("tool_invocations_company_idempotency_uq").on(table.companyId, table.idempotencyKey), ], ); export const toolActionRequests = pgTable( "tool_action_requests", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), invocationId: uuid("invocation_id").notNull().references(() => toolInvocations.id, { onDelete: "cascade" }), issueId: uuid("issue_id").references(() => issues.id, { onDelete: "set null" }), interactionId: uuid("interaction_id").references(() => issueThreadInteractions.id, { onDelete: "set null" }), approvalId: uuid("approval_id").references(() => approvals.id, { onDelete: "set null" }), status: text("status").$type().notNull().default("pending"), canonicalArgumentsHash: text("canonical_arguments_hash").notNull(), canonicalArgumentsSummary: jsonb("canonical_arguments_summary").$type().notNull(), signedArguments: text("signed_arguments"), previewMarkdown: text("preview_markdown"), requestedByAgentId: uuid("requested_by_agent_id").references(() => agents.id, { onDelete: "set null" }), requestedByUserId: text("requested_by_user_id"), resolvedByAgentId: uuid("resolved_by_agent_id").references(() => agents.id, { onDelete: "set null" }), resolvedByUserId: text("resolved_by_user_id"), decidedByAgentId: uuid("decided_by_agent_id").references(() => agents.id, { onDelete: "set null" }), decidedByUserId: text("decided_by_user_id"), decidedAt: timestamp("decided_at", { withTimezone: true }), expiresAt: timestamp("expires_at", { withTimezone: true }), resolvedAt: timestamp("resolved_at", { withTimezone: true }), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_action_requests_company_status_idx").on(table.companyId, table.status), index("tool_action_requests_invocation_idx").on(table.invocationId), index("tool_action_requests_issue_idx").on(table.companyId, table.issueId), ], ); export const toolCallEvents = pgTable( "tool_call_events", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), eventType: text("event_type").$type().notNull(), actorType: text("actor_type").notNull().default("system"), actorId: text("actor_id"), agentId: uuid("agent_id").references(() => agents.id, { onDelete: "set null" }), runId: uuid("run_id").references(() => heartbeatRuns.id, { onDelete: "set null" }), issueId: uuid("issue_id").references(() => issues.id, { onDelete: "set null" }), gatewayId: uuid("gateway_id").references(() => toolMcpGateways.id, { onDelete: "set null" }), gatewayTokenId: uuid("gateway_token_id").references(() => toolMcpGatewayTokens.id, { onDelete: "set null" }), gatewayPublicId: text("gateway_public_id"), clientSubjectType: text("client_subject_type").$type(), clientSubjectId: text("client_subject_id"), clientName: text("client_name"), mcpSessionId: text("mcp_session_id"), correlationId: text("correlation_id"), applicationId: uuid("application_id").references(() => toolApplications.id, { onDelete: "set null" }), connectionId: uuid("connection_id").references(() => toolConnections.id, { onDelete: "set null" }), catalogEntryId: uuid("catalog_entry_id").references(() => toolCatalogEntries.id, { onDelete: "set null" }), invocationId: uuid("invocation_id").references(() => toolInvocations.id, { onDelete: "set null" }), actionRequestId: uuid("action_request_id").references(() => toolActionRequests.id, { onDelete: "set null" }), runtimeSlotId: uuid("runtime_slot_id").references(() => toolRuntimeSlots.id, { onDelete: "set null" }), toolName: text("tool_name"), decision: text("decision").$type(), matchedPolicyIds: jsonb("matched_policy_ids").$type().notNull().default([]), reasonCode: text("reason_code"), policyExplanation: jsonb("policy_explanation").$type>(), credentialScopeSummary: jsonb("credential_scope_summary").$type>(), headerPolicySummary: jsonb("header_policy_summary").$type>(), outcome: text("outcome").$type().notNull().default("pending"), latencyMs: integer("latency_ms"), argumentsSummary: jsonb("arguments_summary").$type(), requestHash: text("request_hash"), requestSummary: jsonb("request_summary").$type(), resultHash: text("result_hash"), resultSummary: jsonb("result_summary").$type(), resultSizeBytes: integer("result_size_bytes"), redactionPlan: jsonb("redaction_plan").$type>(), rateLimitState: jsonb("rate_limit_state").$type>(), metadata: jsonb("metadata").$type>(), errorCode: text("error_code"), errorMessage: text("error_message"), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_call_events_company_created_idx").on(table.companyId, table.createdAt), index("tool_call_events_run_idx").on(table.companyId, table.runId), index("tool_call_events_issue_idx").on(table.companyId, table.issueId), index("tool_call_events_invocation_idx").on(table.invocationId), index("tool_call_events_gateway_idx").on(table.companyId, table.gatewayId), ], ); export const connectionTokenIssuances = pgTable( "connection_token_issuances", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), applicationId: uuid("application_id").references(() => toolApplications.id, { onDelete: "set null" }), connectionId: uuid("connection_id").notNull().references(() => toolConnections.id, { onDelete: "cascade" }), agentId: uuid("agent_id").notNull().references(() => agents.id, { onDelete: "cascade" }), runId: uuid("run_id").references(() => heartbeatRuns.id, { onDelete: "set null" }), issueId: uuid("issue_id").references(() => issues.id, { onDelete: "set null" }), projectId: uuid("project_id").references(() => projects.id, { onDelete: "set null" }), responsibleUserId: text("responsible_user_id"), path: text("path").$type().notNull(), requestedScope: jsonb("requested_scope").$type().notNull().default([]), issuedScope: jsonb("issued_scope").$type().notNull().default([]), ttlSeconds: integer("ttl_seconds"), expiresAt: timestamp("expires_at", { withTimezone: true }), tokenHash: text("token_hash"), outcome: text("outcome").$type().notNull(), errorCode: text("error_code"), metadata: jsonb("metadata").$type>().notNull().default({}), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("connection_token_issuances_company_created_idx").on(table.companyId, table.createdAt), index("connection_token_issuances_connection_created_idx").on(table.companyId, table.connectionId, table.createdAt), index("connection_token_issuances_agent_connection_idx").on(table.companyId, table.agentId, table.connectionId, table.createdAt), index("connection_token_issuances_run_idx").on(table.companyId, table.runId), sql`CONSTRAINT connection_token_issuances_path_check CHECK (${table.path} IN ('exchange', 'oauth_access', 'static'))`, sql`CONSTRAINT connection_token_issuances_outcome_check CHECK (${table.outcome} IN ('success', 'denied', 'rate_limited', 'use_env_lease', 'upstream_error', 'failure'))`, sql`CONSTRAINT connection_token_issuances_ttl_bounds CHECK (${table.ttlSeconds} IS NULL OR (${table.ttlSeconds} >= 1 AND ${table.ttlSeconds} <= 900))`, sql`CONSTRAINT connection_token_issuances_token_hash_format CHECK (${table.tokenHash} IS NULL OR ${table.tokenHash} ~ '^[a-f0-9]{64}$')`, ], ); export const toolRateLimitCounters = pgTable( "tool_rate_limit_counters", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), policyId: uuid("policy_id").notNull().references(() => toolPolicies.id, { onDelete: "cascade" }), counterKey: text("counter_key").notNull(), scopeType: text("scope_type").notNull(), scopeId: text("scope_id").notNull(), windowKind: text("window_kind").$type().notNull(), windowStartAt: timestamp("window_start_at", { withTimezone: true }).notNull(), limit: integer("limit").notNull(), remaining: integer("remaining").notNull(), resetAt: timestamp("reset_at", { withTimezone: true }).notNull(), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_rate_limit_counters_company_idx").on(table.companyId), uniqueIndex("tool_rate_limit_counters_window_uq").on( table.companyId, table.policyId, table.counterKey, table.windowKind, table.windowStartAt, ), ], ); export const toolRuntimeMetricCounters = pgTable( "tool_runtime_metric_counters", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), metric: text("metric").notNull(), bucketStartAt: timestamp("bucket_start_at", { withTimezone: true }).notNull(), count: integer("count").notNull().default(0), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_runtime_metric_counters_company_metric_idx").on(table.companyId, table.metric, table.bucketStartAt), uniqueIndex("tool_runtime_metric_counters_bucket_uq").on(table.companyId, table.metric, table.bucketStartAt), sql`CONSTRAINT tool_runtime_metric_counters_count_nonnegative CHECK (${table.count} >= 0)`, ], ); export const toolAccessAuditEvents = pgTable( "tool_access_audit_events", { id: uuid("id").primaryKey().defaultRandom(), companyId: uuid("company_id").notNull().references(() => companies.id, { onDelete: "cascade" }), gatewayId: uuid("gateway_id").references(() => toolMcpGateways.id, { onDelete: "set null" }), gatewayTokenId: uuid("gateway_token_id").references(() => toolMcpGatewayTokens.id, { onDelete: "set null" }), gatewayPublicId: text("gateway_public_id"), clientName: text("client_name"), correlationId: text("correlation_id"), connectionId: uuid("connection_id").references(() => toolConnections.id, { onDelete: "set null" }), catalogEntryId: uuid("catalog_entry_id").references(() => toolCatalogEntries.id, { onDelete: "set null" }), actorType: text("actor_type").notNull().default("system"), actorId: text("actor_id"), action: text("action").notNull(), outcome: text("outcome").notNull(), reasonCode: text("reason_code"), details: jsonb("details").$type>().notNull().default({}), createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(), }, (table) => [ index("tool_access_audit_company_created_idx").on(table.companyId, table.createdAt), index("tool_access_audit_connection_idx").on(table.connectionId), index("tool_access_audit_gateway_idx").on(table.companyId, table.gatewayId), ], );