@axiom-lattice/pg-stores 1.0.65 → 1.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/stores/PostgreSQLThreadStore.ts","../src/migrations/migration.ts","../src/migrations/thread_migrations.ts","../src/migrations/thread_tenant_migration.ts","../src/migrations/thread_pk_migration.ts","../src/stores/PostgreSQLAssistantStore.ts","../src/migrations/assistant_migrations.ts","../src/migrations/assistant_tenant_migration.ts","../src/migrations/assistant_pk_migration.ts","../src/stores/PostgreSQLScheduleStorage.ts","../src/migrations/schedule_migrations.ts","../src/migrations/schedule_tenant_migration.ts","../src/stores/PostgreSQLSkillStore.ts","../src/migrations/skill_migrations.ts","../src/migrations/skill_tenant_migration.ts","../src/migrations/skill_pk_migration.ts","../src/stores/PostgreSQLDatabaseConfigStore.ts","../src/migrations/database_config_migrations.ts","../src/stores/PostgreSQLMetricsServerConfigStore.ts","../src/migrations/metrics_config_migrations.ts","../src/stores/PostgreSQLMcpServerConfigStore.ts","../src/migrations/mcp_server_config_migrations.ts","../src/stores/PostgreSQLWorkspaceStore.ts","../src/migrations/workspace_migrations.ts","../src/stores/PostgreSQLProjectStore.ts","../src/migrations/project_migrations.ts","../src/stores/PostgreSQLUserStore.ts","../src/migrations/user_migrations.ts","../src/migrations/user_status_migration.ts","../src/stores/PostgreSQLTenantStore.ts","../src/migrations/tenant_migrations.ts","../src/stores/PostgreSQLUserTenantLinkStore.ts","../src/migrations/user_tenant_link_migrations.ts","../src/migrations/thread_message_queue_migrations.ts","../src/migrations/channel_identity_mapping_migration.ts","../src/migrations/channel_installation_migrations.ts","../src/migrations/channel_installations_alter_migration.ts","../src/migrations/channel_bindings_migration.ts","../src/migrations/workflow_tracking_migrations.ts","../src/stores/ChannelBindingStore.ts","../src/stores/ThreadMessageQueueStore.ts","../src/migrations/add_priority_command_columns.ts","../src/migrations/add_custom_run_config_column.ts","../src/migrations/alter_message_queue_id_column.ts","../src/stores/ChannelIdentityMappingStore.ts","../src/stores/PostgreSQLChannelInstallationStore.ts","../src/stores/PostgreSQLWorkflowTrackingStore.ts","../src/stores/PostgreSQLEvalStore.ts","../src/migrations/eval_migrations.ts"],"sourcesContent":["/**\n * PostgreSQL Stores Package\n *\n * Provides PostgreSQL implementations for various stores\n */\n\n// Re-export pg types for convenience\nexport { Pool } from \"pg\";\nexport type { PoolConfig } from \"pg\";\n\nexport * from \"./stores/PostgreSQLThreadStore\";\nexport * from \"./stores/PostgreSQLAssistantStore\";\nexport * from \"./stores/PostgreSQLScheduleStorage\";\nexport * from \"./stores/PostgreSQLSkillStore\";\nexport * from \"./stores/PostgreSQLDatabaseConfigStore\";\nexport * from \"./stores/PostgreSQLMetricsServerConfigStore\";\nexport * from \"./stores/PostgreSQLMcpServerConfigStore\";\nexport * from \"./stores/PostgreSQLWorkspaceStore\";\nexport * from \"./stores/PostgreSQLProjectStore\";\nexport * from \"./stores/PostgreSQLUserStore\";\nexport * from \"./stores/PostgreSQLTenantStore\";\nexport * from \"./stores/PostgreSQLUserTenantLinkStore\";\nexport * from \"./migrations/migration\";\nexport * from \"./migrations/thread_migrations\";\nexport * from \"./migrations/thread_tenant_migration\";\nexport * from \"./migrations/thread_pk_migration\";\nexport * from \"./migrations/assistant_migrations\";\nexport * from \"./migrations/assistant_tenant_migration\";\nexport * from \"./migrations/assistant_pk_migration\";\nexport * from \"./migrations/schedule_migrations\";\nexport * from \"./migrations/schedule_tenant_migration\";\nexport * from \"./migrations/skill_migrations\";\nexport * from \"./migrations/skill_tenant_migration\";\nexport * from \"./migrations/skill_pk_migration\";\nexport * from \"./migrations/database_config_migrations\";\nexport * from \"./migrations/metrics_config_migrations\";\nexport * from \"./migrations/mcp_server_config_migrations\";\nexport * from \"./migrations/workspace_migrations\";\nexport * from \"./migrations/project_migrations\";\nexport * from \"./migrations/user_migrations\";\nexport * from \"./migrations/tenant_migrations\";\nexport * from \"./migrations/thread_message_queue_migrations\";\nexport * from \"./migrations/channel_identity_mapping_migration\";\nexport * from \"./migrations/channel_installation_migrations\";\nexport * from \"./migrations/channel_installations_alter_migration\";\nexport * from \"./migrations/channel_bindings_migration\";\nexport * from \"./migrations/workflow_tracking_migrations\";\nexport * from \"./stores/ChannelBindingStore\";\nexport * from \"./stores/ThreadMessageQueueStore\";\nexport * from \"./stores/ChannelIdentityMappingStore\";\nexport * from \"./stores/PostgreSQLChannelInstallationStore\";\nexport * from \"./stores/PostgreSQLWorkflowTrackingStore\";\nexport * from \"./stores/PostgreSQLEvalStore\";\nexport * from \"./migrations/eval_migrations\";\n\n// Re-export for convenience\nexport { PostgreSQLThreadStore } from \"./stores/PostgreSQLThreadStore\";\nexport { PostgreSQLAssistantStore } from \"./stores/PostgreSQLAssistantStore\";\nexport { PostgreSQLScheduleStorage } from \"./stores/PostgreSQLScheduleStorage\";\nexport { PostgreSQLSkillStore } from \"./stores/PostgreSQLSkillStore\";\nexport { PostgreSQLDatabaseConfigStore } from \"./stores/PostgreSQLDatabaseConfigStore\";\nexport { PostgreSQLMetricsServerConfigStore } from \"./stores/PostgreSQLMetricsServerConfigStore\";\nexport { PostgreSQLMcpServerConfigStore } from \"./stores/PostgreSQLMcpServerConfigStore\";\nexport { PostgreSQLWorkspaceStore } from \"./stores/PostgreSQLWorkspaceStore\";\nexport { PostgreSQLProjectStore } from \"./stores/PostgreSQLProjectStore\";\nexport { PostgreSQLUserStore } from \"./stores/PostgreSQLUserStore\";\nexport { PostgreSQLTenantStore } from \"./stores/PostgreSQLTenantStore\";\nexport { PostgreSQLUserTenantLinkStore } from \"./stores/PostgreSQLUserTenantLinkStore\";\nexport { ChannelBindingStore } from \"./stores/ChannelBindingStore\";\nexport { ChannelIdentityMappingStore } from \"./stores/ChannelIdentityMappingStore\";\nexport { PostgreSQLChannelInstallationStore } from \"./stores/PostgreSQLChannelInstallationStore\";\nexport { PostgreSQLWorkflowTrackingStore } from \"./stores/PostgreSQLWorkflowTrackingStore\";\nexport { PostgreSQLEvalStore } from \"./stores/PostgreSQLEvalStore\";\n\n// Re-export types from protocols\nexport type {\n ThreadStore,\n Thread,\n CreateThreadRequest,\n AssistantStore,\n Assistant,\n CreateAssistantRequest,\n ScheduleStorage,\n ScheduledTaskDefinition,\n ScheduledTaskStatus,\n ScheduleExecutionType,\n SkillStore,\n Skill,\n CreateSkillRequest,\n DatabaseConfigStore,\n DatabaseConfigEntry,\n CreateDatabaseConfigRequest,\n UpdateDatabaseConfigRequest,\n DatabaseConfig,\n DatabaseType,\n Binding,\n BindingRegistry,\n CreateBindingInput,\n ChannelInstallationStore,\n ChannelInstallation,\n CreateChannelInstallationRequest,\n UpdateChannelInstallationRequest,\n LarkChannelInstallationConfig,\n MetricsServerConfigStore,\n MetricsServerConfigEntry,\n CreateMetricsServerConfigRequest,\n UpdateMetricsServerConfigRequest,\n MetricsServerConfig,\n McpServerConfigStore,\n McpServerConfigEntry,\n CreateMcpServerConfigRequest,\n UpdateMcpServerConfigRequest,\n WorkspaceStore,\n Workspace,\n CreateWorkspaceRequest,\n UpdateWorkspaceRequest,\n StorageType,\n ProjectStore,\n Project,\n CreateProjectRequest,\n UpdateProjectRequest,\n UserStore,\n User,\n CreateUserRequest,\n UpdateUserRequest,\n TenantStore,\n Tenant,\n TenantStatus,\n CreateTenantRequest,\n UpdateTenantRequest,\n UserTenantLinkStore,\n UserTenantLink,\n UserTenantRole,\n CreateUserTenantLinkRequest,\n UpdateUserTenantLinkRequest,\n WorkflowTrackingStore,\n WorkflowRun,\n RunStep,\n CreateWorkflowRunRequest,\n UpdateWorkflowRunRequest,\n CreateRunStepRequest,\n UpdateRunStepRequest,\n EvalStore,\n EvalProject,\n CreateEvalProjectRequest,\n EvalSuite,\n CreateEvalSuiteRequest,\n EvalCase,\n CreateEvalCaseRequest,\n EvalRun,\n CreateEvalRunRequest,\n EvalRunResult,\n EvalProjectReport,\n} from \"@axiom-lattice/protocols\";\n","/**\n * PostgreSQL implementation of ThreadStore\n */\n\nimport { Pool, PoolClient } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n ThreadStore,\n Thread,\n CreateThreadRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createThreadsTable } from \"../migrations/thread_migrations\";\nimport { addThreadTenantId } from \"../migrations/thread_tenant_migration\";\nimport { changeThreadPrimaryKey } from \"../migrations/thread_pk_migration\";\n\n/**\n * PostgreSQL ThreadStore options\n */\nexport interface PostgreSQLThreadStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of ThreadStore\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n */\nexport class PostgreSQLThreadStore implements ThreadStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLThreadStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createThreadsTable);\n this.migrationManager.register(addThreadTenantId);\n this.migrationManager.register(changeThreadPrimaryKey);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLThreadStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all threads for a specific tenant and assistant\n */\n async getThreadsByAssistantId(\n tenantId: string,\n assistantId: string,\n metadataFilter?: Record<string, string>\n ): Promise<Thread[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n assistant_id: string;\n metadata: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, assistant_id, metadata, created_at, updated_at\n FROM lattice_threads\n WHERE tenant_id = $1 AND assistant_id = $2\n ORDER BY created_at DESC\n `,\n [tenantId, assistantId]\n );\n\n let threads = result.rows.map(this.mapRowToThread);\n\n // Apply metadata filtering if provided\n if (metadataFilter && Object.keys(metadataFilter).length > 0) {\n threads = threads.filter((thread) =>\n Object.entries(metadataFilter).every(\n ([key, value]) => thread.metadata?.[key] === value\n )\n );\n }\n\n return threads;\n }\n\n /**\n * Get a thread by ID for a specific tenant\n */\n async getThreadById(\n tenantId: string,\n threadId: string\n ): Promise<Thread | undefined> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n assistant_id: string;\n metadata: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, assistant_id, metadata, created_at, updated_at\n FROM lattice_threads\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, threadId]\n );\n\n if (result.rows.length === 0) {\n return undefined;\n }\n\n return this.mapRowToThread(result.rows[0]);\n }\n\n /**\n * Create a new thread for a tenant and assistant\n */\n async createThread(\n tenantId: string,\n assistantId: string,\n threadId: string,\n data: CreateThreadRequest\n ): Promise<Thread> {\n await this.ensureInitialized();\n\n const now = new Date();\n const metadata = data.metadata || {};\n\n await this.pool.query(\n `\n INSERT INTO lattice_threads (id, tenant_id, assistant_id, metadata, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (id, tenant_id) DO UPDATE SET\n assistant_id = EXCLUDED.assistant_id,\n metadata = EXCLUDED.metadata,\n updated_at = EXCLUDED.updated_at\n `,\n [threadId, tenantId, assistantId, JSON.stringify(metadata), now, now]\n );\n\n return {\n id: threadId,\n tenantId,\n assistantId,\n metadata,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing thread\n */\n async updateThread(\n tenantId: string,\n threadId: string,\n updates: Partial<CreateThreadRequest>\n ): Promise<Thread | null> {\n await this.ensureInitialized();\n\n // Get existing thread\n const existing = await this.getThreadById(tenantId, threadId);\n if (!existing) {\n return null;\n }\n\n // Merge metadata\n const updatedMetadata = {\n ...existing.metadata,\n ...(updates.metadata || {}),\n };\n\n const now = new Date();\n\n await this.pool.query(\n `\n UPDATE lattice_threads\n SET metadata = $1, updated_at = $2\n WHERE tenant_id = $3 AND id = $4\n `,\n [JSON.stringify(updatedMetadata), now, tenantId, threadId]\n );\n\n return {\n ...existing,\n metadata: updatedMetadata,\n updatedAt: now,\n };\n }\n\n /**\n * Delete a thread by ID\n */\n async deleteThread(tenantId: string, threadId: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_threads\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, threadId]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if thread exists\n */\n async hasThread(tenantId: string, threadId: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_threads\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, threadId]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Thread object\n */\n private mapRowToThread(row: {\n id: string;\n tenant_id: string;\n assistant_id: string;\n metadata: any;\n created_at: Date;\n updated_at: Date;\n }): Thread {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n assistantId: row.assistant_id,\n metadata:\n typeof row.metadata === \"string\"\n ? JSON.parse(row.metadata)\n : row.metadata || {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n}\n","/**\n * Migration system for database schema management\n */\n\nimport { Pool, PoolClient } from \"pg\";\n\n/**\n * Migration record stored in database\n */\ninterface MigrationRecord {\n version: number;\n name: string;\n applied_at: Date;\n}\n\n/**\n * Migration definition\n */\nexport interface Migration {\n version: number;\n name: string;\n up: (client: PoolClient) => Promise<void>;\n down?: (client: PoolClient) => Promise<void>;\n}\n\n/**\n * Migration manager\n */\nexport class MigrationManager {\n private pool: Pool;\n private migrations: Migration[] = [];\n\n constructor(pool: Pool) {\n this.pool = pool;\n }\n\n /**\n * Register a migration\n */\n register(migration: Migration): void {\n this.migrations.push(migration);\n // Sort migrations by version\n this.migrations.sort((a, b) => a.version - b.version);\n }\n\n /**\n * Initialize migrations table if it doesn't exist\n */\n private async ensureMigrationsTable(client: PoolClient): Promise<void> {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_schema_migrations (\n version INTEGER PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n }\n\n /**\n * Get applied migrations from database\n */\n private async getAppliedMigrations(\n client: PoolClient\n ): Promise<MigrationRecord[]> {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_schema_migrations (\n version INTEGER PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n const result = await client.query<MigrationRecord>(\n \"SELECT version, name, applied_at FROM lattice_schema_migrations ORDER BY version\"\n );\n return result.rows;\n }\n\n /**\n * Apply pending migrations\n * Uses PostgreSQL advisory locks to prevent concurrent migrations\n */\n async migrate(): Promise<void> {\n const client = await this.pool.connect();\n try {\n // Use advisory lock to prevent concurrent migrations\n // Lock ID: 123456789 (arbitrary but consistent)\n const lockId = 123456789;\n \n // Acquire advisory lock (blocks until lock is available)\n // This ensures only one migration runs at a time across all instances\n await client.query(\"SELECT pg_advisory_lock($1)\", [lockId]);\n \n try {\n await client.query(\"BEGIN\");\n\n await this.ensureMigrationsTable(client);\n const appliedMigrations = await this.getAppliedMigrations(client);\n const appliedVersions = new Set(appliedMigrations.map((m) => m.version));\n\n // Find pending migrations\n const pendingMigrations = this.migrations.filter(\n (m) => !appliedVersions.has(m.version)\n );\n\n if (pendingMigrations.length === 0) {\n console.log(\"No pending migrations\");\n await client.query(\"COMMIT\");\n return;\n }\n\n // Apply pending migrations\n for (const migration of pendingMigrations) {\n console.log(\n `Applying migration ${migration.version}: ${migration.name}`\n );\n await migration.up(client);\n // Use ON CONFLICT DO NOTHING to handle race conditions gracefully\n await client.query(\n \"INSERT INTO lattice_schema_migrations (version, name) VALUES ($1, $2) ON CONFLICT (version) DO NOTHING\",\n [migration.version, migration.name]\n );\n }\n\n await client.query(\"COMMIT\");\n console.log(`Applied ${pendingMigrations.length} migration(s)`);\n } catch (error) {\n await client.query(\"ROLLBACK\");\n throw error;\n } finally {\n // Release advisory lock\n await client.query(\"SELECT pg_advisory_unlock($1)\", [lockId]);\n }\n } catch (error) {\n throw error;\n } finally {\n client.release();\n }\n }\n\n /**\n * Rollback last migration\n */\n async rollback(): Promise<void> {\n const client = await this.pool.connect();\n try {\n await client.query(\"BEGIN\");\n\n const appliedMigrations = await this.getAppliedMigrations(client);\n if (appliedMigrations.length === 0) {\n console.log(\"No migrations to rollback\");\n await client.query(\"COMMIT\");\n return;\n }\n\n const lastMigration = appliedMigrations[appliedMigrations.length - 1];\n const migration = this.migrations.find(\n (m) => m.version === lastMigration.version\n );\n\n if (!migration || !migration.down) {\n throw new Error(\n `Migration ${lastMigration.version} does not have a down migration`\n );\n }\n\n console.log(\n `Rolling back migration ${lastMigration.version}: ${lastMigration.name}`\n );\n await migration.down(client);\n await client.query(\n \"DELETE FROM lattice_schema_migrations WHERE version = $1\",\n [lastMigration.version]\n );\n\n await client.query(\"COMMIT\");\n console.log(\"Rollback completed\");\n } catch (error) {\n await client.query(\"ROLLBACK\");\n throw error;\n } finally {\n client.release();\n }\n }\n\n /**\n * Get current migration version\n */\n async getCurrentVersion(): Promise<number> {\n const client = await this.pool.connect();\n try {\n const appliedMigrations = await this.getAppliedMigrations(client);\n if (appliedMigrations.length === 0) {\n return 0;\n }\n return Math.max(...appliedMigrations.map((m) => m.version));\n } finally {\n client.release();\n }\n }\n}\n","/**\n * Thread table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create threads table\n */\nexport const createThreadsTable: Migration = {\n version: 1,\n name: \"create_threads_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_threads (\n id VARCHAR(255) NOT NULL,\n assistant_id VARCHAR(255) NOT NULL,\n metadata JSONB DEFAULT '{}',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id, assistant_id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_threads_assistant_id \n ON lattice_threads(assistant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_threads_created_at \n ON lattice_threads(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_threads_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_threads_assistant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_threads\");\n },\n};\n","/**\n * Thread table tenant isolation migration\n * Adds tenant_id column to lattice_threads table\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add tenant_id column to threads table\n */\nexport const addThreadTenantId: Migration = {\n version: 15,\n name: \"add_thread_tenant_id\",\n up: async (client: PoolClient) => {\n // Add tenant_id column\n await client.query(`\n ALTER TABLE lattice_threads\n ADD COLUMN IF NOT EXISTS tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_threads \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL after setting defaults\n await client.query(`\n ALTER TABLE lattice_threads\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the default constraint\n await client.query(`\n ALTER TABLE lattice_threads\n ALTER COLUMN tenant_id DROP DEFAULT\n `);\n\n // Create index for tenant-based queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_threads_tenant_id \n ON lattice_threads(tenant_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_lattice_threads_tenant_id\"\n );\n await client.query(\n \"ALTER TABLE lattice_threads DROP COLUMN IF EXISTS tenant_id\"\n );\n },\n};\n","/**\n * Thread table primary key migration\n * Changes primary key from (id, assistant_id) to (id, tenant_id) for multi-tenancy\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Change primary key to support multi-tenancy\n */\nexport const changeThreadPrimaryKey: Migration = {\n version: 19,\n name: \"change_thread_primary_key\",\n up: async (client: PoolClient) => {\n // Check if table exists\n const tableExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.tables \n WHERE table_name = 'lattice_threads'\n )\n `);\n\n if (!tableExists.rows[0].exists) {\n // Table doesn't exist, it will be created with correct schema\n return;\n }\n\n // Check current primary key\n const pkResult = await client.query(`\n SELECT a.attname as column_name\n FROM pg_index i\n JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n WHERE i.indrelid = 'lattice_threads'::regclass\n AND i.indisprimary\n `);\n\n const pkColumns = pkResult.rows.map(row => row.column_name);\n \n // If primary key is already (id, tenant_id), nothing to do\n if (pkColumns.includes('tenant_id') && pkColumns.includes('id') && pkColumns.length === 2) {\n console.log('Primary key already correct (id, tenant_id)');\n return;\n }\n\n // If primary key is (id, assistant_id), we need to change it\n if (pkColumns.includes('id') && pkColumns.includes('assistant_id')) {\n console.log('Changing primary key from (id, assistant_id) to (id, tenant_id)');\n \n // Check if tenant_id column exists\n const tenantIdExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.columns \n WHERE table_name = 'lattice_threads' \n AND column_name = 'tenant_id'\n )\n `);\n\n if (!tenantIdExists.rows[0].exists) {\n // Add tenant_id column if it doesn't exist\n await client.query(`\n ALTER TABLE lattice_threads\n ADD COLUMN tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n }\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_threads \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL\n await client.query(`\n ALTER TABLE lattice_threads\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the old primary key\n await client.query(`\n ALTER TABLE lattice_threads \n DROP CONSTRAINT IF EXISTS lattice_threads_pkey\n `);\n\n // Add new composite primary key\n await client.query(`\n ALTER TABLE lattice_threads \n ADD PRIMARY KEY (id, tenant_id)\n `);\n\n console.log('Primary key changed successfully to (id, tenant_id)');\n }\n },\n down: async (client: PoolClient) => {\n // Reverting this is complex and potentially dangerous\n console.warn('Down migration for changeThreadPrimaryKey is not supported');\n },\n};\n","/**\n * PostgreSQL implementation of AssistantStore\n */\n\nimport { Pool, PoolClient } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n AssistantStore,\n Assistant,\n CreateAssistantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createAssistantsTable } from \"../migrations/assistant_migrations\";\nimport { addAssistantTenantId } from \"../migrations/assistant_tenant_migration\";\nimport { changeAssistantPrimaryKey } from \"../migrations/assistant_pk_migration\";\n\n/**\n * PostgreSQL AssistantStore options\n */\nexport interface PostgreSQLAssistantStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of AssistantStore\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n */\nexport class PostgreSQLAssistantStore implements AssistantStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLAssistantStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createAssistantsTable);\n this.migrationManager.register(addAssistantTenantId);\n this.migrationManager.register(changeAssistantPrimaryKey);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLAssistantStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all assistants for a tenant\n */\n async getAllAssistants(tenantId: string): Promise<Assistant[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n graph_definition: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, graph_definition, created_at, updated_at\n FROM lattice_assistants\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map(this.mapRowToAssistant);\n }\n\n /**\n * Get assistant by ID\n */\n async getAssistantById(tenantId: string, id: string): Promise<Assistant | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n graph_definition: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, graph_definition, created_at, updated_at\n FROM lattice_assistants\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToAssistant(result.rows[0]);\n }\n\n /**\n * Create a new assistant\n */\n async createAssistant(\n tenantId: string,\n id: string,\n data: CreateAssistantRequest\n ): Promise<Assistant> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_assistants (id, tenant_id, name, description, graph_definition, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id, tenant_id) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n graph_definition = EXCLUDED.graph_definition,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.name,\n data.description || null,\n JSON.stringify(data.graphDefinition),\n now,\n now,\n ]\n );\n\n return {\n id,\n tenantId,\n name: data.name,\n description: data.description,\n graphDefinition: data.graphDefinition,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing assistant\n */\n async updateAssistant(\n tenantId: string,\n id: string,\n updates: Partial<CreateAssistantRequest>\n ): Promise<Assistant | null> {\n await this.ensureInitialized();\n\n // Get existing assistant\n const existing = await this.getAssistantById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description || null);\n }\n\n if (updates.graphDefinition !== undefined) {\n updateFields.push(`graph_definition = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.graphDefinition));\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add tenant_id and id for WHERE clause\n updateValues.push(tenantId);\n updateValues.push(id);\n\n await this.pool.query(\n `\n UPDATE lattice_assistants\n SET ${updateFields.join(\", \")}\n WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex}\n `,\n updateValues\n );\n\n // Return updated assistant\n return await this.getAssistantById(tenantId, id);\n }\n\n /**\n * Delete an assistant by ID\n */\n async deleteAssistant(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_assistants\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if assistant exists\n */\n async hasAssistant(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_assistants\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Assistant object\n */\n private mapRowToAssistant(row: {\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n graph_definition: any;\n created_at: Date;\n updated_at: Date;\n }): Assistant {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n name: row.name,\n description: row.description || undefined,\n graphDefinition:\n typeof row.graph_definition === \"string\"\n ? JSON.parse(row.graph_definition)\n : row.graph_definition,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n}\n","/**\n * Assistant table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create assistants table\n */\nexport const createAssistantsTable: Migration = {\n version: 3,\n name: \"create_assistants_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_assistants (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL DEFAULT 'default',\n name VARCHAR(255) NOT NULL,\n description TEXT,\n graph_definition JSONB NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (tenant_id, id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_assistants_name \n ON lattice_assistants(name)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_assistants_created_at \n ON lattice_assistants(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_lattice_assistants_created_at\"\n );\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_assistants_name\");\n await client.query(\"DROP TABLE IF EXISTS lattice_assistants\");\n },\n};\n","/**\n * Assistant table tenant isolation migration\n * Adds tenant_id column to lattice_assistants table\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add tenant_id column to assistants table\n */\nexport const addAssistantTenantId: Migration = {\n version: 14,\n name: \"add_assistant_tenant_id\",\n up: async (client: PoolClient) => {\n // tenant_id column is now created in the initial migration\n // This migration is kept for backward compatibility but does nothing\n // Create index for tenant-based queries if not exists\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_assistants_tenant_id \n ON lattice_assistants(tenant_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_lattice_assistants_tenant_id\"\n );\n },\n};\n","/**\n * Assistant table primary key migration\n * Changes primary key from (id) to (tenant_id, id) for multi-tenancy\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Change primary key to support multi-tenancy\n */\nexport const changeAssistantPrimaryKey: Migration = {\n version: 15,\n name: \"change_assistant_primary_key\",\n up: async (client: PoolClient) => {\n // Check if table exists and has the old primary key structure\n const tableExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.tables \n WHERE table_name = 'lattice_assistants'\n )\n `);\n\n if (!tableExists.rows[0].exists) {\n // Table doesn't exist, it will be created by createAssistantsTable migration\n // with the correct primary key (tenant_id, id)\n return;\n }\n\n // Check current primary key\n const pkResult = await client.query(`\n SELECT a.attname as column_name\n FROM pg_index i\n JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n WHERE i.indrelid = 'lattice_assistants'::regclass\n AND i.indisprimary\n `);\n\n const pkColumns = pkResult.rows.map(row => row.column_name);\n \n // If primary key is already (tenant_id, id), nothing to do\n if (pkColumns.includes('tenant_id') && pkColumns.includes('id')) {\n console.log('Primary key already correct (tenant_id, id)');\n return;\n }\n\n // If primary key is just (id), we need to change it\n if (pkColumns.length === 1 && pkColumns[0] === 'id') {\n console.log('Changing primary key from (id) to (tenant_id, id)');\n \n // Check if tenant_id column exists\n const tenantIdExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.columns \n WHERE table_name = 'lattice_assistants' \n AND column_name = 'tenant_id'\n )\n `);\n\n if (!tenantIdExists.rows[0].exists) {\n // Add tenant_id column if it doesn't exist\n await client.query(`\n ALTER TABLE lattice_assistants\n ADD COLUMN tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n }\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_assistants \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL\n await client.query(`\n ALTER TABLE lattice_assistants\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the old primary key\n await client.query(`\n ALTER TABLE lattice_assistants \n DROP CONSTRAINT IF EXISTS lattice_assistants_pkey\n `);\n\n // Add new composite primary key\n await client.query(`\n ALTER TABLE lattice_assistants \n ADD PRIMARY KEY (tenant_id, id)\n `);\n\n console.log('Primary key changed successfully to (tenant_id, id)');\n }\n },\n down: async (client: PoolClient) => {\n // Reverting this is complex and potentially dangerous\n // as it would require ensuring no duplicate IDs across tenants\n console.warn('Down migration for changeAssistantPrimaryKey is not supported');\n },\n};\n","/**\n * PostgreSQL implementation of ScheduleStorage\n *\n * Provides persistent storage for scheduled tasks\n * Data survives service restarts\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n ScheduleStorage,\n ScheduledTaskDefinition,\n ScheduledTaskStatus,\n ScheduleExecutionType,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createScheduledTasksTable } from \"../migrations/schedule_migrations\";\nimport { addScheduleTenantId } from \"../migrations/schedule_tenant_migration\";\n\n/**\n * PostgreSQL ScheduleStorage options\n */\nexport interface PostgreSQLScheduleStorageOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * Database row type for scheduled tasks\n */\ninterface ScheduledTaskRow {\n task_id: string;\n task_type: string;\n tenant_id: string;\n payload: string | Record<string, any>;\n assistant_id: string | null;\n thread_id: string | null;\n execution_type: string;\n execute_at: Date | null;\n delay_ms: number | null;\n cron_expression: string | null;\n timezone: string | null;\n next_run_at: Date | null;\n last_run_at: Date | null;\n status: string;\n run_count: number;\n max_runs: number | null;\n retry_count: number;\n max_retries: number;\n last_error: string | null;\n created_at: Date;\n updated_at: Date;\n expires_at: Date | null;\n metadata: string | Record<string, any> | null;\n}\n\n/**\n * PostgreSQL implementation of ScheduleStorage\n */\nexport class PostgreSQLScheduleStorage implements ScheduleStorage {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n\n constructor(options: PostgreSQLScheduleStorageOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createScheduledTasksTable);\n this.migrationManager.register(addScheduleTenantId);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLScheduleStorage:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n */\n async dispose(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Save a new task\n */\n async save(task: ScheduledTaskDefinition): Promise<void> {\n await this.ensureInitialized();\n\n await this.pool.query(\n `\n INSERT INTO lattice_scheduled_tasks (\n task_id, task_type, tenant_id, payload, assistant_id, thread_id, execution_type,\n execute_at, delay_ms, cron_expression, timezone,\n next_run_at, last_run_at, status, run_count, max_runs,\n retry_count, max_retries, last_error,\n created_at, updated_at, expires_at, metadata\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7,\n $8, $9, $10, $11,\n $12, $13, $14, $15, $16,\n $17, $18, $19,\n $20, $21, $22, $23\n )\n ON CONFLICT (task_id) DO UPDATE SET\n task_type = EXCLUDED.task_type,\n tenant_id = EXCLUDED.tenant_id,\n payload = EXCLUDED.payload,\n assistant_id = EXCLUDED.assistant_id,\n thread_id = EXCLUDED.thread_id,\n execution_type = EXCLUDED.execution_type,\n execute_at = EXCLUDED.execute_at,\n delay_ms = EXCLUDED.delay_ms,\n cron_expression = EXCLUDED.cron_expression,\n timezone = EXCLUDED.timezone,\n next_run_at = EXCLUDED.next_run_at,\n last_run_at = EXCLUDED.last_run_at,\n status = EXCLUDED.status,\n run_count = EXCLUDED.run_count,\n max_runs = EXCLUDED.max_runs,\n retry_count = EXCLUDED.retry_count,\n max_retries = EXCLUDED.max_retries,\n last_error = EXCLUDED.last_error,\n updated_at = EXCLUDED.updated_at,\n expires_at = EXCLUDED.expires_at,\n metadata = EXCLUDED.metadata\n `,\n [\n task.taskId,\n task.taskType,\n task.tenantId,\n JSON.stringify(task.payload),\n task.assistantId ?? null,\n task.threadId ?? null,\n task.executionType,\n task.executeAt ? new Date(task.executeAt) : null,\n task.delayMs ?? null,\n task.cronExpression ?? null,\n task.timezone ?? null,\n task.nextRunAt ? new Date(task.nextRunAt) : null,\n task.lastRunAt ? new Date(task.lastRunAt) : null,\n task.status,\n task.runCount,\n task.maxRuns ?? null,\n task.retryCount,\n task.maxRetries,\n task.lastError ?? null,\n new Date(task.createdAt),\n new Date(task.updatedAt),\n task.expiresAt ? new Date(task.expiresAt) : null,\n task.metadata ? JSON.stringify(task.metadata) : null,\n ]\n );\n }\n\n /**\n * Get task by ID\n */\n async get(taskId: string): Promise<ScheduledTaskDefinition | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE task_id = $1`,\n [taskId]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToTask(result.rows[0]);\n }\n\n /**\n * Update task\n */\n async update(\n taskId: string,\n updates: Partial<ScheduledTaskDefinition>\n ): Promise<void> {\n await this.ensureInitialized();\n\n const setClauses: string[] = [];\n const values: any[] = [];\n let paramIndex = 1;\n\n // Build dynamic UPDATE query\n if (updates.taskType !== undefined) {\n setClauses.push(`task_type = $${paramIndex++}`);\n values.push(updates.taskType);\n }\n if (updates.payload !== undefined) {\n setClauses.push(`payload = $${paramIndex++}`);\n values.push(JSON.stringify(updates.payload));\n }\n if (updates.assistantId !== undefined) {\n setClauses.push(`assistant_id = $${paramIndex++}`);\n values.push(updates.assistantId);\n }\n if (updates.threadId !== undefined) {\n setClauses.push(`thread_id = $${paramIndex++}`);\n values.push(updates.threadId);\n }\n if (updates.executionType !== undefined) {\n setClauses.push(`execution_type = $${paramIndex++}`);\n values.push(updates.executionType);\n }\n if (updates.executeAt !== undefined) {\n setClauses.push(`execute_at = $${paramIndex++}`);\n values.push(updates.executeAt ? new Date(updates.executeAt) : null);\n }\n if (updates.delayMs !== undefined) {\n setClauses.push(`delay_ms = $${paramIndex++}`);\n values.push(updates.delayMs);\n }\n if (updates.cronExpression !== undefined) {\n setClauses.push(`cron_expression = $${paramIndex++}`);\n values.push(updates.cronExpression);\n }\n if (updates.timezone !== undefined) {\n setClauses.push(`timezone = $${paramIndex++}`);\n values.push(updates.timezone);\n }\n if (updates.nextRunAt !== undefined) {\n setClauses.push(`next_run_at = $${paramIndex++}`);\n values.push(updates.nextRunAt ? new Date(updates.nextRunAt) : null);\n }\n if (updates.lastRunAt !== undefined) {\n setClauses.push(`last_run_at = $${paramIndex++}`);\n values.push(updates.lastRunAt ? new Date(updates.lastRunAt) : null);\n }\n if (updates.status !== undefined) {\n setClauses.push(`status = $${paramIndex++}`);\n values.push(updates.status);\n }\n if (updates.runCount !== undefined) {\n setClauses.push(`run_count = $${paramIndex++}`);\n values.push(updates.runCount);\n }\n if (updates.maxRuns !== undefined) {\n setClauses.push(`max_runs = $${paramIndex++}`);\n values.push(updates.maxRuns);\n }\n if (updates.retryCount !== undefined) {\n setClauses.push(`retry_count = $${paramIndex++}`);\n values.push(updates.retryCount);\n }\n if (updates.maxRetries !== undefined) {\n setClauses.push(`max_retries = $${paramIndex++}`);\n values.push(updates.maxRetries);\n }\n if (updates.lastError !== undefined) {\n setClauses.push(`last_error = $${paramIndex++}`);\n values.push(updates.lastError);\n }\n if (updates.expiresAt !== undefined) {\n setClauses.push(`expires_at = $${paramIndex++}`);\n values.push(updates.expiresAt ? new Date(updates.expiresAt) : null);\n }\n if (updates.metadata !== undefined) {\n setClauses.push(`metadata = $${paramIndex++}`);\n values.push(updates.metadata ? JSON.stringify(updates.metadata) : null);\n }\n\n // Always update updated_at\n setClauses.push(`updated_at = $${paramIndex++}`);\n values.push(new Date());\n\n // Add taskId as the last parameter\n values.push(taskId);\n\n if (setClauses.length === 0) {\n return;\n }\n\n await this.pool.query(\n `UPDATE lattice_scheduled_tasks SET ${setClauses.join(\n \", \"\n )} WHERE task_id = $${paramIndex}`,\n values\n );\n }\n\n /**\n * Delete task\n */\n async delete(taskId: string): Promise<void> {\n await this.ensureInitialized();\n\n await this.pool.query(\n `DELETE FROM lattice_scheduled_tasks WHERE task_id = $1`,\n [taskId]\n );\n }\n\n /**\n * Get all active tasks (pending or paused)\n */\n async getActiveTasks(): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE status IN ($1, $2) ORDER BY created_at ASC`,\n [ScheduledTaskStatus.PENDING, ScheduledTaskStatus.PAUSED]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by type\n */\n async getTasksByType(taskType: string): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE task_type = $1 ORDER BY created_at DESC`,\n [taskType]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by status\n */\n async getTasksByStatus(\n status: ScheduledTaskStatus\n ): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE status = $1 ORDER BY created_at DESC`,\n [status]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by execution type\n */\n async getTasksByExecutionType(\n executionType: ScheduleExecutionType\n ): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE execution_type = $1 ORDER BY created_at DESC`,\n [executionType]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by assistant ID\n */\n async getTasksByAssistantId(\n assistantId: string\n ): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE assistant_id = $1 ORDER BY created_at DESC`,\n [assistantId]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by thread ID\n */\n async getTasksByThreadId(\n threadId: string\n ): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE thread_id = $1 ORDER BY created_at DESC`,\n [threadId]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get all tasks with optional filters\n */\n async getAllTasks(filters?: {\n tenantId?: string;\n status?: ScheduledTaskStatus;\n executionType?: ScheduleExecutionType;\n taskType?: string;\n assistantId?: string;\n threadId?: string;\n limit?: number;\n offset?: number;\n }): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const whereClauses: string[] = [];\n const values: any[] = [];\n let paramIndex = 1;\n\n // Always filter by tenantId if provided\n if (filters?.tenantId !== undefined) {\n whereClauses.push(`tenant_id = $${paramIndex++}`);\n values.push(filters.tenantId);\n }\n\n if (filters?.status !== undefined) {\n whereClauses.push(`status = $${paramIndex++}`);\n values.push(filters.status);\n }\n if (filters?.executionType !== undefined) {\n whereClauses.push(`execution_type = $${paramIndex++}`);\n values.push(filters.executionType);\n }\n if (filters?.taskType !== undefined) {\n whereClauses.push(`task_type = $${paramIndex++}`);\n values.push(filters.taskType);\n }\n if (filters?.assistantId !== undefined) {\n whereClauses.push(`assistant_id = $${paramIndex++}`);\n values.push(filters.assistantId);\n }\n if (filters?.threadId !== undefined) {\n whereClauses.push(`thread_id = $${paramIndex++}`);\n values.push(filters.threadId);\n }\n\n let query = `SELECT * FROM lattice_scheduled_tasks`;\n if (whereClauses.length > 0) {\n query += ` WHERE ${whereClauses.join(\" AND \")}`;\n }\n query += ` ORDER BY created_at DESC`;\n\n if (filters?.limit !== undefined) {\n query += ` LIMIT $${paramIndex++}`;\n values.push(filters.limit);\n }\n if (filters?.offset !== undefined) {\n query += ` OFFSET $${paramIndex++}`;\n values.push(filters.offset);\n }\n\n const result = await this.pool.query<ScheduledTaskRow>(query, values);\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Count tasks with optional filters\n */\n async countTasks(filters?: {\n tenantId?: string;\n status?: ScheduledTaskStatus;\n executionType?: ScheduleExecutionType;\n taskType?: string;\n assistantId?: string;\n threadId?: string;\n }): Promise<number> {\n await this.ensureInitialized();\n\n const whereClauses: string[] = [];\n const values: any[] = [];\n let paramIndex = 1;\n\n // Always filter by tenantId if provided\n if (filters?.tenantId !== undefined) {\n whereClauses.push(`tenant_id = $${paramIndex++}`);\n values.push(filters.tenantId);\n }\n\n if (filters?.status !== undefined) {\n whereClauses.push(`status = $${paramIndex++}`);\n values.push(filters.status);\n }\n if (filters?.executionType !== undefined) {\n whereClauses.push(`execution_type = $${paramIndex++}`);\n values.push(filters.executionType);\n }\n if (filters?.taskType !== undefined) {\n whereClauses.push(`task_type = $${paramIndex++}`);\n values.push(filters.taskType);\n }\n if (filters?.assistantId !== undefined) {\n whereClauses.push(`assistant_id = $${paramIndex++}`);\n values.push(filters.assistantId);\n }\n if (filters?.threadId !== undefined) {\n whereClauses.push(`thread_id = $${paramIndex++}`);\n values.push(filters.threadId);\n }\n\n let query = `SELECT COUNT(*) as count FROM lattice_scheduled_tasks`;\n if (whereClauses.length > 0) {\n query += ` WHERE ${whereClauses.join(\" AND \")}`;\n }\n\n const result = await this.pool.query<{ count: string }>(query, values);\n\n return parseInt(result.rows[0].count, 10);\n }\n\n /**\n * Delete completed/cancelled/failed tasks older than specified time\n */\n async deleteOldTasks(olderThanMs: number): Promise<number> {\n await this.ensureInitialized();\n\n const cutoff = new Date(Date.now() - olderThanMs);\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_scheduled_tasks \n WHERE status IN ($1, $2, $3) \n AND updated_at < $4\n `,\n [\n ScheduledTaskStatus.COMPLETED,\n ScheduledTaskStatus.CANCELLED,\n ScheduledTaskStatus.FAILED,\n cutoff,\n ]\n );\n\n return result.rowCount ?? 0;\n }\n\n /**\n * Map database row to ScheduledTaskDefinition\n */\n private mapRowToTask(row: ScheduledTaskRow): ScheduledTaskDefinition {\n return {\n taskId: row.task_id,\n taskType: row.task_type,\n tenantId: row.tenant_id,\n payload:\n typeof row.payload === \"string\"\n ? JSON.parse(row.payload)\n : row.payload || {},\n assistantId: row.assistant_id ?? undefined,\n threadId: row.thread_id ?? undefined,\n executionType: row.execution_type as ScheduleExecutionType,\n executeAt: row.execute_at ? row.execute_at.getTime() : undefined,\n delayMs: row.delay_ms ?? undefined,\n cronExpression: row.cron_expression ?? undefined,\n timezone: row.timezone ?? undefined,\n nextRunAt: row.next_run_at ? row.next_run_at.getTime() : undefined,\n lastRunAt: row.last_run_at ? row.last_run_at.getTime() : undefined,\n status: row.status as ScheduledTaskStatus,\n runCount: row.run_count,\n maxRuns: row.max_runs ?? undefined,\n retryCount: row.retry_count,\n maxRetries: row.max_retries,\n lastError: row.last_error ?? undefined,\n createdAt: row.created_at.getTime(),\n updatedAt: row.updated_at.getTime(),\n expiresAt: row.expires_at ? row.expires_at.getTime() : undefined,\n metadata:\n row.metadata === null\n ? undefined\n : typeof row.metadata === \"string\"\n ? JSON.parse(row.metadata)\n : row.metadata,\n };\n }\n}\n","/**\n * PostgreSQL migrations for scheduled tasks table\n */\n\nimport { Migration } from \"./migration\";\n\n/**\n * Create the scheduled_tasks table\n */\nexport const createScheduledTasksTable: Migration = {\n name: \"create_scheduled_tasks_table\",\n version: 2,\n\n up: async (client) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_scheduled_tasks (\n -- Primary key\n task_id VARCHAR(255) PRIMARY KEY,\n \n -- Task type (maps to handler)\n task_type VARCHAR(255) NOT NULL,\n \n -- Payload (JSON-serializable data)\n payload JSONB NOT NULL DEFAULT '{}',\n \n -- Context fields for querying\n assistant_id VARCHAR(255),\n thread_id VARCHAR(255),\n \n -- Execution type: 'once' or 'cron'\n execution_type VARCHAR(50) NOT NULL,\n \n -- For ONCE type\n execute_at TIMESTAMPTZ,\n delay_ms BIGINT,\n \n -- For CRON type\n cron_expression VARCHAR(255),\n timezone VARCHAR(100),\n next_run_at TIMESTAMPTZ,\n last_run_at TIMESTAMPTZ,\n \n -- Status\n status VARCHAR(50) NOT NULL DEFAULT 'pending',\n \n -- Execution tracking\n run_count INTEGER NOT NULL DEFAULT 0,\n max_runs INTEGER,\n \n -- Error handling\n retry_count INTEGER NOT NULL DEFAULT 0,\n max_retries INTEGER NOT NULL DEFAULT 0,\n last_error TEXT,\n \n -- Timestamps\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n expires_at TIMESTAMPTZ,\n \n -- Metadata\n metadata JSONB\n );\n\n -- Index for querying active tasks\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_status \n ON lattice_scheduled_tasks (status);\n \n -- Index for querying by task type\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_task_type \n ON lattice_scheduled_tasks (task_type);\n \n -- Index for querying by execution type\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_execution_type \n ON lattice_scheduled_tasks (execution_type);\n \n -- Index for querying by assistant ID\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_assistant_id \n ON lattice_scheduled_tasks (assistant_id)\n WHERE assistant_id IS NOT NULL;\n \n -- Index for querying by thread ID\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_thread_id \n ON lattice_scheduled_tasks (thread_id)\n WHERE thread_id IS NOT NULL;\n \n -- Index for querying pending tasks by next run time\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_next_run \n ON lattice_scheduled_tasks (next_run_at) \n WHERE status = 'pending';\n \n -- Index for querying pending one-time tasks by execute time\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_execute_at \n ON lattice_scheduled_tasks (execute_at) \n WHERE status = 'pending' AND execution_type = 'once';\n \n -- Index for cleanup queries (old completed/cancelled tasks)\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_cleanup \n ON lattice_scheduled_tasks (updated_at) \n WHERE status IN ('completed', 'cancelled', 'failed');\n `);\n },\n\n down: async (client) => {\n await client.query(`\n DROP INDEX IF EXISTS idx_scheduled_tasks_cleanup;\n DROP INDEX IF EXISTS idx_scheduled_tasks_execute_at;\n DROP INDEX IF EXISTS idx_scheduled_tasks_next_run;\n DROP INDEX IF EXISTS idx_scheduled_tasks_thread_id;\n DROP INDEX IF EXISTS idx_scheduled_tasks_assistant_id;\n DROP INDEX IF EXISTS idx_scheduled_tasks_execution_type;\n DROP INDEX IF EXISTS idx_scheduled_tasks_task_type;\n DROP INDEX IF EXISTS idx_scheduled_tasks_status;\n DROP TABLE IF EXISTS lattice_scheduled_tasks;\n `);\n },\n};\n","/**\n * Schedule table tenant isolation migration\n * Adds tenant_id column to lattice_scheduled_tasks table\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add tenant_id column to scheduled tasks table\n */\nexport const addScheduleTenantId: Migration = {\n version: 18,\n name: \"add_schedule_tenant_id\",\n up: async (client: PoolClient) => {\n // Add tenant_id column\n await client.query(`\n ALTER TABLE lattice_scheduled_tasks\n ADD COLUMN IF NOT EXISTS tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_scheduled_tasks \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL after setting defaults\n await client.query(`\n ALTER TABLE lattice_scheduled_tasks\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the default constraint\n await client.query(`\n ALTER TABLE lattice_scheduled_tasks\n ALTER COLUMN tenant_id DROP DEFAULT\n `);\n\n // Create index for tenant-based queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_tenant_id \n ON lattice_scheduled_tasks(tenant_id)\n `);\n\n // Create composite index for common tenant+assistant queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_tenant_assistant \n ON lattice_scheduled_tasks(tenant_id, assistant_id)\n WHERE assistant_id IS NOT NULL\n `);\n\n // Create composite index for common tenant+thread queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_tenant_thread \n ON lattice_scheduled_tasks(tenant_id, thread_id)\n WHERE thread_id IS NOT NULL\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_scheduled_tasks_tenant_thread\"\n );\n await client.query(\n \"DROP INDEX IF EXISTS idx_scheduled_tasks_tenant_assistant\"\n );\n await client.query(\n \"DROP INDEX IF EXISTS idx_scheduled_tasks_tenant_id\"\n );\n await client.query(\n \"ALTER TABLE lattice_scheduled_tasks DROP COLUMN IF EXISTS tenant_id\"\n );\n },\n};\n","/**\n * PostgreSQL implementation of SkillStore with tenant isolation\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n SkillStore,\n Skill,\n CreateSkillRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createSkillsTable } from \"../migrations/skill_migrations\";\nimport { addSkillTenantId } from \"../migrations/skill_tenant_migration\";\nimport { changeSkillPrimaryKey } from \"../migrations/skill_pk_migration\";\n\nexport interface PostgreSQLSkillStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of SkillStore with tenant isolation\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n */\nexport class PostgreSQLSkillStore implements SkillStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLSkillStoreOptions) {\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createSkillsTable);\n this.migrationManager.register(addSkillTenantId);\n this.migrationManager.register(changeSkillPrimaryKey);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLSkillStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Skill object\n */\n private mapRowToSkill(row: {\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }): Skill {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n name: row.name,\n description: row.description,\n license: row.license || undefined,\n compatibility: row.compatibility || undefined,\n metadata: row.metadata || {},\n content: row.content || undefined,\n subSkills: Array.isArray(row.sub_skills) ? row.sub_skills : undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Get all skills for a tenant\n */\n async getAllSkills(tenantId: string): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n\n /**\n * Get skill by ID for a tenant\n */\n async getSkillById(tenantId: string, id: string): Promise<Skill | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToSkill(result.rows[0]);\n }\n\n /**\n * Create a new skill for a tenant\n */\n async createSkill(\n tenantId: string,\n id: string,\n data: CreateSkillRequest\n ): Promise<Skill> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_skills (id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n ON CONFLICT (id) DO UPDATE SET\n tenant_id = EXCLUDED.tenant_id,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n license = EXCLUDED.license,\n compatibility = EXCLUDED.compatibility,\n metadata = EXCLUDED.metadata,\n content = EXCLUDED.content,\n sub_skills = EXCLUDED.sub_skills,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.name,\n data.description,\n data.license || null,\n data.compatibility || null,\n JSON.stringify(data.metadata || {}),\n data.content || null,\n JSON.stringify(data.subSkills || []),\n now,\n now,\n ]\n );\n\n return {\n id,\n tenantId,\n name: data.name,\n description: data.description,\n license: data.license,\n compatibility: data.compatibility,\n metadata: data.metadata || {},\n content: data.content,\n subSkills: data.subSkills,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing skill for a tenant\n */\n async updateSkill(\n tenantId: string,\n id: string,\n updates: Partial<CreateSkillRequest>\n ): Promise<Skill | null> {\n await this.ensureInitialized();\n\n // Get existing skill\n const existing = await this.getSkillById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description);\n }\n\n if (updates.license !== undefined) {\n updateFields.push(`license = $${paramIndex++}`);\n updateValues.push(updates.license || null);\n }\n\n if (updates.compatibility !== undefined) {\n updateFields.push(`compatibility = $${paramIndex++}`);\n updateValues.push(updates.compatibility || null);\n }\n\n if (updates.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.metadata || {}));\n }\n\n if (updates.content !== undefined) {\n updateFields.push(`content = $${paramIndex++}`);\n updateValues.push(updates.content || null);\n }\n\n if (updates.subSkills !== undefined) {\n updateFields.push(`sub_skills = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.subSkills || []));\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add tenant_id and id for WHERE clause\n updateValues.push(tenantId);\n updateValues.push(id);\n\n await this.pool.query(\n `\n UPDATE lattice_skills\n SET ${updateFields.join(\", \")}\n WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex}\n `,\n updateValues\n );\n\n // Return updated skill\n return await this.getSkillById(tenantId, id);\n }\n\n /**\n * Delete a skill by ID for a tenant\n */\n async deleteSkill(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_skills\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if skill exists for a tenant\n */\n async hasSkill(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_skills\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Search skills by metadata within a tenant\n */\n async searchByMetadata(\n tenantId: string,\n metadataKey: string,\n metadataValue: string\n ): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND metadata ->> $2 = $3\n ORDER BY created_at DESC\n `,\n [tenantId, metadataKey, metadataValue]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n\n /**\n * Filter skills by compatibility within a tenant\n */\n async filterByCompatibility(\n tenantId: string,\n compatibility: string\n ): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND compatibility = $2\n ORDER BY created_at DESC\n `,\n [tenantId, compatibility]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n\n /**\n * Filter skills by license within a tenant\n */\n async filterByLicense(\n tenantId: string,\n license: string\n ): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND license = $2\n ORDER BY created_at DESC\n `,\n [tenantId, license]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n\n /**\n * Get sub-skills of a parent skill within a tenant\n * Note: This searches for skills that have the parent skill name in their subSkills array\n */\n async getSubSkills(\n tenantId: string,\n parentSkillName: string\n ): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND sub_skills @> to_jsonb($2::text)\n ORDER BY created_at DESC\n `,\n [tenantId, JSON.stringify([parentSkillName])]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n}\n","/**\n * Skill table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create skills table\n */\nexport const createSkillsTable: Migration = {\n version: 4,\n name: \"create_skills_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_skills (\n id VARCHAR(255) PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n description TEXT NOT NULL,\n license VARCHAR(255),\n compatibility VARCHAR(255),\n metadata JSONB DEFAULT '{}',\n content TEXT,\n sub_skills JSONB DEFAULT '[]',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_name \n ON lattice_skills(name)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_license \n ON lattice_skills(license)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_compatibility \n ON lattice_skills(compatibility)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_created_at \n ON lattice_skills(created_at DESC)\n `);\n\n // Create GIN index for metadata JSONB queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_metadata \n ON lattice_skills USING GIN (metadata)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_metadata\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_compatibility\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_license\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_name\");\n await client.query(\"DROP TABLE IF EXISTS lattice_skills\");\n },\n};\n","/**\n * Skill table tenant isolation migration\n * Adds tenant_id column to lattice_skills table\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add tenant_id column to skills table\n */\nexport const addSkillTenantId: Migration = {\n version: 16,\n name: \"add_skill_tenant_id\",\n up: async (client: PoolClient) => {\n // Add tenant_id column\n await client.query(`\n ALTER TABLE lattice_skills\n ADD COLUMN IF NOT EXISTS tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_skills \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL after setting defaults\n await client.query(`\n ALTER TABLE lattice_skills\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the default constraint\n await client.query(`\n ALTER TABLE lattice_skills\n ALTER COLUMN tenant_id DROP DEFAULT\n `);\n\n // Create index for tenant-based queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_tenant_id \n ON lattice_skills(tenant_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_lattice_skills_tenant_id\"\n );\n await client.query(\n \"ALTER TABLE lattice_skills DROP COLUMN IF EXISTS tenant_id\"\n );\n },\n};\n","/**\n * Skill table primary key migration\n * Changes primary key from (id) to (tenant_id, id) for multi-tenancy\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Change skill table primary key to support multi-tenancy\n */\nexport const changeSkillPrimaryKey: Migration = {\n version: 17,\n name: \"change_skill_primary_key\",\n up: async (client: PoolClient) => {\n // Check if table exists\n const tableExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.tables \n WHERE table_name = 'lattice_skills'\n )\n `);\n\n if (!tableExists.rows[0].exists) {\n return;\n }\n\n // Check current primary key\n const pkResult = await client.query(`\n SELECT a.attname as column_name\n FROM pg_index i\n JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n WHERE i.indrelid = 'lattice_skills'::regclass\n AND i.indisprimary\n `);\n\n const pkColumns = pkResult.rows.map(row => row.column_name);\n \n // If primary key is already (tenant_id, id), nothing to do\n if (pkColumns.includes('tenant_id') && pkColumns.includes('id')) {\n console.log('Skill table primary key already correct (tenant_id, id)');\n return;\n }\n\n // If primary key is just (id), we need to change it\n if (pkColumns.length === 1 && pkColumns[0] === 'id') {\n console.log('Changing skill table primary key from (id) to (tenant_id, id)');\n \n // Check if tenant_id column exists\n const tenantIdExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.columns \n WHERE table_name = 'lattice_skills' \n AND column_name = 'tenant_id'\n )\n `);\n\n if (!tenantIdExists.rows[0].exists) {\n // Add tenant_id column if it doesn't exist\n await client.query(`\n ALTER TABLE lattice_skills\n ADD COLUMN tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n }\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_skills \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL\n await client.query(`\n ALTER TABLE lattice_skills\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the old primary key\n await client.query(`\n ALTER TABLE lattice_skills \n DROP CONSTRAINT IF EXISTS lattice_skills_pkey\n `);\n\n // Add new composite primary key\n await client.query(`\n ALTER TABLE lattice_skills \n ADD PRIMARY KEY (tenant_id, id)\n `);\n\n console.log('Skill table primary key changed successfully to (tenant_id, id)');\n }\n },\n down: async (client: PoolClient) => {\n console.warn('Down migration for changeSkillPrimaryKey is not supported');\n },\n};\n","/**\n * PostgreSQL implementation of DatabaseConfigStore\n */\n\nimport { Pool, PoolClient } from 'pg';\nimport type { PoolConfig } from 'pg';\nimport {\n DatabaseConfigStore,\n DatabaseConfigEntry,\n CreateDatabaseConfigRequest,\n UpdateDatabaseConfigRequest,\n DatabaseConfig,\n} from '@axiom-lattice/protocols';\nimport { MigrationManager } from '../migrations/migration';\nimport { createDatabaseConfigsTable } from '../migrations/database_config_migrations';\nimport { encrypt, decrypt } from '@axiom-lattice/core';\n\n/**\n * PostgreSQL DatabaseConfigStore options\n */\nexport interface PostgreSQLDatabaseConfigStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of DatabaseConfigStore\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n * - Automatic password encryption/decryption\n * - Unique constraint on (tenant_id, key)\n */\nexport class PostgreSQLDatabaseConfigStore implements DatabaseConfigStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLDatabaseConfigStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === 'string') {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createDatabaseConfigsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error('Failed to initialize PostgreSQLDatabaseConfigStore:', error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all database configurations for a tenant\n */\n async getAllConfigs(tenantId: string): Promise<DatabaseConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_database_configs\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get all database configurations across all tenants\n */\n async getAllConfigsWithoutTenant(): Promise<DatabaseConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_database_configs\n ORDER BY created_at DESC\n `\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get database configuration by ID\n */\n async getConfigById(tenantId: string, id: string): Promise<DatabaseConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_database_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Get database configuration by business key\n */\n async getConfigByKey(tenantId: string, key: string): Promise<DatabaseConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_database_configs\n WHERE tenant_id = $1 AND key = $2\n `,\n [tenantId, key]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Create a new database configuration\n */\n async createConfig(\n tenantId: string,\n id: string,\n data: CreateDatabaseConfigRequest\n ): Promise<DatabaseConfigEntry> {\n await this.ensureInitialized();\n\n const now = new Date();\n const nowString = now.toISOString();\n const configWithEncryptedPassword = this.encryptPasswordInConfig(data.config);\n\n await this.pool.query(\n `\n INSERT INTO lattice_database_configs (id, tenant_id, key, name, description, config, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7::timestamp, $8::timestamp)\n ON CONFLICT (tenant_id, id) DO UPDATE SET\n key = EXCLUDED.key,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n config = EXCLUDED.config,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.key,\n data.name || null,\n data.description || null,\n JSON.stringify(configWithEncryptedPassword),\n nowString,\n nowString,\n ]\n );\n\n return {\n id,\n tenantId,\n key: data.key,\n config: data.config,\n name: data.name,\n description: data.description,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing database configuration\n */\n async updateConfig(\n tenantId: string,\n id: string,\n updates: Partial<UpdateDatabaseConfigRequest>\n ): Promise<DatabaseConfigEntry | null> {\n await this.ensureInitialized();\n\n const existing = await this.getConfigById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update fields and values as key-value pairs for clarity\n const updateData: Record<string, any> = {};\n\n if (updates.key !== undefined) {\n updateData.key = updates.key;\n }\n\n if (updates.name !== undefined) {\n updateData.name = updates.name || null;\n }\n\n if (updates.description !== undefined) {\n updateData.description = updates.description || null;\n }\n\n if (updates.config !== undefined) {\n const configWithEncryptedPassword = this.encryptPasswordInConfig(updates.config);\n updateData.config = JSON.stringify(configWithEncryptedPassword);\n }\n\n if (Object.keys(updateData).length === 0) {\n return existing;\n }\n\n // Always update the updated_at timestamp\n updateData.updated_at = new Date().toISOString();\n\n // Build SQL with tenantId and id at fixed positions at the end\n const fields = Object.keys(updateData);\n const values = Object.values(updateData);\n \n // Add WHERE clause values at the end\n values.push(tenantId);\n values.push(id);\n\n // Build SET clause with numbered parameters\n const setClauses = fields.map((field, index) => {\n if (field === 'updated_at') {\n return `${field} = $${index + 1}::timestamp`;\n }\n return `${field} = $${index + 1}`;\n });\n\n // WHERE clause parameters are at the end\n const whereTenantIndex = fields.length + 1;\n const whereIdIndex = fields.length + 2;\n\n const sql = `\n UPDATE lattice_database_configs\n SET ${setClauses.join(', ')}\n WHERE tenant_id = $${whereTenantIndex} AND id = $${whereIdIndex}\n `;\n\n await this.pool.query(sql, values);\n\n return await this.getConfigById(tenantId, id);\n }\n\n /**\n * Delete a database configuration by ID\n */\n async deleteConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_database_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if configuration exists\n */\n async hasConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_database_configs\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Dispose resources and close the connection pool\n */\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to DatabaseConfigEntry object\n * Automatically decrypts password if present\n */\n private mapRowToEntry(row: {\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }): DatabaseConfigEntry {\n const config: DatabaseConfig = typeof row.config === 'string'\n ? JSON.parse(row.config)\n : row.config;\n\n // Decrypt password if present\n if (config.password) {\n try {\n config.password = decrypt(config.password);\n } catch (error) {\n console.error('Failed to decrypt database password:', error);\n throw new Error('Failed to decrypt database configuration');\n }\n }\n\n return {\n id: row.id,\n tenantId: row.tenant_id,\n key: row.key,\n config,\n name: row.name || undefined,\n description: row.description || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Encrypt password in config before storing\n */\n private encryptPasswordInConfig(config: DatabaseConfig): DatabaseConfig {\n const configCopy = { ...config };\n \n if (configCopy.password) {\n configCopy.password = encrypt(configCopy.password);\n }\n \n return configCopy;\n }\n}\n","/**\n * Database configuration table migrations\n */\n\nimport { PoolClient } from 'pg';\nimport { Migration } from './migration';\n\n/**\n * Initial migration: Create database configs table\n */\nexport const createDatabaseConfigsTable: Migration = {\n version: 4,\n name: 'create_database_configs_table',\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_database_configs (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n key VARCHAR(255) NOT NULL,\n name VARCHAR(255),\n description TEXT,\n config JSONB NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n \n PRIMARY KEY (tenant_id, id),\n CONSTRAINT uk_lattice_database_configs_tenant_key UNIQUE (tenant_id, key)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_database_configs_tenant_id \n ON lattice_database_configs(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_database_configs_key \n ON lattice_database_configs(key)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query('DROP INDEX IF EXISTS idx_lattice_database_configs_key');\n await client.query('DROP INDEX IF EXISTS idx_lattice_database_configs_tenant_id');\n await client.query('DROP TABLE IF EXISTS lattice_database_configs');\n },\n};\n","/**\n * PostgreSQL implementation of MetricsServerConfigStore\n */\n\nimport { Pool, PoolClient } from 'pg';\nimport type { PoolConfig } from 'pg';\nimport {\n MetricsServerConfigStore,\n MetricsServerConfigEntry,\n CreateMetricsServerConfigRequest,\n UpdateMetricsServerConfigRequest,\n MetricsServerConfig,\n} from '@axiom-lattice/protocols';\nimport { MigrationManager } from '../migrations/migration';\nimport { createMetricsConfigsTable } from '../migrations/metrics_config_migrations';\nimport { encrypt, decrypt } from '@axiom-lattice/core';\n\n/**\n * PostgreSQL MetricsServerConfigStore options\n */\nexport interface PostgreSQLMetricsServerConfigStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of MetricsServerConfigStore\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n * - Automatic apiKey and password encryption/decryption\n * - Unique constraint on (tenant_id, key)\n */\nexport class PostgreSQLMetricsServerConfigStore implements MetricsServerConfigStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLMetricsServerConfigStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === 'string') {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createMetricsConfigsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error('Failed to initialize PostgreSQLMetricsServerConfigStore:', error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all metrics server configurations for a tenant\n */\n async getAllConfigs(tenantId: string): Promise<MetricsServerConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_metrics_configs\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get all metrics server configurations across all tenants\n */\n async getAllConfigsWithoutTenant(): Promise<MetricsServerConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_metrics_configs\n ORDER BY created_at DESC\n `\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get metrics server configuration by ID\n */\n async getConfigById(tenantId: string, id: string): Promise<MetricsServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_metrics_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Get metrics server configuration by business key\n */\n async getConfigByKey(tenantId: string, key: string): Promise<MetricsServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_metrics_configs\n WHERE tenant_id = $1 AND key = $2\n `,\n [tenantId, key]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Create a new metrics server configuration\n */\n async createConfig(\n tenantId: string,\n id: string,\n data: CreateMetricsServerConfigRequest\n ): Promise<MetricsServerConfigEntry> {\n await this.ensureInitialized();\n\n const now = new Date();\n const nowString = now.toISOString();\n const configWithEncryptedSecrets = this.encryptSecretsInConfig(data.config);\n\n await this.pool.query(\n `\n INSERT INTO lattice_metrics_configs (id, tenant_id, key, name, description, config, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7::timestamp, $8::timestamp)\n ON CONFLICT (tenant_id, id) DO UPDATE SET\n key = EXCLUDED.key,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n config = EXCLUDED.config,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.key,\n data.name || null,\n data.description || null,\n JSON.stringify(configWithEncryptedSecrets),\n nowString,\n nowString,\n ]\n );\n\n return {\n id,\n tenantId,\n key: data.key,\n config: data.config,\n name: data.name,\n description: data.description,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing metrics server configuration\n */\n async updateConfig(\n tenantId: string,\n id: string,\n updates: Partial<UpdateMetricsServerConfigRequest>\n ): Promise<MetricsServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const existing = await this.getConfigById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update fields and values as key-value pairs for clarity\n const updateData: Record<string, any> = {};\n\n if (updates.key !== undefined) {\n updateData.key = updates.key;\n }\n\n if (updates.name !== undefined) {\n updateData.name = updates.name || null;\n }\n\n if (updates.description !== undefined) {\n updateData.description = updates.description || null;\n }\n\n if (updates.config !== undefined) {\n const configWithEncryptedSecrets = this.encryptSecretsInConfig(updates.config);\n updateData.config = JSON.stringify(configWithEncryptedSecrets);\n }\n\n if (Object.keys(updateData).length === 0) {\n return existing;\n }\n\n // Always update the updated_at timestamp\n updateData.updated_at = new Date().toISOString();\n\n // Build SQL with tenantId and id at fixed positions at the end\n const fields = Object.keys(updateData);\n const values = Object.values(updateData);\n \n // Add WHERE clause values at the end\n values.push(tenantId);\n values.push(id);\n\n // Build SET clause with numbered parameters\n const setClauses = fields.map((field, index) => {\n if (field === 'updated_at') {\n return `${field} = $${index + 1}::timestamp`;\n }\n return `${field} = $${index + 1}`;\n });\n\n // WHERE clause parameters are at the end\n const whereTenantIndex = fields.length + 1;\n const whereIdIndex = fields.length + 2;\n\n const sql = `\n UPDATE lattice_metrics_configs\n SET ${setClauses.join(', ')}\n WHERE tenant_id = $${whereTenantIndex} AND id = $${whereIdIndex}\n `;\n\n await this.pool.query(sql, values);\n\n return await this.getConfigById(tenantId, id);\n }\n\n /**\n * Delete a metrics server configuration by ID\n */\n async deleteConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_metrics_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if configuration exists\n */\n async hasConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_metrics_configs\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Dispose resources and close the connection pool\n */\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to MetricsServerConfigEntry object\n * Automatically decrypts apiKey and password if present\n */\n private mapRowToEntry(row: {\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }): MetricsServerConfigEntry {\n const config: MetricsServerConfig = typeof row.config === 'string'\n ? JSON.parse(row.config)\n : row.config;\n\n // Decrypt apiKey if present\n if (config.apiKey) {\n try {\n config.apiKey = decrypt(config.apiKey);\n } catch (error) {\n console.error('Failed to decrypt apiKey:', error);\n throw new Error('Failed to decrypt metrics server configuration');\n }\n }\n\n // Decrypt password if present\n if (config.password) {\n try {\n config.password = decrypt(config.password);\n } catch (error) {\n console.error('Failed to decrypt password:', error);\n throw new Error('Failed to decrypt metrics server configuration');\n }\n }\n\n return {\n id: row.id,\n tenantId: row.tenant_id,\n key: row.key,\n config,\n name: row.name || undefined,\n description: row.description || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Encrypt apiKey and password in config before storing\n */\n private encryptSecretsInConfig(config: MetricsServerConfig): MetricsServerConfig {\n const configCopy = { ...config };\n \n if (configCopy.apiKey) {\n configCopy.apiKey = encrypt(configCopy.apiKey);\n }\n \n if (configCopy.password) {\n configCopy.password = encrypt(configCopy.password);\n }\n \n return configCopy;\n }\n}\n","/**\n * Metrics server configuration table migrations\n */\n\nimport { PoolClient } from 'pg';\nimport { Migration } from './migration';\n\n/**\n * Initial migration: Create metrics configs table\n */\nexport const createMetricsConfigsTable: Migration = {\n version: 12,\n name: 'create_metrics_configs_table',\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_metrics_configs (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n key VARCHAR(255) NOT NULL,\n name VARCHAR(255),\n description TEXT,\n config JSONB NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n \n PRIMARY KEY (tenant_id, id),\n CONSTRAINT uk_lattice_metrics_configs_tenant_key UNIQUE (tenant_id, key)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_metrics_configs_tenant_id \n ON lattice_metrics_configs(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_metrics_configs_key \n ON lattice_metrics_configs(key)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query('DROP INDEX IF EXISTS idx_lattice_metrics_configs_key');\n await client.query('DROP INDEX IF EXISTS idx_lattice_metrics_configs_tenant_id');\n await client.query('DROP TABLE IF EXISTS lattice_metrics_configs');\n },\n};\n","/**\n * PostgreSQL implementation of McpServerConfigStore\n */\n\nimport { Pool } from 'pg';\nimport type { PoolConfig } from 'pg';\nimport {\n McpServerConfigStore,\n McpServerConfigEntry,\n CreateMcpServerConfigRequest,\n UpdateMcpServerConfigRequest,\n McpServerConfig,\n} from '@axiom-lattice/protocols';\nimport { MigrationManager } from '../migrations/migration';\nimport { createMcpServerConfigsTable } from '../migrations/mcp_server_config_migrations';\nimport { encrypt, decrypt } from '@axiom-lattice/core';\n\n/**\n * PostgreSQL McpServerConfigStore options\n */\nexport interface PostgreSQLMcpServerConfigStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of McpServerConfigStore\n *\n * Features:\n * - Multi-tenant isolation via tenant_id\n * - Automatic env encryption/decryption\n * - Unique constraint on (tenant_id, key)\n */\nexport class PostgreSQLMcpServerConfigStore implements McpServerConfigStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLMcpServerConfigStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === 'string') {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createMcpServerConfigsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error('Failed to initialize PostgreSQLMcpServerConfigStore:', error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all MCP server configurations for a tenant\n */\n async getAllConfigs(tenantId: string): Promise<McpServerConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at\n FROM lattice_mcp_server_configs\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get all MCP server configurations across all tenants\n */\n async getAllConfigsWithoutTenant(): Promise<McpServerConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at\n FROM lattice_mcp_server_configs\n ORDER BY created_at DESC\n `\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get MCP server configuration by ID\n */\n async getConfigById(tenantId: string, id: string): Promise<McpServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at\n FROM lattice_mcp_server_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Get MCP server configuration by business key\n */\n async getConfigByKey(tenantId: string, key: string): Promise<McpServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at\n FROM lattice_mcp_server_configs\n WHERE tenant_id = $1 AND key = $2\n `,\n [tenantId, key]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Create a new MCP server configuration\n */\n async createConfig(\n tenantId: string,\n id: string,\n data: CreateMcpServerConfigRequest\n ): Promise<McpServerConfigEntry> {\n await this.ensureInitialized();\n\n const now = new Date();\n const nowString = now.toISOString();\n const { config: configWithEncryptedEnv, isEnvEncrypted } = this.encryptEnvInConfig(data.config);\n\n await this.pool.query(\n `\n INSERT INTO lattice_mcp_server_configs (id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10::timestamp, $11::timestamp)\n ON CONFLICT (tenant_id, id) DO UPDATE SET\n key = EXCLUDED.key,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n config = EXCLUDED.config,\n selected_tools = EXCLUDED.selected_tools,\n is_env_encrypted = EXCLUDED.is_env_encrypted,\n status = EXCLUDED.status,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.key,\n data.name || null,\n data.description || null,\n JSON.stringify(configWithEncryptedEnv),\n data.selectedTools || [],\n isEnvEncrypted,\n 'disconnected',\n nowString,\n nowString,\n ]\n );\n\n return {\n id,\n tenantId,\n key: data.key,\n config: data.config,\n selectedTools: data.selectedTools || [],\n isEnvEncrypted,\n status: 'disconnected',\n name: data.name,\n description: data.description,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing MCP server configuration\n */\n async updateConfig(\n tenantId: string,\n id: string,\n updates: Partial<UpdateMcpServerConfigRequest>\n ): Promise<McpServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const existing = await this.getConfigById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update fields and values as key-value pairs for clarity\n const updateData: Record<string, any> = {};\n\n if (updates.key !== undefined) {\n updateData.key = updates.key;\n }\n\n if (updates.name !== undefined) {\n updateData.name = updates.name || null;\n }\n\n if (updates.description !== undefined) {\n updateData.description = updates.description || null;\n }\n\n if (updates.config !== undefined) {\n const { config: configWithEncryptedEnv, isEnvEncrypted } = this.encryptEnvInConfig(updates.config);\n updateData.config = JSON.stringify(configWithEncryptedEnv);\n updateData.is_env_encrypted = isEnvEncrypted;\n }\n\n if (updates.selectedTools !== undefined) {\n updateData.selected_tools = updates.selectedTools;\n }\n\n if (updates.status !== undefined) {\n updateData.status = updates.status;\n }\n\n if (Object.keys(updateData).length === 0) {\n return existing;\n }\n\n // Always update the updated_at timestamp\n updateData.updated_at = new Date().toISOString();\n\n // Build SQL with tenantId and id at fixed positions at the end\n const fields = Object.keys(updateData);\n const values = Object.values(updateData);\n\n // Add WHERE clause values at the end\n values.push(tenantId);\n values.push(id);\n\n // Build SET clause with numbered parameters\n const setClauses = fields.map((field, index) => {\n if (field === 'updated_at') {\n return `${field} = $${index + 1}::timestamp`;\n }\n return `${field} = $${index + 1}`;\n });\n\n // WHERE clause parameters are at the end\n const whereTenantIndex = fields.length + 1;\n const whereIdIndex = fields.length + 2;\n\n const sql = `\n UPDATE lattice_mcp_server_configs\n SET ${setClauses.join(', ')}\n WHERE tenant_id = $${whereTenantIndex} AND id = $${whereIdIndex}\n `;\n\n await this.pool.query(sql, values);\n\n return await this.getConfigById(tenantId, id);\n }\n\n /**\n * Delete a MCP server configuration by ID\n */\n async deleteConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_mcp_server_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if configuration exists\n */\n async hasConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_mcp_server_configs\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Dispose resources and close the connection pool\n */\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to McpServerConfigEntry object\n * Automatically decrypts env values if present\n */\n private mapRowToEntry(row: {\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }): McpServerConfigEntry {\n const config: McpServerConfig = typeof row.config === 'string'\n ? JSON.parse(row.config)\n : row.config;\n\n // Decrypt env values if present and encrypted\n if (config.env && row.is_env_encrypted) {\n try {\n const decryptedEnv: Record<string, string> = {};\n for (const [key, value] of Object.entries(config.env)) {\n decryptedEnv[key] = decrypt(value);\n }\n config.env = decryptedEnv;\n } catch (error) {\n console.error('Failed to decrypt MCP server env:', error);\n throw new Error('Failed to decrypt MCP server configuration');\n }\n }\n\n return {\n id: row.id,\n tenantId: row.tenant_id,\n key: row.key,\n config,\n selectedTools: row.selected_tools || [],\n isEnvEncrypted: row.is_env_encrypted,\n status: row.status as 'disconnected' | 'connected' | 'error',\n name: row.name || undefined,\n description: row.description || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Encrypt env values in config before storing\n */\n private encryptEnvInConfig(config: McpServerConfig): { config: McpServerConfig; isEnvEncrypted: boolean } {\n const configCopy = { ...config };\n let isEnvEncrypted = false;\n\n if (configCopy.env && Object.keys(configCopy.env).length > 0) {\n const encryptedEnv: Record<string, string> = {};\n for (const [key, value] of Object.entries(configCopy.env)) {\n encryptedEnv[key] = encrypt(value);\n }\n configCopy.env = encryptedEnv;\n isEnvEncrypted = true;\n }\n\n return { config: configCopy, isEnvEncrypted };\n }\n}\n","/**\n * MCP Server configuration table migrations\n */\n\nimport { PoolClient } from 'pg';\nimport { Migration } from './migration';\n\n/**\n * Migration: Create MCP server configs table\n */\nexport const createMcpServerConfigsTable: Migration = {\n version: 13, // Use next available version number\n name: 'create_mcp_server_configs_table',\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_mcp_server_configs (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n key VARCHAR(255) NOT NULL,\n name VARCHAR(255),\n description TEXT,\n config JSONB NOT NULL,\n selected_tools JSONB NOT NULL DEFAULT '[]',\n is_env_encrypted BOOLEAN NOT NULL DEFAULT FALSE,\n status VARCHAR(50) NOT NULL DEFAULT 'disconnected',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n \n PRIMARY KEY (tenant_id, id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_mcp_server_configs_tenant_id \n ON lattice_mcp_server_configs(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_mcp_server_configs_key \n ON lattice_mcp_server_configs(key)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_mcp_server_configs_status \n ON lattice_mcp_server_configs(status)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query('DROP INDEX IF EXISTS idx_lattice_mcp_server_configs_status');\n await client.query('DROP INDEX IF EXISTS idx_lattice_mcp_server_configs_key');\n await client.query('DROP INDEX IF EXISTS idx_lattice_mcp_server_configs_tenant_id');\n await client.query('DROP TABLE IF EXISTS lattice_mcp_server_configs');\n },\n};\n","/**\n * PostgreSQL implementation of WorkspaceStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n WorkspaceStore,\n Workspace,\n CreateWorkspaceRequest,\n UpdateWorkspaceRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createWorkspacesTable } from \"../migrations/workspace_migrations\";\n\n/**\n * PostgreSQL WorkspaceStore options\n */\nexport interface PostgreSQLWorkspaceStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of WorkspaceStore\n */\nexport class PostgreSQLWorkspaceStore implements WorkspaceStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n\n constructor(options: PostgreSQLWorkspaceStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createWorkspacesTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLWorkspaceStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Workspace object\n */\n private mapRowToWorkspace(row: {\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n storage_type: string;\n created_at: Date;\n updated_at: Date;\n }): Workspace {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n name: row.name,\n description: row.description || undefined,\n storageType: row.storage_type as Workspace[\"storageType\"],\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Get all workspaces for a tenant\n */\n async getAllWorkspaces(tenantId: string): Promise<Workspace[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n storage_type: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, storage_type, created_at, updated_at\n FROM lattice_workspaces\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map(this.mapRowToWorkspace);\n }\n\n /**\n * Get a workspace by ID for a specific tenant\n */\n async getWorkspaceById(tenantId: string, id: string): Promise<Workspace | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n storage_type: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, storage_type, created_at, updated_at\n FROM lattice_workspaces\n WHERE id = $1 AND tenant_id = $2\n `,\n [id, tenantId]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToWorkspace(result.rows[0]);\n }\n\n /**\n * Create a new workspace\n */\n async createWorkspace(\n tenantId: string,\n id: string,\n data: CreateWorkspaceRequest\n ): Promise<Workspace> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_workspaces (id, tenant_id, name, description, storage_type, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id, tenant_id) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n storage_type = EXCLUDED.storage_type,\n updated_at = EXCLUDED.updated_at\n `,\n [id, tenantId, data.name, data.description || null, data.storageType, now, now]\n );\n\n return {\n id,\n tenantId,\n name: data.name,\n description: data.description,\n storageType: data.storageType,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing workspace\n */\n async updateWorkspace(\n tenantId: string,\n id: string,\n updates: UpdateWorkspaceRequest\n ): Promise<Workspace | null> {\n await this.ensureInitialized();\n\n // Get existing workspace\n const existing = await this.getWorkspaceById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description || null);\n }\n\n if (updates.storageType !== undefined) {\n updateFields.push(`storage_type = $${paramIndex++}`);\n updateValues.push(updates.storageType);\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add id and tenant_id for WHERE clause\n updateValues.push(id);\n updateValues.push(tenantId);\n\n await this.pool.query(\n `\n UPDATE lattice_workspaces\n SET ${updateFields.join(\", \")}\n WHERE id = $${paramIndex} AND tenant_id = $${paramIndex + 1}\n `,\n updateValues\n );\n\n // Return updated workspace\n return await this.getWorkspaceById(tenantId, id);\n }\n\n /**\n * Delete a workspace by ID\n */\n async deleteWorkspace(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_workspaces\n WHERE id = $1 AND tenant_id = $2\n `,\n [id, tenantId]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n}\n","/**\n * Workspace table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create workspaces table\n */\nexport const createWorkspacesTable: Migration = {\n version: 5,\n name: \"create_workspaces_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_workspaces (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n name VARCHAR(255) NOT NULL,\n description TEXT,\n storage_type VARCHAR(50) NOT NULL DEFAULT 'sandbox',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id, tenant_id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_workspaces_tenant_id \n ON lattice_workspaces(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_workspaces_created_at \n ON lattice_workspaces(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_workspaces_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_workspaces_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_workspaces\");\n },\n};\n","/**\n * PostgreSQL implementation of ProjectStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n ProjectStore,\n Project,\n CreateProjectRequest,\n UpdateProjectRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createProjectsTable } from \"../migrations/project_migrations\";\n\n/**\n * PostgreSQL ProjectStore options\n */\nexport interface PostgreSQLProjectStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of ProjectStore\n */\nexport class PostgreSQLProjectStore implements ProjectStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n\n constructor(options: PostgreSQLProjectStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createProjectsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLProjectStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Project object\n */\n private mapRowToProject(row: {\n id: string;\n tenant_id: string;\n workspace_id: string;\n name: string;\n description: string | null;\n created_at: Date;\n updated_at: Date;\n }): Project {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n workspaceId: row.workspace_id,\n name: row.name,\n description: row.description || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Get all projects for a specific workspace\n */\n async getProjectsByWorkspace(tenantId: string, workspaceId: string): Promise<Project[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n workspace_id: string;\n name: string;\n description: string | null;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, workspace_id, name, description, created_at, updated_at\n FROM lattice_projects\n WHERE tenant_id = $1 AND workspace_id = $2\n ORDER BY created_at DESC\n `,\n [tenantId, workspaceId]\n );\n\n return result.rows.map(this.mapRowToProject);\n }\n\n /**\n * Get a project by ID for a specific tenant\n */\n async getProjectById(tenantId: string, id: string): Promise<Project | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n workspace_id: string;\n name: string;\n description: string | null;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, workspace_id, name, description, created_at, updated_at\n FROM lattice_projects\n WHERE id = $1 AND tenant_id = $2\n `,\n [id, tenantId]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToProject(result.rows[0]);\n }\n\n /**\n * Create a new project\n */\n async createProject(\n tenantId: string,\n workspaceId: string,\n id: string,\n data: CreateProjectRequest\n ): Promise<Project> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_projects (id, tenant_id, workspace_id, name, description, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id, tenant_id) DO UPDATE SET\n workspace_id = EXCLUDED.workspace_id,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n updated_at = EXCLUDED.updated_at\n `,\n [id, tenantId, workspaceId, data.name, data.description || null, now, now]\n );\n\n return {\n id,\n tenantId,\n workspaceId,\n name: data.name,\n description: data.description,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing project\n */\n async updateProject(\n tenantId: string,\n id: string,\n updates: UpdateProjectRequest\n ): Promise<Project | null> {\n await this.ensureInitialized();\n\n // Get existing project\n const existing = await this.getProjectById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description || null);\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add id and tenant_id for WHERE clause\n updateValues.push(id);\n updateValues.push(tenantId);\n\n await this.pool.query(\n `\n UPDATE lattice_projects\n SET ${updateFields.join(\", \")}\n WHERE id = $${paramIndex} AND tenant_id = $${paramIndex + 1}\n `,\n updateValues\n );\n\n // Return updated project\n return await this.getProjectById(tenantId, id);\n }\n\n /**\n * Delete a project by ID\n */\n async deleteProject(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_projects\n WHERE id = $1 AND tenant_id = $2\n `,\n [id, tenantId]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n}\n","/**\n * Project table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create projects table\n */\nexport const createProjectsTable: Migration = {\n version: 6,\n name: \"create_projects_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_projects (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n workspace_id VARCHAR(255) NOT NULL,\n name VARCHAR(255) NOT NULL,\n description TEXT,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id, tenant_id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_projects_tenant_id \n ON lattice_projects(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_projects_workspace_id \n ON lattice_projects(workspace_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_projects_created_at \n ON lattice_projects(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_projects_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_projects_workspace_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_projects_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_projects\");\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport { UserStore, User, CreateUserRequest, UpdateUserRequest } from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createUsersTable } from \"../migrations/user_migrations\";\nimport { addUserStatusColumn } from \"../migrations/user_status_migration\";\n\nexport interface PostgreSQLUserStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport class PostgreSQLUserStore implements UserStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n\n constructor(options: PostgreSQLUserStoreOptions) {\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createUsersTable);\n this.migrationManager.register(addUserStatusColumn);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLUserStore:\", error);\n throw error;\n });\n }\n }\n\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) await this.initialize();\n }\n\n private mapRowToUser(row: {\n id: string;\n email: string;\n name: string;\n status: string;\n metadata: Record<string, any>;\n created_at: Date;\n updated_at: Date;\n }): User {\n return {\n id: row.id,\n email: row.email,\n name: row.name,\n status: row.status as import(\"@axiom-lattice/protocols\").UserStatus,\n metadata: row.metadata,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n async getAllUsers(): Promise<User[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT id, email, name, status, metadata, created_at, updated_at\n FROM lattice_users\n ORDER BY created_at DESC\n `\n );\n\n return result.rows.map(this.mapRowToUser);\n }\n\n async getUserById(id: string): Promise<User | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT id, email, name, status, metadata, created_at, updated_at\n FROM lattice_users\n WHERE id = $1\n `,\n [id]\n );\n\n if (result.rows.length === 0) return null;\n return this.mapRowToUser(result.rows[0]);\n }\n\n async getUserByEmail(email: string): Promise<User | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT id, email, name, status, metadata, created_at, updated_at\n FROM lattice_users\n WHERE email = $1\n `,\n [email]\n );\n\n if (result.rows.length === 0) return null;\n return this.mapRowToUser(result.rows[0]);\n }\n\n async createUser(id: string, data: CreateUserRequest): Promise<User> {\n await this.ensureInitialized();\n\n const now = new Date();\n const metadata = data.metadata || {};\n const status = data.status || \"pending\";\n\n await this.pool.query(\n `\n INSERT INTO lattice_users (id, email, name, status, metadata, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id) DO UPDATE SET\n email = EXCLUDED.email,\n name = EXCLUDED.name,\n status = EXCLUDED.status,\n metadata = EXCLUDED.metadata,\n updated_at = EXCLUDED.updated_at\n `,\n [id, data.email, data.name, status, JSON.stringify(metadata), now, now]\n );\n\n return {\n id,\n email: data.email,\n name: data.name,\n status,\n metadata: data.metadata,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n async updateUser(id: string, updates: UpdateUserRequest): Promise<User | null> {\n await this.ensureInitialized();\n\n const existing = await this.getUserById(id);\n if (!existing) return null;\n\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.email !== undefined) {\n updateFields.push(`email = $${paramIndex++}`);\n updateValues.push(updates.email);\n }\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.status !== undefined) {\n updateFields.push(`status = $${paramIndex++}`);\n updateValues.push(updates.status);\n }\n\n if (updates.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.metadata));\n }\n\n if (updateFields.length === 0) return existing;\n\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n updateValues.push(id);\n\n await this.pool.query(\n `\n UPDATE lattice_users\n SET ${updateFields.join(\", \")}\n WHERE id = $${paramIndex}\n `,\n updateValues\n );\n\n return this.getUserById(id);\n }\n\n async deleteUser(id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `DELETE FROM lattice_users WHERE id = $1`,\n [id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n}\n","/**\n * User table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Create users table (multi-tenant refactor: removed tenant_id)\n */\nexport const createUsersTable: Migration = {\n version: 7,\n name: \"create_users_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_users (\n id VARCHAR(255) PRIMARY KEY,\n email VARCHAR(255) NOT NULL UNIQUE,\n name VARCHAR(255) NOT NULL,\n metadata JSONB DEFAULT '{}',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_users_email \n ON lattice_users(email)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_users_created_at \n ON lattice_users(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_users_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_users_email\");\n await client.query(\"DROP TABLE IF EXISTS lattice_users\");\n },\n};\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration to create lattice_users table with status support\n * Version 9: Adds status column to support user approval workflow\n */\nexport const addUserStatusColumn: Migration = {\n version: 9,\n name: \"add_user_status_column\",\n up: async (client: PoolClient) => {\n // Add status column if not exists\n await client.query(`\n ALTER TABLE lattice_users \n ADD COLUMN IF NOT EXISTS status VARCHAR(50) NOT NULL DEFAULT 'pending'\n `);\n \n // Create index on status for filtering\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_users_status \n ON lattice_users(tenant_id, status)\n `);\n \n // Migrate existing users to active status\n await client.query(`\n UPDATE lattice_users \n SET status = 'active' \n WHERE status = 'pending'\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(`\n DROP INDEX IF EXISTS idx_lattice_users_status\n `);\n await client.query(`\n ALTER TABLE lattice_users \n DROP COLUMN IF EXISTS status\n `);\n },\n};\n","/**\n * PostgreSQL implementation of TenantStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n TenantStore,\n Tenant,\n TenantStatus,\n CreateTenantRequest,\n UpdateTenantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createTenantsTable } from \"../migrations/tenant_migrations\";\n\n/**\n * PostgreSQL TenantStore options\n */\nexport interface PostgreSQLTenantStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of TenantStore\n * Tenant is a top-level entity with single column primary key\n */\nexport class PostgreSQLTenantStore implements TenantStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n\n constructor(options: PostgreSQLTenantStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createTenantsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLTenantStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Tenant object\n */\n private mapRowToTenant(row: {\n id: string;\n name: string;\n description: string | null;\n status: string;\n metadata: Record<string, any>;\n created_at: Date;\n updated_at: Date;\n }): Tenant {\n return {\n id: row.id,\n name: row.name,\n description: row.description || undefined,\n status: row.status as TenantStatus,\n metadata: row.metadata || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Get all tenants\n */\n async getAllTenants(): Promise<Tenant[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n name: string;\n description: string | null;\n status: string;\n metadata: Record<string, any>;\n created_at: Date;\n updated_at: Date;\n }>(`\n SELECT id, name, description, status, metadata, created_at, updated_at\n FROM lattice_tenants\n ORDER BY created_at DESC\n `);\n\n return result.rows.map(this.mapRowToTenant);\n }\n\n /**\n * Get a tenant by ID\n */\n async getTenantById(id: string): Promise<Tenant | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n name: string;\n description: string | null;\n status: string;\n metadata: Record<string, any>;\n created_at: Date;\n updated_at: Date;\n }>(`\n SELECT id, name, description, status, metadata, created_at, updated_at\n FROM lattice_tenants\n WHERE id = $1\n `, [id]);\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToTenant(result.rows[0]);\n }\n\n /**\n * Create a new tenant\n */\n async createTenant(\n id: string,\n data: CreateTenantRequest\n ): Promise<Tenant> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_tenants (id, name, description, status, metadata, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n status = EXCLUDED.status,\n metadata = EXCLUDED.metadata,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n data.name,\n data.description || null,\n data.status || \"active\",\n data.metadata || {},\n now,\n now,\n ]\n );\n\n return {\n id,\n name: data.name,\n description: data.description,\n status: data.status || \"active\",\n metadata: data.metadata,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing tenant\n */\n async updateTenant(\n id: string,\n updates: UpdateTenantRequest\n ): Promise<Tenant | null> {\n await this.ensureInitialized();\n\n // Get existing tenant\n const existing = await this.getTenantById(id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description || null);\n }\n\n if (updates.status !== undefined) {\n updateFields.push(`status = $${paramIndex++}`);\n updateValues.push(updates.status);\n }\n\n if (updates.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n updateValues.push(updates.metadata);\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add id for WHERE clause\n updateValues.push(id);\n\n await this.pool.query(\n `\n UPDATE lattice_tenants\n SET ${updateFields.join(\", \")}\n WHERE id = $${paramIndex}\n `,\n updateValues\n );\n\n // Return updated tenant\n return await this.getTenantById(id);\n }\n\n /**\n * Delete a tenant by ID\n */\n async deleteTenant(id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_tenants\n WHERE id = $1\n `,\n [id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n}\n","/**\n * Tenant table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Create tenants table\n * Tenant is a top-level entity with single column primary key\n */\nexport const createTenantsTable: Migration = {\n version: 8,\n name: \"create_tenants_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_tenants (\n id VARCHAR(255) PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n description TEXT,\n status VARCHAR(50) NOT NULL DEFAULT 'active',\n metadata JSONB DEFAULT '{}',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_tenants_status \n ON lattice_tenants(status)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_tenants_created_at \n ON lattice_tenants(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_tenants_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_tenants_status\");\n await client.query(\"DROP TABLE IF EXISTS lattice_tenants\");\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n UserTenantLinkStore,\n UserTenantLink,\n CreateUserTenantLinkRequest,\n UpdateUserTenantLinkRequest,\n UserTenantRole,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createUserTenantLinkTable, migrateRemoveTenantIdFromUsers } from \"../migrations/user_tenant_link_migrations\";\n\nexport interface PostgreSQLUserTenantLinkStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport class PostgreSQLUserTenantLinkStore implements UserTenantLinkStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n\n constructor(options: PostgreSQLUserTenantLinkStoreOptions) {\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createUserTenantLinkTable);\n this.migrationManager.register(migrateRemoveTenantIdFromUsers);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLUserTenantLinkStore:\", error);\n throw error;\n });\n }\n }\n\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) await this.initialize();\n }\n\n private mapRowToLink(row: {\n user_id: string;\n tenant_id: string;\n role: string;\n joined_at: Date;\n metadata: Record<string, any>;\n }): UserTenantLink {\n return {\n userId: row.user_id,\n tenantId: row.tenant_id,\n role: row.role as UserTenantRole,\n joinedAt: row.joined_at,\n metadata: row.metadata,\n };\n }\n\n async getTenantsByUser(userId: string): Promise<UserTenantLink[]> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n SELECT user_id, tenant_id, role, joined_at, metadata\n FROM lattice_user_tenant_links\n WHERE user_id = $1\n ORDER BY joined_at DESC\n `,\n [userId]\n );\n \n return result.rows.map(this.mapRowToLink);\n }\n\n async getUsersByTenant(tenantId: string): Promise<UserTenantLink[]> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n SELECT user_id, tenant_id, role, joined_at, metadata\n FROM lattice_user_tenant_links\n WHERE tenant_id = $1\n ORDER BY joined_at DESC\n `,\n [tenantId]\n );\n \n return result.rows.map(this.mapRowToLink);\n }\n\n async getLink(userId: string, tenantId: string): Promise<UserTenantLink | null> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n SELECT user_id, tenant_id, role, joined_at, metadata\n FROM lattice_user_tenant_links\n WHERE user_id = $1 AND tenant_id = $2\n `,\n [userId, tenantId]\n );\n \n if (result.rows.length === 0) return null;\n return this.mapRowToLink(result.rows[0]);\n }\n\n async createLink(data: CreateUserTenantLinkRequest): Promise<UserTenantLink> {\n await this.ensureInitialized();\n \n const now = new Date();\n const role = data.role || \"member\";\n const metadata = data.metadata || {};\n \n await this.pool.query(\n `\n INSERT INTO lattice_user_tenant_links (user_id, tenant_id, role, joined_at, metadata)\n VALUES ($1, $2, $3, $4, $5)\n ON CONFLICT (user_id, tenant_id) DO UPDATE SET\n role = EXCLUDED.role,\n metadata = EXCLUDED.metadata\n `,\n [data.userId, data.tenantId, role, now, JSON.stringify(metadata)]\n );\n \n return {\n userId: data.userId,\n tenantId: data.tenantId,\n role,\n joinedAt: now,\n metadata: data.metadata,\n };\n }\n\n async updateLink(\n userId: string,\n tenantId: string,\n updates: UpdateUserTenantLinkRequest\n ): Promise<UserTenantLink | null> {\n await this.ensureInitialized();\n \n const existing = await this.getLink(userId, tenantId);\n if (!existing) return null;\n \n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n \n if (updates.role !== undefined) {\n updateFields.push(`role = $${paramIndex++}`);\n updateValues.push(updates.role);\n }\n \n if (updates.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.metadata));\n }\n \n if (updateFields.length === 0) return existing;\n \n updateValues.push(userId, tenantId);\n \n await this.pool.query(\n `\n UPDATE lattice_user_tenant_links\n SET ${updateFields.join(\", \")}\n WHERE user_id = $${paramIndex} AND tenant_id = $${paramIndex + 1}\n `,\n updateValues\n );\n \n return this.getLink(userId, tenantId);\n }\n\n async deleteLink(userId: string, tenantId: string): Promise<boolean> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n DELETE FROM lattice_user_tenant_links\n WHERE user_id = $1 AND tenant_id = $2\n `,\n [userId, tenantId]\n );\n \n return result.rowCount !== null && result.rowCount > 0;\n }\n\n async hasLink(userId: string, tenantId: string): Promise<boolean> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_user_tenant_links\n WHERE user_id = $1 AND tenant_id = $2\n LIMIT 1\n `,\n [userId, tenantId]\n );\n \n return result.rows.length > 0;\n }\n}\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const createUserTenantLinkTable: Migration = {\n version: 10,\n name: \"create_user_tenant_link_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_user_tenant_links (\n user_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n role VARCHAR(50) NOT NULL DEFAULT 'member',\n joined_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n metadata JSONB DEFAULT '{}',\n PRIMARY KEY (user_id, tenant_id)\n )\n `);\n \n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_user_tenant_links_user_id \n ON lattice_user_tenant_links(user_id)\n `);\n \n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_user_tenant_links_tenant_id \n ON lattice_user_tenant_links(tenant_id)\n `);\n \n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_user_tenant_links_role \n ON lattice_user_tenant_links(tenant_id, role)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(`DROP TABLE IF EXISTS lattice_user_tenant_links`);\n },\n};\n\nexport const migrateRemoveTenantIdFromUsers: Migration = {\n version: 11,\n name: \"migrate_remove_tenant_id_from_users\",\n up: async (client: PoolClient) => {\n const hasTenantId = await client.query(`\n SELECT column_name \n FROM information_schema.columns \n WHERE table_name = 'lattice_users' AND column_name = 'tenant_id'\n `);\n \n if (hasTenantId.rows.length > 0) {\n await client.query(`\n INSERT INTO lattice_user_tenant_links (user_id, tenant_id, role, joined_at)\n SELECT id, tenant_id, 'member', created_at\n FROM lattice_users\n WHERE tenant_id IS NOT NULL\n ON CONFLICT (user_id, tenant_id) DO NOTHING\n `);\n \n await client.query(`\n ALTER TABLE lattice_users DROP COLUMN IF EXISTS tenant_id\n `);\n \n await client.query(`\n ALTER TABLE lattice_users DROP CONSTRAINT IF EXISTS lattice_users_pkey\n `);\n \n await client.query(`\n ALTER TABLE lattice_users ADD PRIMARY KEY (id)\n `);\n }\n },\n down: async (client: PoolClient) => {\n await client.query(`\n ALTER TABLE lattice_users ADD COLUMN IF NOT EXISTS tenant_id VARCHAR(255)\n `);\n },\n};\n","/**\n * Thread message queue migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Create thread message queue table\n */\nexport const createThreadMessageQueueTable: Migration = {\n version: 100,\n name: \"create_lattice_thread_message_queue_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_thread_message_queue (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n thread_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n assistant_id VARCHAR(255) NOT NULL,\n message_content JSONB NOT NULL,\n message_type VARCHAR(50) DEFAULT 'human',\n sequence_order INTEGER NOT NULL,\n status VARCHAR(50) DEFAULT 'pending',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_thread \n ON lattice_thread_message_queue(thread_id, status)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_tenant \n ON lattice_thread_message_queue(tenant_id, thread_id, status)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_status \n ON lattice_thread_message_queue(status, created_at)\n `);\n\n // Index for sequence order per thread (for ordering, not unique constraint)\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_sequence \n ON lattice_thread_message_queue(thread_id, sequence_order)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_sequence\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_status\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_tenant\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_thread\");\n await client.query(\"DROP TABLE IF EXISTS lattice_thread_message_queue\");\n },\n};\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const createChannelIdentityMappingTables: Migration = {\n version: 20,\n name: \"create_channel_identity_mapping_tables\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS channel_identity_mappings (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n channel VARCHAR(50) NOT NULL,\n channel_app_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n assistant_id VARCHAR(255) NOT NULL,\n mapping_mode VARCHAR(20) NOT NULL CHECK (mapping_mode IN ('user', 'group', 'hybrid')),\n external_subject_type VARCHAR(20) NOT NULL CHECK (external_subject_type IN ('user', 'chat')),\n external_subject_key VARCHAR(512) NOT NULL,\n lark_open_id VARCHAR(255),\n lark_chat_id VARCHAR(255) NOT NULL,\n lark_message_id VARCHAR(255),\n thread_id VARCHAR(255) NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n last_activity_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n UNIQUE (channel, channel_app_id, tenant_id, assistant_id, external_subject_key)\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_channel_identity_lookup\n ON channel_identity_mappings(channel, channel_app_id, tenant_id, assistant_id, external_subject_key)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_channel_identity_thread\n ON channel_identity_mappings(thread_id, tenant_id)\n `);\n\n await client.query(`\n CREATE TABLE IF NOT EXISTS channel_inbound_message_receipts (\n channel VARCHAR(50) NOT NULL,\n channel_app_id VARCHAR(255) NOT NULL,\n external_message_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n status VARCHAR(20) NOT NULL DEFAULT 'processing' CHECK (status IN ('processing', 'completed', 'failed')),\n thread_id VARCHAR(255),\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (channel, channel_app_id, external_message_id)\n )\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP TABLE IF EXISTS channel_inbound_message_receipts\");\n await client.query(\"DROP INDEX IF EXISTS idx_channel_identity_thread\");\n await client.query(\"DROP INDEX IF EXISTS idx_channel_identity_lookup\");\n await client.query(\"DROP TABLE IF EXISTS channel_identity_mappings\");\n },\n};\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const createChannelInstallationsTable: Migration = {\n version: 21,\n name: \"create_channel_installations_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_channel_installations (\n id UUID PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n channel VARCHAR(50) NOT NULL,\n name VARCHAR(255),\n config JSONB NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_channel_installations_tenant_channel\n ON lattice_channel_installations(tenant_id, channel)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_channel_installations_tenant_channel\",\n );\n await client.query(\"DROP TABLE IF EXISTS lattice_channel_installations\");\n },\n};\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const alterChannelInstallationsTable: Migration = {\n version: 109,\n name: \"alter_channel_installations_add_columns\",\n up: async (client: PoolClient) => {\n await client.query(`\n ALTER TABLE lattice_channel_installations\n ADD COLUMN IF NOT EXISTS enabled BOOLEAN NOT NULL DEFAULT true\n `);\n await client.query(`\n ALTER TABLE lattice_channel_installations\n ADD COLUMN IF NOT EXISTS fallback_agent_id VARCHAR(255)\n `);\n await client.query(`\n ALTER TABLE lattice_channel_installations\n ADD COLUMN IF NOT EXISTS reject_when_no_binding BOOLEAN NOT NULL DEFAULT true\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"ALTER TABLE lattice_channel_installations DROP COLUMN IF EXISTS reject_when_no_binding\",\n );\n await client.query(\n \"ALTER TABLE lattice_channel_installations DROP COLUMN IF EXISTS fallback_agent_id\",\n );\n await client.query(\n \"ALTER TABLE lattice_channel_installations DROP COLUMN IF EXISTS enabled\",\n );\n },\n};\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const createChannelBindingsTable: Migration = {\n version: 110,\n name: \"create_channel_bindings_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_channel_bindings (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n channel VARCHAR(50) NOT NULL,\n channel_installation_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n sender_id VARCHAR(255) NOT NULL,\n agent_id VARCHAR(255) NOT NULL,\n thread_id VARCHAR(255),\n workspace_id VARCHAR(255),\n project_id VARCHAR(255),\n thread_mode VARCHAR(20) NOT NULL DEFAULT 'fixed'\n CHECK (thread_mode IN ('fixed', 'per_conversation')),\n sender_display_name VARCHAR(255),\n sender_metadata JSONB,\n enabled BOOLEAN NOT NULL DEFAULT true,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMP NOT NULL DEFAULT NOW(),\n UNIQUE (channel, channel_installation_id, tenant_id, sender_id)\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_channel_bindings_lookup\n ON lattice_channel_bindings(channel, channel_installation_id, tenant_id, sender_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_channel_bindings_agent\n ON lattice_channel_bindings(agent_id, tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_channel_bindings_enabled\n ON lattice_channel_bindings(enabled)\n WHERE enabled = true\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP TABLE IF EXISTS lattice_channel_bindings\");\n },\n};\n","/**\n * PostgreSQL migrations for workflow tracking tables\n */\n\nimport { Migration } from \"./migration\";\n\nexport const createWorkflowTrackingTables: Migration = {\n name: \"create_workflow_tracking_tables\",\n version: 103,\n\n up: async (client) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_workflow_runs (\n id VARCHAR(255) PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n assistant_id VARCHAR(255) NOT NULL,\n thread_id VARCHAR(255) NOT NULL,\n status VARCHAR(50) NOT NULL DEFAULT 'running',\n topology_edges JSONB NOT NULL DEFAULT '[]',\n total_edges INTEGER NOT NULL DEFAULT 0,\n completed_edges INTEGER NOT NULL DEFAULT 0,\n error_message TEXT,\n metadata JSONB DEFAULT '{}',\n started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n completed_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n );\n\n CREATE TABLE IF NOT EXISTS lattice_workflow_steps (\n id VARCHAR(255) NOT NULL,\n run_id VARCHAR(255) NOT NULL REFERENCES lattice_workflow_runs(id) ON DELETE CASCADE,\n tenant_id VARCHAR(255) NOT NULL,\n step_type VARCHAR(50) NOT NULL,\n step_name VARCHAR(255) NOT NULL,\n edge_from VARCHAR(255),\n edge_to VARCHAR(255),\n edge_purpose TEXT,\n input JSONB,\n output JSONB,\n status VARCHAR(50) NOT NULL DEFAULT 'running',\n error_message TEXT,\n started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n completed_at TIMESTAMPTZ,\n duration_ms INTEGER,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n PRIMARY KEY (id, run_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_workflow_runs_tenant\n ON lattice_workflow_runs (tenant_id);\n CREATE INDEX IF NOT EXISTS idx_workflow_runs_thread\n ON lattice_workflow_runs (tenant_id, thread_id);\n CREATE INDEX IF NOT EXISTS idx_workflow_runs_assistant\n ON lattice_workflow_runs (tenant_id, assistant_id);\n CREATE INDEX IF NOT EXISTS idx_workflow_runs_status\n ON lattice_workflow_runs (status);\n\n CREATE INDEX IF NOT EXISTS idx_workflow_steps_run\n ON lattice_workflow_steps (run_id);\n CREATE INDEX IF NOT EXISTS idx_workflow_steps_type_status\n ON lattice_workflow_steps (run_id, step_type, status);\n `);\n },\n\n down: async (client) => {\n await client.query(`\n DROP INDEX IF EXISTS idx_workflow_steps_type_status;\n DROP INDEX IF EXISTS idx_workflow_steps_run;\n DROP INDEX IF EXISTS idx_workflow_runs_status;\n DROP INDEX IF EXISTS idx_workflow_runs_assistant;\n DROP INDEX IF EXISTS idx_workflow_runs_thread;\n DROP INDEX IF EXISTS idx_workflow_runs_tenant;\n DROP TABLE IF EXISTS lattice_workflow_steps;\n DROP TABLE IF EXISTS lattice_workflow_runs;\n `);\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport type {\n Binding,\n BindingRegistry,\n CreateBindingInput,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createChannelBindingsTable } from \"../migrations/channel_bindings_migration\";\n\nexport interface ChannelBindingStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\ntype BindingRow = {\n id: string;\n channel: string;\n channel_installation_id: string;\n tenant_id: string;\n sender_id: string;\n agent_id: string;\n thread_id: string | null;\n workspace_id: string | null;\n project_id: string | null;\n thread_mode: \"fixed\" | \"per_conversation\";\n sender_display_name: string | null;\n sender_metadata: Record<string, unknown> | null;\n enabled: boolean;\n created_at: Date;\n updated_at: Date;\n};\n\nexport class ChannelBindingStore implements BindingRegistry {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: ChannelBindingStoreOptions) {\n this.pool =\n typeof options.poolConfig === \"string\"\n ? new Pool({ connectionString: options.poolConfig })\n : new Pool(options.poolConfig);\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createChannelBindingsTable);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize ChannelBindingStore:\", error);\n throw error;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n if (this.initPromise) return this.initPromise;\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n return this.initPromise;\n }\n\n async resolve(params: {\n channel: string;\n senderId: string;\n channelInstallationId: string;\n tenantId: string;\n }): Promise<Binding | null> {\n await this.ensureInitialized();\n const result = await this.pool.query<BindingRow>(\n `SELECT * FROM lattice_channel_bindings\n WHERE channel = $1\n AND sender_id = $2\n AND channel_installation_id = $3\n AND tenant_id = $4\n AND enabled = true\n LIMIT 1`,\n [params.channel, params.senderId, params.channelInstallationId, params.tenantId],\n );\n if (result.rows.length === 0) return null;\n return this.mapRowToBinding(result.rows[0]);\n }\n\n async create(input: CreateBindingInput): Promise<Binding> {\n await this.ensureInitialized();\n const result = await this.pool.query<BindingRow>(\n `INSERT INTO lattice_channel_bindings\n (channel, channel_installation_id, tenant_id, sender_id, agent_id,\n thread_mode, sender_display_name, sender_metadata, workspace_id, project_id)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n RETURNING *`,\n [\n input.channel,\n input.channelInstallationId,\n input.tenantId,\n input.senderId,\n input.agentId,\n input.threadMode || \"fixed\",\n input.senderDisplayName || null,\n input.senderMetadata ? JSON.stringify(input.senderMetadata) : null,\n input.workspaceId || null,\n input.projectId || null,\n ],\n );\n return this.mapRowToBinding(result.rows[0]);\n }\n\n async update(id: string, patch: Partial<Binding>): Promise<Binding> {\n await this.ensureInitialized();\n const existing = await this.pool.query<BindingRow>(\n `SELECT * FROM lattice_channel_bindings WHERE id = $1`,\n [id],\n );\n if (existing.rows.length === 0) {\n throw new Error(`Binding ${id} not found`);\n }\n\n const row = existing.rows[0];\n const updated = {\n channel: patch.channel ?? row.channel,\n channel_installation_id: patch.channelInstallationId ?? row.channel_installation_id,\n sender_id: patch.senderId ?? row.sender_id,\n agent_id: patch.agentId ?? row.agent_id,\n thread_id: patch.threadId !== undefined ? patch.threadId : row.thread_id,\n workspace_id: patch.workspaceId !== undefined ? patch.workspaceId : row.workspace_id,\n project_id: patch.projectId !== undefined ? patch.projectId : row.project_id,\n thread_mode: patch.threadMode ?? row.thread_mode,\n sender_display_name: patch.senderDisplayName !== undefined\n ? patch.senderDisplayName : row.sender_display_name,\n sender_metadata: patch.senderMetadata !== undefined\n ? patch.senderMetadata : row.sender_metadata,\n enabled: patch.enabled ?? row.enabled,\n };\n\n const result = await this.pool.query<BindingRow>(\n `UPDATE lattice_channel_bindings SET\n channel = $1, channel_installation_id = $2, sender_id = $3,\n agent_id = $4, thread_id = $5, workspace_id = $6, project_id = $7,\n thread_mode = $8, sender_display_name = $9, sender_metadata = $10,\n enabled = $11, updated_at = NOW()\n WHERE id = $12\n RETURNING *`,\n [\n updated.channel, updated.channel_installation_id, updated.sender_id,\n updated.agent_id, updated.thread_id, updated.workspace_id,\n updated.project_id, updated.thread_mode, updated.sender_display_name,\n updated.sender_metadata ? JSON.stringify(updated.sender_metadata) : null,\n updated.enabled, id,\n ],\n );\n return this.mapRowToBinding(result.rows[0]);\n }\n\n async delete(id: string): Promise<void> {\n await this.ensureInitialized();\n await this.pool.query(`DELETE FROM lattice_channel_bindings WHERE id = $1`, [id]);\n }\n\n async list(params: {\n channel?: string;\n agentId?: string;\n tenantId: string;\n channelInstallationId?: string;\n limit?: number;\n offset?: number;\n }): Promise<Binding[]> {\n await this.ensureInitialized();\n const conditions: string[] = [\"tenant_id = $1\"];\n const values: unknown[] = [params.tenantId];\n let idx = 2;\n\n if (params.channel) {\n conditions.push(`channel = $${idx++}`);\n values.push(params.channel);\n }\n if (params.agentId) {\n conditions.push(`agent_id = $${idx++}`);\n values.push(params.agentId);\n }\n if (params.channelInstallationId) {\n conditions.push(`channel_installation_id = $${idx++}`);\n values.push(params.channelInstallationId);\n }\n\n const limit = params.limit ?? 50;\n const offset = params.offset ?? 0;\n values.push(limit, offset);\n\n const result = await this.pool.query<BindingRow>(\n `SELECT * FROM lattice_channel_bindings\n WHERE ${conditions.join(\" AND \")}\n ORDER BY created_at DESC\n LIMIT $${idx++} OFFSET $${idx}`,\n values,\n );\n return result.rows.map((r) => this.mapRowToBinding(r));\n }\n\n async import(bindings: CreateBindingInput[]): Promise<Binding[]> {\n const result: Binding[] = [];\n for (const input of bindings) {\n result.push(await this.create(input));\n }\n return result;\n }\n\n async export(params: { tenantId: string }): Promise<Binding[]> {\n return this.list({ tenantId: params.tenantId, limit: 10000, offset: 0 });\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n private mapRowToBinding(row: BindingRow): Binding {\n return {\n id: row.id,\n channel: row.channel,\n channelInstallationId: row.channel_installation_id,\n tenantId: row.tenant_id,\n senderId: row.sender_id,\n agentId: row.agent_id,\n threadId: row.thread_id || undefined,\n workspaceId: row.workspace_id || undefined,\n projectId: row.project_id || undefined,\n threadMode: row.thread_mode,\n senderDisplayName: row.sender_display_name || undefined,\n senderMetadata: row.sender_metadata || undefined,\n enabled: row.enabled,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n}\n","/**\n * Thread Message Queue Store\n *\n * Provides PostgreSQL storage for thread message queues\n */\n\nimport { Pool, PoolClient } from \"pg\";\nimport crypto from \"crypto\";\nimport type {\n IMessageQueueStore,\n PendingMessage,\n AddMessageParams,\n ThreadInfo,\n} from \"@axiom-lattice/core\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createThreadMessageQueueTable } from \"../migrations/thread_message_queue_migrations\";\nimport { addPriorityAndCommandColumns } from \"../migrations/add_priority_command_columns\";\nimport { addCustomRunConfigColumn } from \"../migrations/add_custom_run_config_column\";\nimport { alterMessageQueueIdColumn } from \"../migrations/alter_message_queue_id_column\";\n\nexport type { PendingMessage, AddMessageParams, ThreadInfo };\n\nexport class ThreadMessageQueueStore implements IMessageQueueStore {\n private static _instance: ThreadMessageQueueStore;\n private pool: Pool | null = null;\n private initialized: boolean = false;\n\n public static getInstance(): ThreadMessageQueueStore {\n if (!ThreadMessageQueueStore._instance) {\n ThreadMessageQueueStore._instance = new ThreadMessageQueueStore();\n }\n return ThreadMessageQueueStore._instance;\n }\n\n private constructor() {}\n\n /**\n * Initialize with PostgreSQL pool\n * @param pool - PostgreSQL connection pool\n * @param autoMigrate - Whether to run migrations automatically (default: true)\n */\n async initialize(pool: Pool, autoMigrate: boolean = true): Promise<void> {\n this.pool = pool;\n\n if (autoMigrate && !this.initialized) {\n const migrationManager = new MigrationManager(pool);\n migrationManager.register(createThreadMessageQueueTable);\n migrationManager.register(addPriorityAndCommandColumns);\n migrationManager.register(addCustomRunConfigColumn);\n migrationManager.register(alterMessageQueueIdColumn);\n await migrationManager.migrate();\n this.initialized = true;\n }\n }\n\n private getPool(): Pool {\n if (!this.pool) {\n throw new Error(\"ThreadMessageQueueStore not initialized. Call initialize() first.\");\n }\n return this.pool;\n }\n\n /**\n * Add message to queue\n */\n async addMessage(params: AddMessageParams): Promise<PendingMessage> {\n const pool = this.getPool();\n const { threadId, tenantId, assistantId, content, type = \"human\", priority = 0, command, custom_run_config, id } = params;\n\n // Get current max sequence (no lock needed without unique constraint)\n const seqResult = await pool.query(\n `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq\n FROM lattice_thread_message_queue \n WHERE thread_id = $1`,\n [threadId]\n );\n const nextSeq = seqResult.rows[0].next_seq;\n\n const result = await pool.query(\n `INSERT INTO lattice_thread_message_queue \n (id, thread_id, tenant_id, assistant_id, message_content, message_type, sequence_order, priority, command, custom_run_config)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n RETURNING *`,\n [id || crypto.randomUUID(), threadId, tenantId, assistantId, JSON.stringify(content), type, nextSeq, priority, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]\n );\n\n return this.rowToMessage(result.rows[0]);\n }\n\n /**\n * Add message at head of queue (high priority, e.g., STEER/Command messages)\n * Uses priority=100 to ensure message is processed first\n */\n async addMessageAtHead(params: AddMessageParams): Promise<PendingMessage> {\n const pool = this.getPool();\n const { threadId, tenantId, assistantId, content, type = \"human\", command, custom_run_config, id } = params;\n\n // Use provided tenantId and assistantId directly\n // These should always be provided by the caller (Agent)\n const resolvedTenantId = tenantId!;\n const resolvedAssistantId = assistantId!;\n\n // Get current max sequence for ordering within same priority\n const seqResult = await pool.query(\n `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq\n FROM lattice_thread_message_queue \n WHERE thread_id = $1`,\n [threadId]\n );\n const nextSeq = seqResult.rows[0].next_seq;\n\n // Insert with high priority (100)\n const result = await pool.query(\n `INSERT INTO lattice_thread_message_queue \n (id, thread_id, tenant_id, assistant_id, message_content, message_type, sequence_order, priority, command, custom_run_config)\n VALUES ($1, $2, $3, $4, $5, $6, $7, 100, $8, $9)\n RETURNING *`,\n [id || crypto.randomUUID(), threadId, resolvedTenantId, resolvedAssistantId, JSON.stringify(content), type, nextSeq, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]\n );\n\n return this.rowToMessage(result.rows[0]);\n }\n\n /**\n * Get pending messages for thread\n */\n async getPendingMessages(threadId: string): Promise<PendingMessage[]> {\n const pool = this.getPool();\n const result = await pool.query(\n `SELECT * FROM lattice_thread_message_queue \n WHERE thread_id = $1 AND status = 'pending'\n ORDER BY priority DESC, sequence_order ASC`,\n [threadId]\n );\n\n return result.rows.map(row => this.rowToMessage(row));\n }\n\n /**\n * Get processing messages for a thread\n */\n async getProcessingMessages(threadId: string): Promise<PendingMessage[]> {\n const pool = this.getPool();\n const result = await pool.query(\n `SELECT * FROM lattice_thread_message_queue \n WHERE thread_id = $1 AND status = 'processing'\n ORDER BY priority DESC, sequence_order ASC`,\n [threadId]\n );\n\n return result.rows.map(row => this.rowToMessage(row));\n }\n\n /**\n * Get queue size\n */\n async getQueueSize(threadId: string): Promise<number> {\n const pool = this.getPool();\n const result = await pool.query(\n `SELECT COUNT(*) as count FROM lattice_thread_message_queue \n WHERE thread_id = $1 AND status = 'pending'`,\n [threadId]\n );\n\n return parseInt(result.rows[0].count, 10);\n }\n\n /**\n * Get all threads with pending or processing messages\n */\n async getThreadsWithPendingMessages(): Promise<ThreadInfo[]> {\n const pool = this.getPool();\n const result = await pool.query(\n `SELECT DISTINCT tenant_id, assistant_id, thread_id \n FROM lattice_thread_message_queue \n WHERE status IN ('pending', 'processing')\n ORDER BY thread_id`\n );\n\n return result.rows.map(row => ({\n tenantId: row.tenant_id,\n assistantId: row.assistant_id,\n threadId: row.thread_id,\n }));\n }\n\n /**\n * Remove message\n */\n async removeMessage(messageId: string): Promise<boolean> {\n const pool = this.getPool();\n const result = await pool.query(\n `DELETE FROM lattice_thread_message_queue WHERE id = $1 RETURNING id`,\n [messageId]\n );\n\n return (result.rowCount ?? 0) > 0;\n }\n\n /**\n * Clear all messages for thread\n */\n async clearMessages(threadId: string): Promise<void> {\n const pool = this.getPool();\n await pool.query(\n `DELETE FROM lattice_thread_message_queue WHERE thread_id = $1`,\n [threadId]\n );\n }\n\n /**\n * Mark message as processing\n */\n async markProcessing(messageId: string): Promise<void> {\n const pool = this.getPool();\n await pool.query(\n `UPDATE lattice_thread_message_queue SET status = 'processing' WHERE id = $1`,\n [messageId]\n );\n }\n\n /**\n * Mark message as completed\n */\n async markCompleted(messageId: string): Promise<void> {\n const pool = this.getPool();\n await pool.query(\n `UPDATE lattice_thread_message_queue SET status = 'completed' WHERE id = $1`,\n [messageId]\n );\n }\n\n /**\n * Clear completed messages for thread\n */\n async clearCompletedMessages(threadId: string): Promise<void> {\n const pool = this.getPool();\n await pool.query(\n `DELETE FROM lattice_thread_message_queue \n WHERE thread_id = $1 AND status = 'completed'`,\n [threadId]\n );\n }\n\n /**\n * Reset all processing messages to pending state for a thread\n * Returns the number of messages reset\n */\n async resetProcessingToPending(threadId: string): Promise<number> {\n const pool = this.getPool();\n const result = await pool.query(\n `UPDATE lattice_thread_message_queue \n SET status = 'pending'\n WHERE thread_id = $1 AND status = 'processing'\n RETURNING id`,\n [threadId]\n );\n return result.rowCount ?? 0;\n }\n\n private rowToMessage(row: any): PendingMessage {\n return {\n id: row.id,\n content: typeof row.message_content === \"string\"\n ? JSON.parse(row.message_content)\n : row.message_content,\n type: row.message_type,\n sequence: row.sequence_order,\n createdAt: new Date(row.created_at),\n priority: row.priority || 0,\n command: row.command ? (typeof row.command === \"string\" ? JSON.parse(row.command) : row.command) : undefined,\n custom_run_config: row.custom_run_config\n ? (typeof row.custom_run_config === \"string\" ? JSON.parse(row.custom_run_config) : row.custom_run_config)\n : undefined,\n };\n }\n}\n\nexport const getThreadMessageQueueStore = () => ThreadMessageQueueStore.getInstance();\n","/**\n * Add priority and command columns to thread message queue\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add priority and command columns\n */\nexport const addPriorityAndCommandColumns: Migration = {\n version: 101,\n name: \"add_priority_and_command_columns\",\n up: async (client: PoolClient) => {\n // Add priority column\n await client.query(`\n ALTER TABLE lattice_thread_message_queue \n ADD COLUMN IF NOT EXISTS priority INTEGER DEFAULT 0\n `);\n\n // Add command column for steer messages\n await client.query(`\n ALTER TABLE lattice_thread_message_queue \n ADD COLUMN IF NOT EXISTS command JSONB\n `);\n\n // Create index for priority-based queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_priority \n ON lattice_thread_message_queue(thread_id, priority DESC, sequence_order ASC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_priority\");\n await client.query(\"ALTER TABLE lattice_thread_message_queue DROP COLUMN IF EXISTS command\");\n await client.query(\"ALTER TABLE lattice_thread_message_queue DROP COLUMN IF EXISTS priority\");\n },\n};\n","/**\n * Add custom_run_config column to thread message queue\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add custom_run_config column\n */\nexport const addCustomRunConfigColumn: Migration = {\n version: 102,\n name: \"add_custom_run_config_column\",\n up: async (client: PoolClient) => {\n await client.query(`\n ALTER TABLE lattice_thread_message_queue\n ADD COLUMN IF NOT EXISTS custom_run_config JSONB\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"ALTER TABLE lattice_thread_message_queue DROP COLUMN IF EXISTS custom_run_config\"\n );\n },\n};\n","/**\n * Alter thread message queue id column to allow explicit ID insertion\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Alter id column to allow explicit UUID insertion\n * This enables client-provided message IDs to be used consistently\n */\nexport const alterMessageQueueIdColumn: Migration = {\n version: 102,\n name: \"alter_message_queue_id_column\",\n up: async (client: PoolClient) => {\n // Change id column to allow NULL (we'll provide the ID explicitly)\n // The DEFAULT is removed so we must provide the ID\n await client.query(`\n ALTER TABLE lattice_thread_message_queue \n ALTER COLUMN id DROP DEFAULT\n `);\n\n // Add comment explaining the change\n await client.query(`\n COMMENT ON COLUMN lattice_thread_message_queue.id IS \n 'Message ID - must be provided explicitly (UUID format). Used for consistent ID across client and server.'\n `);\n },\n down: async (client: PoolClient) => {\n // Restore the default UUID generation\n await client.query(`\n ALTER TABLE lattice_thread_message_queue \n ALTER COLUMN id SET DEFAULT gen_random_uuid()\n `);\n\n // Remove comment\n await client.query(`\n COMMENT ON COLUMN lattice_thread_message_queue.id IS NULL\n `);\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createChannelIdentityMappingTables } from \"../migrations/channel_identity_mapping_migration\";\n\nexport interface ChannelIdentityMappingStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport interface CreateChannelIdentityMappingInput {\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n mappingMode: \"user\" | \"group\" | \"hybrid\";\n externalSubjectType: \"user\" | \"chat\";\n externalSubjectKey: string;\n larkOpenId?: string;\n larkChatId: string;\n larkMessageId?: string;\n threadId: string;\n}\n\ninterface ChannelIdentityMappingRow {\n id: string;\n channel: string;\n channel_app_id: string;\n tenant_id: string;\n assistant_id: string;\n mapping_mode: \"user\" | \"group\" | \"hybrid\";\n external_subject_type: \"user\" | \"chat\";\n external_subject_key: string;\n lark_open_id: string | null;\n lark_chat_id: string;\n lark_message_id: string | null;\n thread_id: string;\n created_at: Date;\n updated_at: Date;\n last_activity_at: Date;\n}\n\nexport interface ChannelIdentityMapping {\n id: string;\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n mappingMode: \"user\" | \"group\" | \"hybrid\";\n externalSubjectType: \"user\" | \"chat\";\n externalSubjectKey: string;\n larkOpenId?: string;\n larkChatId: string;\n larkMessageId?: string;\n threadId: string;\n createdAt: Date;\n updatedAt: Date;\n lastActivityAt: Date;\n}\n\nexport class ChannelIdentityMappingStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: ChannelIdentityMappingStoreOptions) {\n this.pool =\n typeof options.poolConfig === \"string\"\n ? new Pool({ connectionString: options.poolConfig })\n : new Pool(options.poolConfig);\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createChannelIdentityMappingTables);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize ChannelIdentityMappingStore:\", error);\n throw error;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n async createMapping(\n input: CreateChannelIdentityMappingInput,\n ): Promise<ChannelIdentityMapping> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ChannelIdentityMappingRow>(\n `\n INSERT INTO channel_identity_mappings (\n channel,\n channel_app_id,\n tenant_id,\n assistant_id,\n mapping_mode,\n external_subject_type,\n external_subject_key,\n lark_open_id,\n lark_chat_id,\n lark_message_id,\n thread_id\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n RETURNING *\n `,\n [\n input.channel,\n input.channelAppId,\n input.tenantId,\n input.assistantId,\n input.mappingMode,\n input.externalSubjectType,\n input.externalSubjectKey,\n input.larkOpenId || null,\n input.larkChatId,\n input.larkMessageId || null,\n input.threadId,\n ],\n );\n\n return mapRowToChannelIdentityMapping(result.rows[0]);\n }\n\n async getMappingBySubject(input: {\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n externalSubjectKey: string;\n }): Promise<ChannelIdentityMapping | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ChannelIdentityMappingRow>(\n `\n SELECT *\n FROM channel_identity_mappings\n WHERE channel = $1\n AND channel_app_id = $2\n AND tenant_id = $3\n AND assistant_id = $4\n AND external_subject_key = $5\n LIMIT 1\n `,\n [\n input.channel,\n input.channelAppId,\n input.tenantId,\n input.assistantId,\n input.externalSubjectKey,\n ],\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return mapRowToChannelIdentityMapping(result.rows[0]);\n }\n\n async claimInboundReceipt(input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n }): Promise<{ accepted: boolean; status: \"processing\" | \"completed\" }> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n source: \"inserted\" | \"existing\" | \"retried\";\n status: \"processing\" | \"completed\" | \"failed\";\n }>(\n `\n WITH existing AS (\n SELECT status\n FROM channel_inbound_message_receipts\n WHERE channel = $1\n AND channel_app_id = $2\n AND external_message_id = $3\n AND tenant_id = $4\n ),\n inserted AS (\n INSERT INTO channel_inbound_message_receipts (\n channel,\n channel_app_id,\n external_message_id,\n tenant_id,\n status\n )\n SELECT $1, $2, $3, $4, 'processing'\n WHERE NOT EXISTS (SELECT 1 FROM existing)\n RETURNING 'inserted'::text AS source, status\n ),\n retried AS (\n UPDATE channel_inbound_message_receipts\n SET status = 'processing', updated_at = CURRENT_TIMESTAMP\n WHERE channel = $1\n AND channel_app_id = $2\n AND external_message_id = $3\n AND tenant_id = $4\n AND EXISTS (SELECT 1 FROM existing WHERE status = 'failed')\n RETURNING 'retried'::text AS source, status\n )\n SELECT source, status FROM inserted\n UNION ALL\n SELECT source, status FROM retried\n UNION ALL\n SELECT 'existing'::text AS source, status FROM existing\n WHERE EXISTS (SELECT 1 FROM existing WHERE status IN ('processing', 'completed'))\n LIMIT 1\n `,\n [\n input.channel,\n input.channelAppId,\n input.externalMessageId,\n input.tenantId,\n ],\n );\n\n const source = result.rows[0]?.source;\n const status = result.rows[0]?.status || \"processing\";\n\n if (source === \"inserted\" || source === \"retried\") {\n return { accepted: true, status: \"processing\" };\n }\n\n if (status === \"completed\") {\n return { accepted: false, status: \"completed\" };\n }\n\n return { accepted: false, status: \"processing\" };\n }\n\n async markInboundReceiptCompleted(input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n threadId: string;\n }): Promise<void> {\n await this.ensureInitialized();\n\n await this.pool.query(\n `\n UPDATE channel_inbound_message_receipts\n SET status = 'completed', thread_id = $1, updated_at = CURRENT_TIMESTAMP\n WHERE channel = $2\n AND channel_app_id = $3\n AND external_message_id = $4\n AND tenant_id = $5\n `,\n [\n input.threadId,\n input.channel,\n input.channelAppId,\n input.externalMessageId,\n input.tenantId,\n ],\n );\n }\n\n async markInboundReceiptFailed(input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n }): Promise<void> {\n await this.ensureInitialized();\n\n await this.pool.query(\n `\n UPDATE channel_inbound_message_receipts\n SET status = 'failed', updated_at = CURRENT_TIMESTAMP\n WHERE channel = $1\n AND channel_app_id = $2\n AND external_message_id = $3\n AND tenant_id = $4\n `,\n [\n input.channel,\n input.channelAppId,\n input.externalMessageId,\n input.tenantId,\n ],\n );\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n}\n\nfunction mapRowToChannelIdentityMapping(\n row: ChannelIdentityMappingRow,\n): ChannelIdentityMapping {\n return {\n id: row.id,\n channel: row.channel,\n channelAppId: row.channel_app_id,\n tenantId: row.tenant_id,\n assistantId: row.assistant_id,\n mappingMode: row.mapping_mode,\n externalSubjectType: row.external_subject_type,\n externalSubjectKey: row.external_subject_key,\n larkOpenId: row.lark_open_id || undefined,\n larkChatId: row.lark_chat_id,\n larkMessageId: row.lark_message_id || undefined,\n threadId: row.thread_id,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n lastActivityAt: row.last_activity_at,\n };\n}\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n ChannelInstallation,\n ChannelInstallationStore,\n ChannelInstallationType,\n CreateChannelInstallationRequest,\n LarkChannelInstallationConfig,\n UpdateChannelInstallationRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createChannelInstallationsTable } from \"../migrations/channel_installation_migrations\";\nimport { alterChannelInstallationsTable } from \"../migrations/channel_installations_alter_migration\";\nimport { decrypt, encrypt } from \"@axiom-lattice/core\";\n\nexport interface PostgreSQLChannelInstallationStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\ntype ChannelInstallationRow = {\n id: string;\n tenant_id: string;\n channel: ChannelInstallationType;\n name: string | null;\n config: Record<string, unknown>;\n enabled: boolean;\n fallback_agent_id: string | null;\n reject_when_no_binding: boolean;\n created_at: Date;\n updated_at: Date;\n};\n\nexport class PostgreSQLChannelInstallationStore\n implements ChannelInstallationStore\n{\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLChannelInstallationStoreOptions) {\n this.pool =\n typeof options.poolConfig === \"string\"\n ? new Pool({ connectionString: options.poolConfig })\n : new Pool(options.poolConfig);\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createChannelInstallationsTable);\n this.migrationManager.register(alterChannelInstallationsTable);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\n \"Failed to initialize PostgreSQLChannelInstallationStore:\",\n error,\n );\n throw error;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n async getInstallationById(\n installationId: string,\n ): Promise<ChannelInstallation | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ChannelInstallationRow>(\n `\n SELECT id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at\n FROM lattice_channel_installations\n WHERE id = $1\n LIMIT 1\n `,\n [installationId],\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToInstallation(result.rows[0]);\n }\n\n async getInstallationsByTenant(\n tenantId: string,\n channel?: ChannelInstallationType,\n ): Promise<ChannelInstallation[]> {\n await this.ensureInitialized();\n\n const result = channel\n ? await this.pool.query<ChannelInstallationRow>(\n `\n SELECT id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at\n FROM lattice_channel_installations\n WHERE tenant_id = $1 AND channel = $2\n ORDER BY created_at DESC\n `,\n [tenantId, channel],\n )\n : await this.pool.query<ChannelInstallationRow>(\n `\n SELECT id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at\n FROM lattice_channel_installations\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId],\n );\n\n return result.rows.map((row) => this.mapRowToInstallation(row));\n }\n\n async createInstallation(\n tenantId: string,\n installationId: string,\n data: CreateChannelInstallationRequest,\n ): Promise<ChannelInstallation> {\n await this.ensureInitialized();\n\n const now = new Date();\n const encryptedConfig = this.encryptSecrets(data.config as unknown as Record<string, unknown>);\n\n await this.pool.query(\n `\n INSERT INTO lattice_channel_installations (\n id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n `,\n [\n installationId,\n tenantId,\n data.channel,\n data.name || null,\n JSON.stringify(encryptedConfig),\n data.enabled ?? true,\n data.fallbackAgentId || null,\n data.rejectWhenNoBinding ?? true,\n now,\n now,\n ],\n );\n\n return {\n id: installationId,\n tenantId,\n channel: data.channel,\n name: data.name,\n config: data.config,\n enabled: data.enabled ?? true,\n fallbackAgentId: data.fallbackAgentId,\n rejectWhenNoBinding: data.rejectWhenNoBinding ?? true,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n async updateInstallation(\n tenantId: string,\n installationId: string,\n updates: UpdateChannelInstallationRequest,\n ): Promise<ChannelInstallation | null> {\n await this.ensureInitialized();\n\n const existing = await this.getInstallationById(installationId);\n if (!existing || existing.tenantId !== tenantId) {\n return null;\n }\n\n const existingConfig = (existing.config ?? {}) as Record<string, unknown>;\n const mergedConfig = {\n ...existingConfig,\n ...(updates.config || {}),\n };\n const now = new Date();\n\n await this.pool.query(\n `\n UPDATE lattice_channel_installations\n SET name = $1,\n config = $2,\n enabled = $3,\n fallback_agent_id = $4,\n reject_when_no_binding = $5,\n updated_at = $6\n WHERE tenant_id = $7 AND id = $8\n `,\n [\n updates.name ?? existing.name ?? null,\n JSON.stringify(this.encryptSecrets(mergedConfig)),\n updates.enabled ?? existing.enabled,\n updates.fallbackAgentId !== undefined ? updates.fallbackAgentId : existing.fallbackAgentId ?? null,\n updates.rejectWhenNoBinding ?? existing.rejectWhenNoBinding,\n now,\n tenantId,\n installationId,\n ],\n );\n\n return {\n ...existing,\n name: updates.name ?? existing.name,\n config: mergedConfig,\n enabled: updates.enabled ?? existing.enabled,\n fallbackAgentId: updates.fallbackAgentId !== undefined ? updates.fallbackAgentId : existing.fallbackAgentId,\n rejectWhenNoBinding: updates.rejectWhenNoBinding ?? existing.rejectWhenNoBinding,\n updatedAt: now,\n };\n }\n\n async deleteInstallation(\n tenantId: string,\n installationId: string,\n ): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_channel_installations\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, installationId],\n );\n\n return (result.rowCount || 0) > 0;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n private mapRowToInstallation(\n row: ChannelInstallationRow,\n ): ChannelInstallation {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n channel: row.channel,\n name: row.name || undefined,\n config: this.decryptSecrets(\n typeof row.config === \"string\"\n ? JSON.parse(row.config)\n : row.config,\n ) as unknown as LarkChannelInstallationConfig,\n enabled: row.enabled,\n fallbackAgentId: row.fallback_agent_id || undefined,\n rejectWhenNoBinding: row.reject_when_no_binding,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n private encryptSecrets(\n config: Record<string, unknown>,\n ): Record<string, unknown> {\n return {\n ...config,\n appSecret:\n typeof config.appSecret === \"string\"\n ? encrypt(config.appSecret)\n : config.appSecret,\n verificationToken:\n typeof config.verificationToken === \"string\"\n ? encrypt(config.verificationToken)\n : config.verificationToken,\n encryptKey:\n typeof config.encryptKey === \"string\"\n ? encrypt(config.encryptKey)\n : config.encryptKey,\n };\n }\n\n private decryptSecrets(\n config: Record<string, unknown>,\n ): Record<string, unknown> {\n return {\n ...config,\n appSecret:\n typeof config.appSecret === \"string\"\n ? decrypt(config.appSecret)\n : config.appSecret,\n verificationToken:\n typeof config.verificationToken === \"string\"\n ? decrypt(config.verificationToken)\n : config.verificationToken,\n encryptKey:\n typeof config.encryptKey === \"string\"\n ? decrypt(config.encryptKey)\n : config.encryptKey,\n };\n }\n}\n","/**\n * PostgreSQL implementation of WorkflowTrackingStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n WorkflowTrackingStore,\n WorkflowRun,\n RunStep,\n CreateWorkflowRunRequest,\n UpdateWorkflowRunRequest,\n CreateRunStepRequest,\n UpdateRunStepRequest,\n StepType,\n WorkflowRunStatus,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createWorkflowTrackingTables } from \"../migrations/workflow_tracking_migrations\";\n\nexport interface PostgreSQLWorkflowTrackingStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport class PostgreSQLWorkflowTrackingStore implements WorkflowTrackingStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLWorkflowTrackingStoreOptions) {\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createWorkflowTrackingTables);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLWorkflowTrackingStore:\", error);\n throw error;\n });\n }\n }\n\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n if (this.initPromise) return this.initPromise;\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) await this.initialize();\n }\n\n async createWorkflowRun(request: CreateWorkflowRunRequest): Promise<WorkflowRun> {\n await this.ensureInitialized();\n const now = new Date();\n const id = `${request.threadId}_${Date.now()}`;\n\n await this.pool.query(\n `INSERT INTO lattice_workflow_runs (id, tenant_id, assistant_id, thread_id, status, topology_edges, total_edges, completed_edges, metadata, started_at, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`,\n [id, request.tenantId, request.assistantId, request.threadId, 'running',\n JSON.stringify(request.topologyEdges), request.topologyEdges.length, 0,\n JSON.stringify(request.metadata || {}), now, now, now]\n );\n\n return {\n id, status: 'running', startedAt: now, completedAt: undefined,\n ...request, completedEdges: 0, totalEdges: request.topologyEdges.length,\n createdAt: now, updatedAt: now,\n };\n }\n\n async getWorkflowRun(runId: string): Promise<WorkflowRun | null> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_runs WHERE id = $1`, [runId]\n );\n if (result.rows.length === 0) return null;\n return this.mapRowToWorkflowRun(result.rows[0]);\n }\n\n async updateWorkflowRun(runId: string, updates: UpdateWorkflowRunRequest): Promise<WorkflowRun | null> {\n await this.ensureInitialized();\n const now = new Date();\n const setClauses: string[] = ['updated_at = $2'];\n const values: any[] = [runId, now];\n let paramIdx = 3;\n\n if (updates.status !== undefined) {\n setClauses.push(`status = $${paramIdx++}`);\n values.push(updates.status);\n }\n if (updates.completedEdges !== undefined) {\n setClauses.push(`completed_edges = $${paramIdx++}`);\n values.push(updates.completedEdges);\n }\n if (updates.errorMessage !== undefined) {\n setClauses.push(`error_message = $${paramIdx++}`);\n values.push(updates.errorMessage);\n }\n if (updates.completedAt !== undefined) {\n setClauses.push(`completed_at = $${paramIdx++}`);\n values.push(updates.completedAt);\n }\n if (updates.metadata !== undefined) {\n setClauses.push(`metadata = $${paramIdx++}`);\n values.push(JSON.stringify(updates.metadata));\n }\n\n const query = `UPDATE lattice_workflow_runs SET ${setClauses.join(', ')} WHERE id = $1`;\n await this.pool.query(query, values);\n return this.getWorkflowRun(runId);\n }\n\n async deleteWorkflowRun(runId: string): Promise<void> {\n await this.ensureInitialized();\n await this.pool.query(`DELETE FROM lattice_workflow_runs WHERE id = $1`, [runId]);\n }\n\n async getWorkflowRunsByThreadId(tenantId: string, threadId: string): Promise<WorkflowRun[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 AND thread_id = $2 ORDER BY created_at DESC`,\n [tenantId, threadId]\n );\n return result.rows.map(this.mapRowToWorkflowRun);\n }\n\n async getWorkflowRunsByAssistantId(tenantId: string, assistantId: string): Promise<WorkflowRun[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 AND assistant_id = $2 ORDER BY created_at DESC`,\n [tenantId, assistantId]\n );\n return result.rows.map(this.mapRowToWorkflowRun);\n }\n\n async getWorkflowRunsByTenantId(tenantId: string): Promise<WorkflowRun[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 ORDER BY created_at DESC`,\n [tenantId]\n );\n return result.rows.map(this.mapRowToWorkflowRun);\n }\n\n async createRunStep(request: CreateRunStepRequest): Promise<RunStep> {\n await this.ensureInitialized();\n const now = new Date();\n const id = `step_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n await this.pool.query(\n `INSERT INTO lattice_workflow_steps (id, run_id, tenant_id, step_type, step_name, edge_from, edge_to, edge_purpose, input, status, started_at, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`,\n [id, request.runId, request.tenantId, request.stepType, request.stepName,\n request.edgeFrom || null, request.edgeTo || null, request.edgePurpose || null,\n request.input ? JSON.stringify(request.input) : null,\n 'running', now, now, now]\n );\n\n return {\n id, runId: request.runId, tenantId: request.tenantId,\n stepType: request.stepType, stepName: request.stepName,\n edgeFrom: request.edgeFrom, edgeTo: request.edgeTo, edgePurpose: request.edgePurpose,\n input: request.input, status: 'running', startedAt: now,\n createdAt: now, updatedAt: now,\n };\n }\n\n async updateRunStep(runId: string, stepId: string, updates: UpdateRunStepRequest): Promise<RunStep | null> {\n await this.ensureInitialized();\n const now = new Date();\n const setClauses: string[] = ['updated_at = $3'];\n const values: any[] = [runId, stepId, now];\n let paramIdx = 4;\n\n if (updates.status !== undefined) {\n setClauses.push(`status = $${paramIdx++}`);\n values.push(updates.status);\n }\n if (updates.output !== undefined) {\n setClauses.push(`output = $${paramIdx++}`);\n values.push(JSON.stringify(updates.output));\n }\n if (updates.errorMessage !== undefined) {\n setClauses.push(`error_message = $${paramIdx++}`);\n values.push(updates.errorMessage);\n }\n if (updates.completedAt !== undefined) {\n setClauses.push(`completed_at = $${paramIdx++}`);\n values.push(updates.completedAt);\n }\n if (updates.durationMs !== undefined) {\n setClauses.push(`duration_ms = $${paramIdx++}`);\n values.push(updates.durationMs);\n }\n\n const query = `UPDATE lattice_workflow_steps SET ${setClauses.join(', ')} WHERE run_id = $1 AND id = $2`;\n const result = await this.pool.query(query, values);\n\n if (result.rowCount === 0) return null;\n\n const row = await this.pool.query(\n `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND id = $2`,\n [runId, stepId]\n );\n return row.rows.length > 0 ? this.mapRowToRunStep(row.rows[0]) : null;\n }\n\n async getRunSteps(runId: string): Promise<RunStep[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 ORDER BY created_at ASC`,\n [runId]\n );\n return result.rows.map(this.mapRowToRunStep);\n }\n\n async getRunStepsByType(runId: string, stepType: StepType): Promise<RunStep[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND step_type = $2 ORDER BY created_at ASC`,\n [runId, stepType]\n );\n return result.rows.map(this.mapRowToRunStep);\n }\n\n async getInterruptedSteps(runId: string): Promise<RunStep[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND status = 'interrupted' ORDER BY created_at ASC`,\n [runId]\n );\n return result.rows.map(this.mapRowToRunStep);\n }\n\n private mapRowToWorkflowRun(row: any): WorkflowRun {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n assistantId: row.assistant_id,\n threadId: row.thread_id,\n status: row.status as WorkflowRunStatus,\n topologyEdges: typeof row.topology_edges === 'string' ? JSON.parse(row.topology_edges) : row.topology_edges || [],\n totalEdges: row.total_edges,\n completedEdges: row.completed_edges,\n errorMessage: row.error_message,\n metadata: typeof row.metadata === 'string' ? JSON.parse(row.metadata) : row.metadata || {},\n startedAt: row.started_at,\n completedAt: row.completed_at,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n private mapRowToRunStep(row: any): RunStep {\n return {\n id: row.id,\n runId: row.run_id,\n tenantId: row.tenant_id,\n stepType: row.step_type as StepType,\n stepName: row.step_name,\n edgeFrom: row.edge_from,\n edgeTo: row.edge_to,\n edgePurpose: row.edge_purpose,\n input: typeof row.input === 'string' ? JSON.parse(row.input) : row.input,\n output: typeof row.output === 'string' ? JSON.parse(row.output) : row.output,\n status: row.status,\n errorMessage: row.error_message,\n startedAt: row.started_at,\n completedAt: row.completed_at,\n durationMs: row.duration_ms,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n}\n","/**\n * PostgreSQL implementation of EvalStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n EvalStore,\n EvalProject,\n CreateEvalProjectRequest,\n EvalSuite,\n CreateEvalSuiteRequest,\n EvalCase,\n CreateEvalCaseRequest,\n EvalRun,\n CreateEvalRunRequest,\n EvalRunResult,\n EvalProjectReport,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { evalMigrations } from \"../migrations/eval_migrations\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/** PostgreSQL EvalStore options */\nexport interface PostgreSQLEvalStoreOptions {\n /** PostgreSQL connection pool configuration */\n poolConfig: string | PoolConfig;\n /** Whether to run migrations automatically on initialization @default true */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of EvalStore\n *\n * Features:\n * - Multi-tenant isolation via tenant_id\n * - Full CRUD for projects, suites, cases, runs, run results\n * - Project report aggregation\n */\nexport class PostgreSQLEvalStore implements EvalStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLEvalStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n for (const m of evalMigrations) {\n this.migrationManager.register(m);\n }\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLEvalStore:\", error);\n throw error;\n });\n }\n }\n\n /** Dispose resources and close the connection pool */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /** Ensure store is initialized */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n // ---------------------------------------------------------------------------\n // Row mappers\n // ---------------------------------------------------------------------------\n\n private mapRowToProject(row: Record<string, unknown>): EvalProject {\n return {\n id: row.id as string,\n tenantId: row.tenant_id as string,\n name: row.name as string,\n description: row.description as string | undefined,\n version: row.version as string | undefined,\n judgeModelConfig: this.parseRequiredJson<Record<string, unknown>>(row.judge_model_config, {}),\n targetServerConfig: this.parseRequiredJson<Record<string, unknown>>(row.target_server_config, {}),\n concurrency: (row.concurrency as number) ?? 3,\n reportConfig: this.parseOptionalJson<Record<string, unknown>>(row.report_config),\n createdAt: new Date(row.created_at as string),\n updatedAt: new Date(row.updated_at as string),\n };\n }\n\n private mapRowToSuite(row: Record<string, unknown>): EvalSuite {\n return {\n id: row.id as string,\n tenantId: row.tenant_id as string,\n projectId: row.project_id as string,\n name: row.name as string,\n createdAt: new Date(row.created_at as string),\n updatedAt: new Date(row.updated_at as string),\n caseCount: row.case_count !== undefined ? (row.case_count as number) : undefined,\n };\n }\n\n private mapRowToCase(row: Record<string, unknown>): EvalCase {\n return {\n id: row.id as string,\n tenantId: row.tenant_id as string,\n suiteId: row.suite_id as string,\n inputMessage: row.input_message as string,\n inputFiles: this.parseOptionalJson<Record<string, string>>(row.input_files),\n steps: this.parseRequiredJson<Array<{ agent_id: string; override_message?: string }>>(row.steps, []),\n outputType: (row.output_type as EvalCase[\"outputType\"]) || \"message_content\",\n contentAssertion: (row.content_assertion as string) || \"\",\n rubrics: this.parseOptionalJson<Array<{ name: string; weight: number; description: string }>>(row.rubrics),\n createdAt: new Date(row.created_at as string),\n updatedAt: new Date(row.updated_at as string),\n };\n }\n\n private mapRowToRun(row: Record<string, unknown>): EvalRun {\n return {\n id: row.id as string,\n projectId: row.project_id as string,\n tenantId: row.tenant_id as string,\n status: row.status as EvalRun[\"status\"],\n concurrency: (row.concurrency as number) ?? 3,\n totalCases: (row.total_cases as number) ?? 0,\n passedCases: (row.passed_cases as number) ?? 0,\n failedCases: (row.failed_cases as number) ?? 0,\n avgScore: (row.avg_score as number) ?? 0,\n error: row.error as string | undefined,\n createdAt: new Date(row.created_at as string),\n startedAt: row.started_at ? new Date(row.started_at as string) : undefined,\n completedAt: row.completed_at ? new Date(row.completed_at as string) : undefined,\n };\n }\n\n private mapRowToRunResult(row: Record<string, unknown>): EvalRunResult {\n return {\n id: row.id as string,\n runId: row.run_id as string,\n suiteName: row.suite_name as string,\n caseId: row.case_id as string | undefined,\n pass: (row.pass as boolean) ?? false,\n score: (row.score as number) ?? 0,\n summary: row.summary as string | undefined,\n dimensionResults: this.parseOptionalJson<Array<{ name: string; score: number; reason: string }>>(row.dimension_results),\n durationMs: row.duration_ms as number | undefined,\n messages: this.parseOptionalJson<Array<{ role: string; content: string; id?: string }>>(row.messages),\n logs: this.parseOptionalJson<Array<{ timestamp: string; level: string; message: string; data?: unknown }>>(row.logs),\n error: row.error as string | undefined,\n createdAt: new Date(row.created_at as string),\n };\n }\n\n private parseRequiredJson<T>(val: unknown, fallback: T): T {\n if (val == null) return fallback;\n if (typeof val === \"string\") {\n try {\n return JSON.parse(val) as T;\n } catch {\n return fallback;\n }\n }\n return val as T;\n }\n\n private parseOptionalJson<T>(val: unknown): T | undefined {\n if (val == null) return undefined;\n if (typeof val === \"string\") {\n try {\n return JSON.parse(val) as T;\n } catch {\n return undefined;\n }\n }\n return val as T;\n }\n\n // ---------------------------------------------------------------------------\n // Projects\n // ---------------------------------------------------------------------------\n\n /** Get all eval projects for a tenant */\n async getProjectsByTenant(tenantId: string): Promise<EvalProject[]> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at\n FROM lattice_eval_projects\n WHERE tenant_id = $1\n ORDER BY created_at DESC`,\n [tenantId]\n );\n return rows.map((r) => this.mapRowToProject(r as unknown as Record<string, unknown>));\n }\n\n /** Get a single eval project by ID for a tenant */\n async getProjectById(tenantId: string, id: string): Promise<EvalProject | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at\n FROM lattice_eval_projects\n WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return rows.length ? this.mapRowToProject(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Create a new eval project */\n async createProject(\n tenantId: string,\n id: string,\n data: CreateEvalProjectRequest\n ): Promise<EvalProject> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `INSERT INTO lattice_eval_projects\n (id, tenant_id, name, description, version, judge_model_config, target_server_config, concurrency, report_config)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)\n RETURNING id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at`,\n [\n actualId,\n tenantId,\n data.name,\n data.description || null,\n data.version || null,\n JSON.stringify(data.judgeModelConfig),\n JSON.stringify(data.targetServerConfig),\n data.concurrency ?? 3,\n data.reportConfig === undefined ? null : JSON.stringify(data.reportConfig),\n ]\n );\n return this.mapRowToProject(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update an eval project */\n async updateProject(\n tenantId: string,\n id: string,\n updates: Partial<CreateEvalProjectRequest>\n ): Promise<EvalProject | null> {\n await this.ensureInitialized();\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.name !== undefined) { set.push(`name = $${i++}`); vals.push(updates.name); }\n if (updates.description !== undefined) { set.push(`description = $${i++}`); vals.push(updates.description); }\n if (updates.version !== undefined) { set.push(`version = $${i++}`); vals.push(updates.version); }\n if (updates.judgeModelConfig !== undefined) { set.push(`judge_model_config = $${i++}`); vals.push(JSON.stringify(updates.judgeModelConfig)); }\n if (updates.targetServerConfig !== undefined) { set.push(`target_server_config = $${i++}`); vals.push(JSON.stringify(updates.targetServerConfig)); }\n if (updates.concurrency !== undefined) { set.push(`concurrency = $${i++}`); vals.push(updates.concurrency); }\n if (updates.reportConfig !== undefined) { set.push(`report_config = $${i++}`); vals.push(JSON.stringify(updates.reportConfig)); }\n if (set.length === 0) return this.getProjectById(tenantId, id);\n set.push(`updated_at = NOW()`);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `UPDATE lattice_eval_projects SET ${set.join(\", \")}\n WHERE id = $${i} AND tenant_id = $${i + 1}\n RETURNING id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at`,\n vals\n );\n return rows.length ? this.mapRowToProject(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Delete an eval project */\n async deleteProject(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `DELETE FROM lattice_eval_projects WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return (result.rowCount ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Suites\n // ---------------------------------------------------------------------------\n\n /** Get all suites in a project with case counts */\n async getSuitesByProject(tenantId: string, projectId: string): Promise<EvalSuite[]> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; project_id: string; name: string;\n created_at: string; updated_at: string; case_count: number;\n }>(\n `SELECT s.id, s.tenant_id, s.project_id, s.name, s.created_at, s.updated_at,\n COUNT(c.id)::int AS case_count\n FROM lattice_eval_suites s\n LEFT JOIN lattice_eval_cases c ON c.suite_id = s.id\n WHERE s.tenant_id = $1 AND s.project_id = $2\n GROUP BY s.id\n ORDER BY s.created_at DESC`,\n [tenantId, projectId]\n );\n return rows.map((r) => this.mapRowToSuite(r as unknown as Record<string, unknown>));\n }\n\n /** Get a single suite by ID with case count */\n async getSuiteById(tenantId: string, id: string): Promise<EvalSuite | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; project_id: string; name: string;\n created_at: string; updated_at: string; case_count: number;\n }>(\n `SELECT s.id, s.tenant_id, s.project_id, s.name, s.created_at, s.updated_at,\n COUNT(c.id)::int AS case_count\n FROM lattice_eval_suites s\n LEFT JOIN lattice_eval_cases c ON c.suite_id = s.id\n WHERE s.tenant_id = $1 AND s.id = $2\n GROUP BY s.id`,\n [tenantId, id]\n );\n return rows.length ? this.mapRowToSuite(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Create a new eval suite */\n async createSuite(\n tenantId: string,\n projectId: string,\n id: string,\n data: CreateEvalSuiteRequest\n ): Promise<EvalSuite> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; project_id: string; name: string;\n created_at: string; updated_at: string;\n }>(\n `INSERT INTO lattice_eval_suites (id, tenant_id, project_id, name)\n VALUES ($1, $2, $3, $4)\n RETURNING id, tenant_id, project_id, name, created_at, updated_at`,\n [actualId, tenantId, projectId, data.name]\n );\n return this.mapRowToSuite(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update a suite's name */\n async updateSuite(\n tenantId: string,\n id: string,\n updates: Partial<CreateEvalSuiteRequest>\n ): Promise<EvalSuite | null> {\n await this.ensureInitialized();\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.name !== undefined) { set.push(`name = $${i++}`); vals.push(updates.name); }\n if (set.length === 0) return this.getSuiteById(tenantId, id);\n set.push(`updated_at = NOW()`);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; project_id: string; name: string;\n created_at: string; updated_at: string;\n }>(\n `UPDATE lattice_eval_suites SET ${set.join(\", \")}\n WHERE id = $${i} AND tenant_id = $${i + 1}\n RETURNING id, tenant_id, project_id, name, created_at, updated_at`,\n vals\n );\n return rows.length ? this.mapRowToSuite(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Delete a suite */\n async deleteSuite(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `DELETE FROM lattice_eval_suites WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return (result.rowCount ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Cases\n // ---------------------------------------------------------------------------\n\n /** Get all test cases in a suite */\n async getCasesBySuite(tenantId: string, suiteId: string): Promise<EvalCase[]> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; suite_id: string;\n input_message: string; input_files: unknown; steps: unknown;\n output_type: string; content_assertion: string; rubrics: unknown;\n created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, suite_id,\n input_message, input_files, steps,\n output_type, content_assertion, rubrics,\n created_at, updated_at\n FROM lattice_eval_cases\n WHERE tenant_id = $1 AND suite_id = $2\n ORDER BY created_at`,\n [tenantId, suiteId]\n );\n return rows.map((r) => this.mapRowToCase(r as unknown as Record<string, unknown>));\n }\n\n /** Get a single test case by ID */\n async getCaseById(tenantId: string, id: string): Promise<EvalCase | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; suite_id: string;\n input_message: string; input_files: unknown; steps: unknown;\n output_type: string; content_assertion: string; rubrics: unknown;\n created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, suite_id,\n input_message, input_files, steps,\n output_type, content_assertion, rubrics,\n created_at, updated_at\n FROM lattice_eval_cases\n WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return rows.length ? this.mapRowToCase(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Create a new test case */\n async createCase(\n tenantId: string,\n suiteId: string,\n id: string,\n data: CreateEvalCaseRequest\n ): Promise<EvalCase> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; suite_id: string;\n input_message: string; input_files: unknown; steps: unknown;\n output_type: string; content_assertion: string; rubrics: unknown;\n created_at: string; updated_at: string;\n }>(\n `INSERT INTO lattice_eval_cases\n (id, tenant_id, suite_id, input_message, input_files, steps, output_type, content_assertion, rubrics)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)\n RETURNING id, tenant_id, suite_id,\n input_message, input_files, steps,\n output_type, content_assertion, rubrics,\n created_at, updated_at`,\n [\n actualId,\n tenantId,\n suiteId,\n data.inputMessage,\n JSON.stringify(data.inputFiles || {}),\n JSON.stringify(data.steps),\n data.outputType,\n data.contentAssertion || null,\n JSON.stringify(data.rubrics || []),\n ]\n );\n return this.mapRowToCase(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update a test case */\n async updateCase(\n tenantId: string,\n id: string,\n updates: Partial<CreateEvalCaseRequest>\n ): Promise<EvalCase | null> {\n await this.ensureInitialized();\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.inputMessage !== undefined) { set.push(`input_message = $${i++}`); vals.push(updates.inputMessage); }\n if (updates.inputFiles !== undefined) { set.push(`input_files = $${i++}`); vals.push(JSON.stringify(updates.inputFiles)); }\n if (updates.steps !== undefined) { set.push(`steps = $${i++}`); vals.push(JSON.stringify(updates.steps)); }\n if (updates.outputType !== undefined) { set.push(`output_type = $${i++}`); vals.push(updates.outputType); }\n if (updates.contentAssertion !== undefined) { set.push(`content_assertion = $${i++}`); vals.push(updates.contentAssertion); }\n if (updates.rubrics !== undefined) { set.push(`rubrics = $${i++}`); vals.push(JSON.stringify(updates.rubrics)); }\n if (set.length === 0) return this.getCaseById(tenantId, id);\n set.push(`updated_at = NOW()`);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; suite_id: string;\n input_message: string; input_files: unknown; steps: unknown;\n output_type: string; content_assertion: string; rubrics: unknown;\n created_at: string; updated_at: string;\n }>(\n `UPDATE lattice_eval_cases SET ${set.join(\", \")}\n WHERE id = $${i} AND tenant_id = $${i + 1}\n RETURNING id, tenant_id, suite_id,\n input_message, input_files, steps,\n output_type, content_assertion, rubrics,\n created_at, updated_at`,\n vals\n );\n return rows.length ? this.mapRowToCase(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Delete a test case */\n async deleteCase(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `DELETE FROM lattice_eval_cases WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return (result.rowCount ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Runs\n // ---------------------------------------------------------------------------\n\n /** Get all runs for a tenant, optionally filtered by project or status */\n async getRunsByTenant(\n tenantId: string,\n opts?: { projectId?: string; status?: string }\n ): Promise<EvalRun[]> {\n await this.ensureInitialized();\n const conditions: string[] = [\"tenant_id = $1\"];\n const vals: unknown[] = [tenantId];\n let i = 2;\n if (opts?.projectId) { conditions.push(`project_id = $${i++}`); vals.push(opts.projectId); }\n if (opts?.status) { conditions.push(`status = $${i++}`); vals.push(opts.status); }\n const { rows } = await this.pool.query<{\n id: string; project_id: string; tenant_id: string;\n status: string; concurrency: number; total_cases: number;\n passed_cases: number; failed_cases: number; avg_score: number;\n error: string | null; created_at: string; started_at: string | null;\n completed_at: string | null;\n }>(\n `SELECT id, project_id, tenant_id,\n status, concurrency, total_cases,\n passed_cases, failed_cases, avg_score,\n error, created_at, started_at, completed_at\n FROM lattice_eval_runs\n WHERE ${conditions.join(\" AND \")}\n ORDER BY created_at DESC`,\n vals\n );\n return rows.map((r) => this.mapRowToRun(r as unknown as Record<string, unknown>));\n }\n\n /** Get a single run by ID */\n async getRunById(tenantId: string, id: string): Promise<EvalRun | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; project_id: string; tenant_id: string;\n status: string; concurrency: number; total_cases: number;\n passed_cases: number; failed_cases: number; avg_score: number;\n error: string | null; created_at: string; started_at: string | null;\n completed_at: string | null;\n }>(\n `SELECT id, project_id, tenant_id,\n status, concurrency, total_cases,\n passed_cases, failed_cases, avg_score,\n error, created_at, started_at, completed_at\n FROM lattice_eval_runs\n WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return rows.length ? this.mapRowToRun(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Create a new eval run */\n async createRun(\n tenantId: string,\n projectId: string,\n id: string,\n data: CreateEvalRunRequest\n ): Promise<EvalRun> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; project_id: string; tenant_id: string;\n status: string; concurrency: number; total_cases: number;\n passed_cases: number; failed_cases: number; avg_score: number;\n error: string | null; created_at: string; started_at: string | null;\n completed_at: string | null;\n }>(\n `INSERT INTO lattice_eval_runs\n (id, project_id, tenant_id, status, concurrency, total_cases, passed_cases, failed_cases, avg_score, started_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n RETURNING id, project_id, tenant_id,\n status, concurrency, total_cases,\n passed_cases, failed_cases, avg_score,\n error, created_at, started_at, completed_at`,\n [\n actualId,\n projectId,\n tenantId,\n \"running\",\n data.concurrency,\n data.totalCases,\n 0,\n 0,\n 0,\n new Date(),\n ]\n );\n return this.mapRowToRun(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update a run's status and aggregate fields */\n async updateRunStatus(\n tenantId: string,\n id: string,\n updates: {\n status?: EvalRun[\"status\"];\n passedCases?: number;\n failedCases?: number;\n avgScore?: number;\n error?: string;\n completedAt?: Date;\n }\n ): Promise<EvalRun | null> {\n await this.ensureInitialized();\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.status !== undefined) { set.push(`status = $${i++}`); vals.push(updates.status); }\n if (updates.passedCases !== undefined) { set.push(`passed_cases = $${i++}`); vals.push(updates.passedCases); }\n if (updates.failedCases !== undefined) { set.push(`failed_cases = $${i++}`); vals.push(updates.failedCases); }\n if (updates.avgScore !== undefined) { set.push(`avg_score = $${i++}`); vals.push(updates.avgScore); }\n if (updates.completedAt !== undefined) { set.push(`completed_at = $${i++}`); vals.push(updates.completedAt); }\n if (updates.error !== undefined) { set.push(`error = $${i++}`); vals.push(updates.error); }\n if (set.length === 0) return this.getRunById(tenantId, id);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; project_id: string; tenant_id: string;\n status: string; concurrency: number; total_cases: number;\n passed_cases: number; failed_cases: number; avg_score: number;\n error: string | null; created_at: string; started_at: string | null;\n completed_at: string | null;\n }>(\n `UPDATE lattice_eval_runs SET ${set.join(\", \")}\n WHERE id = $${i} AND tenant_id = $${i + 1}\n RETURNING id, project_id, tenant_id,\n status, concurrency, total_cases,\n passed_cases, failed_cases, avg_score,\n error, created_at, started_at, completed_at`,\n vals\n );\n return rows.length ? this.mapRowToRun(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Delete a run and its results */\n async deleteRun(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n // Delete results first, then the run\n await this.pool.query(`DELETE FROM lattice_eval_run_results WHERE run_id = $1 AND tenant_id = $2`, [id, tenantId]);\n const { rowCount } = await this.pool.query(\n `DELETE FROM lattice_eval_runs WHERE id = $1 AND tenant_id = $2`, [id, tenantId]\n );\n return (rowCount ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Run Results\n // ---------------------------------------------------------------------------\n\n /** Get all results belonging to a run */\n async getResultsByRun(tenantId: string, runId: string): Promise<EvalRunResult[]> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; run_id: string; suite_name: string;\n case_id: string | null; pass: boolean; score: number;\n summary: string | null; dimension_results: unknown;\n duration_ms: number | null; messages: unknown; logs: unknown;\n error: string | null; created_at: string;\n }>(\n `SELECT rr.id, rr.run_id, rr.suite_name, rr.case_id,\n rr.pass, rr.score, rr.summary, rr.dimension_results,\n rr.duration_ms, rr.messages, rr.logs, rr.error, rr.created_at\n FROM lattice_eval_run_results rr\n INNER JOIN lattice_eval_runs r ON r.id = rr.run_id\n WHERE r.tenant_id = $1 AND rr.run_id = $2\n ORDER BY rr.created_at`,\n [tenantId, runId]\n );\n return rows.map((r) => this.mapRowToRunResult(r as unknown as Record<string, unknown>));\n }\n\n /** Create a result for a case within a run */\n async createRunResult(\n tenantId: string,\n runId: string,\n id: string,\n data: Omit<EvalRunResult, \"id\" | \"runId\" | \"createdAt\">\n ): Promise<EvalRunResult> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; run_id: string; suite_name: string;\n case_id: string | null; pass: boolean; score: number;\n summary: string | null; dimension_results: unknown;\n duration_ms: number | null; messages: unknown; logs: unknown;\n error: string | null; created_at: string;\n }>(\n `INSERT INTO lattice_eval_run_results\n (id, run_id, suite_name, case_id, pass, score, summary, dimension_results, duration_ms, messages, logs, error)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)\n RETURNING id, run_id, suite_name, case_id,\n pass, score, summary, dimension_results,\n duration_ms, messages, logs, error, created_at`,\n [\n actualId,\n runId,\n data.suiteName,\n data.caseId || null,\n data.pass,\n data.score,\n data.summary || null,\n JSON.stringify(data.dimensionResults || []),\n data.durationMs ?? null,\n JSON.stringify(data.messages || []),\n JSON.stringify(data.logs || []),\n data.error || null,\n ]\n );\n return this.mapRowToRunResult(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update a run result with tenant isolation via the parent run */\n async updateRunResult(\n tenantId: string,\n id: string,\n updates: Partial<EvalRunResult>\n ): Promise<EvalRunResult | null> {\n await this.ensureInitialized();\n if (updates.runId !== undefined) {\n throw new Error(\"runId cannot be updated on an existing result\");\n }\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.suiteName !== undefined) { set.push(`suite_name = $${i++}`); vals.push(updates.suiteName); }\n if (updates.caseId !== undefined) { set.push(`case_id = $${i++}`); vals.push(updates.caseId); }\n if (updates.pass !== undefined) { set.push(`pass = $${i++}`); vals.push(updates.pass); }\n if (updates.score !== undefined) { set.push(`score = $${i++}`); vals.push(updates.score); }\n if (updates.summary !== undefined) { set.push(`summary = $${i++}`); vals.push(updates.summary); }\n if (updates.dimensionResults !== undefined) { set.push(`dimension_results = $${i++}`); vals.push(JSON.stringify(updates.dimensionResults)); }\n if (updates.durationMs !== undefined) { set.push(`duration_ms = $${i++}`); vals.push(updates.durationMs); }\n if (updates.messages !== undefined) { set.push(`messages = $${i++}`); vals.push(JSON.stringify(updates.messages)); }\n if (updates.logs !== undefined) { set.push(`logs = $${i++}`); vals.push(JSON.stringify(updates.logs)); }\n if (updates.error !== undefined) { set.push(`error = $${i++}`); vals.push(updates.error); }\n if (set.length === 0) return this.getRunResultById(tenantId, id);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; run_id: string; suite_name: string;\n case_id: string | null; pass: boolean; score: number;\n summary: string | null; dimension_results: unknown;\n duration_ms: number | null; messages: unknown; logs: unknown;\n error: string | null; created_at: string;\n }>(\n `UPDATE lattice_eval_run_results SET ${set.join(\", \")}\n WHERE id = $${i}\n AND run_id IN (SELECT id FROM lattice_eval_runs WHERE tenant_id = $${i + 1})\n RETURNING id, run_id, suite_name, case_id,\n pass, score, summary, dimension_results,\n duration_ms, messages, logs, error, created_at`,\n vals\n );\n return rows.length ? this.mapRowToRunResult(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Get a single run result by ID with tenant isolation */\n private async getRunResultById(tenantId: string, id: string): Promise<EvalRunResult | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; run_id: string; suite_name: string;\n case_id: string | null; pass: boolean; score: number;\n summary: string | null; dimension_results: unknown;\n duration_ms: number | null; messages: unknown; logs: unknown;\n error: string | null; created_at: string;\n }>(\n `SELECT rr.id, rr.run_id, rr.suite_name, rr.case_id,\n rr.pass, rr.score, rr.summary, rr.dimension_results,\n rr.duration_ms, rr.messages, rr.logs, rr.error, rr.created_at\n FROM lattice_eval_run_results rr\n INNER JOIN lattice_eval_runs r ON r.id = rr.run_id\n WHERE rr.id = $1 AND r.tenant_id = $2`,\n [id, tenantId]\n );\n return rows.length ? this.mapRowToRunResult(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n // ---------------------------------------------------------------------------\n // Reports\n // ---------------------------------------------------------------------------\n\n /** Aggregate report for a project including all runs */\n async getProjectReport(tenantId: string, projectId: string): Promise<EvalProjectReport | null> {\n await this.ensureInitialized();\n const projectRows = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at\n FROM lattice_eval_projects\n WHERE id = $1 AND tenant_id = $2`,\n [projectId, tenantId]\n );\n if (projectRows.rows.length === 0) return null;\n\n const project = this.mapRowToProject(projectRows.rows[0] as unknown as Record<string, unknown>);\n const runs = await this.getRunsByTenant(tenantId, { projectId });\n const totalRuns = runs.length;\n const latestPassRate = runs.length > 0\n ? (runs[0].totalCases > 0 ? runs[0].passedCases / runs[0].totalCases : 0)\n : 0;\n const avgScore = runs.length > 0\n ? runs.reduce((sum, r) => sum + r.avgScore, 0) / runs.length\n : 0;\n\n return {\n projectId: project.id,\n projectName: project.name,\n totalRuns,\n latestPassRate,\n avgScore,\n runs,\n };\n }\n}\n","/**\n * Eval table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/** Create the eval projects table */\nexport const createEvalProjectsTable: Migration = {\n version: 104,\n name: \"create_eval_projects_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_projects (\n id UUID PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n name TEXT NOT NULL,\n description TEXT,\n version TEXT,\n judge_model_config JSONB NOT NULL DEFAULT '{}',\n target_server_config JSONB NOT NULL DEFAULT '{}',\n concurrency INTEGER NOT NULL DEFAULT 3,\n report_config JSONB DEFAULT '{}',\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_projects_tenant_id\n ON lattice_eval_projects(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_projects_created_at\n ON lattice_eval_projects(created_at)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_projects_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_projects_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_projects\");\n },\n};\n\n/** Create the eval suites table */\nexport const createEvalSuitesTable: Migration = {\n version: 105,\n name: \"create_eval_suites_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_suites (\n id UUID PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n project_id UUID NOT NULL REFERENCES lattice_eval_projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n UNIQUE(project_id, name)\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_suites_tenant_id\n ON lattice_eval_suites(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_suites_project_id\n ON lattice_eval_suites(project_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_suites_project_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_suites_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_suites\");\n },\n};\n\n/** Create the eval cases table */\nexport const createEvalCasesTable: Migration = {\n version: 106,\n name: \"create_eval_cases_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_cases (\n id UUID PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n suite_id UUID NOT NULL REFERENCES lattice_eval_suites(id) ON DELETE CASCADE,\n template_id UUID,\n input_message TEXT NOT NULL,\n input_files JSONB DEFAULT '{}',\n steps JSONB NOT NULL DEFAULT '[]',\n output_type TEXT NOT NULL DEFAULT 'message_content',\n content_assertion TEXT,\n rubrics JSONB DEFAULT '[]',\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_cases_tenant_id\n ON lattice_eval_cases(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_cases_suite_id\n ON lattice_eval_cases(suite_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_cases_suite_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_cases_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_cases\");\n },\n};\n\n/** Create the eval runs table */\nexport const createEvalRunsTable: Migration = {\n version: 107,\n name: \"create_eval_runs_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_runs (\n id UUID PRIMARY KEY,\n project_id UUID NOT NULL REFERENCES lattice_eval_projects(id) ON DELETE CASCADE,\n tenant_id VARCHAR(255) NOT NULL,\n status TEXT NOT NULL DEFAULT 'running',\n concurrency INTEGER NOT NULL DEFAULT 3,\n total_cases INTEGER NOT NULL DEFAULT 0,\n passed_cases INTEGER NOT NULL DEFAULT 0,\n failed_cases INTEGER NOT NULL DEFAULT 0,\n avg_score FLOAT NOT NULL DEFAULT 0,\n error TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n started_at TIMESTAMPTZ,\n completed_at TIMESTAMPTZ\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_tenant_id\n ON lattice_eval_runs(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_project_id\n ON lattice_eval_runs(project_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_status\n ON lattice_eval_runs(status)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_created_at\n ON lattice_eval_runs(created_at)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_runs_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_runs_status\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_runs_project_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_runs_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_runs\");\n },\n};\n\n/** Create the eval run results table */\nexport const createEvalRunResultsTable: Migration = {\n version: 108,\n name: \"create_eval_run_results_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_run_results (\n id UUID PRIMARY KEY,\n run_id UUID NOT NULL REFERENCES lattice_eval_runs(id) ON DELETE CASCADE,\n suite_name TEXT NOT NULL DEFAULT '',\n case_id UUID,\n pass BOOLEAN NOT NULL DEFAULT false,\n score FLOAT NOT NULL DEFAULT 0,\n summary TEXT,\n dimension_results JSONB DEFAULT '[]',\n duration_ms INTEGER DEFAULT 0,\n messages JSONB DEFAULT '[]',\n logs JSONB DEFAULT '[]',\n error TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_run_results_run_id\n ON lattice_eval_run_results(run_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_run_results_case_id\n ON lattice_eval_run_results(case_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_run_results_case_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_run_results_run_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_run_results\");\n },\n};\n\n/** All eval migrations in version order */\nexport const evalMigrations: Migration[] = [\n createEvalProjectsTable,\n createEvalSuitesTable,\n createEvalCasesTable,\n createEvalRunsTable,\n createEvalRunResultsTable,\n];\n"],"mappings":"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","names":["Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","encrypt","decrypt","Pool","Pool","encrypt","decrypt","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","decrypt","encrypt","Pool","Pool","Pool","Pool","Pool"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/stores/PostgreSQLThreadStore.ts","../src/migrations/migration.ts","../src/migrations/thread_migrations.ts","../src/migrations/thread_tenant_migration.ts","../src/migrations/thread_pk_migration.ts","../src/stores/PostgreSQLAssistantStore.ts","../src/migrations/assistant_migrations.ts","../src/migrations/assistant_tenant_migration.ts","../src/migrations/assistant_pk_migration.ts","../src/stores/PostgreSQLDatabaseConfigStore.ts","../src/migrations/database_config_migrations.ts","../src/stores/PostgreSQLMetricsServerConfigStore.ts","../src/migrations/metrics_config_migrations.ts","../src/stores/PostgreSQLMcpServerConfigStore.ts","../src/migrations/mcp_server_config_migrations.ts","../src/stores/PostgreSQLWorkspaceStore.ts","../src/migrations/workspace_migrations.ts","../src/stores/PostgreSQLProjectStore.ts","../src/migrations/project_migrations.ts","../src/stores/PostgreSQLUserStore.ts","../src/migrations/user_migrations.ts","../src/migrations/user_status_migration.ts","../src/stores/PostgreSQLTenantStore.ts","../src/migrations/tenant_migrations.ts","../src/stores/PostgreSQLUserTenantLinkStore.ts","../src/migrations/user_tenant_link_migrations.ts","../src/stores/PostgreSQLWorkflowTrackingStore.ts","../src/migrations/workflow_tracking_migrations.ts","../src/stores/PostgreSQLEvalStore.ts","../src/migrations/eval_migrations.ts","../src/stores/ThreadMessageQueueStore.ts","../src/migrations/thread_message_queue_migrations.ts","../src/migrations/add_priority_command_columns.ts","../src/migrations/add_custom_run_config_column.ts","../src/migrations/alter_message_queue_id_column.ts","../src/stores/ChannelBindingStore.ts","../src/migrations/channel_bindings_migration.ts","../src/stores/PostgreSQLChannelInstallationStore.ts","../src/migrations/channel_installation_migrations.ts","../src/migrations/channel_installations_alter_migration.ts","../src/stores/PostgreSQLScheduleStorage.ts","../src/migrations/schedule_migrations.ts","../src/migrations/schedule_tenant_migration.ts","../src/createPgStoreConfig.ts","../src/stores/PostgreSQLSkillStore.ts","../src/migrations/skill_migrations.ts","../src/migrations/skill_tenant_migration.ts","../src/migrations/skill_pk_migration.ts","../src/migrations/channel_identity_mapping_migration.ts","../src/stores/ChannelIdentityMappingStore.ts"],"sourcesContent":["/**\n * PostgreSQL Stores Package\n *\n * Provides PostgreSQL implementations for various stores\n */\n\n// Re-export pg types for convenience\nexport { Pool } from \"pg\";\nexport type { PoolConfig } from \"pg\";\n\nexport * from \"./createPgStoreConfig\";\n\nexport * from \"./stores/PostgreSQLThreadStore\";\nexport * from \"./stores/PostgreSQLAssistantStore\";\nexport * from \"./stores/PostgreSQLScheduleStorage\";\nexport * from \"./stores/PostgreSQLSkillStore\";\nexport * from \"./stores/PostgreSQLDatabaseConfigStore\";\nexport * from \"./stores/PostgreSQLMetricsServerConfigStore\";\nexport * from \"./stores/PostgreSQLMcpServerConfigStore\";\nexport * from \"./stores/PostgreSQLWorkspaceStore\";\nexport * from \"./stores/PostgreSQLProjectStore\";\nexport * from \"./stores/PostgreSQLUserStore\";\nexport * from \"./stores/PostgreSQLTenantStore\";\nexport * from \"./stores/PostgreSQLUserTenantLinkStore\";\nexport * from \"./migrations/migration\";\nexport * from \"./migrations/thread_migrations\";\nexport * from \"./migrations/thread_tenant_migration\";\nexport * from \"./migrations/thread_pk_migration\";\nexport * from \"./migrations/assistant_migrations\";\nexport * from \"./migrations/assistant_tenant_migration\";\nexport * from \"./migrations/assistant_pk_migration\";\nexport * from \"./migrations/schedule_migrations\";\nexport * from \"./migrations/schedule_tenant_migration\";\nexport * from \"./migrations/skill_migrations\";\nexport * from \"./migrations/skill_tenant_migration\";\nexport * from \"./migrations/skill_pk_migration\";\nexport * from \"./migrations/database_config_migrations\";\nexport * from \"./migrations/metrics_config_migrations\";\nexport * from \"./migrations/mcp_server_config_migrations\";\nexport * from \"./migrations/workspace_migrations\";\nexport * from \"./migrations/project_migrations\";\nexport * from \"./migrations/user_migrations\";\nexport * from \"./migrations/tenant_migrations\";\nexport * from \"./migrations/thread_message_queue_migrations\";\nexport * from \"./migrations/channel_identity_mapping_migration\";\nexport * from \"./migrations/channel_installation_migrations\";\nexport * from \"./migrations/channel_installations_alter_migration\";\nexport * from \"./migrations/channel_bindings_migration\";\nexport * from \"./migrations/workflow_tracking_migrations\";\nexport * from \"./stores/ChannelBindingStore\";\nexport * from \"./stores/ThreadMessageQueueStore\";\nexport * from \"./stores/ChannelIdentityMappingStore\";\nexport * from \"./stores/PostgreSQLChannelInstallationStore\";\nexport * from \"./stores/PostgreSQLWorkflowTrackingStore\";\nexport * from \"./stores/PostgreSQLEvalStore\";\nexport * from \"./migrations/eval_migrations\";\n\n// Re-export for convenience\nexport { PostgreSQLThreadStore } from \"./stores/PostgreSQLThreadStore\";\nexport { PostgreSQLAssistantStore } from \"./stores/PostgreSQLAssistantStore\";\nexport { PostgreSQLScheduleStorage } from \"./stores/PostgreSQLScheduleStorage\";\nexport { PostgreSQLSkillStore } from \"./stores/PostgreSQLSkillStore\";\nexport { PostgreSQLDatabaseConfigStore } from \"./stores/PostgreSQLDatabaseConfigStore\";\nexport { PostgreSQLMetricsServerConfigStore } from \"./stores/PostgreSQLMetricsServerConfigStore\";\nexport { PostgreSQLMcpServerConfigStore } from \"./stores/PostgreSQLMcpServerConfigStore\";\nexport { PostgreSQLWorkspaceStore } from \"./stores/PostgreSQLWorkspaceStore\";\nexport { PostgreSQLProjectStore } from \"./stores/PostgreSQLProjectStore\";\nexport { PostgreSQLUserStore } from \"./stores/PostgreSQLUserStore\";\nexport { PostgreSQLTenantStore } from \"./stores/PostgreSQLTenantStore\";\nexport { PostgreSQLUserTenantLinkStore } from \"./stores/PostgreSQLUserTenantLinkStore\";\nexport { ChannelBindingStore } from \"./stores/ChannelBindingStore\";\nexport { ChannelIdentityMappingStore } from \"./stores/ChannelIdentityMappingStore\";\nexport { PostgreSQLChannelInstallationStore } from \"./stores/PostgreSQLChannelInstallationStore\";\nexport { PostgreSQLWorkflowTrackingStore } from \"./stores/PostgreSQLWorkflowTrackingStore\";\nexport { PostgreSQLEvalStore } from \"./stores/PostgreSQLEvalStore\";\n\n// Re-export types from protocols\nexport type {\n ThreadStore,\n Thread,\n CreateThreadRequest,\n AssistantStore,\n Assistant,\n CreateAssistantRequest,\n ScheduleStorage,\n ScheduledTaskDefinition,\n ScheduledTaskStatus,\n ScheduleExecutionType,\n SkillStore,\n Skill,\n CreateSkillRequest,\n DatabaseConfigStore,\n DatabaseConfigEntry,\n CreateDatabaseConfigRequest,\n UpdateDatabaseConfigRequest,\n DatabaseConfig,\n DatabaseType,\n Binding,\n BindingRegistry,\n CreateBindingInput,\n ChannelInstallationStore,\n ChannelInstallation,\n CreateChannelInstallationRequest,\n UpdateChannelInstallationRequest,\n LarkChannelInstallationConfig,\n MetricsServerConfigStore,\n MetricsServerConfigEntry,\n CreateMetricsServerConfigRequest,\n UpdateMetricsServerConfigRequest,\n MetricsServerConfig,\n McpServerConfigStore,\n McpServerConfigEntry,\n CreateMcpServerConfigRequest,\n UpdateMcpServerConfigRequest,\n WorkspaceStore,\n Workspace,\n CreateWorkspaceRequest,\n UpdateWorkspaceRequest,\n StorageType,\n ProjectStore,\n Project,\n CreateProjectRequest,\n UpdateProjectRequest,\n UserStore,\n User,\n CreateUserRequest,\n UpdateUserRequest,\n TenantStore,\n Tenant,\n TenantStatus,\n CreateTenantRequest,\n UpdateTenantRequest,\n UserTenantLinkStore,\n UserTenantLink,\n UserTenantRole,\n CreateUserTenantLinkRequest,\n UpdateUserTenantLinkRequest,\n WorkflowTrackingStore,\n WorkflowRun,\n RunStep,\n CreateWorkflowRunRequest,\n UpdateWorkflowRunRequest,\n CreateRunStepRequest,\n UpdateRunStepRequest,\n EvalStore,\n EvalProject,\n CreateEvalProjectRequest,\n EvalSuite,\n CreateEvalSuiteRequest,\n EvalCase,\n CreateEvalCaseRequest,\n EvalRun,\n CreateEvalRunRequest,\n EvalRunResult,\n EvalProjectReport,\n} from \"@axiom-lattice/protocols\";\n","/**\n * PostgreSQL implementation of ThreadStore\n */\n\nimport { Pool, PoolClient } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n ThreadStore,\n Thread,\n CreateThreadRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createThreadsTable } from \"../migrations/thread_migrations\";\nimport { addThreadTenantId } from \"../migrations/thread_tenant_migration\";\nimport { changeThreadPrimaryKey } from \"../migrations/thread_pk_migration\";\n\n/**\n * PostgreSQL ThreadStore options\n */\nexport interface PostgreSQLThreadStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of ThreadStore\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n */\nexport class PostgreSQLThreadStore implements ThreadStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLThreadStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createThreadsTable);\n this.migrationManager.register(addThreadTenantId);\n this.migrationManager.register(changeThreadPrimaryKey);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLThreadStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all threads for a specific tenant and assistant\n */\n async getThreadsByAssistantId(\n tenantId: string,\n assistantId: string,\n metadataFilter?: Record<string, string>\n ): Promise<Thread[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n assistant_id: string;\n metadata: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, assistant_id, metadata, created_at, updated_at\n FROM lattice_threads\n WHERE tenant_id = $1 AND assistant_id = $2\n ORDER BY created_at DESC\n `,\n [tenantId, assistantId]\n );\n\n let threads = result.rows.map(this.mapRowToThread);\n\n // Apply metadata filtering if provided\n if (metadataFilter && Object.keys(metadataFilter).length > 0) {\n threads = threads.filter((thread) =>\n Object.entries(metadataFilter).every(\n ([key, value]) => thread.metadata?.[key] === value\n )\n );\n }\n\n return threads;\n }\n\n /**\n * Get a thread by ID for a specific tenant\n */\n async getThreadById(\n tenantId: string,\n threadId: string\n ): Promise<Thread | undefined> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n assistant_id: string;\n metadata: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, assistant_id, metadata, created_at, updated_at\n FROM lattice_threads\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, threadId]\n );\n\n if (result.rows.length === 0) {\n return undefined;\n }\n\n return this.mapRowToThread(result.rows[0]);\n }\n\n /**\n * Create a new thread for a tenant and assistant\n */\n async createThread(\n tenantId: string,\n assistantId: string,\n threadId: string,\n data: CreateThreadRequest\n ): Promise<Thread> {\n await this.ensureInitialized();\n\n const now = new Date();\n const metadata = data.metadata || {};\n\n await this.pool.query(\n `\n INSERT INTO lattice_threads (id, tenant_id, assistant_id, metadata, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6)\n ON CONFLICT (id, tenant_id) DO UPDATE SET\n assistant_id = EXCLUDED.assistant_id,\n metadata = EXCLUDED.metadata,\n updated_at = EXCLUDED.updated_at\n `,\n [threadId, tenantId, assistantId, JSON.stringify(metadata), now, now]\n );\n\n return {\n id: threadId,\n tenantId,\n assistantId,\n metadata,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing thread\n */\n async updateThread(\n tenantId: string,\n threadId: string,\n updates: Partial<CreateThreadRequest>\n ): Promise<Thread | null> {\n await this.ensureInitialized();\n\n // Get existing thread\n const existing = await this.getThreadById(tenantId, threadId);\n if (!existing) {\n return null;\n }\n\n // Merge metadata\n const updatedMetadata = {\n ...existing.metadata,\n ...(updates.metadata || {}),\n };\n\n const now = new Date();\n\n await this.pool.query(\n `\n UPDATE lattice_threads\n SET metadata = $1, updated_at = $2\n WHERE tenant_id = $3 AND id = $4\n `,\n [JSON.stringify(updatedMetadata), now, tenantId, threadId]\n );\n\n return {\n ...existing,\n metadata: updatedMetadata,\n updatedAt: now,\n };\n }\n\n /**\n * Delete a thread by ID\n */\n async deleteThread(tenantId: string, threadId: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_threads\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, threadId]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if thread exists\n */\n async hasThread(tenantId: string, threadId: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_threads\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, threadId]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Thread object\n */\n private mapRowToThread(row: {\n id: string;\n tenant_id: string;\n assistant_id: string;\n metadata: any;\n created_at: Date;\n updated_at: Date;\n }): Thread {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n assistantId: row.assistant_id,\n metadata:\n typeof row.metadata === \"string\"\n ? JSON.parse(row.metadata)\n : row.metadata || {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n}\n","/**\n * Migration system for database schema management\n */\n\nimport { Pool, PoolClient } from \"pg\";\n\n/**\n * Migration record stored in database\n */\ninterface MigrationRecord {\n version: number;\n name: string;\n applied_at: Date;\n}\n\n/**\n * Migration definition\n */\nexport interface Migration {\n version: number;\n name: string;\n up: (client: PoolClient) => Promise<void>;\n down?: (client: PoolClient) => Promise<void>;\n}\n\n/**\n * Migration manager\n */\nexport class MigrationManager {\n private pool: Pool;\n private migrations: Migration[] = [];\n\n constructor(pool: Pool) {\n this.pool = pool;\n }\n\n /**\n * Register a migration\n */\n register(migration: Migration): void {\n this.migrations.push(migration);\n // Sort migrations by version\n this.migrations.sort((a, b) => a.version - b.version);\n }\n\n /**\n * Initialize migrations table if it doesn't exist\n */\n private async ensureMigrationsTable(client: PoolClient): Promise<void> {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_schema_migrations (\n version INTEGER PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n }\n\n /**\n * Get applied migrations from database\n */\n private async getAppliedMigrations(\n client: PoolClient\n ): Promise<MigrationRecord[]> {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_schema_migrations (\n version INTEGER PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n const result = await client.query<MigrationRecord>(\n \"SELECT version, name, applied_at FROM lattice_schema_migrations ORDER BY version\"\n );\n return result.rows;\n }\n\n /**\n * Apply pending migrations\n * Uses PostgreSQL advisory locks to prevent concurrent migrations\n */\n async migrate(): Promise<void> {\n const client = await this.pool.connect();\n try {\n // Use advisory lock to prevent concurrent migrations\n // Lock ID: 123456789 (arbitrary but consistent)\n const lockId = 123456789;\n \n // Acquire advisory lock (blocks until lock is available)\n // This ensures only one migration runs at a time across all instances\n await client.query(\"SELECT pg_advisory_lock($1)\", [lockId]);\n \n try {\n await client.query(\"BEGIN\");\n\n await this.ensureMigrationsTable(client);\n const appliedMigrations = await this.getAppliedMigrations(client);\n const appliedVersions = new Set(appliedMigrations.map((m) => m.version));\n\n // Find pending migrations\n const pendingMigrations = this.migrations.filter(\n (m) => !appliedVersions.has(m.version)\n );\n\n if (pendingMigrations.length === 0) {\n console.log(\"No pending migrations\");\n await client.query(\"COMMIT\");\n return;\n }\n\n // Apply pending migrations\n for (const migration of pendingMigrations) {\n console.log(\n `Applying migration ${migration.version}: ${migration.name}`\n );\n await migration.up(client);\n // Use ON CONFLICT DO NOTHING to handle race conditions gracefully\n await client.query(\n \"INSERT INTO lattice_schema_migrations (version, name) VALUES ($1, $2) ON CONFLICT (version) DO NOTHING\",\n [migration.version, migration.name]\n );\n }\n\n await client.query(\"COMMIT\");\n console.log(`Applied ${pendingMigrations.length} migration(s)`);\n } catch (error) {\n await client.query(\"ROLLBACK\");\n throw error;\n } finally {\n // Release advisory lock\n await client.query(\"SELECT pg_advisory_unlock($1)\", [lockId]);\n }\n } catch (error) {\n throw error;\n } finally {\n client.release();\n }\n }\n\n /**\n * Rollback last migration\n */\n async rollback(): Promise<void> {\n const client = await this.pool.connect();\n try {\n await client.query(\"BEGIN\");\n\n const appliedMigrations = await this.getAppliedMigrations(client);\n if (appliedMigrations.length === 0) {\n console.log(\"No migrations to rollback\");\n await client.query(\"COMMIT\");\n return;\n }\n\n const lastMigration = appliedMigrations[appliedMigrations.length - 1];\n const migration = this.migrations.find(\n (m) => m.version === lastMigration.version\n );\n\n if (!migration || !migration.down) {\n throw new Error(\n `Migration ${lastMigration.version} does not have a down migration`\n );\n }\n\n console.log(\n `Rolling back migration ${lastMigration.version}: ${lastMigration.name}`\n );\n await migration.down(client);\n await client.query(\n \"DELETE FROM lattice_schema_migrations WHERE version = $1\",\n [lastMigration.version]\n );\n\n await client.query(\"COMMIT\");\n console.log(\"Rollback completed\");\n } catch (error) {\n await client.query(\"ROLLBACK\");\n throw error;\n } finally {\n client.release();\n }\n }\n\n /**\n * Get current migration version\n */\n async getCurrentVersion(): Promise<number> {\n const client = await this.pool.connect();\n try {\n const appliedMigrations = await this.getAppliedMigrations(client);\n if (appliedMigrations.length === 0) {\n return 0;\n }\n return Math.max(...appliedMigrations.map((m) => m.version));\n } finally {\n client.release();\n }\n }\n}\n","/**\n * Thread table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create threads table\n */\nexport const createThreadsTable: Migration = {\n version: 1,\n name: \"create_threads_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_threads (\n id VARCHAR(255) NOT NULL,\n assistant_id VARCHAR(255) NOT NULL,\n metadata JSONB DEFAULT '{}',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id, assistant_id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_threads_assistant_id \n ON lattice_threads(assistant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_threads_created_at \n ON lattice_threads(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_threads_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_threads_assistant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_threads\");\n },\n};\n","/**\n * Thread table tenant isolation migration\n * Adds tenant_id column to lattice_threads table\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add tenant_id column to threads table\n */\nexport const addThreadTenantId: Migration = {\n version: 23,\n name: \"add_thread_tenant_id\",\n up: async (client: PoolClient) => {\n // Add tenant_id column\n await client.query(`\n ALTER TABLE lattice_threads\n ADD COLUMN IF NOT EXISTS tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_threads \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL after setting defaults\n await client.query(`\n ALTER TABLE lattice_threads\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the default constraint\n await client.query(`\n ALTER TABLE lattice_threads\n ALTER COLUMN tenant_id DROP DEFAULT\n `);\n\n // Create index for tenant-based queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_threads_tenant_id \n ON lattice_threads(tenant_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_lattice_threads_tenant_id\"\n );\n await client.query(\n \"ALTER TABLE lattice_threads DROP COLUMN IF EXISTS tenant_id\"\n );\n },\n};\n","/**\n * Thread table primary key migration\n * Changes primary key from (id, assistant_id) to (id, tenant_id) for multi-tenancy\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Change primary key to support multi-tenancy\n */\nexport const changeThreadPrimaryKey: Migration = {\n version: 19,\n name: \"change_thread_primary_key\",\n up: async (client: PoolClient) => {\n // Check if table exists\n const tableExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.tables \n WHERE table_name = 'lattice_threads'\n )\n `);\n\n if (!tableExists.rows[0].exists) {\n // Table doesn't exist, it will be created with correct schema\n return;\n }\n\n // Check current primary key\n const pkResult = await client.query(`\n SELECT a.attname as column_name\n FROM pg_index i\n JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n WHERE i.indrelid = 'lattice_threads'::regclass\n AND i.indisprimary\n `);\n\n const pkColumns = pkResult.rows.map(row => row.column_name);\n \n // If primary key is already (id, tenant_id), nothing to do\n if (pkColumns.includes('tenant_id') && pkColumns.includes('id') && pkColumns.length === 2) {\n console.log('Primary key already correct (id, tenant_id)');\n return;\n }\n\n // If primary key is (id, assistant_id), we need to change it\n if (pkColumns.includes('id') && pkColumns.includes('assistant_id')) {\n console.log('Changing primary key from (id, assistant_id) to (id, tenant_id)');\n \n // Check if tenant_id column exists\n const tenantIdExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.columns \n WHERE table_name = 'lattice_threads' \n AND column_name = 'tenant_id'\n )\n `);\n\n if (!tenantIdExists.rows[0].exists) {\n // Add tenant_id column if it doesn't exist\n await client.query(`\n ALTER TABLE lattice_threads\n ADD COLUMN tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n }\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_threads \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL\n await client.query(`\n ALTER TABLE lattice_threads\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the old primary key\n await client.query(`\n ALTER TABLE lattice_threads \n DROP CONSTRAINT IF EXISTS lattice_threads_pkey\n `);\n\n // Add new composite primary key\n await client.query(`\n ALTER TABLE lattice_threads \n ADD PRIMARY KEY (id, tenant_id)\n `);\n\n console.log('Primary key changed successfully to (id, tenant_id)');\n }\n },\n down: async (client: PoolClient) => {\n // Reverting this is complex and potentially dangerous\n console.warn('Down migration for changeThreadPrimaryKey is not supported');\n },\n};\n","/**\n * PostgreSQL implementation of AssistantStore\n */\n\nimport { Pool, PoolClient } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n AssistantStore,\n Assistant,\n CreateAssistantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createAssistantsTable } from \"../migrations/assistant_migrations\";\nimport { addAssistantTenantId } from \"../migrations/assistant_tenant_migration\";\nimport { changeAssistantPrimaryKey } from \"../migrations/assistant_pk_migration\";\n\n/**\n * PostgreSQL AssistantStore options\n */\nexport interface PostgreSQLAssistantStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of AssistantStore\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n */\nexport class PostgreSQLAssistantStore implements AssistantStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLAssistantStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createAssistantsTable);\n this.migrationManager.register(addAssistantTenantId);\n this.migrationManager.register(changeAssistantPrimaryKey);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLAssistantStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all assistants for a tenant\n */\n async getAllAssistants(tenantId: string): Promise<Assistant[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n graph_definition: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, graph_definition, created_at, updated_at\n FROM lattice_assistants\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map(this.mapRowToAssistant);\n }\n\n /**\n * Get assistant by ID\n */\n async getAssistantById(tenantId: string, id: string): Promise<Assistant | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n graph_definition: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, graph_definition, created_at, updated_at\n FROM lattice_assistants\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToAssistant(result.rows[0]);\n }\n\n /**\n * Create a new assistant\n */\n async createAssistant(\n tenantId: string,\n id: string,\n data: CreateAssistantRequest\n ): Promise<Assistant> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_assistants (id, tenant_id, name, description, graph_definition, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id, tenant_id) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n graph_definition = EXCLUDED.graph_definition,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.name,\n data.description || null,\n JSON.stringify(data.graphDefinition),\n now,\n now,\n ]\n );\n\n return {\n id,\n tenantId,\n name: data.name,\n description: data.description,\n graphDefinition: data.graphDefinition,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing assistant\n */\n async updateAssistant(\n tenantId: string,\n id: string,\n updates: Partial<CreateAssistantRequest>\n ): Promise<Assistant | null> {\n await this.ensureInitialized();\n\n // Get existing assistant\n const existing = await this.getAssistantById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description || null);\n }\n\n if (updates.graphDefinition !== undefined) {\n updateFields.push(`graph_definition = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.graphDefinition));\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add tenant_id and id for WHERE clause\n updateValues.push(tenantId);\n updateValues.push(id);\n\n await this.pool.query(\n `\n UPDATE lattice_assistants\n SET ${updateFields.join(\", \")}\n WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex}\n `,\n updateValues\n );\n\n // Return updated assistant\n return await this.getAssistantById(tenantId, id);\n }\n\n /**\n * Delete an assistant by ID\n */\n async deleteAssistant(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_assistants\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if assistant exists\n */\n async hasAssistant(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_assistants\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Assistant object\n */\n private mapRowToAssistant(row: {\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n graph_definition: any;\n created_at: Date;\n updated_at: Date;\n }): Assistant {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n name: row.name,\n description: row.description || undefined,\n graphDefinition:\n typeof row.graph_definition === \"string\"\n ? JSON.parse(row.graph_definition)\n : row.graph_definition,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n}\n","/**\n * Assistant table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create assistants table\n */\nexport const createAssistantsTable: Migration = {\n version: 3,\n name: \"create_assistants_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_assistants (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL DEFAULT 'default',\n name VARCHAR(255) NOT NULL,\n description TEXT,\n graph_definition JSONB NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (tenant_id, id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_assistants_name \n ON lattice_assistants(name)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_assistants_created_at \n ON lattice_assistants(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_lattice_assistants_created_at\"\n );\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_assistants_name\");\n await client.query(\"DROP TABLE IF EXISTS lattice_assistants\");\n },\n};\n","/**\n * Assistant table tenant isolation migration\n * Adds tenant_id column to lattice_assistants table\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add tenant_id column to assistants table\n */\nexport const addAssistantTenantId: Migration = {\n version: 14,\n name: \"add_assistant_tenant_id\",\n up: async (client: PoolClient) => {\n // tenant_id column is now created in the initial migration\n // This migration is kept for backward compatibility but does nothing\n // Create index for tenant-based queries if not exists\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_assistants_tenant_id \n ON lattice_assistants(tenant_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_lattice_assistants_tenant_id\"\n );\n },\n};\n","/**\n * Assistant table primary key migration\n * Changes primary key from (id) to (tenant_id, id) for multi-tenancy\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Change primary key to support multi-tenancy\n */\nexport const changeAssistantPrimaryKey: Migration = {\n version: 112,\n name: \"change_assistant_primary_key\",\n up: async (client: PoolClient) => {\n // Check if table exists and has the old primary key structure\n const tableExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.tables \n WHERE table_name = 'lattice_assistants'\n )\n `);\n\n if (!tableExists.rows[0].exists) {\n // Table doesn't exist, it will be created by createAssistantsTable migration\n // with the correct primary key (tenant_id, id)\n return;\n }\n\n // Check current primary key\n const pkResult = await client.query(`\n SELECT a.attname as column_name\n FROM pg_index i\n JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n WHERE i.indrelid = 'lattice_assistants'::regclass\n AND i.indisprimary\n `);\n\n const pkColumns = pkResult.rows.map(row => row.column_name);\n \n // If primary key is already (tenant_id, id), nothing to do\n if (pkColumns.includes('tenant_id') && pkColumns.includes('id')) {\n console.log('Primary key already correct (tenant_id, id)');\n return;\n }\n\n // If primary key is just (id), we need to change it\n if (pkColumns.length === 1 && pkColumns[0] === 'id') {\n console.log('Changing primary key from (id) to (tenant_id, id)');\n \n // Check if tenant_id column exists\n const tenantIdExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.columns \n WHERE table_name = 'lattice_assistants' \n AND column_name = 'tenant_id'\n )\n `);\n\n if (!tenantIdExists.rows[0].exists) {\n // Add tenant_id column if it doesn't exist\n await client.query(`\n ALTER TABLE lattice_assistants\n ADD COLUMN tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n }\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_assistants \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL\n await client.query(`\n ALTER TABLE lattice_assistants\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the old primary key\n await client.query(`\n ALTER TABLE lattice_assistants \n DROP CONSTRAINT IF EXISTS lattice_assistants_pkey\n `);\n\n // Add new composite primary key\n await client.query(`\n ALTER TABLE lattice_assistants \n ADD PRIMARY KEY (tenant_id, id)\n `);\n\n console.log('Primary key changed successfully to (tenant_id, id)');\n }\n },\n down: async (client: PoolClient) => {\n // Reverting this is complex and potentially dangerous\n // as it would require ensuring no duplicate IDs across tenants\n console.warn('Down migration for changeAssistantPrimaryKey is not supported');\n },\n};\n","/**\n * PostgreSQL implementation of DatabaseConfigStore\n */\n\nimport { Pool, PoolClient } from 'pg';\nimport type { PoolConfig } from 'pg';\nimport {\n DatabaseConfigStore,\n DatabaseConfigEntry,\n CreateDatabaseConfigRequest,\n UpdateDatabaseConfigRequest,\n DatabaseConfig,\n} from '@axiom-lattice/protocols';\nimport { MigrationManager } from '../migrations/migration';\nimport { createDatabaseConfigsTable } from '../migrations/database_config_migrations';\nimport { encrypt, decrypt } from '@axiom-lattice/core';\n\n/**\n * PostgreSQL DatabaseConfigStore options\n */\nexport interface PostgreSQLDatabaseConfigStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of DatabaseConfigStore\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n * - Automatic password encryption/decryption\n * - Unique constraint on (tenant_id, key)\n */\nexport class PostgreSQLDatabaseConfigStore implements DatabaseConfigStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLDatabaseConfigStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === 'string') {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createDatabaseConfigsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error('Failed to initialize PostgreSQLDatabaseConfigStore:', error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all database configurations for a tenant\n */\n async getAllConfigs(tenantId: string): Promise<DatabaseConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_database_configs\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get all database configurations across all tenants\n */\n async getAllConfigsWithoutTenant(): Promise<DatabaseConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_database_configs\n ORDER BY created_at DESC\n `\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get database configuration by ID\n */\n async getConfigById(tenantId: string, id: string): Promise<DatabaseConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_database_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Get database configuration by business key\n */\n async getConfigByKey(tenantId: string, key: string): Promise<DatabaseConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_database_configs\n WHERE tenant_id = $1 AND key = $2\n `,\n [tenantId, key]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Create a new database configuration\n */\n async createConfig(\n tenantId: string,\n id: string,\n data: CreateDatabaseConfigRequest\n ): Promise<DatabaseConfigEntry> {\n await this.ensureInitialized();\n\n const now = new Date();\n const nowString = now.toISOString();\n const configWithEncryptedPassword = this.encryptPasswordInConfig(data.config);\n\n await this.pool.query(\n `\n INSERT INTO lattice_database_configs (id, tenant_id, key, name, description, config, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7::timestamp, $8::timestamp)\n ON CONFLICT (tenant_id, id) DO UPDATE SET\n key = EXCLUDED.key,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n config = EXCLUDED.config,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.key,\n data.name || null,\n data.description || null,\n JSON.stringify(configWithEncryptedPassword),\n nowString,\n nowString,\n ]\n );\n\n return {\n id,\n tenantId,\n key: data.key,\n config: data.config,\n name: data.name,\n description: data.description,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing database configuration\n */\n async updateConfig(\n tenantId: string,\n id: string,\n updates: Partial<UpdateDatabaseConfigRequest>\n ): Promise<DatabaseConfigEntry | null> {\n await this.ensureInitialized();\n\n const existing = await this.getConfigById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update fields and values as key-value pairs for clarity\n const updateData: Record<string, any> = {};\n\n if (updates.key !== undefined) {\n updateData.key = updates.key;\n }\n\n if (updates.name !== undefined) {\n updateData.name = updates.name || null;\n }\n\n if (updates.description !== undefined) {\n updateData.description = updates.description || null;\n }\n\n if (updates.config !== undefined) {\n const configWithEncryptedPassword = this.encryptPasswordInConfig(updates.config);\n updateData.config = JSON.stringify(configWithEncryptedPassword);\n }\n\n if (Object.keys(updateData).length === 0) {\n return existing;\n }\n\n // Always update the updated_at timestamp\n updateData.updated_at = new Date().toISOString();\n\n // Build SQL with tenantId and id at fixed positions at the end\n const fields = Object.keys(updateData);\n const values = Object.values(updateData);\n \n // Add WHERE clause values at the end\n values.push(tenantId);\n values.push(id);\n\n // Build SET clause with numbered parameters\n const setClauses = fields.map((field, index) => {\n if (field === 'updated_at') {\n return `${field} = $${index + 1}::timestamp`;\n }\n return `${field} = $${index + 1}`;\n });\n\n // WHERE clause parameters are at the end\n const whereTenantIndex = fields.length + 1;\n const whereIdIndex = fields.length + 2;\n\n const sql = `\n UPDATE lattice_database_configs\n SET ${setClauses.join(', ')}\n WHERE tenant_id = $${whereTenantIndex} AND id = $${whereIdIndex}\n `;\n\n await this.pool.query(sql, values);\n\n return await this.getConfigById(tenantId, id);\n }\n\n /**\n * Delete a database configuration by ID\n */\n async deleteConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_database_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if configuration exists\n */\n async hasConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_database_configs\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Dispose resources and close the connection pool\n */\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to DatabaseConfigEntry object\n * Automatically decrypts password if present\n */\n private mapRowToEntry(row: {\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }): DatabaseConfigEntry {\n const config: DatabaseConfig = typeof row.config === 'string'\n ? JSON.parse(row.config)\n : row.config;\n\n // Decrypt password if present\n if (config.password) {\n try {\n config.password = decrypt(config.password);\n } catch (error) {\n console.error('Failed to decrypt database password:', error);\n throw new Error('Failed to decrypt database configuration');\n }\n }\n\n return {\n id: row.id,\n tenantId: row.tenant_id,\n key: row.key,\n config,\n name: row.name || undefined,\n description: row.description || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Encrypt password in config before storing\n */\n private encryptPasswordInConfig(config: DatabaseConfig): DatabaseConfig {\n const configCopy = { ...config };\n \n if (configCopy.password) {\n configCopy.password = encrypt(configCopy.password);\n }\n \n return configCopy;\n }\n}\n","/**\n * Database configuration table migrations\n */\n\nimport { PoolClient } from 'pg';\nimport { Migration } from './migration';\n\n/**\n * Initial migration: Create database configs table\n */\nexport const createDatabaseConfigsTable: Migration = {\n version: 111,\n name: 'create_database_configs_table',\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_database_configs (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n key VARCHAR(255) NOT NULL,\n name VARCHAR(255),\n description TEXT,\n config JSONB NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n \n PRIMARY KEY (tenant_id, id),\n CONSTRAINT uk_lattice_database_configs_tenant_key UNIQUE (tenant_id, key)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_database_configs_tenant_id \n ON lattice_database_configs(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_database_configs_key \n ON lattice_database_configs(key)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query('DROP INDEX IF EXISTS idx_lattice_database_configs_key');\n await client.query('DROP INDEX IF EXISTS idx_lattice_database_configs_tenant_id');\n await client.query('DROP TABLE IF EXISTS lattice_database_configs');\n },\n};\n","/**\n * PostgreSQL implementation of MetricsServerConfigStore\n */\n\nimport { Pool, PoolClient } from 'pg';\nimport type { PoolConfig } from 'pg';\nimport {\n MetricsServerConfigStore,\n MetricsServerConfigEntry,\n CreateMetricsServerConfigRequest,\n UpdateMetricsServerConfigRequest,\n MetricsServerConfig,\n} from '@axiom-lattice/protocols';\nimport { MigrationManager } from '../migrations/migration';\nimport { createMetricsConfigsTable } from '../migrations/metrics_config_migrations';\nimport { encrypt, decrypt } from '@axiom-lattice/core';\n\n/**\n * PostgreSQL MetricsServerConfigStore options\n */\nexport interface PostgreSQLMetricsServerConfigStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of MetricsServerConfigStore\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n * - Automatic apiKey and password encryption/decryption\n * - Unique constraint on (tenant_id, key)\n */\nexport class PostgreSQLMetricsServerConfigStore implements MetricsServerConfigStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLMetricsServerConfigStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === 'string') {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createMetricsConfigsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error('Failed to initialize PostgreSQLMetricsServerConfigStore:', error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all metrics server configurations for a tenant\n */\n async getAllConfigs(tenantId: string): Promise<MetricsServerConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_metrics_configs\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get all metrics server configurations across all tenants\n */\n async getAllConfigsWithoutTenant(): Promise<MetricsServerConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_metrics_configs\n ORDER BY created_at DESC\n `\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get metrics server configuration by ID\n */\n async getConfigById(tenantId: string, id: string): Promise<MetricsServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_metrics_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Get metrics server configuration by business key\n */\n async getConfigByKey(tenantId: string, key: string): Promise<MetricsServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, created_at, updated_at\n FROM lattice_metrics_configs\n WHERE tenant_id = $1 AND key = $2\n `,\n [tenantId, key]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Create a new metrics server configuration\n */\n async createConfig(\n tenantId: string,\n id: string,\n data: CreateMetricsServerConfigRequest\n ): Promise<MetricsServerConfigEntry> {\n await this.ensureInitialized();\n\n const now = new Date();\n const nowString = now.toISOString();\n const configWithEncryptedSecrets = this.encryptSecretsInConfig(data.config);\n\n await this.pool.query(\n `\n INSERT INTO lattice_metrics_configs (id, tenant_id, key, name, description, config, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7::timestamp, $8::timestamp)\n ON CONFLICT (tenant_id, id) DO UPDATE SET\n key = EXCLUDED.key,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n config = EXCLUDED.config,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.key,\n data.name || null,\n data.description || null,\n JSON.stringify(configWithEncryptedSecrets),\n nowString,\n nowString,\n ]\n );\n\n return {\n id,\n tenantId,\n key: data.key,\n config: data.config,\n name: data.name,\n description: data.description,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing metrics server configuration\n */\n async updateConfig(\n tenantId: string,\n id: string,\n updates: Partial<UpdateMetricsServerConfigRequest>\n ): Promise<MetricsServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const existing = await this.getConfigById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update fields and values as key-value pairs for clarity\n const updateData: Record<string, any> = {};\n\n if (updates.key !== undefined) {\n updateData.key = updates.key;\n }\n\n if (updates.name !== undefined) {\n updateData.name = updates.name || null;\n }\n\n if (updates.description !== undefined) {\n updateData.description = updates.description || null;\n }\n\n if (updates.config !== undefined) {\n const configWithEncryptedSecrets = this.encryptSecretsInConfig(updates.config);\n updateData.config = JSON.stringify(configWithEncryptedSecrets);\n }\n\n if (Object.keys(updateData).length === 0) {\n return existing;\n }\n\n // Always update the updated_at timestamp\n updateData.updated_at = new Date().toISOString();\n\n // Build SQL with tenantId and id at fixed positions at the end\n const fields = Object.keys(updateData);\n const values = Object.values(updateData);\n \n // Add WHERE clause values at the end\n values.push(tenantId);\n values.push(id);\n\n // Build SET clause with numbered parameters\n const setClauses = fields.map((field, index) => {\n if (field === 'updated_at') {\n return `${field} = $${index + 1}::timestamp`;\n }\n return `${field} = $${index + 1}`;\n });\n\n // WHERE clause parameters are at the end\n const whereTenantIndex = fields.length + 1;\n const whereIdIndex = fields.length + 2;\n\n const sql = `\n UPDATE lattice_metrics_configs\n SET ${setClauses.join(', ')}\n WHERE tenant_id = $${whereTenantIndex} AND id = $${whereIdIndex}\n `;\n\n await this.pool.query(sql, values);\n\n return await this.getConfigById(tenantId, id);\n }\n\n /**\n * Delete a metrics server configuration by ID\n */\n async deleteConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_metrics_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if configuration exists\n */\n async hasConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_metrics_configs\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Dispose resources and close the connection pool\n */\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to MetricsServerConfigEntry object\n * Automatically decrypts apiKey and password if present\n */\n private mapRowToEntry(row: {\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n created_at: Date;\n updated_at: Date;\n }): MetricsServerConfigEntry {\n const config: MetricsServerConfig = typeof row.config === 'string'\n ? JSON.parse(row.config)\n : row.config;\n\n // Decrypt apiKey if present\n if (config.apiKey) {\n try {\n config.apiKey = decrypt(config.apiKey);\n } catch (error) {\n console.error('Failed to decrypt apiKey:', error);\n throw new Error('Failed to decrypt metrics server configuration');\n }\n }\n\n // Decrypt password if present\n if (config.password) {\n try {\n config.password = decrypt(config.password);\n } catch (error) {\n console.error('Failed to decrypt password:', error);\n throw new Error('Failed to decrypt metrics server configuration');\n }\n }\n\n return {\n id: row.id,\n tenantId: row.tenant_id,\n key: row.key,\n config,\n name: row.name || undefined,\n description: row.description || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Encrypt apiKey and password in config before storing\n */\n private encryptSecretsInConfig(config: MetricsServerConfig): MetricsServerConfig {\n const configCopy = { ...config };\n \n if (configCopy.apiKey) {\n configCopy.apiKey = encrypt(configCopy.apiKey);\n }\n \n if (configCopy.password) {\n configCopy.password = encrypt(configCopy.password);\n }\n \n return configCopy;\n }\n}\n","/**\n * Metrics server configuration table migrations\n */\n\nimport { PoolClient } from 'pg';\nimport { Migration } from './migration';\n\n/**\n * Initial migration: Create metrics configs table\n */\nexport const createMetricsConfigsTable: Migration = {\n version: 12,\n name: 'create_metrics_configs_table',\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_metrics_configs (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n key VARCHAR(255) NOT NULL,\n name VARCHAR(255),\n description TEXT,\n config JSONB NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n \n PRIMARY KEY (tenant_id, id),\n CONSTRAINT uk_lattice_metrics_configs_tenant_key UNIQUE (tenant_id, key)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_metrics_configs_tenant_id \n ON lattice_metrics_configs(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_metrics_configs_key \n ON lattice_metrics_configs(key)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query('DROP INDEX IF EXISTS idx_lattice_metrics_configs_key');\n await client.query('DROP INDEX IF EXISTS idx_lattice_metrics_configs_tenant_id');\n await client.query('DROP TABLE IF EXISTS lattice_metrics_configs');\n },\n};\n","/**\n * PostgreSQL implementation of McpServerConfigStore\n */\n\nimport { Pool } from 'pg';\nimport type { PoolConfig } from 'pg';\nimport {\n McpServerConfigStore,\n McpServerConfigEntry,\n CreateMcpServerConfigRequest,\n UpdateMcpServerConfigRequest,\n McpServerConfig,\n} from '@axiom-lattice/protocols';\nimport { MigrationManager } from '../migrations/migration';\nimport { createMcpServerConfigsTable } from '../migrations/mcp_server_config_migrations';\nimport { encrypt, decrypt } from '@axiom-lattice/core';\n\n/**\n * PostgreSQL McpServerConfigStore options\n */\nexport interface PostgreSQLMcpServerConfigStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of McpServerConfigStore\n *\n * Features:\n * - Multi-tenant isolation via tenant_id\n * - Automatic env encryption/decryption\n * - Unique constraint on (tenant_id, key)\n */\nexport class PostgreSQLMcpServerConfigStore implements McpServerConfigStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLMcpServerConfigStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === 'string') {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createMcpServerConfigsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error('Failed to initialize PostgreSQLMcpServerConfigStore:', error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Get all MCP server configurations for a tenant\n */\n async getAllConfigs(tenantId: string): Promise<McpServerConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at\n FROM lattice_mcp_server_configs\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get all MCP server configurations across all tenants\n */\n async getAllConfigsWithoutTenant(): Promise<McpServerConfigEntry[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at\n FROM lattice_mcp_server_configs\n ORDER BY created_at DESC\n `\n );\n\n return result.rows.map((row) => this.mapRowToEntry(row));\n }\n\n /**\n * Get MCP server configuration by ID\n */\n async getConfigById(tenantId: string, id: string): Promise<McpServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at\n FROM lattice_mcp_server_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Get MCP server configuration by business key\n */\n async getConfigByKey(tenantId: string, key: string): Promise<McpServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at\n FROM lattice_mcp_server_configs\n WHERE tenant_id = $1 AND key = $2\n `,\n [tenantId, key]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToEntry(result.rows[0]);\n }\n\n /**\n * Create a new MCP server configuration\n */\n async createConfig(\n tenantId: string,\n id: string,\n data: CreateMcpServerConfigRequest\n ): Promise<McpServerConfigEntry> {\n await this.ensureInitialized();\n\n const now = new Date();\n const nowString = now.toISOString();\n const { config: configWithEncryptedEnv, isEnvEncrypted } = this.encryptEnvInConfig(data.config);\n\n await this.pool.query(\n `\n INSERT INTO lattice_mcp_server_configs (id, tenant_id, key, name, description, config, selected_tools, is_env_encrypted, status, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10::timestamp, $11::timestamp)\n ON CONFLICT (tenant_id, id) DO UPDATE SET\n key = EXCLUDED.key,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n config = EXCLUDED.config,\n selected_tools = EXCLUDED.selected_tools,\n is_env_encrypted = EXCLUDED.is_env_encrypted,\n status = EXCLUDED.status,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.key,\n data.name || null,\n data.description || null,\n JSON.stringify(configWithEncryptedEnv),\n data.selectedTools || [],\n isEnvEncrypted,\n 'disconnected',\n nowString,\n nowString,\n ]\n );\n\n return {\n id,\n tenantId,\n key: data.key,\n config: data.config,\n selectedTools: data.selectedTools || [],\n isEnvEncrypted,\n status: 'disconnected',\n name: data.name,\n description: data.description,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing MCP server configuration\n */\n async updateConfig(\n tenantId: string,\n id: string,\n updates: Partial<UpdateMcpServerConfigRequest>\n ): Promise<McpServerConfigEntry | null> {\n await this.ensureInitialized();\n\n const existing = await this.getConfigById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update fields and values as key-value pairs for clarity\n const updateData: Record<string, any> = {};\n\n if (updates.key !== undefined) {\n updateData.key = updates.key;\n }\n\n if (updates.name !== undefined) {\n updateData.name = updates.name || null;\n }\n\n if (updates.description !== undefined) {\n updateData.description = updates.description || null;\n }\n\n if (updates.config !== undefined) {\n const { config: configWithEncryptedEnv, isEnvEncrypted } = this.encryptEnvInConfig(updates.config);\n updateData.config = JSON.stringify(configWithEncryptedEnv);\n updateData.is_env_encrypted = isEnvEncrypted;\n }\n\n if (updates.selectedTools !== undefined) {\n updateData.selected_tools = updates.selectedTools;\n }\n\n if (updates.status !== undefined) {\n updateData.status = updates.status;\n }\n\n if (Object.keys(updateData).length === 0) {\n return existing;\n }\n\n // Always update the updated_at timestamp\n updateData.updated_at = new Date().toISOString();\n\n // Build SQL with tenantId and id at fixed positions at the end\n const fields = Object.keys(updateData);\n const values = Object.values(updateData);\n\n // Add WHERE clause values at the end\n values.push(tenantId);\n values.push(id);\n\n // Build SET clause with numbered parameters\n const setClauses = fields.map((field, index) => {\n if (field === 'updated_at') {\n return `${field} = $${index + 1}::timestamp`;\n }\n return `${field} = $${index + 1}`;\n });\n\n // WHERE clause parameters are at the end\n const whereTenantIndex = fields.length + 1;\n const whereIdIndex = fields.length + 2;\n\n const sql = `\n UPDATE lattice_mcp_server_configs\n SET ${setClauses.join(', ')}\n WHERE tenant_id = $${whereTenantIndex} AND id = $${whereIdIndex}\n `;\n\n await this.pool.query(sql, values);\n\n return await this.getConfigById(tenantId, id);\n }\n\n /**\n * Delete a MCP server configuration by ID\n */\n async deleteConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_mcp_server_configs\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if configuration exists\n */\n async hasConfig(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_mcp_server_configs\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Dispose resources and close the connection pool\n */\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to McpServerConfigEntry object\n * Automatically decrypts env values if present\n */\n private mapRowToEntry(row: {\n id: string;\n tenant_id: string;\n key: string;\n name: string | null;\n description: string | null;\n config: any;\n selected_tools: string[];\n is_env_encrypted: boolean;\n status: string;\n created_at: Date;\n updated_at: Date;\n }): McpServerConfigEntry {\n const config: McpServerConfig = typeof row.config === 'string'\n ? JSON.parse(row.config)\n : row.config;\n\n // Decrypt env values if present and encrypted\n if (config.env && row.is_env_encrypted) {\n try {\n const decryptedEnv: Record<string, string> = {};\n for (const [key, value] of Object.entries(config.env)) {\n decryptedEnv[key] = decrypt(value);\n }\n config.env = decryptedEnv;\n } catch (error) {\n console.error('Failed to decrypt MCP server env:', error);\n throw new Error('Failed to decrypt MCP server configuration');\n }\n }\n\n return {\n id: row.id,\n tenantId: row.tenant_id,\n key: row.key,\n config,\n selectedTools: row.selected_tools || [],\n isEnvEncrypted: row.is_env_encrypted,\n status: row.status as 'disconnected' | 'connected' | 'error',\n name: row.name || undefined,\n description: row.description || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Encrypt env values in config before storing\n */\n private encryptEnvInConfig(config: McpServerConfig): { config: McpServerConfig; isEnvEncrypted: boolean } {\n const configCopy = { ...config };\n let isEnvEncrypted = false;\n\n if (configCopy.env && Object.keys(configCopy.env).length > 0) {\n const encryptedEnv: Record<string, string> = {};\n for (const [key, value] of Object.entries(configCopy.env)) {\n encryptedEnv[key] = encrypt(value);\n }\n configCopy.env = encryptedEnv;\n isEnvEncrypted = true;\n }\n\n return { config: configCopy, isEnvEncrypted };\n }\n}\n","/**\n * MCP Server configuration table migrations\n */\n\nimport { PoolClient } from 'pg';\nimport { Migration } from './migration';\n\n/**\n * Migration: Create MCP server configs table\n */\nexport const createMcpServerConfigsTable: Migration = {\n version: 13, // Use next available version number\n name: 'create_mcp_server_configs_table',\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_mcp_server_configs (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n key VARCHAR(255) NOT NULL,\n name VARCHAR(255),\n description TEXT,\n config JSONB NOT NULL,\n selected_tools JSONB NOT NULL DEFAULT '[]',\n is_env_encrypted BOOLEAN NOT NULL DEFAULT FALSE,\n status VARCHAR(50) NOT NULL DEFAULT 'disconnected',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n \n PRIMARY KEY (tenant_id, id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_mcp_server_configs_tenant_id \n ON lattice_mcp_server_configs(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_mcp_server_configs_key \n ON lattice_mcp_server_configs(key)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_mcp_server_configs_status \n ON lattice_mcp_server_configs(status)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query('DROP INDEX IF EXISTS idx_lattice_mcp_server_configs_status');\n await client.query('DROP INDEX IF EXISTS idx_lattice_mcp_server_configs_key');\n await client.query('DROP INDEX IF EXISTS idx_lattice_mcp_server_configs_tenant_id');\n await client.query('DROP TABLE IF EXISTS lattice_mcp_server_configs');\n },\n};\n","/**\n * PostgreSQL implementation of WorkspaceStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n WorkspaceStore,\n Workspace,\n CreateWorkspaceRequest,\n UpdateWorkspaceRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createWorkspacesTable } from \"../migrations/workspace_migrations\";\n\n/**\n * PostgreSQL WorkspaceStore options\n */\nexport interface PostgreSQLWorkspaceStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of WorkspaceStore\n */\nexport class PostgreSQLWorkspaceStore implements WorkspaceStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n\n constructor(options: PostgreSQLWorkspaceStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createWorkspacesTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLWorkspaceStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Workspace object\n */\n private mapRowToWorkspace(row: {\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n storage_type: string;\n created_at: Date;\n updated_at: Date;\n }): Workspace {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n name: row.name,\n description: row.description || undefined,\n storageType: row.storage_type as Workspace[\"storageType\"],\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Get all workspaces for a tenant\n */\n async getAllWorkspaces(tenantId: string): Promise<Workspace[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n storage_type: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, storage_type, created_at, updated_at\n FROM lattice_workspaces\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map(this.mapRowToWorkspace);\n }\n\n /**\n * Get a workspace by ID for a specific tenant\n */\n async getWorkspaceById(tenantId: string, id: string): Promise<Workspace | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n storage_type: string;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, storage_type, created_at, updated_at\n FROM lattice_workspaces\n WHERE id = $1 AND tenant_id = $2\n `,\n [id, tenantId]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToWorkspace(result.rows[0]);\n }\n\n /**\n * Create a new workspace\n */\n async createWorkspace(\n tenantId: string,\n id: string,\n data: CreateWorkspaceRequest\n ): Promise<Workspace> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_workspaces (id, tenant_id, name, description, storage_type, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id, tenant_id) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n storage_type = EXCLUDED.storage_type,\n updated_at = EXCLUDED.updated_at\n `,\n [id, tenantId, data.name, data.description || null, data.storageType, now, now]\n );\n\n return {\n id,\n tenantId,\n name: data.name,\n description: data.description,\n storageType: data.storageType,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing workspace\n */\n async updateWorkspace(\n tenantId: string,\n id: string,\n updates: UpdateWorkspaceRequest\n ): Promise<Workspace | null> {\n await this.ensureInitialized();\n\n // Get existing workspace\n const existing = await this.getWorkspaceById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description || null);\n }\n\n if (updates.storageType !== undefined) {\n updateFields.push(`storage_type = $${paramIndex++}`);\n updateValues.push(updates.storageType);\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add id and tenant_id for WHERE clause\n updateValues.push(id);\n updateValues.push(tenantId);\n\n await this.pool.query(\n `\n UPDATE lattice_workspaces\n SET ${updateFields.join(\", \")}\n WHERE id = $${paramIndex} AND tenant_id = $${paramIndex + 1}\n `,\n updateValues\n );\n\n // Return updated workspace\n return await this.getWorkspaceById(tenantId, id);\n }\n\n /**\n * Delete a workspace by ID\n */\n async deleteWorkspace(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_workspaces\n WHERE id = $1 AND tenant_id = $2\n `,\n [id, tenantId]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n}\n","/**\n * Workspace table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create workspaces table\n */\nexport const createWorkspacesTable: Migration = {\n version: 5,\n name: \"create_workspaces_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_workspaces (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n name VARCHAR(255) NOT NULL,\n description TEXT,\n storage_type VARCHAR(50) NOT NULL DEFAULT 'sandbox',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id, tenant_id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_workspaces_tenant_id \n ON lattice_workspaces(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_workspaces_created_at \n ON lattice_workspaces(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_workspaces_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_workspaces_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_workspaces\");\n },\n};\n","/**\n * PostgreSQL implementation of ProjectStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n ProjectStore,\n Project,\n CreateProjectRequest,\n UpdateProjectRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createProjectsTable } from \"../migrations/project_migrations\";\n\n/**\n * PostgreSQL ProjectStore options\n */\nexport interface PostgreSQLProjectStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of ProjectStore\n */\nexport class PostgreSQLProjectStore implements ProjectStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n\n constructor(options: PostgreSQLProjectStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createProjectsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLProjectStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Project object\n */\n private mapRowToProject(row: {\n id: string;\n tenant_id: string;\n workspace_id: string;\n name: string;\n description: string | null;\n created_at: Date;\n updated_at: Date;\n }): Project {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n workspaceId: row.workspace_id,\n name: row.name,\n description: row.description || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Get all projects for a specific workspace\n */\n async getProjectsByWorkspace(tenantId: string, workspaceId: string): Promise<Project[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n workspace_id: string;\n name: string;\n description: string | null;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, workspace_id, name, description, created_at, updated_at\n FROM lattice_projects\n WHERE tenant_id = $1 AND workspace_id = $2\n ORDER BY created_at DESC\n `,\n [tenantId, workspaceId]\n );\n\n return result.rows.map(this.mapRowToProject);\n }\n\n /**\n * Get a project by ID for a specific tenant\n */\n async getProjectById(tenantId: string, id: string): Promise<Project | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n workspace_id: string;\n name: string;\n description: string | null;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, workspace_id, name, description, created_at, updated_at\n FROM lattice_projects\n WHERE id = $1 AND tenant_id = $2\n `,\n [id, tenantId]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToProject(result.rows[0]);\n }\n\n /**\n * Create a new project\n */\n async createProject(\n tenantId: string,\n workspaceId: string,\n id: string,\n data: CreateProjectRequest\n ): Promise<Project> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_projects (id, tenant_id, workspace_id, name, description, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id, tenant_id) DO UPDATE SET\n workspace_id = EXCLUDED.workspace_id,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n updated_at = EXCLUDED.updated_at\n `,\n [id, tenantId, workspaceId, data.name, data.description || null, now, now]\n );\n\n return {\n id,\n tenantId,\n workspaceId,\n name: data.name,\n description: data.description,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing project\n */\n async updateProject(\n tenantId: string,\n id: string,\n updates: UpdateProjectRequest\n ): Promise<Project | null> {\n await this.ensureInitialized();\n\n // Get existing project\n const existing = await this.getProjectById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description || null);\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add id and tenant_id for WHERE clause\n updateValues.push(id);\n updateValues.push(tenantId);\n\n await this.pool.query(\n `\n UPDATE lattice_projects\n SET ${updateFields.join(\", \")}\n WHERE id = $${paramIndex} AND tenant_id = $${paramIndex + 1}\n `,\n updateValues\n );\n\n // Return updated project\n return await this.getProjectById(tenantId, id);\n }\n\n /**\n * Delete a project by ID\n */\n async deleteProject(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_projects\n WHERE id = $1 AND tenant_id = $2\n `,\n [id, tenantId]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n}\n","/**\n * Project table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create projects table\n */\nexport const createProjectsTable: Migration = {\n version: 6,\n name: \"create_projects_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_projects (\n id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n workspace_id VARCHAR(255) NOT NULL,\n name VARCHAR(255) NOT NULL,\n description TEXT,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id, tenant_id)\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_projects_tenant_id \n ON lattice_projects(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_projects_workspace_id \n ON lattice_projects(workspace_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_projects_created_at \n ON lattice_projects(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_projects_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_projects_workspace_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_projects_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_projects\");\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport { UserStore, User, CreateUserRequest, UpdateUserRequest } from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createUsersTable } from \"../migrations/user_migrations\";\nimport { addUserStatusColumn } from \"../migrations/user_status_migration\";\n\nexport interface PostgreSQLUserStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport class PostgreSQLUserStore implements UserStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n\n constructor(options: PostgreSQLUserStoreOptions) {\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createUsersTable);\n this.migrationManager.register(addUserStatusColumn);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLUserStore:\", error);\n throw error;\n });\n }\n }\n\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) await this.initialize();\n }\n\n private mapRowToUser(row: {\n id: string;\n email: string;\n name: string;\n status: string;\n metadata: Record<string, any>;\n created_at: Date;\n updated_at: Date;\n }): User {\n return {\n id: row.id,\n email: row.email,\n name: row.name,\n status: row.status as import(\"@axiom-lattice/protocols\").UserStatus,\n metadata: row.metadata,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n async getAllUsers(): Promise<User[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT id, email, name, status, metadata, created_at, updated_at\n FROM lattice_users\n ORDER BY created_at DESC\n `\n );\n\n return result.rows.map(this.mapRowToUser);\n }\n\n async getUserById(id: string): Promise<User | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT id, email, name, status, metadata, created_at, updated_at\n FROM lattice_users\n WHERE id = $1\n `,\n [id]\n );\n\n if (result.rows.length === 0) return null;\n return this.mapRowToUser(result.rows[0]);\n }\n\n async getUserByEmail(email: string): Promise<User | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT id, email, name, status, metadata, created_at, updated_at\n FROM lattice_users\n WHERE email = $1\n `,\n [email]\n );\n\n if (result.rows.length === 0) return null;\n return this.mapRowToUser(result.rows[0]);\n }\n\n async createUser(id: string, data: CreateUserRequest): Promise<User> {\n await this.ensureInitialized();\n\n const now = new Date();\n const metadata = data.metadata || {};\n const status = data.status || \"pending\";\n\n await this.pool.query(\n `\n INSERT INTO lattice_users (id, email, name, status, metadata, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id) DO UPDATE SET\n email = EXCLUDED.email,\n name = EXCLUDED.name,\n status = EXCLUDED.status,\n metadata = EXCLUDED.metadata,\n updated_at = EXCLUDED.updated_at\n `,\n [id, data.email, data.name, status, JSON.stringify(metadata), now, now]\n );\n\n return {\n id,\n email: data.email,\n name: data.name,\n status,\n metadata: data.metadata,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n async updateUser(id: string, updates: UpdateUserRequest): Promise<User | null> {\n await this.ensureInitialized();\n\n const existing = await this.getUserById(id);\n if (!existing) return null;\n\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.email !== undefined) {\n updateFields.push(`email = $${paramIndex++}`);\n updateValues.push(updates.email);\n }\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.status !== undefined) {\n updateFields.push(`status = $${paramIndex++}`);\n updateValues.push(updates.status);\n }\n\n if (updates.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.metadata));\n }\n\n if (updateFields.length === 0) return existing;\n\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n updateValues.push(id);\n\n await this.pool.query(\n `\n UPDATE lattice_users\n SET ${updateFields.join(\", \")}\n WHERE id = $${paramIndex}\n `,\n updateValues\n );\n\n return this.getUserById(id);\n }\n\n async deleteUser(id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `DELETE FROM lattice_users WHERE id = $1`,\n [id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n}\n","/**\n * User table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Create users table (multi-tenant refactor: removed tenant_id)\n */\nexport const createUsersTable: Migration = {\n version: 7,\n name: \"create_users_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_users (\n id VARCHAR(255) PRIMARY KEY,\n email VARCHAR(255) NOT NULL UNIQUE,\n name VARCHAR(255) NOT NULL,\n metadata JSONB DEFAULT '{}',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_users_email \n ON lattice_users(email)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_users_created_at \n ON lattice_users(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_users_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_users_email\");\n await client.query(\"DROP TABLE IF EXISTS lattice_users\");\n },\n};\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration to create lattice_users table with status support\n * Version 9: Adds status column to support user approval workflow\n */\nexport const addUserStatusColumn: Migration = {\n version: 9,\n name: \"add_user_status_column\",\n up: async (client: PoolClient) => {\n // Add status column if not exists\n await client.query(`\n ALTER TABLE lattice_users \n ADD COLUMN IF NOT EXISTS status VARCHAR(50) NOT NULL DEFAULT 'pending'\n `);\n \n // Create index on status for filtering\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_users_status \n ON lattice_users(status)\n `);\n \n // Migrate existing users to active status\n await client.query(`\n UPDATE lattice_users \n SET status = 'active' \n WHERE status = 'pending'\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(`\n DROP INDEX IF EXISTS idx_lattice_users_status\n `);\n await client.query(`\n ALTER TABLE lattice_users \n DROP COLUMN IF EXISTS status\n `);\n },\n};\n","/**\n * PostgreSQL implementation of TenantStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n TenantStore,\n Tenant,\n TenantStatus,\n CreateTenantRequest,\n UpdateTenantRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createTenantsTable } from \"../migrations/tenant_migrations\";\n\n/**\n * PostgreSQL TenantStore options\n */\nexport interface PostgreSQLTenantStoreOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of TenantStore\n * Tenant is a top-level entity with single column primary key\n */\nexport class PostgreSQLTenantStore implements TenantStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n\n constructor(options: PostgreSQLTenantStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createTenantsTable);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLTenantStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n * Should be called when the store is no longer needed\n */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Tenant object\n */\n private mapRowToTenant(row: {\n id: string;\n name: string;\n description: string | null;\n status: string;\n metadata: Record<string, any>;\n created_at: Date;\n updated_at: Date;\n }): Tenant {\n return {\n id: row.id,\n name: row.name,\n description: row.description || undefined,\n status: row.status as TenantStatus,\n metadata: row.metadata || undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Get all tenants\n */\n async getAllTenants(): Promise<Tenant[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n name: string;\n description: string | null;\n status: string;\n metadata: Record<string, any>;\n created_at: Date;\n updated_at: Date;\n }>(`\n SELECT id, name, description, status, metadata, created_at, updated_at\n FROM lattice_tenants\n ORDER BY created_at DESC\n `);\n\n return result.rows.map(this.mapRowToTenant);\n }\n\n /**\n * Get a tenant by ID\n */\n async getTenantById(id: string): Promise<Tenant | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n name: string;\n description: string | null;\n status: string;\n metadata: Record<string, any>;\n created_at: Date;\n updated_at: Date;\n }>(`\n SELECT id, name, description, status, metadata, created_at, updated_at\n FROM lattice_tenants\n WHERE id = $1\n `, [id]);\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToTenant(result.rows[0]);\n }\n\n /**\n * Create a new tenant\n */\n async createTenant(\n id: string,\n data: CreateTenantRequest\n ): Promise<Tenant> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_tenants (id, name, description, status, metadata, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT (id) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n status = EXCLUDED.status,\n metadata = EXCLUDED.metadata,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n data.name,\n data.description || null,\n data.status || \"active\",\n data.metadata || {},\n now,\n now,\n ]\n );\n\n return {\n id,\n name: data.name,\n description: data.description,\n status: data.status || \"active\",\n metadata: data.metadata,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing tenant\n */\n async updateTenant(\n id: string,\n updates: UpdateTenantRequest\n ): Promise<Tenant | null> {\n await this.ensureInitialized();\n\n // Get existing tenant\n const existing = await this.getTenantById(id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description || null);\n }\n\n if (updates.status !== undefined) {\n updateFields.push(`status = $${paramIndex++}`);\n updateValues.push(updates.status);\n }\n\n if (updates.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n updateValues.push(updates.metadata);\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add id for WHERE clause\n updateValues.push(id);\n\n await this.pool.query(\n `\n UPDATE lattice_tenants\n SET ${updateFields.join(\", \")}\n WHERE id = $${paramIndex}\n `,\n updateValues\n );\n\n // Return updated tenant\n return await this.getTenantById(id);\n }\n\n /**\n * Delete a tenant by ID\n */\n async deleteTenant(id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_tenants\n WHERE id = $1\n `,\n [id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n}\n","/**\n * Tenant table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Create tenants table\n * Tenant is a top-level entity with single column primary key\n */\nexport const createTenantsTable: Migration = {\n version: 8,\n name: \"create_tenants_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_tenants (\n id VARCHAR(255) PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n description TEXT,\n status VARCHAR(50) NOT NULL DEFAULT 'active',\n metadata JSONB DEFAULT '{}',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_tenants_status \n ON lattice_tenants(status)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_tenants_created_at \n ON lattice_tenants(created_at DESC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_tenants_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_tenants_status\");\n await client.query(\"DROP TABLE IF EXISTS lattice_tenants\");\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n UserTenantLinkStore,\n UserTenantLink,\n CreateUserTenantLinkRequest,\n UpdateUserTenantLinkRequest,\n UserTenantRole,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createUserTenantLinkTable, migrateRemoveTenantIdFromUsers } from \"../migrations/user_tenant_link_migrations\";\n\nexport interface PostgreSQLUserTenantLinkStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport class PostgreSQLUserTenantLinkStore implements UserTenantLinkStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n\n constructor(options: PostgreSQLUserTenantLinkStoreOptions) {\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createUserTenantLinkTable);\n this.migrationManager.register(migrateRemoveTenantIdFromUsers);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLUserTenantLinkStore:\", error);\n throw error;\n });\n }\n }\n\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) await this.initialize();\n }\n\n private mapRowToLink(row: {\n user_id: string;\n tenant_id: string;\n role: string;\n joined_at: Date;\n metadata: Record<string, any>;\n }): UserTenantLink {\n return {\n userId: row.user_id,\n tenantId: row.tenant_id,\n role: row.role as UserTenantRole,\n joinedAt: row.joined_at,\n metadata: row.metadata,\n };\n }\n\n async getTenantsByUser(userId: string): Promise<UserTenantLink[]> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n SELECT user_id, tenant_id, role, joined_at, metadata\n FROM lattice_user_tenant_links\n WHERE user_id = $1\n ORDER BY joined_at DESC\n `,\n [userId]\n );\n \n return result.rows.map(this.mapRowToLink);\n }\n\n async getUsersByTenant(tenantId: string): Promise<UserTenantLink[]> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n SELECT user_id, tenant_id, role, joined_at, metadata\n FROM lattice_user_tenant_links\n WHERE tenant_id = $1\n ORDER BY joined_at DESC\n `,\n [tenantId]\n );\n \n return result.rows.map(this.mapRowToLink);\n }\n\n async getLink(userId: string, tenantId: string): Promise<UserTenantLink | null> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n SELECT user_id, tenant_id, role, joined_at, metadata\n FROM lattice_user_tenant_links\n WHERE user_id = $1 AND tenant_id = $2\n `,\n [userId, tenantId]\n );\n \n if (result.rows.length === 0) return null;\n return this.mapRowToLink(result.rows[0]);\n }\n\n async createLink(data: CreateUserTenantLinkRequest): Promise<UserTenantLink> {\n await this.ensureInitialized();\n \n const now = new Date();\n const role = data.role || \"member\";\n const metadata = data.metadata || {};\n \n await this.pool.query(\n `\n INSERT INTO lattice_user_tenant_links (user_id, tenant_id, role, joined_at, metadata)\n VALUES ($1, $2, $3, $4, $5)\n ON CONFLICT (user_id, tenant_id) DO UPDATE SET\n role = EXCLUDED.role,\n metadata = EXCLUDED.metadata\n `,\n [data.userId, data.tenantId, role, now, JSON.stringify(metadata)]\n );\n \n return {\n userId: data.userId,\n tenantId: data.tenantId,\n role,\n joinedAt: now,\n metadata: data.metadata,\n };\n }\n\n async updateLink(\n userId: string,\n tenantId: string,\n updates: UpdateUserTenantLinkRequest\n ): Promise<UserTenantLink | null> {\n await this.ensureInitialized();\n \n const existing = await this.getLink(userId, tenantId);\n if (!existing) return null;\n \n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n \n if (updates.role !== undefined) {\n updateFields.push(`role = $${paramIndex++}`);\n updateValues.push(updates.role);\n }\n \n if (updates.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.metadata));\n }\n \n if (updateFields.length === 0) return existing;\n \n updateValues.push(userId, tenantId);\n \n await this.pool.query(\n `\n UPDATE lattice_user_tenant_links\n SET ${updateFields.join(\", \")}\n WHERE user_id = $${paramIndex} AND tenant_id = $${paramIndex + 1}\n `,\n updateValues\n );\n \n return this.getLink(userId, tenantId);\n }\n\n async deleteLink(userId: string, tenantId: string): Promise<boolean> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n DELETE FROM lattice_user_tenant_links\n WHERE user_id = $1 AND tenant_id = $2\n `,\n [userId, tenantId]\n );\n \n return result.rowCount !== null && result.rowCount > 0;\n }\n\n async hasLink(userId: string, tenantId: string): Promise<boolean> {\n await this.ensureInitialized();\n \n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_user_tenant_links\n WHERE user_id = $1 AND tenant_id = $2\n LIMIT 1\n `,\n [userId, tenantId]\n );\n \n return result.rows.length > 0;\n }\n}\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const createUserTenantLinkTable: Migration = {\n version: 10,\n name: \"create_user_tenant_link_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_user_tenant_links (\n user_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n role VARCHAR(50) NOT NULL DEFAULT 'member',\n joined_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n metadata JSONB DEFAULT '{}',\n PRIMARY KEY (user_id, tenant_id)\n )\n `);\n \n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_user_tenant_links_user_id \n ON lattice_user_tenant_links(user_id)\n `);\n \n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_user_tenant_links_tenant_id \n ON lattice_user_tenant_links(tenant_id)\n `);\n \n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_user_tenant_links_role \n ON lattice_user_tenant_links(tenant_id, role)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(`DROP TABLE IF EXISTS lattice_user_tenant_links`);\n },\n};\n\nexport const migrateRemoveTenantIdFromUsers: Migration = {\n version: 11,\n name: \"migrate_remove_tenant_id_from_users\",\n up: async (client: PoolClient) => {\n const hasTenantId = await client.query(`\n SELECT column_name \n FROM information_schema.columns \n WHERE table_name = 'lattice_users' AND column_name = 'tenant_id'\n `);\n \n if (hasTenantId.rows.length > 0) {\n await client.query(`\n INSERT INTO lattice_user_tenant_links (user_id, tenant_id, role, joined_at)\n SELECT id, tenant_id, 'member', created_at\n FROM lattice_users\n WHERE tenant_id IS NOT NULL\n ON CONFLICT (user_id, tenant_id) DO NOTHING\n `);\n \n await client.query(`\n ALTER TABLE lattice_users DROP COLUMN IF EXISTS tenant_id\n `);\n \n await client.query(`\n ALTER TABLE lattice_users DROP CONSTRAINT IF EXISTS lattice_users_pkey\n `);\n \n await client.query(`\n ALTER TABLE lattice_users ADD PRIMARY KEY (id)\n `);\n }\n },\n down: async (client: PoolClient) => {\n await client.query(`\n ALTER TABLE lattice_users ADD COLUMN IF NOT EXISTS tenant_id VARCHAR(255)\n `);\n },\n};\n","/**\n * PostgreSQL implementation of WorkflowTrackingStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n WorkflowTrackingStore,\n WorkflowRun,\n RunStep,\n CreateWorkflowRunRequest,\n UpdateWorkflowRunRequest,\n CreateRunStepRequest,\n UpdateRunStepRequest,\n StepType,\n WorkflowRunStatus,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createWorkflowTrackingTables } from \"../migrations/workflow_tracking_migrations\";\n\nexport interface PostgreSQLWorkflowTrackingStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport class PostgreSQLWorkflowTrackingStore implements WorkflowTrackingStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLWorkflowTrackingStoreOptions) {\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createWorkflowTrackingTables);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLWorkflowTrackingStore:\", error);\n throw error;\n });\n }\n }\n\n async dispose(): Promise<void> {\n await this.pool.end();\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n if (this.initPromise) return this.initPromise;\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) await this.initialize();\n }\n\n async createWorkflowRun(request: CreateWorkflowRunRequest): Promise<WorkflowRun> {\n await this.ensureInitialized();\n const now = new Date();\n const id = `${request.threadId}_${Date.now()}`;\n\n await this.pool.query(\n `INSERT INTO lattice_workflow_runs (id, tenant_id, assistant_id, thread_id, status, topology_edges, total_edges, completed_edges, metadata, started_at, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`,\n [id, request.tenantId, request.assistantId, request.threadId, 'running',\n JSON.stringify(request.topologyEdges), request.topologyEdges.length, 0,\n JSON.stringify(request.metadata || {}), now, now, now]\n );\n\n return {\n id, status: 'running', startedAt: now, completedAt: undefined,\n ...request, completedEdges: 0, totalEdges: request.topologyEdges.length,\n createdAt: now, updatedAt: now,\n };\n }\n\n async getWorkflowRun(runId: string): Promise<WorkflowRun | null> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_runs WHERE id = $1`, [runId]\n );\n if (result.rows.length === 0) return null;\n return this.mapRowToWorkflowRun(result.rows[0]);\n }\n\n async updateWorkflowRun(runId: string, updates: UpdateWorkflowRunRequest): Promise<WorkflowRun | null> {\n await this.ensureInitialized();\n const now = new Date();\n const setClauses: string[] = ['updated_at = $2'];\n const values: any[] = [runId, now];\n let paramIdx = 3;\n\n if (updates.status !== undefined) {\n setClauses.push(`status = $${paramIdx++}`);\n values.push(updates.status);\n }\n if (updates.completedEdges !== undefined) {\n setClauses.push(`completed_edges = $${paramIdx++}`);\n values.push(updates.completedEdges);\n }\n if (updates.errorMessage !== undefined) {\n setClauses.push(`error_message = $${paramIdx++}`);\n values.push(updates.errorMessage);\n }\n if (updates.completedAt !== undefined) {\n setClauses.push(`completed_at = $${paramIdx++}`);\n values.push(updates.completedAt);\n }\n if (updates.metadata !== undefined) {\n setClauses.push(`metadata = $${paramIdx++}`);\n values.push(JSON.stringify(updates.metadata));\n }\n\n const query = `UPDATE lattice_workflow_runs SET ${setClauses.join(', ')} WHERE id = $1`;\n await this.pool.query(query, values);\n return this.getWorkflowRun(runId);\n }\n\n async deleteWorkflowRun(runId: string): Promise<void> {\n await this.ensureInitialized();\n await this.pool.query(`DELETE FROM lattice_workflow_runs WHERE id = $1`, [runId]);\n }\n\n async getWorkflowRunsByThreadId(tenantId: string, threadId: string): Promise<WorkflowRun[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 AND thread_id = $2 ORDER BY created_at DESC`,\n [tenantId, threadId]\n );\n return result.rows.map(this.mapRowToWorkflowRun);\n }\n\n async getWorkflowRunsByAssistantId(tenantId: string, assistantId: string): Promise<WorkflowRun[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 AND assistant_id = $2 ORDER BY created_at DESC`,\n [tenantId, assistantId]\n );\n return result.rows.map(this.mapRowToWorkflowRun);\n }\n\n async getWorkflowRunsByTenantId(tenantId: string): Promise<WorkflowRun[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_runs WHERE tenant_id = $1 ORDER BY created_at DESC`,\n [tenantId]\n );\n return result.rows.map(this.mapRowToWorkflowRun);\n }\n\n async createRunStep(request: CreateRunStepRequest): Promise<RunStep> {\n await this.ensureInitialized();\n const now = new Date();\n const id = `step_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n await this.pool.query(\n `INSERT INTO lattice_workflow_steps (id, run_id, tenant_id, step_type, step_name, edge_from, edge_to, edge_purpose, input, status, started_at, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`,\n [id, request.runId, request.tenantId, request.stepType, request.stepName,\n request.edgeFrom || null, request.edgeTo || null, request.edgePurpose || null,\n request.input ? JSON.stringify(request.input) : null,\n 'running', now, now, now]\n );\n\n return {\n id, runId: request.runId, tenantId: request.tenantId,\n stepType: request.stepType, stepName: request.stepName,\n edgeFrom: request.edgeFrom, edgeTo: request.edgeTo, edgePurpose: request.edgePurpose,\n input: request.input, status: 'running', startedAt: now,\n createdAt: now, updatedAt: now,\n };\n }\n\n async updateRunStep(runId: string, stepId: string, updates: UpdateRunStepRequest): Promise<RunStep | null> {\n await this.ensureInitialized();\n const now = new Date();\n const setClauses: string[] = ['updated_at = $3'];\n const values: any[] = [runId, stepId, now];\n let paramIdx = 4;\n\n if (updates.status !== undefined) {\n setClauses.push(`status = $${paramIdx++}`);\n values.push(updates.status);\n }\n if (updates.output !== undefined) {\n setClauses.push(`output = $${paramIdx++}`);\n values.push(JSON.stringify(updates.output));\n }\n if (updates.errorMessage !== undefined) {\n setClauses.push(`error_message = $${paramIdx++}`);\n values.push(updates.errorMessage);\n }\n if (updates.completedAt !== undefined) {\n setClauses.push(`completed_at = $${paramIdx++}`);\n values.push(updates.completedAt);\n }\n if (updates.durationMs !== undefined) {\n setClauses.push(`duration_ms = $${paramIdx++}`);\n values.push(updates.durationMs);\n }\n\n const query = `UPDATE lattice_workflow_steps SET ${setClauses.join(', ')} WHERE run_id = $1 AND id = $2`;\n const result = await this.pool.query(query, values);\n\n if (result.rowCount === 0) return null;\n\n const row = await this.pool.query(\n `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND id = $2`,\n [runId, stepId]\n );\n return row.rows.length > 0 ? this.mapRowToRunStep(row.rows[0]) : null;\n }\n\n async getRunSteps(runId: string): Promise<RunStep[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 ORDER BY created_at ASC`,\n [runId]\n );\n return result.rows.map(this.mapRowToRunStep);\n }\n\n async getRunStepsByType(runId: string, stepType: StepType): Promise<RunStep[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND step_type = $2 ORDER BY created_at ASC`,\n [runId, stepType]\n );\n return result.rows.map(this.mapRowToRunStep);\n }\n\n async getInterruptedSteps(runId: string): Promise<RunStep[]> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `SELECT * FROM lattice_workflow_steps WHERE run_id = $1 AND status = 'interrupted' ORDER BY created_at ASC`,\n [runId]\n );\n return result.rows.map(this.mapRowToRunStep);\n }\n\n private mapRowToWorkflowRun(row: any): WorkflowRun {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n assistantId: row.assistant_id,\n threadId: row.thread_id,\n status: row.status as WorkflowRunStatus,\n topologyEdges: typeof row.topology_edges === 'string' ? JSON.parse(row.topology_edges) : row.topology_edges || [],\n totalEdges: row.total_edges,\n completedEdges: row.completed_edges,\n errorMessage: row.error_message,\n metadata: typeof row.metadata === 'string' ? JSON.parse(row.metadata) : row.metadata || {},\n startedAt: row.started_at,\n completedAt: row.completed_at,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n private mapRowToRunStep(row: any): RunStep {\n return {\n id: row.id,\n runId: row.run_id,\n tenantId: row.tenant_id,\n stepType: row.step_type as StepType,\n stepName: row.step_name,\n edgeFrom: row.edge_from,\n edgeTo: row.edge_to,\n edgePurpose: row.edge_purpose,\n input: typeof row.input === 'string' ? JSON.parse(row.input) : row.input,\n output: typeof row.output === 'string' ? JSON.parse(row.output) : row.output,\n status: row.status,\n errorMessage: row.error_message,\n startedAt: row.started_at,\n completedAt: row.completed_at,\n durationMs: row.duration_ms,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n}\n","/**\n * PostgreSQL migrations for workflow tracking tables\n */\n\nimport { Migration } from \"./migration\";\n\nexport const createWorkflowTrackingTables: Migration = {\n name: \"create_workflow_tracking_tables\",\n version: 103,\n\n up: async (client) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_workflow_runs (\n id VARCHAR(255) PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n assistant_id VARCHAR(255) NOT NULL,\n thread_id VARCHAR(255) NOT NULL,\n status VARCHAR(50) NOT NULL DEFAULT 'running',\n topology_edges JSONB NOT NULL DEFAULT '[]',\n total_edges INTEGER NOT NULL DEFAULT 0,\n completed_edges INTEGER NOT NULL DEFAULT 0,\n error_message TEXT,\n metadata JSONB DEFAULT '{}',\n started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n completed_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n );\n\n CREATE TABLE IF NOT EXISTS lattice_workflow_steps (\n id VARCHAR(255) NOT NULL,\n run_id VARCHAR(255) NOT NULL REFERENCES lattice_workflow_runs(id) ON DELETE CASCADE,\n tenant_id VARCHAR(255) NOT NULL,\n step_type VARCHAR(50) NOT NULL,\n step_name VARCHAR(255) NOT NULL,\n edge_from VARCHAR(255),\n edge_to VARCHAR(255),\n edge_purpose TEXT,\n input JSONB,\n output JSONB,\n status VARCHAR(50) NOT NULL DEFAULT 'running',\n error_message TEXT,\n started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n completed_at TIMESTAMPTZ,\n duration_ms INTEGER,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n PRIMARY KEY (id, run_id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_workflow_runs_tenant\n ON lattice_workflow_runs (tenant_id);\n CREATE INDEX IF NOT EXISTS idx_workflow_runs_thread\n ON lattice_workflow_runs (tenant_id, thread_id);\n CREATE INDEX IF NOT EXISTS idx_workflow_runs_assistant\n ON lattice_workflow_runs (tenant_id, assistant_id);\n CREATE INDEX IF NOT EXISTS idx_workflow_runs_status\n ON lattice_workflow_runs (status);\n\n CREATE INDEX IF NOT EXISTS idx_workflow_steps_run\n ON lattice_workflow_steps (run_id);\n CREATE INDEX IF NOT EXISTS idx_workflow_steps_type_status\n ON lattice_workflow_steps (run_id, step_type, status);\n `);\n },\n\n down: async (client) => {\n await client.query(`\n DROP INDEX IF EXISTS idx_workflow_steps_type_status;\n DROP INDEX IF EXISTS idx_workflow_steps_run;\n DROP INDEX IF EXISTS idx_workflow_runs_status;\n DROP INDEX IF EXISTS idx_workflow_runs_assistant;\n DROP INDEX IF EXISTS idx_workflow_runs_thread;\n DROP INDEX IF EXISTS idx_workflow_runs_tenant;\n DROP TABLE IF EXISTS lattice_workflow_steps;\n DROP TABLE IF EXISTS lattice_workflow_runs;\n `);\n },\n};\n","/**\n * PostgreSQL implementation of EvalStore\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n EvalStore,\n EvalProject,\n CreateEvalProjectRequest,\n EvalSuite,\n CreateEvalSuiteRequest,\n EvalCase,\n CreateEvalCaseRequest,\n EvalRun,\n CreateEvalRunRequest,\n EvalRunResult,\n EvalProjectReport,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { evalMigrations } from \"../migrations/eval_migrations\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/** PostgreSQL EvalStore options */\nexport interface PostgreSQLEvalStoreOptions {\n /** PostgreSQL connection pool configuration */\n poolConfig: string | PoolConfig;\n /** Whether to run migrations automatically on initialization @default true */\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of EvalStore\n *\n * Features:\n * - Multi-tenant isolation via tenant_id\n * - Full CRUD for projects, suites, cases, runs, run results\n * - Project report aggregation\n */\nexport class PostgreSQLEvalStore implements EvalStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLEvalStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n for (const m of evalMigrations) {\n this.migrationManager.register(m);\n }\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLEvalStore:\", error);\n throw error;\n });\n }\n }\n\n /** Dispose resources and close the connection pool */\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n /** Ensure store is initialized */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n // ---------------------------------------------------------------------------\n // Row mappers\n // ---------------------------------------------------------------------------\n\n private mapRowToProject(row: Record<string, unknown>): EvalProject {\n return {\n id: row.id as string,\n tenantId: row.tenant_id as string,\n name: row.name as string,\n description: row.description as string | undefined,\n version: row.version as string | undefined,\n judgeModelConfig: this.parseRequiredJson<Record<string, unknown>>(row.judge_model_config, {}),\n targetServerConfig: this.parseRequiredJson<Record<string, unknown>>(row.target_server_config, {}),\n concurrency: (row.concurrency as number) ?? 3,\n reportConfig: this.parseOptionalJson<Record<string, unknown>>(row.report_config),\n createdAt: new Date(row.created_at as string),\n updatedAt: new Date(row.updated_at as string),\n };\n }\n\n private mapRowToSuite(row: Record<string, unknown>): EvalSuite {\n return {\n id: row.id as string,\n tenantId: row.tenant_id as string,\n projectId: row.project_id as string,\n name: row.name as string,\n createdAt: new Date(row.created_at as string),\n updatedAt: new Date(row.updated_at as string),\n caseCount: row.case_count !== undefined ? (row.case_count as number) : undefined,\n };\n }\n\n private mapRowToCase(row: Record<string, unknown>): EvalCase {\n return {\n id: row.id as string,\n tenantId: row.tenant_id as string,\n suiteId: row.suite_id as string,\n inputMessage: row.input_message as string,\n inputFiles: this.parseOptionalJson<Record<string, string>>(row.input_files),\n steps: this.parseRequiredJson<Array<{ agent_id: string; override_message?: string }>>(row.steps, []),\n outputType: (row.output_type as EvalCase[\"outputType\"]) || \"message_content\",\n contentAssertion: (row.content_assertion as string) || \"\",\n rubrics: this.parseOptionalJson<Array<{ name: string; weight: number; description: string }>>(row.rubrics),\n createdAt: new Date(row.created_at as string),\n updatedAt: new Date(row.updated_at as string),\n };\n }\n\n private mapRowToRun(row: Record<string, unknown>): EvalRun {\n return {\n id: row.id as string,\n projectId: row.project_id as string,\n tenantId: row.tenant_id as string,\n status: row.status as EvalRun[\"status\"],\n concurrency: (row.concurrency as number) ?? 3,\n totalCases: (row.total_cases as number) ?? 0,\n passedCases: (row.passed_cases as number) ?? 0,\n failedCases: (row.failed_cases as number) ?? 0,\n avgScore: (row.avg_score as number) ?? 0,\n error: row.error as string | undefined,\n createdAt: new Date(row.created_at as string),\n startedAt: row.started_at ? new Date(row.started_at as string) : undefined,\n completedAt: row.completed_at ? new Date(row.completed_at as string) : undefined,\n };\n }\n\n private mapRowToRunResult(row: Record<string, unknown>): EvalRunResult {\n return {\n id: row.id as string,\n runId: row.run_id as string,\n suiteName: row.suite_name as string,\n caseId: row.case_id as string | undefined,\n pass: (row.pass as boolean) ?? false,\n score: (row.score as number) ?? 0,\n summary: row.summary as string | undefined,\n dimensionResults: this.parseOptionalJson<Array<{ name: string; score: number; reason: string }>>(row.dimension_results),\n durationMs: row.duration_ms as number | undefined,\n messages: this.parseOptionalJson<Array<{ role: string; content: string; id?: string }>>(row.messages),\n logs: this.parseOptionalJson<Array<{ timestamp: string; level: string; message: string; data?: unknown }>>(row.logs),\n error: row.error as string | undefined,\n createdAt: new Date(row.created_at as string),\n };\n }\n\n private parseRequiredJson<T>(val: unknown, fallback: T): T {\n if (val == null) return fallback;\n if (typeof val === \"string\") {\n try {\n return JSON.parse(val) as T;\n } catch {\n return fallback;\n }\n }\n return val as T;\n }\n\n private parseOptionalJson<T>(val: unknown): T | undefined {\n if (val == null) return undefined;\n if (typeof val === \"string\") {\n try {\n return JSON.parse(val) as T;\n } catch {\n return undefined;\n }\n }\n return val as T;\n }\n\n // ---------------------------------------------------------------------------\n // Projects\n // ---------------------------------------------------------------------------\n\n /** Get all eval projects for a tenant */\n async getProjectsByTenant(tenantId: string): Promise<EvalProject[]> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at\n FROM lattice_eval_projects\n WHERE tenant_id = $1\n ORDER BY created_at DESC`,\n [tenantId]\n );\n return rows.map((r) => this.mapRowToProject(r as unknown as Record<string, unknown>));\n }\n\n /** Get a single eval project by ID for a tenant */\n async getProjectById(tenantId: string, id: string): Promise<EvalProject | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at\n FROM lattice_eval_projects\n WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return rows.length ? this.mapRowToProject(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Create a new eval project */\n async createProject(\n tenantId: string,\n id: string,\n data: CreateEvalProjectRequest\n ): Promise<EvalProject> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `INSERT INTO lattice_eval_projects\n (id, tenant_id, name, description, version, judge_model_config, target_server_config, concurrency, report_config)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)\n RETURNING id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at`,\n [\n actualId,\n tenantId,\n data.name,\n data.description || null,\n data.version || null,\n JSON.stringify(data.judgeModelConfig),\n JSON.stringify(data.targetServerConfig),\n data.concurrency ?? 3,\n data.reportConfig === undefined ? null : JSON.stringify(data.reportConfig),\n ]\n );\n return this.mapRowToProject(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update an eval project */\n async updateProject(\n tenantId: string,\n id: string,\n updates: Partial<CreateEvalProjectRequest>\n ): Promise<EvalProject | null> {\n await this.ensureInitialized();\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.name !== undefined) { set.push(`name = $${i++}`); vals.push(updates.name); }\n if (updates.description !== undefined) { set.push(`description = $${i++}`); vals.push(updates.description); }\n if (updates.version !== undefined) { set.push(`version = $${i++}`); vals.push(updates.version); }\n if (updates.judgeModelConfig !== undefined) { set.push(`judge_model_config = $${i++}`); vals.push(JSON.stringify(updates.judgeModelConfig)); }\n if (updates.targetServerConfig !== undefined) { set.push(`target_server_config = $${i++}`); vals.push(JSON.stringify(updates.targetServerConfig)); }\n if (updates.concurrency !== undefined) { set.push(`concurrency = $${i++}`); vals.push(updates.concurrency); }\n if (updates.reportConfig !== undefined) { set.push(`report_config = $${i++}`); vals.push(JSON.stringify(updates.reportConfig)); }\n if (set.length === 0) return this.getProjectById(tenantId, id);\n set.push(`updated_at = NOW()`);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `UPDATE lattice_eval_projects SET ${set.join(\", \")}\n WHERE id = $${i} AND tenant_id = $${i + 1}\n RETURNING id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at`,\n vals\n );\n return rows.length ? this.mapRowToProject(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Delete an eval project */\n async deleteProject(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `DELETE FROM lattice_eval_projects WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return (result.rowCount ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Suites\n // ---------------------------------------------------------------------------\n\n /** Get all suites in a project with case counts */\n async getSuitesByProject(tenantId: string, projectId: string): Promise<EvalSuite[]> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; project_id: string; name: string;\n created_at: string; updated_at: string; case_count: number;\n }>(\n `SELECT s.id, s.tenant_id, s.project_id, s.name, s.created_at, s.updated_at,\n COUNT(c.id)::int AS case_count\n FROM lattice_eval_suites s\n LEFT JOIN lattice_eval_cases c ON c.suite_id = s.id\n WHERE s.tenant_id = $1 AND s.project_id = $2\n GROUP BY s.id\n ORDER BY s.created_at DESC`,\n [tenantId, projectId]\n );\n return rows.map((r) => this.mapRowToSuite(r as unknown as Record<string, unknown>));\n }\n\n /** Get a single suite by ID with case count */\n async getSuiteById(tenantId: string, id: string): Promise<EvalSuite | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; project_id: string; name: string;\n created_at: string; updated_at: string; case_count: number;\n }>(\n `SELECT s.id, s.tenant_id, s.project_id, s.name, s.created_at, s.updated_at,\n COUNT(c.id)::int AS case_count\n FROM lattice_eval_suites s\n LEFT JOIN lattice_eval_cases c ON c.suite_id = s.id\n WHERE s.tenant_id = $1 AND s.id = $2\n GROUP BY s.id`,\n [tenantId, id]\n );\n return rows.length ? this.mapRowToSuite(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Create a new eval suite */\n async createSuite(\n tenantId: string,\n projectId: string,\n id: string,\n data: CreateEvalSuiteRequest\n ): Promise<EvalSuite> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; project_id: string; name: string;\n created_at: string; updated_at: string;\n }>(\n `INSERT INTO lattice_eval_suites (id, tenant_id, project_id, name)\n VALUES ($1, $2, $3, $4)\n RETURNING id, tenant_id, project_id, name, created_at, updated_at`,\n [actualId, tenantId, projectId, data.name]\n );\n return this.mapRowToSuite(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update a suite's name */\n async updateSuite(\n tenantId: string,\n id: string,\n updates: Partial<CreateEvalSuiteRequest>\n ): Promise<EvalSuite | null> {\n await this.ensureInitialized();\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.name !== undefined) { set.push(`name = $${i++}`); vals.push(updates.name); }\n if (set.length === 0) return this.getSuiteById(tenantId, id);\n set.push(`updated_at = NOW()`);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; project_id: string; name: string;\n created_at: string; updated_at: string;\n }>(\n `UPDATE lattice_eval_suites SET ${set.join(\", \")}\n WHERE id = $${i} AND tenant_id = $${i + 1}\n RETURNING id, tenant_id, project_id, name, created_at, updated_at`,\n vals\n );\n return rows.length ? this.mapRowToSuite(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Delete a suite */\n async deleteSuite(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `DELETE FROM lattice_eval_suites WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return (result.rowCount ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Cases\n // ---------------------------------------------------------------------------\n\n /** Get all test cases in a suite */\n async getCasesBySuite(tenantId: string, suiteId: string): Promise<EvalCase[]> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; suite_id: string;\n input_message: string; input_files: unknown; steps: unknown;\n output_type: string; content_assertion: string; rubrics: unknown;\n created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, suite_id,\n input_message, input_files, steps,\n output_type, content_assertion, rubrics,\n created_at, updated_at\n FROM lattice_eval_cases\n WHERE tenant_id = $1 AND suite_id = $2\n ORDER BY created_at`,\n [tenantId, suiteId]\n );\n return rows.map((r) => this.mapRowToCase(r as unknown as Record<string, unknown>));\n }\n\n /** Get a single test case by ID */\n async getCaseById(tenantId: string, id: string): Promise<EvalCase | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; suite_id: string;\n input_message: string; input_files: unknown; steps: unknown;\n output_type: string; content_assertion: string; rubrics: unknown;\n created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, suite_id,\n input_message, input_files, steps,\n output_type, content_assertion, rubrics,\n created_at, updated_at\n FROM lattice_eval_cases\n WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return rows.length ? this.mapRowToCase(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Create a new test case */\n async createCase(\n tenantId: string,\n suiteId: string,\n id: string,\n data: CreateEvalCaseRequest\n ): Promise<EvalCase> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; suite_id: string;\n input_message: string; input_files: unknown; steps: unknown;\n output_type: string; content_assertion: string; rubrics: unknown;\n created_at: string; updated_at: string;\n }>(\n `INSERT INTO lattice_eval_cases\n (id, tenant_id, suite_id, input_message, input_files, steps, output_type, content_assertion, rubrics)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)\n RETURNING id, tenant_id, suite_id,\n input_message, input_files, steps,\n output_type, content_assertion, rubrics,\n created_at, updated_at`,\n [\n actualId,\n tenantId,\n suiteId,\n data.inputMessage,\n JSON.stringify(data.inputFiles || {}),\n JSON.stringify(data.steps),\n data.outputType,\n data.contentAssertion || null,\n JSON.stringify(data.rubrics || []),\n ]\n );\n return this.mapRowToCase(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update a test case */\n async updateCase(\n tenantId: string,\n id: string,\n updates: Partial<CreateEvalCaseRequest>\n ): Promise<EvalCase | null> {\n await this.ensureInitialized();\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.inputMessage !== undefined) { set.push(`input_message = $${i++}`); vals.push(updates.inputMessage); }\n if (updates.inputFiles !== undefined) { set.push(`input_files = $${i++}`); vals.push(JSON.stringify(updates.inputFiles)); }\n if (updates.steps !== undefined) { set.push(`steps = $${i++}`); vals.push(JSON.stringify(updates.steps)); }\n if (updates.outputType !== undefined) { set.push(`output_type = $${i++}`); vals.push(updates.outputType); }\n if (updates.contentAssertion !== undefined) { set.push(`content_assertion = $${i++}`); vals.push(updates.contentAssertion); }\n if (updates.rubrics !== undefined) { set.push(`rubrics = $${i++}`); vals.push(JSON.stringify(updates.rubrics)); }\n if (set.length === 0) return this.getCaseById(tenantId, id);\n set.push(`updated_at = NOW()`);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; tenant_id: string; suite_id: string;\n input_message: string; input_files: unknown; steps: unknown;\n output_type: string; content_assertion: string; rubrics: unknown;\n created_at: string; updated_at: string;\n }>(\n `UPDATE lattice_eval_cases SET ${set.join(\", \")}\n WHERE id = $${i} AND tenant_id = $${i + 1}\n RETURNING id, tenant_id, suite_id,\n input_message, input_files, steps,\n output_type, content_assertion, rubrics,\n created_at, updated_at`,\n vals\n );\n return rows.length ? this.mapRowToCase(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Delete a test case */\n async deleteCase(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n const result = await this.pool.query(\n `DELETE FROM lattice_eval_cases WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return (result.rowCount ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Runs\n // ---------------------------------------------------------------------------\n\n /** Get all runs for a tenant, optionally filtered by project or status */\n async getRunsByTenant(\n tenantId: string,\n opts?: { projectId?: string; status?: string }\n ): Promise<EvalRun[]> {\n await this.ensureInitialized();\n const conditions: string[] = [\"tenant_id = $1\"];\n const vals: unknown[] = [tenantId];\n let i = 2;\n if (opts?.projectId) { conditions.push(`project_id = $${i++}`); vals.push(opts.projectId); }\n if (opts?.status) { conditions.push(`status = $${i++}`); vals.push(opts.status); }\n const { rows } = await this.pool.query<{\n id: string; project_id: string; tenant_id: string;\n status: string; concurrency: number; total_cases: number;\n passed_cases: number; failed_cases: number; avg_score: number;\n error: string | null; created_at: string; started_at: string | null;\n completed_at: string | null;\n }>(\n `SELECT id, project_id, tenant_id,\n status, concurrency, total_cases,\n passed_cases, failed_cases, avg_score,\n error, created_at, started_at, completed_at\n FROM lattice_eval_runs\n WHERE ${conditions.join(\" AND \")}\n ORDER BY created_at DESC`,\n vals\n );\n return rows.map((r) => this.mapRowToRun(r as unknown as Record<string, unknown>));\n }\n\n /** Get a single run by ID */\n async getRunById(tenantId: string, id: string): Promise<EvalRun | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; project_id: string; tenant_id: string;\n status: string; concurrency: number; total_cases: number;\n passed_cases: number; failed_cases: number; avg_score: number;\n error: string | null; created_at: string; started_at: string | null;\n completed_at: string | null;\n }>(\n `SELECT id, project_id, tenant_id,\n status, concurrency, total_cases,\n passed_cases, failed_cases, avg_score,\n error, created_at, started_at, completed_at\n FROM lattice_eval_runs\n WHERE id = $1 AND tenant_id = $2`,\n [id, tenantId]\n );\n return rows.length ? this.mapRowToRun(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Create a new eval run */\n async createRun(\n tenantId: string,\n projectId: string,\n id: string,\n data: CreateEvalRunRequest\n ): Promise<EvalRun> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; project_id: string; tenant_id: string;\n status: string; concurrency: number; total_cases: number;\n passed_cases: number; failed_cases: number; avg_score: number;\n error: string | null; created_at: string; started_at: string | null;\n completed_at: string | null;\n }>(\n `INSERT INTO lattice_eval_runs\n (id, project_id, tenant_id, status, concurrency, total_cases, passed_cases, failed_cases, avg_score, started_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n RETURNING id, project_id, tenant_id,\n status, concurrency, total_cases,\n passed_cases, failed_cases, avg_score,\n error, created_at, started_at, completed_at`,\n [\n actualId,\n projectId,\n tenantId,\n \"running\",\n data.concurrency,\n data.totalCases,\n 0,\n 0,\n 0,\n new Date(),\n ]\n );\n return this.mapRowToRun(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update a run's status and aggregate fields */\n async updateRunStatus(\n tenantId: string,\n id: string,\n updates: {\n status?: EvalRun[\"status\"];\n passedCases?: number;\n failedCases?: number;\n avgScore?: number;\n error?: string;\n completedAt?: Date;\n }\n ): Promise<EvalRun | null> {\n await this.ensureInitialized();\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.status !== undefined) { set.push(`status = $${i++}`); vals.push(updates.status); }\n if (updates.passedCases !== undefined) { set.push(`passed_cases = $${i++}`); vals.push(updates.passedCases); }\n if (updates.failedCases !== undefined) { set.push(`failed_cases = $${i++}`); vals.push(updates.failedCases); }\n if (updates.avgScore !== undefined) { set.push(`avg_score = $${i++}`); vals.push(updates.avgScore); }\n if (updates.completedAt !== undefined) { set.push(`completed_at = $${i++}`); vals.push(updates.completedAt); }\n if (updates.error !== undefined) { set.push(`error = $${i++}`); vals.push(updates.error); }\n if (set.length === 0) return this.getRunById(tenantId, id);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; project_id: string; tenant_id: string;\n status: string; concurrency: number; total_cases: number;\n passed_cases: number; failed_cases: number; avg_score: number;\n error: string | null; created_at: string; started_at: string | null;\n completed_at: string | null;\n }>(\n `UPDATE lattice_eval_runs SET ${set.join(\", \")}\n WHERE id = $${i} AND tenant_id = $${i + 1}\n RETURNING id, project_id, tenant_id,\n status, concurrency, total_cases,\n passed_cases, failed_cases, avg_score,\n error, created_at, started_at, completed_at`,\n vals\n );\n return rows.length ? this.mapRowToRun(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Delete a run and its results */\n async deleteRun(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n // Delete results first, then the run\n await this.pool.query(`DELETE FROM lattice_eval_run_results WHERE run_id = $1 AND run_id IN (SELECT id FROM lattice_eval_runs WHERE tenant_id = $2)`, [id, tenantId]);\n const { rowCount } = await this.pool.query(\n `DELETE FROM lattice_eval_runs WHERE id = $1 AND tenant_id = $2`, [id, tenantId]\n );\n return (rowCount ?? 0) > 0;\n }\n\n // ---------------------------------------------------------------------------\n // Run Results\n // ---------------------------------------------------------------------------\n\n /** Get all results belonging to a run */\n async getResultsByRun(tenantId: string, runId: string): Promise<EvalRunResult[]> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; run_id: string; suite_name: string;\n case_id: string | null; pass: boolean; score: number;\n summary: string | null; dimension_results: unknown;\n duration_ms: number | null; messages: unknown; logs: unknown;\n error: string | null; created_at: string;\n }>(\n `SELECT rr.id, rr.run_id, rr.suite_name, rr.case_id,\n rr.pass, rr.score, rr.summary, rr.dimension_results,\n rr.duration_ms, rr.messages, rr.logs, rr.error, rr.created_at\n FROM lattice_eval_run_results rr\n INNER JOIN lattice_eval_runs r ON r.id = rr.run_id\n WHERE r.tenant_id = $1 AND rr.run_id = $2\n ORDER BY rr.created_at`,\n [tenantId, runId]\n );\n return rows.map((r) => this.mapRowToRunResult(r as unknown as Record<string, unknown>));\n }\n\n /** Create a result for a case within a run */\n async createRunResult(\n tenantId: string,\n runId: string,\n id: string,\n data: Omit<EvalRunResult, \"id\" | \"runId\" | \"createdAt\">\n ): Promise<EvalRunResult> {\n await this.ensureInitialized();\n const actualId = id || uuidv4();\n const { rows } = await this.pool.query<{\n id: string; run_id: string; suite_name: string;\n case_id: string | null; pass: boolean; score: number;\n summary: string | null; dimension_results: unknown;\n duration_ms: number | null; messages: unknown; logs: unknown;\n error: string | null; created_at: string;\n }>(\n `INSERT INTO lattice_eval_run_results\n (id, run_id, suite_name, case_id, pass, score, summary, dimension_results, duration_ms, messages, logs, error)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)\n RETURNING id, run_id, suite_name, case_id,\n pass, score, summary, dimension_results,\n duration_ms, messages, logs, error, created_at`,\n [\n actualId,\n runId,\n data.suiteName,\n data.caseId || null,\n data.pass,\n data.score,\n data.summary || null,\n JSON.stringify(data.dimensionResults || []),\n data.durationMs ?? null,\n JSON.stringify(data.messages || []),\n JSON.stringify(data.logs || []),\n data.error || null,\n ]\n );\n return this.mapRowToRunResult(rows[0] as unknown as Record<string, unknown>);\n }\n\n /** Update a run result with tenant isolation via the parent run */\n async updateRunResult(\n tenantId: string,\n id: string,\n updates: Partial<EvalRunResult>\n ): Promise<EvalRunResult | null> {\n await this.ensureInitialized();\n if (updates.runId !== undefined) {\n throw new Error(\"runId cannot be updated on an existing result\");\n }\n const set: string[] = [];\n const vals: unknown[] = [];\n let i = 1;\n if (updates.suiteName !== undefined) { set.push(`suite_name = $${i++}`); vals.push(updates.suiteName); }\n if (updates.caseId !== undefined) { set.push(`case_id = $${i++}`); vals.push(updates.caseId); }\n if (updates.pass !== undefined) { set.push(`pass = $${i++}`); vals.push(updates.pass); }\n if (updates.score !== undefined) { set.push(`score = $${i++}`); vals.push(updates.score); }\n if (updates.summary !== undefined) { set.push(`summary = $${i++}`); vals.push(updates.summary); }\n if (updates.dimensionResults !== undefined) { set.push(`dimension_results = $${i++}`); vals.push(JSON.stringify(updates.dimensionResults)); }\n if (updates.durationMs !== undefined) { set.push(`duration_ms = $${i++}`); vals.push(updates.durationMs); }\n if (updates.messages !== undefined) { set.push(`messages = $${i++}`); vals.push(JSON.stringify(updates.messages)); }\n if (updates.logs !== undefined) { set.push(`logs = $${i++}`); vals.push(JSON.stringify(updates.logs)); }\n if (updates.error !== undefined) { set.push(`error = $${i++}`); vals.push(updates.error); }\n if (set.length === 0) return this.getRunResultById(tenantId, id);\n vals.push(id, tenantId);\n const { rows } = await this.pool.query<{\n id: string; run_id: string; suite_name: string;\n case_id: string | null; pass: boolean; score: number;\n summary: string | null; dimension_results: unknown;\n duration_ms: number | null; messages: unknown; logs: unknown;\n error: string | null; created_at: string;\n }>(\n `UPDATE lattice_eval_run_results SET ${set.join(\", \")}\n WHERE id = $${i}\n AND run_id IN (SELECT id FROM lattice_eval_runs WHERE tenant_id = $${i + 1})\n RETURNING id, run_id, suite_name, case_id,\n pass, score, summary, dimension_results,\n duration_ms, messages, logs, error, created_at`,\n vals\n );\n return rows.length ? this.mapRowToRunResult(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n /** Get a single run result by ID with tenant isolation */\n private async getRunResultById(tenantId: string, id: string): Promise<EvalRunResult | null> {\n await this.ensureInitialized();\n const { rows } = await this.pool.query<{\n id: string; run_id: string; suite_name: string;\n case_id: string | null; pass: boolean; score: number;\n summary: string | null; dimension_results: unknown;\n duration_ms: number | null; messages: unknown; logs: unknown;\n error: string | null; created_at: string;\n }>(\n `SELECT rr.id, rr.run_id, rr.suite_name, rr.case_id,\n rr.pass, rr.score, rr.summary, rr.dimension_results,\n rr.duration_ms, rr.messages, rr.logs, rr.error, rr.created_at\n FROM lattice_eval_run_results rr\n INNER JOIN lattice_eval_runs r ON r.id = rr.run_id\n WHERE rr.id = $1 AND r.tenant_id = $2`,\n [id, tenantId]\n );\n return rows.length ? this.mapRowToRunResult(rows[0] as unknown as Record<string, unknown>) : null;\n }\n\n // ---------------------------------------------------------------------------\n // Reports\n // ---------------------------------------------------------------------------\n\n /** Aggregate report for a project including all runs */\n async getProjectReport(tenantId: string, projectId: string): Promise<EvalProjectReport | null> {\n await this.ensureInitialized();\n const projectRows = await this.pool.query<{\n id: string; tenant_id: string; name: string; description: string | null;\n version: string | null; judge_model_config: unknown; target_server_config: unknown;\n concurrency: number; report_config: unknown; created_at: string; updated_at: string;\n }>(\n `SELECT id, tenant_id, name, description, version,\n judge_model_config, target_server_config, concurrency,\n report_config, created_at, updated_at\n FROM lattice_eval_projects\n WHERE id = $1 AND tenant_id = $2`,\n [projectId, tenantId]\n );\n if (projectRows.rows.length === 0) return null;\n\n const project = this.mapRowToProject(projectRows.rows[0] as unknown as Record<string, unknown>);\n const runs = await this.getRunsByTenant(tenantId, { projectId });\n const totalRuns = runs.length;\n const latestPassRate = runs.length > 0\n ? (runs[0].totalCases > 0 ? runs[0].passedCases / runs[0].totalCases : 0)\n : 0;\n const avgScore = runs.length > 0\n ? runs.reduce((sum, r) => sum + r.avgScore, 0) / runs.length\n : 0;\n\n return {\n projectId: project.id,\n projectName: project.name,\n totalRuns,\n latestPassRate,\n avgScore,\n runs,\n };\n }\n}\n","/**\n * Eval table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/** Create the eval projects table */\nexport const createEvalProjectsTable: Migration = {\n version: 104,\n name: \"create_eval_projects_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_projects (\n id UUID PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n name TEXT NOT NULL,\n description TEXT,\n version TEXT,\n judge_model_config JSONB NOT NULL DEFAULT '{}',\n target_server_config JSONB NOT NULL DEFAULT '{}',\n concurrency INTEGER NOT NULL DEFAULT 3,\n report_config JSONB DEFAULT '{}',\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_projects_tenant_id\n ON lattice_eval_projects(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_projects_created_at\n ON lattice_eval_projects(created_at)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_projects_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_projects_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_projects\");\n },\n};\n\n/** Create the eval suites table */\nexport const createEvalSuitesTable: Migration = {\n version: 105,\n name: \"create_eval_suites_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_suites (\n id UUID PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n project_id UUID NOT NULL REFERENCES lattice_eval_projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n UNIQUE(project_id, name)\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_suites_tenant_id\n ON lattice_eval_suites(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_suites_project_id\n ON lattice_eval_suites(project_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_suites_project_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_suites_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_suites\");\n },\n};\n\n/** Create the eval cases table */\nexport const createEvalCasesTable: Migration = {\n version: 106,\n name: \"create_eval_cases_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_cases (\n id UUID PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n suite_id UUID NOT NULL REFERENCES lattice_eval_suites(id) ON DELETE CASCADE,\n template_id UUID,\n input_message TEXT NOT NULL,\n input_files JSONB DEFAULT '{}',\n steps JSONB NOT NULL DEFAULT '[]',\n output_type TEXT NOT NULL DEFAULT 'message_content',\n content_assertion TEXT,\n rubrics JSONB DEFAULT '[]',\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_cases_tenant_id\n ON lattice_eval_cases(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_cases_suite_id\n ON lattice_eval_cases(suite_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_cases_suite_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_cases_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_cases\");\n },\n};\n\n/** Create the eval runs table */\nexport const createEvalRunsTable: Migration = {\n version: 107,\n name: \"create_eval_runs_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_runs (\n id UUID PRIMARY KEY,\n project_id UUID NOT NULL REFERENCES lattice_eval_projects(id) ON DELETE CASCADE,\n tenant_id VARCHAR(255) NOT NULL,\n status TEXT NOT NULL DEFAULT 'running',\n concurrency INTEGER NOT NULL DEFAULT 3,\n total_cases INTEGER NOT NULL DEFAULT 0,\n passed_cases INTEGER NOT NULL DEFAULT 0,\n failed_cases INTEGER NOT NULL DEFAULT 0,\n avg_score FLOAT NOT NULL DEFAULT 0,\n error TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n started_at TIMESTAMPTZ,\n completed_at TIMESTAMPTZ\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_tenant_id\n ON lattice_eval_runs(tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_project_id\n ON lattice_eval_runs(project_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_status\n ON lattice_eval_runs(status)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_created_at\n ON lattice_eval_runs(created_at)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_runs_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_runs_status\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_runs_project_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_runs_tenant_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_runs\");\n },\n};\n\n/** Create the eval run results table */\nexport const createEvalRunResultsTable: Migration = {\n version: 108,\n name: \"create_eval_run_results_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_eval_run_results (\n id UUID PRIMARY KEY,\n run_id UUID NOT NULL REFERENCES lattice_eval_runs(id) ON DELETE CASCADE,\n suite_name TEXT NOT NULL DEFAULT '',\n case_id UUID,\n pass BOOLEAN NOT NULL DEFAULT false,\n score FLOAT NOT NULL DEFAULT 0,\n summary TEXT,\n dimension_results JSONB DEFAULT '[]',\n duration_ms INTEGER DEFAULT 0,\n messages JSONB DEFAULT '[]',\n logs JSONB DEFAULT '[]',\n error TEXT,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_run_results_run_id\n ON lattice_eval_run_results(run_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_eval_run_results_case_id\n ON lattice_eval_run_results(case_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_run_results_case_id\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_eval_run_results_run_id\");\n await client.query(\"DROP TABLE IF EXISTS lattice_eval_run_results\");\n },\n};\n\n/** All eval migrations in version order */\nexport const evalMigrations: Migration[] = [\n createEvalProjectsTable,\n createEvalSuitesTable,\n createEvalCasesTable,\n createEvalRunsTable,\n createEvalRunResultsTable,\n];\n","/**\n * Thread Message Queue Store\n *\n * Provides PostgreSQL storage for thread message queues\n */\n\nimport { Pool, type PoolConfig } from \"pg\";\nimport crypto from \"crypto\";\nimport type {\n IMessageQueueStore,\n PendingMessage,\n AddMessageParams,\n ThreadInfo,\n} from \"@axiom-lattice/core\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createThreadMessageQueueTable } from \"../migrations/thread_message_queue_migrations\";\nimport { addPriorityAndCommandColumns } from \"../migrations/add_priority_command_columns\";\nimport { addCustomRunConfigColumn } from \"../migrations/add_custom_run_config_column\";\nimport { alterMessageQueueIdColumn } from \"../migrations/alter_message_queue_id_column\";\n\nexport type { PendingMessage, AddMessageParams, ThreadInfo };\n\nexport interface PostgreSQLThreadMessageQueueStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport class ThreadMessageQueueStore implements IMessageQueueStore {\n private pool: Pool;\n private ownsPool: boolean = true;\n private initialized: boolean = false;\n private initPromise: Promise<void> | null = null;\n private migrationManager: MigrationManager;\n\n constructor(options: PostgreSQLThreadMessageQueueStoreOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createThreadMessageQueueTable);\n this.migrationManager.register(addPriorityAndCommandColumns);\n this.migrationManager.register(addCustomRunConfigColumn);\n this.migrationManager.register(alterMessageQueueIdColumn);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize ThreadMessageQueueStore:\", error);\n throw error;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n if (this.initPromise) return this.initPromise;\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n return this.initPromise;\n }\n\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Add message to queue\n */\n async addMessage(params: AddMessageParams): Promise<PendingMessage> {\n const { threadId, tenantId, assistantId, content, type = \"human\", priority = 0, command, custom_run_config, id } = params;\n\n // Get current max sequence (no lock needed without unique constraint)\n const seqResult = await this.pool.query(\n `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq\n FROM lattice_thread_message_queue \n WHERE thread_id = $1`,\n [threadId]\n );\n const nextSeq = seqResult.rows[0].next_seq;\n\n const result = await this.pool.query(\n `INSERT INTO lattice_thread_message_queue \n (id, thread_id, tenant_id, assistant_id, message_content, message_type, sequence_order, priority, command, custom_run_config)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n RETURNING *`,\n [id || crypto.randomUUID(), threadId, tenantId, assistantId, JSON.stringify(content), type, nextSeq, priority, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]\n );\n\n return this.rowToMessage(result.rows[0]);\n }\n\n /**\n * Add message at head of queue (high priority, e.g., STEER/Command messages)\n * Uses priority=100 to ensure message is processed first\n */\n async addMessageAtHead(params: AddMessageParams): Promise<PendingMessage> {\n const { threadId, tenantId, assistantId, content, type = \"human\", command, custom_run_config, id } = params;\n\n const resolvedTenantId = tenantId!;\n const resolvedAssistantId = assistantId!;\n\n // Get current max sequence for ordering within same priority\n const seqResult = await this.pool.query(\n `SELECT COALESCE(MAX(sequence_order), 0) + 1 as next_seq\n FROM lattice_thread_message_queue \n WHERE thread_id = $1`,\n [threadId]\n );\n const nextSeq = seqResult.rows[0].next_seq;\n\n // Insert with high priority (100)\n const result = await this.pool.query(\n `INSERT INTO lattice_thread_message_queue \n (id, thread_id, tenant_id, assistant_id, message_content, message_type, sequence_order, priority, command, custom_run_config)\n VALUES ($1, $2, $3, $4, $5, $6, $7, 100, $8, $9)\n RETURNING *`,\n [id || crypto.randomUUID(), threadId, resolvedTenantId, resolvedAssistantId, JSON.stringify(content), type, nextSeq, command ? JSON.stringify(command) : null, custom_run_config ? JSON.stringify(custom_run_config) : null]\n );\n\n return this.rowToMessage(result.rows[0]);\n }\n\n /**\n * Get pending messages for thread\n */\n async getPendingMessages(threadId: string): Promise<PendingMessage[]> {\n const result = await this.pool.query(\n `SELECT * FROM lattice_thread_message_queue \n WHERE thread_id = $1 AND status = 'pending'\n ORDER BY priority DESC, sequence_order ASC`,\n [threadId]\n );\n\n return result.rows.map(row => this.rowToMessage(row));\n }\n\n /**\n * Get processing messages for a thread\n */\n async getProcessingMessages(threadId: string): Promise<PendingMessage[]> {\n const result = await this.pool.query(\n `SELECT * FROM lattice_thread_message_queue \n WHERE thread_id = $1 AND status = 'processing'\n ORDER BY priority DESC, sequence_order ASC`,\n [threadId]\n );\n\n return result.rows.map(row => this.rowToMessage(row));\n }\n\n /**\n * Get queue size\n */\n async getQueueSize(threadId: string): Promise<number> {\n const result = await this.pool.query(\n `SELECT COUNT(*) as count FROM lattice_thread_message_queue \n WHERE thread_id = $1 AND status = 'pending'`,\n [threadId]\n );\n\n return parseInt(result.rows[0].count, 10);\n }\n\n /**\n * Get all threads with pending or processing messages\n */\n async getThreadsWithPendingMessages(): Promise<ThreadInfo[]> {\n const result = await this.pool.query(\n `SELECT DISTINCT tenant_id, assistant_id, thread_id \n FROM lattice_thread_message_queue \n WHERE status IN ('pending', 'processing')\n ORDER BY thread_id`\n );\n\n return result.rows.map(row => ({\n tenantId: row.tenant_id,\n assistantId: row.assistant_id,\n threadId: row.thread_id,\n }));\n }\n\n /**\n * Remove message\n */\n async removeMessage(messageId: string): Promise<boolean> {\n const result = await this.pool.query(\n `DELETE FROM lattice_thread_message_queue WHERE id = $1 RETURNING id`,\n [messageId]\n );\n\n return (result.rowCount ?? 0) > 0;\n }\n\n /**\n * Clear all messages for thread\n */\n async clearMessages(threadId: string): Promise<void> {\n await this.pool.query(\n `DELETE FROM lattice_thread_message_queue WHERE thread_id = $1`,\n [threadId]\n );\n }\n\n /**\n * Mark message as processing\n */\n async markProcessing(messageId: string): Promise<void> {\n await this.pool.query(\n `UPDATE lattice_thread_message_queue SET status = 'processing' WHERE id = $1`,\n [messageId]\n );\n }\n\n /**\n * Reset all processing messages to pending state for a thread\n * Returns the number of messages reset\n */\n async resetProcessingToPending(threadId: string): Promise<number> {\n const result = await this.pool.query(\n `UPDATE lattice_thread_message_queue \n SET status = 'pending'\n WHERE thread_id = $1 AND status = 'processing'\n RETURNING id`,\n [threadId]\n );\n return result.rowCount ?? 0;\n }\n\n private rowToMessage(row: any): PendingMessage {\n return {\n id: row.id,\n content: typeof row.message_content === \"string\"\n ? JSON.parse(row.message_content)\n : row.message_content,\n type: row.message_type,\n sequence: row.sequence_order,\n createdAt: new Date(row.created_at),\n priority: row.priority || 0,\n command: row.command ? (typeof row.command === \"string\" ? JSON.parse(row.command) : row.command) : undefined,\n custom_run_config: row.custom_run_config\n ? (typeof row.custom_run_config === \"string\" ? JSON.parse(row.custom_run_config) : row.custom_run_config)\n : undefined,\n };\n }\n}\n","/**\n * Thread message queue migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Create thread message queue table\n */\nexport const createThreadMessageQueueTable: Migration = {\n version: 100,\n name: \"create_lattice_thread_message_queue_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_thread_message_queue (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n thread_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n assistant_id VARCHAR(255) NOT NULL,\n message_content JSONB NOT NULL,\n message_type VARCHAR(50) DEFAULT 'human',\n sequence_order INTEGER NOT NULL,\n status VARCHAR(50) DEFAULT 'pending',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_thread \n ON lattice_thread_message_queue(thread_id, status)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_tenant \n ON lattice_thread_message_queue(tenant_id, thread_id, status)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_status \n ON lattice_thread_message_queue(status, created_at)\n `);\n\n // Index for sequence order per thread (for ordering, not unique constraint)\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_sequence \n ON lattice_thread_message_queue(thread_id, sequence_order)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_sequence\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_status\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_tenant\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_thread\");\n await client.query(\"DROP TABLE IF EXISTS lattice_thread_message_queue\");\n },\n};\n","/**\n * Add priority and command columns to thread message queue\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add priority and command columns\n */\nexport const addPriorityAndCommandColumns: Migration = {\n version: 101,\n name: \"add_priority_and_command_columns\",\n up: async (client: PoolClient) => {\n // Add priority column\n await client.query(`\n ALTER TABLE lattice_thread_message_queue \n ADD COLUMN IF NOT EXISTS priority INTEGER DEFAULT 0\n `);\n\n // Add command column for steer messages\n await client.query(`\n ALTER TABLE lattice_thread_message_queue \n ADD COLUMN IF NOT EXISTS command JSONB\n `);\n\n // Create index for priority-based queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_thread_message_queue_priority \n ON lattice_thread_message_queue(thread_id, priority DESC, sequence_order ASC)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_thread_message_queue_priority\");\n await client.query(\"ALTER TABLE lattice_thread_message_queue DROP COLUMN IF EXISTS command\");\n await client.query(\"ALTER TABLE lattice_thread_message_queue DROP COLUMN IF EXISTS priority\");\n },\n};\n","/**\n * Add custom_run_config column to thread message queue\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add custom_run_config column\n */\nexport const addCustomRunConfigColumn: Migration = {\n version: 114,\n name: \"add_custom_run_config_column\",\n up: async (client: PoolClient) => {\n await client.query(`\n ALTER TABLE lattice_thread_message_queue\n ADD COLUMN IF NOT EXISTS custom_run_config JSONB\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"ALTER TABLE lattice_thread_message_queue DROP COLUMN IF EXISTS custom_run_config\"\n );\n },\n};\n","/**\n * Alter thread message queue id column to allow explicit ID insertion\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Alter id column to allow explicit UUID insertion\n * This enables client-provided message IDs to be used consistently\n */\nexport const alterMessageQueueIdColumn: Migration = {\n version: 102,\n name: \"alter_message_queue_id_column\",\n up: async (client: PoolClient) => {\n // Change id column to allow NULL (we'll provide the ID explicitly)\n // The DEFAULT is removed so we must provide the ID\n await client.query(`\n ALTER TABLE lattice_thread_message_queue \n ALTER COLUMN id DROP DEFAULT\n `);\n\n // Add comment explaining the change\n await client.query(`\n COMMENT ON COLUMN lattice_thread_message_queue.id IS \n 'Message ID - must be provided explicitly (UUID format). Used for consistent ID across client and server.'\n `);\n },\n down: async (client: PoolClient) => {\n // Restore the default UUID generation\n await client.query(`\n ALTER TABLE lattice_thread_message_queue \n ALTER COLUMN id SET DEFAULT gen_random_uuid()\n `);\n\n // Remove comment\n await client.query(`\n COMMENT ON COLUMN lattice_thread_message_queue.id IS NULL\n `);\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport type {\n Binding,\n BindingRegistry,\n CreateBindingInput,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createChannelBindingsTable } from \"../migrations/channel_bindings_migration\";\n\nexport interface ChannelBindingStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\ntype BindingRow = {\n id: string;\n channel: string;\n channel_installation_id: string;\n tenant_id: string;\n sender_id: string;\n agent_id: string;\n thread_id: string | null;\n workspace_id: string | null;\n project_id: string | null;\n thread_mode: \"fixed\" | \"per_conversation\";\n sender_display_name: string | null;\n sender_metadata: Record<string, unknown> | null;\n enabled: boolean;\n created_at: Date;\n updated_at: Date;\n};\n\nexport class ChannelBindingStore implements BindingRegistry {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: ChannelBindingStoreOptions) {\n this.pool =\n typeof options.poolConfig === \"string\"\n ? new Pool({ connectionString: options.poolConfig })\n : new Pool(options.poolConfig);\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createChannelBindingsTable);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize ChannelBindingStore:\", error);\n throw error;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n if (this.initPromise) return this.initPromise;\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n return this.initPromise;\n }\n\n async resolve(params: {\n channel: string;\n senderId: string;\n channelInstallationId: string;\n tenantId: string;\n }): Promise<Binding | null> {\n await this.ensureInitialized();\n const result = await this.pool.query<BindingRow>(\n `SELECT * FROM lattice_channel_bindings\n WHERE channel = $1\n AND sender_id = $2\n AND channel_installation_id = $3\n AND tenant_id = $4\n AND enabled = true\n LIMIT 1`,\n [params.channel, params.senderId, params.channelInstallationId, params.tenantId],\n );\n if (result.rows.length === 0) return null;\n return this.mapRowToBinding(result.rows[0]);\n }\n\n async create(input: CreateBindingInput): Promise<Binding> {\n await this.ensureInitialized();\n const result = await this.pool.query<BindingRow>(\n `INSERT INTO lattice_channel_bindings\n (channel, channel_installation_id, tenant_id, sender_id, agent_id,\n thread_mode, sender_display_name, sender_metadata, workspace_id, project_id)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n RETURNING *`,\n [\n input.channel,\n input.channelInstallationId,\n input.tenantId,\n input.senderId,\n input.agentId,\n input.threadMode || \"fixed\",\n input.senderDisplayName || null,\n input.senderMetadata ? JSON.stringify(input.senderMetadata) : null,\n input.workspaceId || null,\n input.projectId || null,\n ],\n );\n return this.mapRowToBinding(result.rows[0]);\n }\n\n async update(id: string, patch: Partial<Binding>): Promise<Binding> {\n await this.ensureInitialized();\n const existing = await this.pool.query<BindingRow>(\n `SELECT * FROM lattice_channel_bindings WHERE id = $1`,\n [id],\n );\n if (existing.rows.length === 0) {\n throw new Error(`Binding ${id} not found`);\n }\n\n const row = existing.rows[0];\n const updated = {\n channel: patch.channel ?? row.channel,\n channel_installation_id: patch.channelInstallationId ?? row.channel_installation_id,\n sender_id: patch.senderId ?? row.sender_id,\n agent_id: patch.agentId ?? row.agent_id,\n thread_id: patch.threadId !== undefined ? patch.threadId : row.thread_id,\n workspace_id: patch.workspaceId !== undefined ? patch.workspaceId : row.workspace_id,\n project_id: patch.projectId !== undefined ? patch.projectId : row.project_id,\n thread_mode: patch.threadMode ?? row.thread_mode,\n sender_display_name: patch.senderDisplayName !== undefined\n ? patch.senderDisplayName : row.sender_display_name,\n sender_metadata: patch.senderMetadata !== undefined\n ? patch.senderMetadata : row.sender_metadata,\n enabled: patch.enabled ?? row.enabled,\n };\n\n const result = await this.pool.query<BindingRow>(\n `UPDATE lattice_channel_bindings SET\n channel = $1, channel_installation_id = $2, sender_id = $3,\n agent_id = $4, thread_id = $5, workspace_id = $6, project_id = $7,\n thread_mode = $8, sender_display_name = $9, sender_metadata = $10,\n enabled = $11, updated_at = NOW()\n WHERE id = $12\n RETURNING *`,\n [\n updated.channel, updated.channel_installation_id, updated.sender_id,\n updated.agent_id, updated.thread_id, updated.workspace_id,\n updated.project_id, updated.thread_mode, updated.sender_display_name,\n updated.sender_metadata ? JSON.stringify(updated.sender_metadata) : null,\n updated.enabled, id,\n ],\n );\n return this.mapRowToBinding(result.rows[0]);\n }\n\n async delete(id: string): Promise<void> {\n await this.ensureInitialized();\n await this.pool.query(`DELETE FROM lattice_channel_bindings WHERE id = $1`, [id]);\n }\n\n async list(params: {\n channel?: string;\n agentId?: string;\n tenantId: string;\n channelInstallationId?: string;\n limit?: number;\n offset?: number;\n }): Promise<Binding[]> {\n await this.ensureInitialized();\n const conditions: string[] = [\"tenant_id = $1\"];\n const values: unknown[] = [params.tenantId];\n let idx = 2;\n\n if (params.channel) {\n conditions.push(`channel = $${idx++}`);\n values.push(params.channel);\n }\n if (params.agentId) {\n conditions.push(`agent_id = $${idx++}`);\n values.push(params.agentId);\n }\n if (params.channelInstallationId) {\n conditions.push(`channel_installation_id = $${idx++}`);\n values.push(params.channelInstallationId);\n }\n\n const limit = params.limit ?? 50;\n const offset = params.offset ?? 0;\n values.push(limit, offset);\n\n const result = await this.pool.query<BindingRow>(\n `SELECT * FROM lattice_channel_bindings\n WHERE ${conditions.join(\" AND \")}\n ORDER BY created_at DESC\n LIMIT $${idx++} OFFSET $${idx}`,\n values,\n );\n return result.rows.map((r) => this.mapRowToBinding(r));\n }\n\n async import(bindings: CreateBindingInput[]): Promise<Binding[]> {\n const result: Binding[] = [];\n for (const input of bindings) {\n result.push(await this.create(input));\n }\n return result;\n }\n\n async export(params: { tenantId: string }): Promise<Binding[]> {\n return this.list({ tenantId: params.tenantId, limit: 10000, offset: 0 });\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n private mapRowToBinding(row: BindingRow): Binding {\n return {\n id: row.id,\n channel: row.channel,\n channelInstallationId: row.channel_installation_id,\n tenantId: row.tenant_id,\n senderId: row.sender_id,\n agentId: row.agent_id,\n threadId: row.thread_id || undefined,\n workspaceId: row.workspace_id || undefined,\n projectId: row.project_id || undefined,\n threadMode: row.thread_mode,\n senderDisplayName: row.sender_display_name || undefined,\n senderMetadata: row.sender_metadata || undefined,\n enabled: row.enabled,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n}\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const createChannelBindingsTable: Migration = {\n version: 110,\n name: \"create_channel_bindings_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_channel_bindings (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n channel VARCHAR(50) NOT NULL,\n channel_installation_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n sender_id VARCHAR(255) NOT NULL,\n agent_id VARCHAR(255) NOT NULL,\n thread_id VARCHAR(255),\n workspace_id VARCHAR(255),\n project_id VARCHAR(255),\n thread_mode VARCHAR(20) NOT NULL DEFAULT 'fixed'\n CHECK (thread_mode IN ('fixed', 'per_conversation')),\n sender_display_name VARCHAR(255),\n sender_metadata JSONB,\n enabled BOOLEAN NOT NULL DEFAULT true,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMP NOT NULL DEFAULT NOW(),\n UNIQUE (channel, channel_installation_id, tenant_id, sender_id)\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_channel_bindings_lookup\n ON lattice_channel_bindings(channel, channel_installation_id, tenant_id, sender_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_channel_bindings_agent\n ON lattice_channel_bindings(agent_id, tenant_id)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_channel_bindings_enabled\n ON lattice_channel_bindings(enabled)\n WHERE enabled = true\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP TABLE IF EXISTS lattice_channel_bindings\");\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n ChannelInstallation,\n ChannelInstallationStore,\n ChannelInstallationType,\n CreateChannelInstallationRequest,\n LarkChannelInstallationConfig,\n UpdateChannelInstallationRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createChannelInstallationsTable } from \"../migrations/channel_installation_migrations\";\nimport { alterChannelInstallationsTable } from \"../migrations/channel_installations_alter_migration\";\nimport { decrypt, encrypt } from \"@axiom-lattice/core\";\n\nexport interface PostgreSQLChannelInstallationStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\ntype ChannelInstallationRow = {\n id: string;\n tenant_id: string;\n channel: ChannelInstallationType;\n name: string | null;\n config: Record<string, unknown>;\n enabled: boolean;\n fallback_agent_id: string | null;\n reject_when_no_binding: boolean;\n created_at: Date;\n updated_at: Date;\n};\n\nexport class PostgreSQLChannelInstallationStore\n implements ChannelInstallationStore\n{\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLChannelInstallationStoreOptions) {\n this.pool =\n typeof options.poolConfig === \"string\"\n ? new Pool({ connectionString: options.poolConfig })\n : new Pool(options.poolConfig);\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createChannelInstallationsTable);\n this.migrationManager.register(alterChannelInstallationsTable);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\n \"Failed to initialize PostgreSQLChannelInstallationStore:\",\n error,\n );\n throw error;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n async getInstallationById(\n installationId: string,\n ): Promise<ChannelInstallation | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ChannelInstallationRow>(\n `\n SELECT id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at\n FROM lattice_channel_installations\n WHERE id = $1\n LIMIT 1\n `,\n [installationId],\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToInstallation(result.rows[0]);\n }\n\n async getInstallationsByTenant(\n tenantId: string,\n channel?: ChannelInstallationType,\n ): Promise<ChannelInstallation[]> {\n await this.ensureInitialized();\n\n const result = channel\n ? await this.pool.query<ChannelInstallationRow>(\n `\n SELECT id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at\n FROM lattice_channel_installations\n WHERE tenant_id = $1 AND channel = $2\n ORDER BY created_at DESC\n `,\n [tenantId, channel],\n )\n : await this.pool.query<ChannelInstallationRow>(\n `\n SELECT id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at\n FROM lattice_channel_installations\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId],\n );\n\n return result.rows.map((row) => this.mapRowToInstallation(row));\n }\n\n async createInstallation(\n tenantId: string,\n installationId: string,\n data: CreateChannelInstallationRequest,\n ): Promise<ChannelInstallation> {\n await this.ensureInitialized();\n\n const now = new Date();\n const encryptedConfig = this.encryptSecrets(data.config as unknown as Record<string, unknown>);\n\n await this.pool.query(\n `\n INSERT INTO lattice_channel_installations (\n id, tenant_id, channel, name, config, enabled, fallback_agent_id, reject_when_no_binding, created_at, updated_at\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)\n `,\n [\n installationId,\n tenantId,\n data.channel,\n data.name || null,\n JSON.stringify(encryptedConfig),\n data.enabled ?? true,\n data.fallbackAgentId || null,\n data.rejectWhenNoBinding ?? true,\n now,\n now,\n ],\n );\n\n return {\n id: installationId,\n tenantId,\n channel: data.channel,\n name: data.name,\n config: data.config,\n enabled: data.enabled ?? true,\n fallbackAgentId: data.fallbackAgentId,\n rejectWhenNoBinding: data.rejectWhenNoBinding ?? true,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n async updateInstallation(\n tenantId: string,\n installationId: string,\n updates: UpdateChannelInstallationRequest,\n ): Promise<ChannelInstallation | null> {\n await this.ensureInitialized();\n\n const existing = await this.getInstallationById(installationId);\n if (!existing || existing.tenantId !== tenantId) {\n return null;\n }\n\n const existingConfig = (existing.config ?? {}) as Record<string, unknown>;\n const mergedConfig = {\n ...existingConfig,\n ...(updates.config || {}),\n };\n const now = new Date();\n\n await this.pool.query(\n `\n UPDATE lattice_channel_installations\n SET name = $1,\n config = $2,\n enabled = $3,\n fallback_agent_id = $4,\n reject_when_no_binding = $5,\n updated_at = $6\n WHERE tenant_id = $7 AND id = $8\n `,\n [\n updates.name ?? existing.name ?? null,\n JSON.stringify(this.encryptSecrets(mergedConfig)),\n updates.enabled ?? existing.enabled,\n updates.fallbackAgentId !== undefined ? updates.fallbackAgentId : existing.fallbackAgentId ?? null,\n updates.rejectWhenNoBinding ?? existing.rejectWhenNoBinding,\n now,\n tenantId,\n installationId,\n ],\n );\n\n return {\n ...existing,\n name: updates.name ?? existing.name,\n config: mergedConfig,\n enabled: updates.enabled ?? existing.enabled,\n fallbackAgentId: updates.fallbackAgentId !== undefined ? updates.fallbackAgentId : existing.fallbackAgentId,\n rejectWhenNoBinding: updates.rejectWhenNoBinding ?? existing.rejectWhenNoBinding,\n updatedAt: now,\n };\n }\n\n async deleteInstallation(\n tenantId: string,\n installationId: string,\n ): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_channel_installations\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, installationId],\n );\n\n return (result.rowCount || 0) > 0;\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n private mapRowToInstallation(\n row: ChannelInstallationRow,\n ): ChannelInstallation {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n channel: row.channel,\n name: row.name || undefined,\n config: this.decryptSecrets(\n typeof row.config === \"string\"\n ? JSON.parse(row.config)\n : row.config,\n ) as unknown as LarkChannelInstallationConfig,\n enabled: row.enabled,\n fallbackAgentId: row.fallback_agent_id || undefined,\n rejectWhenNoBinding: row.reject_when_no_binding,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n private encryptSecrets(\n config: Record<string, unknown>,\n ): Record<string, unknown> {\n return {\n ...config,\n appSecret:\n typeof config.appSecret === \"string\"\n ? encrypt(config.appSecret)\n : config.appSecret,\n verificationToken:\n typeof config.verificationToken === \"string\"\n ? encrypt(config.verificationToken)\n : config.verificationToken,\n encryptKey:\n typeof config.encryptKey === \"string\"\n ? encrypt(config.encryptKey)\n : config.encryptKey,\n };\n }\n\n private decryptSecrets(\n config: Record<string, unknown>,\n ): Record<string, unknown> {\n return {\n ...config,\n appSecret:\n typeof config.appSecret === \"string\"\n ? decrypt(config.appSecret)\n : config.appSecret,\n verificationToken:\n typeof config.verificationToken === \"string\"\n ? decrypt(config.verificationToken)\n : config.verificationToken,\n encryptKey:\n typeof config.encryptKey === \"string\"\n ? decrypt(config.encryptKey)\n : config.encryptKey,\n };\n }\n}\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const createChannelInstallationsTable: Migration = {\n version: 21,\n name: \"create_channel_installations_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_channel_installations (\n id UUID PRIMARY KEY,\n tenant_id VARCHAR(255) NOT NULL,\n channel VARCHAR(50) NOT NULL,\n name VARCHAR(255),\n config JSONB NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_channel_installations_tenant_channel\n ON lattice_channel_installations(tenant_id, channel)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_channel_installations_tenant_channel\",\n );\n await client.query(\"DROP TABLE IF EXISTS lattice_channel_installations\");\n },\n};\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const alterChannelInstallationsTable: Migration = {\n version: 109,\n name: \"alter_channel_installations_add_columns\",\n up: async (client: PoolClient) => {\n await client.query(`\n ALTER TABLE lattice_channel_installations\n ADD COLUMN IF NOT EXISTS enabled BOOLEAN NOT NULL DEFAULT true\n `);\n await client.query(`\n ALTER TABLE lattice_channel_installations\n ADD COLUMN IF NOT EXISTS fallback_agent_id VARCHAR(255)\n `);\n await client.query(`\n ALTER TABLE lattice_channel_installations\n ADD COLUMN IF NOT EXISTS reject_when_no_binding BOOLEAN NOT NULL DEFAULT true\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"ALTER TABLE lattice_channel_installations DROP COLUMN IF EXISTS reject_when_no_binding\",\n );\n await client.query(\n \"ALTER TABLE lattice_channel_installations DROP COLUMN IF EXISTS fallback_agent_id\",\n );\n await client.query(\n \"ALTER TABLE lattice_channel_installations DROP COLUMN IF EXISTS enabled\",\n );\n },\n};\n","/**\n * PostgreSQL implementation of ScheduleStorage\n *\n * Provides persistent storage for scheduled tasks\n * Data survives service restarts\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n ScheduleStorage,\n ScheduledTaskDefinition,\n ScheduledTaskStatus,\n ScheduleExecutionType,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createScheduledTasksTable } from \"../migrations/schedule_migrations\";\nimport { addScheduleTenantId } from \"../migrations/schedule_tenant_migration\";\n\n/**\n * PostgreSQL ScheduleStorage options\n */\nexport interface PostgreSQLScheduleStorageOptions {\n /**\n * PostgreSQL connection pool configuration\n * Can be a connection string or PoolConfig object\n */\n poolConfig: string | PoolConfig;\n\n /**\n * Whether to run migrations automatically on initialization\n * @default true\n */\n autoMigrate?: boolean;\n}\n\n/**\n * Database row type for scheduled tasks\n */\ninterface ScheduledTaskRow {\n task_id: string;\n task_type: string;\n tenant_id: string;\n payload: string | Record<string, any>;\n assistant_id: string | null;\n thread_id: string | null;\n execution_type: string;\n execute_at: Date | null;\n delay_ms: number | null;\n cron_expression: string | null;\n timezone: string | null;\n next_run_at: Date | null;\n last_run_at: Date | null;\n status: string;\n run_count: number;\n max_runs: number | null;\n retry_count: number;\n max_retries: number;\n last_error: string | null;\n created_at: Date;\n updated_at: Date;\n expires_at: Date | null;\n metadata: string | Record<string, any> | null;\n}\n\n/**\n * PostgreSQL implementation of ScheduleStorage\n */\nexport class PostgreSQLScheduleStorage implements ScheduleStorage {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n\n constructor(options: PostgreSQLScheduleStorageOptions) {\n // Create Pool from config\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createScheduledTasksTable);\n this.migrationManager.register(addScheduleTenantId);\n\n // Auto-migrate by default\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLScheduleStorage:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Dispose resources and close the connection pool\n */\n async dispose(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n }\n }\n\n /**\n * Initialize the store and run migrations\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.migrationManager.migrate();\n this.initialized = true;\n }\n\n /**\n * Ensure store is initialized\n */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Save a new task\n */\n async save(task: ScheduledTaskDefinition): Promise<void> {\n await this.ensureInitialized();\n\n await this.pool.query(\n `\n INSERT INTO lattice_scheduled_tasks (\n task_id, task_type, tenant_id, payload, assistant_id, thread_id, execution_type,\n execute_at, delay_ms, cron_expression, timezone,\n next_run_at, last_run_at, status, run_count, max_runs,\n retry_count, max_retries, last_error,\n created_at, updated_at, expires_at, metadata\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7,\n $8, $9, $10, $11,\n $12, $13, $14, $15, $16,\n $17, $18, $19,\n $20, $21, $22, $23\n )\n ON CONFLICT (task_id) DO UPDATE SET\n task_type = EXCLUDED.task_type,\n tenant_id = EXCLUDED.tenant_id,\n payload = EXCLUDED.payload,\n assistant_id = EXCLUDED.assistant_id,\n thread_id = EXCLUDED.thread_id,\n execution_type = EXCLUDED.execution_type,\n execute_at = EXCLUDED.execute_at,\n delay_ms = EXCLUDED.delay_ms,\n cron_expression = EXCLUDED.cron_expression,\n timezone = EXCLUDED.timezone,\n next_run_at = EXCLUDED.next_run_at,\n last_run_at = EXCLUDED.last_run_at,\n status = EXCLUDED.status,\n run_count = EXCLUDED.run_count,\n max_runs = EXCLUDED.max_runs,\n retry_count = EXCLUDED.retry_count,\n max_retries = EXCLUDED.max_retries,\n last_error = EXCLUDED.last_error,\n updated_at = EXCLUDED.updated_at,\n expires_at = EXCLUDED.expires_at,\n metadata = EXCLUDED.metadata\n `,\n [\n task.taskId,\n task.taskType,\n task.tenantId,\n JSON.stringify(task.payload),\n task.assistantId ?? null,\n task.threadId ?? null,\n task.executionType,\n task.executeAt ? new Date(task.executeAt) : null,\n task.delayMs ?? null,\n task.cronExpression ?? null,\n task.timezone ?? null,\n task.nextRunAt ? new Date(task.nextRunAt) : null,\n task.lastRunAt ? new Date(task.lastRunAt) : null,\n task.status,\n task.runCount,\n task.maxRuns ?? null,\n task.retryCount,\n task.maxRetries,\n task.lastError ?? null,\n new Date(task.createdAt),\n new Date(task.updatedAt),\n task.expiresAt ? new Date(task.expiresAt) : null,\n task.metadata ? JSON.stringify(task.metadata) : null,\n ]\n );\n }\n\n /**\n * Get task by ID\n */\n async get(taskId: string): Promise<ScheduledTaskDefinition | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE task_id = $1`,\n [taskId]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToTask(result.rows[0]);\n }\n\n /**\n * Update task\n */\n async update(\n taskId: string,\n updates: Partial<ScheduledTaskDefinition>\n ): Promise<void> {\n await this.ensureInitialized();\n\n const setClauses: string[] = [];\n const values: any[] = [];\n let paramIndex = 1;\n\n // Build dynamic UPDATE query\n if (updates.taskType !== undefined) {\n setClauses.push(`task_type = $${paramIndex++}`);\n values.push(updates.taskType);\n }\n if (updates.payload !== undefined) {\n setClauses.push(`payload = $${paramIndex++}`);\n values.push(JSON.stringify(updates.payload));\n }\n if (updates.assistantId !== undefined) {\n setClauses.push(`assistant_id = $${paramIndex++}`);\n values.push(updates.assistantId);\n }\n if (updates.threadId !== undefined) {\n setClauses.push(`thread_id = $${paramIndex++}`);\n values.push(updates.threadId);\n }\n if (updates.executionType !== undefined) {\n setClauses.push(`execution_type = $${paramIndex++}`);\n values.push(updates.executionType);\n }\n if (updates.executeAt !== undefined) {\n setClauses.push(`execute_at = $${paramIndex++}`);\n values.push(updates.executeAt ? new Date(updates.executeAt) : null);\n }\n if (updates.delayMs !== undefined) {\n setClauses.push(`delay_ms = $${paramIndex++}`);\n values.push(updates.delayMs);\n }\n if (updates.cronExpression !== undefined) {\n setClauses.push(`cron_expression = $${paramIndex++}`);\n values.push(updates.cronExpression);\n }\n if (updates.timezone !== undefined) {\n setClauses.push(`timezone = $${paramIndex++}`);\n values.push(updates.timezone);\n }\n if (updates.nextRunAt !== undefined) {\n setClauses.push(`next_run_at = $${paramIndex++}`);\n values.push(updates.nextRunAt ? new Date(updates.nextRunAt) : null);\n }\n if (updates.lastRunAt !== undefined) {\n setClauses.push(`last_run_at = $${paramIndex++}`);\n values.push(updates.lastRunAt ? new Date(updates.lastRunAt) : null);\n }\n if (updates.status !== undefined) {\n setClauses.push(`status = $${paramIndex++}`);\n values.push(updates.status);\n }\n if (updates.runCount !== undefined) {\n setClauses.push(`run_count = $${paramIndex++}`);\n values.push(updates.runCount);\n }\n if (updates.maxRuns !== undefined) {\n setClauses.push(`max_runs = $${paramIndex++}`);\n values.push(updates.maxRuns);\n }\n if (updates.retryCount !== undefined) {\n setClauses.push(`retry_count = $${paramIndex++}`);\n values.push(updates.retryCount);\n }\n if (updates.maxRetries !== undefined) {\n setClauses.push(`max_retries = $${paramIndex++}`);\n values.push(updates.maxRetries);\n }\n if (updates.lastError !== undefined) {\n setClauses.push(`last_error = $${paramIndex++}`);\n values.push(updates.lastError);\n }\n if (updates.expiresAt !== undefined) {\n setClauses.push(`expires_at = $${paramIndex++}`);\n values.push(updates.expiresAt ? new Date(updates.expiresAt) : null);\n }\n if (updates.metadata !== undefined) {\n setClauses.push(`metadata = $${paramIndex++}`);\n values.push(updates.metadata ? JSON.stringify(updates.metadata) : null);\n }\n\n // Always update updated_at\n setClauses.push(`updated_at = $${paramIndex++}`);\n values.push(new Date());\n\n // Add taskId as the last parameter\n values.push(taskId);\n\n if (setClauses.length === 0) {\n return;\n }\n\n await this.pool.query(\n `UPDATE lattice_scheduled_tasks SET ${setClauses.join(\n \", \"\n )} WHERE task_id = $${paramIndex}`,\n values\n );\n }\n\n /**\n * Delete task\n */\n async delete(taskId: string): Promise<void> {\n await this.ensureInitialized();\n\n await this.pool.query(\n `DELETE FROM lattice_scheduled_tasks WHERE task_id = $1`,\n [taskId]\n );\n }\n\n /**\n * Get all active tasks (pending or paused)\n */\n async getActiveTasks(): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE status IN ($1, $2) ORDER BY created_at ASC`,\n [ScheduledTaskStatus.PENDING, ScheduledTaskStatus.PAUSED]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by type\n */\n async getTasksByType(taskType: string): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE task_type = $1 ORDER BY created_at DESC`,\n [taskType]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by status\n */\n async getTasksByStatus(\n status: ScheduledTaskStatus\n ): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE status = $1 ORDER BY created_at DESC`,\n [status]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by execution type\n */\n async getTasksByExecutionType(\n executionType: ScheduleExecutionType\n ): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE execution_type = $1 ORDER BY created_at DESC`,\n [executionType]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by assistant ID\n */\n async getTasksByAssistantId(\n assistantId: string\n ): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE assistant_id = $1 ORDER BY created_at DESC`,\n [assistantId]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get tasks by thread ID\n */\n async getTasksByThreadId(\n threadId: string\n ): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ScheduledTaskRow>(\n `SELECT * FROM lattice_scheduled_tasks WHERE thread_id = $1 ORDER BY created_at DESC`,\n [threadId]\n );\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Get all tasks with optional filters\n */\n async getAllTasks(filters?: {\n tenantId?: string;\n status?: ScheduledTaskStatus;\n executionType?: ScheduleExecutionType;\n taskType?: string;\n assistantId?: string;\n threadId?: string;\n limit?: number;\n offset?: number;\n }): Promise<ScheduledTaskDefinition[]> {\n await this.ensureInitialized();\n\n const whereClauses: string[] = [];\n const values: any[] = [];\n let paramIndex = 1;\n\n // Always filter by tenantId if provided\n if (filters?.tenantId !== undefined) {\n whereClauses.push(`tenant_id = $${paramIndex++}`);\n values.push(filters.tenantId);\n }\n\n if (filters?.status !== undefined) {\n whereClauses.push(`status = $${paramIndex++}`);\n values.push(filters.status);\n }\n if (filters?.executionType !== undefined) {\n whereClauses.push(`execution_type = $${paramIndex++}`);\n values.push(filters.executionType);\n }\n if (filters?.taskType !== undefined) {\n whereClauses.push(`task_type = $${paramIndex++}`);\n values.push(filters.taskType);\n }\n if (filters?.assistantId !== undefined) {\n whereClauses.push(`assistant_id = $${paramIndex++}`);\n values.push(filters.assistantId);\n }\n if (filters?.threadId !== undefined) {\n whereClauses.push(`thread_id = $${paramIndex++}`);\n values.push(filters.threadId);\n }\n\n let query = `SELECT * FROM lattice_scheduled_tasks`;\n if (whereClauses.length > 0) {\n query += ` WHERE ${whereClauses.join(\" AND \")}`;\n }\n query += ` ORDER BY created_at DESC`;\n\n if (filters?.limit !== undefined) {\n query += ` LIMIT $${paramIndex++}`;\n values.push(filters.limit);\n }\n if (filters?.offset !== undefined) {\n query += ` OFFSET $${paramIndex++}`;\n values.push(filters.offset);\n }\n\n const result = await this.pool.query<ScheduledTaskRow>(query, values);\n\n return result.rows.map((row) => this.mapRowToTask(row));\n }\n\n /**\n * Count tasks with optional filters\n */\n async countTasks(filters?: {\n tenantId?: string;\n status?: ScheduledTaskStatus;\n executionType?: ScheduleExecutionType;\n taskType?: string;\n assistantId?: string;\n threadId?: string;\n }): Promise<number> {\n await this.ensureInitialized();\n\n const whereClauses: string[] = [];\n const values: any[] = [];\n let paramIndex = 1;\n\n // Always filter by tenantId if provided\n if (filters?.tenantId !== undefined) {\n whereClauses.push(`tenant_id = $${paramIndex++}`);\n values.push(filters.tenantId);\n }\n\n if (filters?.status !== undefined) {\n whereClauses.push(`status = $${paramIndex++}`);\n values.push(filters.status);\n }\n if (filters?.executionType !== undefined) {\n whereClauses.push(`execution_type = $${paramIndex++}`);\n values.push(filters.executionType);\n }\n if (filters?.taskType !== undefined) {\n whereClauses.push(`task_type = $${paramIndex++}`);\n values.push(filters.taskType);\n }\n if (filters?.assistantId !== undefined) {\n whereClauses.push(`assistant_id = $${paramIndex++}`);\n values.push(filters.assistantId);\n }\n if (filters?.threadId !== undefined) {\n whereClauses.push(`thread_id = $${paramIndex++}`);\n values.push(filters.threadId);\n }\n\n let query = `SELECT COUNT(*) as count FROM lattice_scheduled_tasks`;\n if (whereClauses.length > 0) {\n query += ` WHERE ${whereClauses.join(\" AND \")}`;\n }\n\n const result = await this.pool.query<{ count: string }>(query, values);\n\n return parseInt(result.rows[0].count, 10);\n }\n\n /**\n * Delete completed/cancelled/failed tasks older than specified time\n */\n async deleteOldTasks(olderThanMs: number): Promise<number> {\n await this.ensureInitialized();\n\n const cutoff = new Date(Date.now() - olderThanMs);\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_scheduled_tasks \n WHERE status IN ($1, $2, $3) \n AND updated_at < $4\n `,\n [\n ScheduledTaskStatus.COMPLETED,\n ScheduledTaskStatus.CANCELLED,\n ScheduledTaskStatus.FAILED,\n cutoff,\n ]\n );\n\n return result.rowCount ?? 0;\n }\n\n /**\n * Map database row to ScheduledTaskDefinition\n */\n private mapRowToTask(row: ScheduledTaskRow): ScheduledTaskDefinition {\n return {\n taskId: row.task_id,\n taskType: row.task_type,\n tenantId: row.tenant_id,\n payload:\n typeof row.payload === \"string\"\n ? JSON.parse(row.payload)\n : row.payload || {},\n assistantId: row.assistant_id ?? undefined,\n threadId: row.thread_id ?? undefined,\n executionType: row.execution_type as ScheduleExecutionType,\n executeAt: row.execute_at ? row.execute_at.getTime() : undefined,\n delayMs: row.delay_ms ?? undefined,\n cronExpression: row.cron_expression ?? undefined,\n timezone: row.timezone ?? undefined,\n nextRunAt: row.next_run_at ? row.next_run_at.getTime() : undefined,\n lastRunAt: row.last_run_at ? row.last_run_at.getTime() : undefined,\n status: row.status as ScheduledTaskStatus,\n runCount: row.run_count,\n maxRuns: row.max_runs ?? undefined,\n retryCount: row.retry_count,\n maxRetries: row.max_retries,\n lastError: row.last_error ?? undefined,\n createdAt: row.created_at.getTime(),\n updatedAt: row.updated_at.getTime(),\n expiresAt: row.expires_at ? row.expires_at.getTime() : undefined,\n metadata:\n row.metadata === null\n ? undefined\n : typeof row.metadata === \"string\"\n ? JSON.parse(row.metadata)\n : row.metadata,\n };\n }\n}\n","/**\n * PostgreSQL migrations for scheduled tasks table\n */\n\nimport { Migration } from \"./migration\";\n\n/**\n * Create the scheduled_tasks table\n */\nexport const createScheduledTasksTable: Migration = {\n name: \"create_scheduled_tasks_table\",\n version: 2,\n\n up: async (client) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_scheduled_tasks (\n -- Primary key\n task_id VARCHAR(255) PRIMARY KEY,\n \n -- Task type (maps to handler)\n task_type VARCHAR(255) NOT NULL,\n \n -- Payload (JSON-serializable data)\n payload JSONB NOT NULL DEFAULT '{}',\n \n -- Context fields for querying\n assistant_id VARCHAR(255),\n thread_id VARCHAR(255),\n \n -- Execution type: 'once' or 'cron'\n execution_type VARCHAR(50) NOT NULL,\n \n -- For ONCE type\n execute_at TIMESTAMPTZ,\n delay_ms BIGINT,\n \n -- For CRON type\n cron_expression VARCHAR(255),\n timezone VARCHAR(100),\n next_run_at TIMESTAMPTZ,\n last_run_at TIMESTAMPTZ,\n \n -- Status\n status VARCHAR(50) NOT NULL DEFAULT 'pending',\n \n -- Execution tracking\n run_count INTEGER NOT NULL DEFAULT 0,\n max_runs INTEGER,\n \n -- Error handling\n retry_count INTEGER NOT NULL DEFAULT 0,\n max_retries INTEGER NOT NULL DEFAULT 0,\n last_error TEXT,\n \n -- Timestamps\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n expires_at TIMESTAMPTZ,\n \n -- Metadata\n metadata JSONB\n );\n\n -- Index for querying active tasks\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_status \n ON lattice_scheduled_tasks (status);\n \n -- Index for querying by task type\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_task_type \n ON lattice_scheduled_tasks (task_type);\n \n -- Index for querying by execution type\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_execution_type \n ON lattice_scheduled_tasks (execution_type);\n \n -- Index for querying by assistant ID\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_assistant_id \n ON lattice_scheduled_tasks (assistant_id)\n WHERE assistant_id IS NOT NULL;\n \n -- Index for querying by thread ID\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_thread_id \n ON lattice_scheduled_tasks (thread_id)\n WHERE thread_id IS NOT NULL;\n \n -- Index for querying pending tasks by next run time\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_next_run \n ON lattice_scheduled_tasks (next_run_at) \n WHERE status = 'pending';\n \n -- Index for querying pending one-time tasks by execute time\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_execute_at \n ON lattice_scheduled_tasks (execute_at) \n WHERE status = 'pending' AND execution_type = 'once';\n \n -- Index for cleanup queries (old completed/cancelled tasks)\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_cleanup \n ON lattice_scheduled_tasks (updated_at) \n WHERE status IN ('completed', 'cancelled', 'failed');\n `);\n },\n\n down: async (client) => {\n await client.query(`\n DROP INDEX IF EXISTS idx_scheduled_tasks_cleanup;\n DROP INDEX IF EXISTS idx_scheduled_tasks_execute_at;\n DROP INDEX IF EXISTS idx_scheduled_tasks_next_run;\n DROP INDEX IF EXISTS idx_scheduled_tasks_thread_id;\n DROP INDEX IF EXISTS idx_scheduled_tasks_assistant_id;\n DROP INDEX IF EXISTS idx_scheduled_tasks_execution_type;\n DROP INDEX IF EXISTS idx_scheduled_tasks_task_type;\n DROP INDEX IF EXISTS idx_scheduled_tasks_status;\n DROP TABLE IF EXISTS lattice_scheduled_tasks;\n `);\n },\n};\n","/**\n * Schedule table tenant isolation migration\n * Adds tenant_id column to lattice_scheduled_tasks table\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add tenant_id column to scheduled tasks table\n */\nexport const addScheduleTenantId: Migration = {\n version: 18,\n name: \"add_schedule_tenant_id\",\n up: async (client: PoolClient) => {\n // Add tenant_id column\n await client.query(`\n ALTER TABLE lattice_scheduled_tasks\n ADD COLUMN IF NOT EXISTS tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_scheduled_tasks \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL after setting defaults\n await client.query(`\n ALTER TABLE lattice_scheduled_tasks\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the default constraint\n await client.query(`\n ALTER TABLE lattice_scheduled_tasks\n ALTER COLUMN tenant_id DROP DEFAULT\n `);\n\n // Create index for tenant-based queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_tenant_id \n ON lattice_scheduled_tasks(tenant_id)\n `);\n\n // Create composite index for common tenant+assistant queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_tenant_assistant \n ON lattice_scheduled_tasks(tenant_id, assistant_id)\n WHERE assistant_id IS NOT NULL\n `);\n\n // Create composite index for common tenant+thread queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_tenant_thread \n ON lattice_scheduled_tasks(tenant_id, thread_id)\n WHERE thread_id IS NOT NULL\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_scheduled_tasks_tenant_thread\"\n );\n await client.query(\n \"DROP INDEX IF EXISTS idx_scheduled_tasks_tenant_assistant\"\n );\n await client.query(\n \"DROP INDEX IF EXISTS idx_scheduled_tasks_tenant_id\"\n );\n await client.query(\n \"ALTER TABLE lattice_scheduled_tasks DROP COLUMN IF EXISTS tenant_id\"\n );\n },\n};\n","/**\n * createPgStoreConfig\n *\n * Creates a map of all PG store instances from a single connection string,\n * ready to pass directly to configureStores().\n */\n\nimport { PostgreSQLThreadStore } from \"./stores/PostgreSQLThreadStore\";\nimport { PostgreSQLAssistantStore } from \"./stores/PostgreSQLAssistantStore\";\nimport { PostgreSQLDatabaseConfigStore } from \"./stores/PostgreSQLDatabaseConfigStore\";\nimport { PostgreSQLMetricsServerConfigStore } from \"./stores/PostgreSQLMetricsServerConfigStore\";\nimport { PostgreSQLMcpServerConfigStore } from \"./stores/PostgreSQLMcpServerConfigStore\";\nimport { PostgreSQLWorkspaceStore } from \"./stores/PostgreSQLWorkspaceStore\";\nimport { PostgreSQLProjectStore } from \"./stores/PostgreSQLProjectStore\";\nimport { PostgreSQLUserStore } from \"./stores/PostgreSQLUserStore\";\nimport { PostgreSQLTenantStore } from \"./stores/PostgreSQLTenantStore\";\nimport { PostgreSQLUserTenantLinkStore } from \"./stores/PostgreSQLUserTenantLinkStore\";\nimport { PostgreSQLWorkflowTrackingStore } from \"./stores/PostgreSQLWorkflowTrackingStore\";\nimport { PostgreSQLEvalStore } from \"./stores/PostgreSQLEvalStore\";\nimport { ThreadMessageQueueStore } from \"./stores/ThreadMessageQueueStore\";\nimport { ChannelBindingStore } from \"./stores/ChannelBindingStore\";\nimport { PostgreSQLChannelInstallationStore } from \"./stores/PostgreSQLChannelInstallationStore\";\nimport { PostgreSQLScheduleStorage } from \"./stores/PostgreSQLScheduleStorage\";\n\nexport function createPgStoreConfig(connectionString: string) {\n const opts = { poolConfig: connectionString, autoMigrate: false } as const;\n const optsAuto = { poolConfig: connectionString, autoMigrate: true } as const;\n\n return {\n workspace: new PostgreSQLWorkspaceStore(opts),\n project: new PostgreSQLProjectStore(opts),\n eval: new PostgreSQLEvalStore(optsAuto),\n user: new PostgreSQLUserStore(opts),\n tenant: new PostgreSQLTenantStore(opts),\n userTenantLink: new PostgreSQLUserTenantLinkStore(opts),\n channelBinding: new ChannelBindingStore(optsAuto),\n channelInstallation: new PostgreSQLChannelInstallationStore(optsAuto),\n thread: new PostgreSQLThreadStore(opts),\n database: new PostgreSQLDatabaseConfigStore(opts),\n metrics: new PostgreSQLMetricsServerConfigStore(opts),\n mcp: new PostgreSQLMcpServerConfigStore(opts),\n assistant: new PostgreSQLAssistantStore(opts),\n workflowTracking: new PostgreSQLWorkflowTrackingStore(optsAuto),\n threadMessageQueue: new ThreadMessageQueueStore(optsAuto),\n schedule: new PostgreSQLScheduleStorage(opts),\n };\n}\n","/**\n * PostgreSQL implementation of SkillStore with tenant isolation\n */\n\nimport { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport {\n SkillStore,\n Skill,\n CreateSkillRequest,\n} from \"@axiom-lattice/protocols\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createSkillsTable } from \"../migrations/skill_migrations\";\nimport { addSkillTenantId } from \"../migrations/skill_tenant_migration\";\nimport { changeSkillPrimaryKey } from \"../migrations/skill_pk_migration\";\n\nexport interface PostgreSQLSkillStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\n/**\n * PostgreSQL implementation of SkillStore with tenant isolation\n * \n * Features:\n * - Multi-tenant isolation via tenant_id\n */\nexport class PostgreSQLSkillStore implements SkillStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized: boolean = false;\n private ownsPool: boolean = true;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: PostgreSQLSkillStoreOptions) {\n if (typeof options.poolConfig === \"string\") {\n this.pool = new Pool({ connectionString: options.poolConfig });\n } else {\n this.pool = new Pool(options.poolConfig);\n }\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createSkillsTable);\n this.migrationManager.register(addSkillTenantId);\n this.migrationManager.register(changeSkillPrimaryKey);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize PostgreSQLSkillStore:\", error);\n throw error;\n });\n }\n }\n\n /**\n * Initialize the store and run migrations\n * Uses a promise-based lock to prevent concurrent initialization\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n async dispose(): Promise<void> {\n if (this.ownsPool && this.pool) {\n await this.pool.end();\n }\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map database row to Skill object\n */\n private mapRowToSkill(row: {\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }): Skill {\n return {\n id: row.id,\n tenantId: row.tenant_id,\n name: row.name,\n description: row.description,\n license: row.license || undefined,\n compatibility: row.compatibility || undefined,\n metadata: row.metadata || {},\n content: row.content || undefined,\n subSkills: Array.isArray(row.sub_skills) ? row.sub_skills : undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n /**\n * Get all skills for a tenant\n */\n async getAllSkills(tenantId: string): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1\n ORDER BY created_at DESC\n `,\n [tenantId]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n\n /**\n * Get skill by ID for a tenant\n */\n async getSkillById(tenantId: string, id: string): Promise<Skill | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return this.mapRowToSkill(result.rows[0]);\n }\n\n /**\n * Create a new skill for a tenant\n */\n async createSkill(\n tenantId: string,\n id: string,\n data: CreateSkillRequest\n ): Promise<Skill> {\n await this.ensureInitialized();\n\n const now = new Date();\n\n await this.pool.query(\n `\n INSERT INTO lattice_skills (id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n ON CONFLICT (tenant_id, id) DO UPDATE SET\n tenant_id = EXCLUDED.tenant_id,\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n license = EXCLUDED.license,\n compatibility = EXCLUDED.compatibility,\n metadata = EXCLUDED.metadata,\n content = EXCLUDED.content,\n sub_skills = EXCLUDED.sub_skills,\n updated_at = EXCLUDED.updated_at\n `,\n [\n id,\n tenantId,\n data.name,\n data.description,\n data.license || null,\n data.compatibility || null,\n JSON.stringify(data.metadata || {}),\n data.content || null,\n JSON.stringify(data.subSkills || []),\n now,\n now,\n ]\n );\n\n return {\n id,\n tenantId,\n name: data.name,\n description: data.description,\n license: data.license,\n compatibility: data.compatibility,\n metadata: data.metadata || {},\n content: data.content,\n subSkills: data.subSkills,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * Update an existing skill for a tenant\n */\n async updateSkill(\n tenantId: string,\n id: string,\n updates: Partial<CreateSkillRequest>\n ): Promise<Skill | null> {\n await this.ensureInitialized();\n\n // Get existing skill\n const existing = await this.getSkillById(tenantId, id);\n if (!existing) {\n return null;\n }\n\n // Build update query dynamically based on provided fields\n const updateFields: string[] = [];\n const updateValues: any[] = [];\n let paramIndex = 1;\n\n if (updates.name !== undefined) {\n updateFields.push(`name = $${paramIndex++}`);\n updateValues.push(updates.name);\n }\n\n if (updates.description !== undefined) {\n updateFields.push(`description = $${paramIndex++}`);\n updateValues.push(updates.description);\n }\n\n if (updates.license !== undefined) {\n updateFields.push(`license = $${paramIndex++}`);\n updateValues.push(updates.license || null);\n }\n\n if (updates.compatibility !== undefined) {\n updateFields.push(`compatibility = $${paramIndex++}`);\n updateValues.push(updates.compatibility || null);\n }\n\n if (updates.metadata !== undefined) {\n updateFields.push(`metadata = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.metadata || {}));\n }\n\n if (updates.content !== undefined) {\n updateFields.push(`content = $${paramIndex++}`);\n updateValues.push(updates.content || null);\n }\n\n if (updates.subSkills !== undefined) {\n updateFields.push(`sub_skills = $${paramIndex++}`);\n updateValues.push(JSON.stringify(updates.subSkills || []));\n }\n\n if (updateFields.length === 0) {\n // No fields to update\n return existing;\n }\n\n // Always update updated_at\n updateFields.push(`updated_at = $${paramIndex++}`);\n updateValues.push(new Date());\n\n // Add tenant_id and id for WHERE clause\n updateValues.push(tenantId);\n updateValues.push(id);\n\n await this.pool.query(\n `\n UPDATE lattice_skills\n SET ${updateFields.join(\", \")}\n WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex}\n `,\n updateValues\n );\n\n // Return updated skill\n return await this.getSkillById(tenantId, id);\n }\n\n /**\n * Delete a skill by ID for a tenant\n */\n async deleteSkill(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n DELETE FROM lattice_skills\n WHERE tenant_id = $1 AND id = $2\n `,\n [tenantId, id]\n );\n\n return result.rowCount !== null && result.rowCount > 0;\n }\n\n /**\n * Check if skill exists for a tenant\n */\n async hasSkill(tenantId: string, id: string): Promise<boolean> {\n await this.ensureInitialized();\n\n const result = await this.pool.query(\n `\n SELECT 1 FROM lattice_skills\n WHERE tenant_id = $1 AND id = $2\n LIMIT 1\n `,\n [tenantId, id]\n );\n\n return result.rows.length > 0;\n }\n\n /**\n * Search skills by metadata within a tenant\n */\n async searchByMetadata(\n tenantId: string,\n metadataKey: string,\n metadataValue: string\n ): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND metadata ->> $2 = $3\n ORDER BY created_at DESC\n `,\n [tenantId, metadataKey, metadataValue]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n\n /**\n * Filter skills by compatibility within a tenant\n */\n async filterByCompatibility(\n tenantId: string,\n compatibility: string\n ): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND compatibility = $2\n ORDER BY created_at DESC\n `,\n [tenantId, compatibility]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n\n /**\n * Filter skills by license within a tenant\n */\n async filterByLicense(\n tenantId: string,\n license: string\n ): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND license = $2\n ORDER BY created_at DESC\n `,\n [tenantId, license]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n\n /**\n * Get sub-skills of a parent skill within a tenant\n * Note: This searches for skills that have the parent skill name in their subSkills array\n */\n async getSubSkills(\n tenantId: string,\n parentSkillName: string\n ): Promise<Skill[]> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n id: string;\n tenant_id: string;\n name: string;\n description: string;\n license: string | null;\n compatibility: string | null;\n metadata: any;\n content: string | null;\n sub_skills: any;\n created_at: Date;\n updated_at: Date;\n }>(\n `\n SELECT id, tenant_id, name, description, license, compatibility, metadata, content, sub_skills, created_at, updated_at\n FROM lattice_skills\n WHERE tenant_id = $1 AND sub_skills @> to_jsonb($2::text)\n ORDER BY created_at DESC\n `,\n [tenantId, JSON.stringify([parentSkillName])]\n );\n\n return result.rows.map(this.mapRowToSkill);\n }\n}\n","/**\n * Skill table migrations\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Initial migration: Create skills table\n */\nexport const createSkillsTable: Migration = {\n version: 4,\n name: \"create_skills_table\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS lattice_skills (\n id VARCHAR(255) PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n description TEXT NOT NULL,\n license VARCHAR(255),\n compatibility VARCHAR(255),\n metadata JSONB DEFAULT '{}',\n content TEXT,\n sub_skills JSONB DEFAULT '[]',\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Create indexes for better query performance\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_name \n ON lattice_skills(name)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_license \n ON lattice_skills(license)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_compatibility \n ON lattice_skills(compatibility)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_created_at \n ON lattice_skills(created_at DESC)\n `);\n\n // Create GIN index for metadata JSONB queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_metadata \n ON lattice_skills USING GIN (metadata)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_metadata\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_created_at\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_compatibility\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_license\");\n await client.query(\"DROP INDEX IF EXISTS idx_lattice_skills_name\");\n await client.query(\"DROP TABLE IF EXISTS lattice_skills\");\n },\n};\n","/**\n * Skill table tenant isolation migration\n * Adds tenant_id column to lattice_skills table\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Add tenant_id column to skills table\n */\nexport const addSkillTenantId: Migration = {\n version: 16,\n name: \"add_skill_tenant_id\",\n up: async (client: PoolClient) => {\n // Add tenant_id column\n await client.query(`\n ALTER TABLE lattice_skills\n ADD COLUMN IF NOT EXISTS tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_skills \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL after setting defaults\n await client.query(`\n ALTER TABLE lattice_skills\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the default constraint\n await client.query(`\n ALTER TABLE lattice_skills\n ALTER COLUMN tenant_id DROP DEFAULT\n `);\n\n // Create index for tenant-based queries\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_lattice_skills_tenant_id \n ON lattice_skills(tenant_id)\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\n \"DROP INDEX IF EXISTS idx_lattice_skills_tenant_id\"\n );\n await client.query(\n \"ALTER TABLE lattice_skills DROP COLUMN IF EXISTS tenant_id\"\n );\n },\n};\n","/**\n * Skill table primary key migration\n * Changes primary key from (id) to (tenant_id, id) for multi-tenancy\n */\n\nimport { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\n/**\n * Migration: Change skill table primary key to support multi-tenancy\n */\nexport const changeSkillPrimaryKey: Migration = {\n version: 17,\n name: \"change_skill_primary_key\",\n up: async (client: PoolClient) => {\n // Check if table exists\n const tableExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.tables \n WHERE table_name = 'lattice_skills'\n )\n `);\n\n if (!tableExists.rows[0].exists) {\n return;\n }\n\n // Check current primary key\n const pkResult = await client.query(`\n SELECT a.attname as column_name\n FROM pg_index i\n JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)\n WHERE i.indrelid = 'lattice_skills'::regclass\n AND i.indisprimary\n `);\n\n const pkColumns = pkResult.rows.map(row => row.column_name);\n \n // If primary key is already (tenant_id, id), nothing to do\n if (pkColumns.includes('tenant_id') && pkColumns.includes('id')) {\n console.log('Skill table primary key already correct (tenant_id, id)');\n return;\n }\n\n // If primary key is just (id), we need to change it\n if (pkColumns.length === 1 && pkColumns[0] === 'id') {\n console.log('Changing skill table primary key from (id) to (tenant_id, id)');\n \n // Check if tenant_id column exists\n const tenantIdExists = await client.query(`\n SELECT EXISTS (\n SELECT FROM information_schema.columns \n WHERE table_name = 'lattice_skills' \n AND column_name = 'tenant_id'\n )\n `);\n\n if (!tenantIdExists.rows[0].exists) {\n // Add tenant_id column if it doesn't exist\n await client.query(`\n ALTER TABLE lattice_skills\n ADD COLUMN tenant_id VARCHAR(255) DEFAULT 'default'\n `);\n }\n\n // Update existing records to have tenant_id\n await client.query(`\n UPDATE lattice_skills \n SET tenant_id = 'default' \n WHERE tenant_id IS NULL\n `);\n\n // Make tenant_id NOT NULL\n await client.query(`\n ALTER TABLE lattice_skills\n ALTER COLUMN tenant_id SET NOT NULL\n `);\n\n // Drop the old primary key\n await client.query(`\n ALTER TABLE lattice_skills \n DROP CONSTRAINT IF EXISTS lattice_skills_pkey\n `);\n\n // Add new composite primary key\n await client.query(`\n ALTER TABLE lattice_skills \n ADD PRIMARY KEY (tenant_id, id)\n `);\n\n console.log('Skill table primary key changed successfully to (tenant_id, id)');\n }\n },\n down: async (client: PoolClient) => {\n console.warn('Down migration for changeSkillPrimaryKey is not supported');\n },\n};\n","import { PoolClient } from \"pg\";\nimport { Migration } from \"./migration\";\n\nexport const createChannelIdentityMappingTables: Migration = {\n version: 20,\n name: \"create_channel_identity_mapping_tables\",\n up: async (client: PoolClient) => {\n await client.query(`\n CREATE TABLE IF NOT EXISTS channel_identity_mappings (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n channel VARCHAR(50) NOT NULL,\n channel_app_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n assistant_id VARCHAR(255) NOT NULL,\n mapping_mode VARCHAR(20) NOT NULL CHECK (mapping_mode IN ('user', 'group', 'hybrid')),\n external_subject_type VARCHAR(20) NOT NULL CHECK (external_subject_type IN ('user', 'chat')),\n external_subject_key VARCHAR(512) NOT NULL,\n lark_open_id VARCHAR(255),\n lark_chat_id VARCHAR(255) NOT NULL,\n lark_message_id VARCHAR(255),\n thread_id VARCHAR(255) NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n last_activity_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n UNIQUE (channel, channel_app_id, tenant_id, assistant_id, external_subject_key)\n )\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_channel_identity_lookup\n ON channel_identity_mappings(channel, channel_app_id, tenant_id, assistant_id, external_subject_key)\n `);\n\n await client.query(`\n CREATE INDEX IF NOT EXISTS idx_channel_identity_thread\n ON channel_identity_mappings(thread_id, tenant_id)\n `);\n\n await client.query(`\n CREATE TABLE IF NOT EXISTS channel_inbound_message_receipts (\n channel VARCHAR(50) NOT NULL,\n channel_app_id VARCHAR(255) NOT NULL,\n external_message_id VARCHAR(255) NOT NULL,\n tenant_id VARCHAR(255) NOT NULL,\n status VARCHAR(20) NOT NULL DEFAULT 'processing' CHECK (status IN ('processing', 'completed', 'failed')),\n thread_id VARCHAR(255),\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (channel, channel_app_id, external_message_id)\n )\n `);\n },\n down: async (client: PoolClient) => {\n await client.query(\"DROP TABLE IF EXISTS channel_inbound_message_receipts\");\n await client.query(\"DROP INDEX IF EXISTS idx_channel_identity_thread\");\n await client.query(\"DROP INDEX IF EXISTS idx_channel_identity_lookup\");\n await client.query(\"DROP TABLE IF EXISTS channel_identity_mappings\");\n },\n};\n","import { Pool } from \"pg\";\nimport type { PoolConfig } from \"pg\";\nimport { MigrationManager } from \"../migrations/migration\";\nimport { createChannelIdentityMappingTables } from \"../migrations/channel_identity_mapping_migration\";\n\nexport interface ChannelIdentityMappingStoreOptions {\n poolConfig: string | PoolConfig;\n autoMigrate?: boolean;\n}\n\nexport interface CreateChannelIdentityMappingInput {\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n mappingMode: \"user\" | \"group\" | \"hybrid\";\n externalSubjectType: \"user\" | \"chat\";\n externalSubjectKey: string;\n larkOpenId?: string;\n larkChatId: string;\n larkMessageId?: string;\n threadId: string;\n}\n\ninterface ChannelIdentityMappingRow {\n id: string;\n channel: string;\n channel_app_id: string;\n tenant_id: string;\n assistant_id: string;\n mapping_mode: \"user\" | \"group\" | \"hybrid\";\n external_subject_type: \"user\" | \"chat\";\n external_subject_key: string;\n lark_open_id: string | null;\n lark_chat_id: string;\n lark_message_id: string | null;\n thread_id: string;\n created_at: Date;\n updated_at: Date;\n last_activity_at: Date;\n}\n\nexport interface ChannelIdentityMapping {\n id: string;\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n mappingMode: \"user\" | \"group\" | \"hybrid\";\n externalSubjectType: \"user\" | \"chat\";\n externalSubjectKey: string;\n larkOpenId?: string;\n larkChatId: string;\n larkMessageId?: string;\n threadId: string;\n createdAt: Date;\n updatedAt: Date;\n lastActivityAt: Date;\n}\n\nexport class ChannelIdentityMappingStore {\n private pool: Pool;\n private migrationManager: MigrationManager;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n\n constructor(options: ChannelIdentityMappingStoreOptions) {\n this.pool =\n typeof options.poolConfig === \"string\"\n ? new Pool({ connectionString: options.poolConfig })\n : new Pool(options.poolConfig);\n\n this.migrationManager = new MigrationManager(this.pool);\n this.migrationManager.register(createChannelIdentityMappingTables);\n\n if (options.autoMigrate !== false) {\n this.initialize().catch((error) => {\n console.error(\"Failed to initialize ChannelIdentityMappingStore:\", error);\n throw error;\n });\n }\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n try {\n await this.migrationManager.migrate();\n this.initialized = true;\n } finally {\n this.initPromise = null;\n }\n })();\n\n return this.initPromise;\n }\n\n async createMapping(\n input: CreateChannelIdentityMappingInput,\n ): Promise<ChannelIdentityMapping> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ChannelIdentityMappingRow>(\n `\n INSERT INTO channel_identity_mappings (\n channel,\n channel_app_id,\n tenant_id,\n assistant_id,\n mapping_mode,\n external_subject_type,\n external_subject_key,\n lark_open_id,\n lark_chat_id,\n lark_message_id,\n thread_id\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n RETURNING *\n `,\n [\n input.channel,\n input.channelAppId,\n input.tenantId,\n input.assistantId,\n input.mappingMode,\n input.externalSubjectType,\n input.externalSubjectKey,\n input.larkOpenId || null,\n input.larkChatId,\n input.larkMessageId || null,\n input.threadId,\n ],\n );\n\n return mapRowToChannelIdentityMapping(result.rows[0]);\n }\n\n async getMappingBySubject(input: {\n channel: string;\n channelAppId: string;\n tenantId: string;\n assistantId: string;\n externalSubjectKey: string;\n }): Promise<ChannelIdentityMapping | null> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<ChannelIdentityMappingRow>(\n `\n SELECT *\n FROM channel_identity_mappings\n WHERE channel = $1\n AND channel_app_id = $2\n AND tenant_id = $3\n AND assistant_id = $4\n AND external_subject_key = $5\n LIMIT 1\n `,\n [\n input.channel,\n input.channelAppId,\n input.tenantId,\n input.assistantId,\n input.externalSubjectKey,\n ],\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return mapRowToChannelIdentityMapping(result.rows[0]);\n }\n\n async claimInboundReceipt(input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n }): Promise<{ accepted: boolean; status: \"processing\" | \"completed\" }> {\n await this.ensureInitialized();\n\n const result = await this.pool.query<{\n source: \"inserted\" | \"existing\" | \"retried\";\n status: \"processing\" | \"completed\" | \"failed\";\n }>(\n `\n WITH existing AS (\n SELECT status\n FROM channel_inbound_message_receipts\n WHERE channel = $1\n AND channel_app_id = $2\n AND external_message_id = $3\n AND tenant_id = $4\n ),\n inserted AS (\n INSERT INTO channel_inbound_message_receipts (\n channel,\n channel_app_id,\n external_message_id,\n tenant_id,\n status\n )\n SELECT $1, $2, $3, $4, 'processing'\n WHERE NOT EXISTS (SELECT 1 FROM existing)\n RETURNING 'inserted'::text AS source, status\n ),\n retried AS (\n UPDATE channel_inbound_message_receipts\n SET status = 'processing', updated_at = CURRENT_TIMESTAMP\n WHERE channel = $1\n AND channel_app_id = $2\n AND external_message_id = $3\n AND tenant_id = $4\n AND EXISTS (SELECT 1 FROM existing WHERE status = 'failed')\n RETURNING 'retried'::text AS source, status\n )\n SELECT source, status FROM inserted\n UNION ALL\n SELECT source, status FROM retried\n UNION ALL\n SELECT 'existing'::text AS source, status FROM existing\n WHERE EXISTS (SELECT 1 FROM existing WHERE status IN ('processing', 'completed'))\n LIMIT 1\n `,\n [\n input.channel,\n input.channelAppId,\n input.externalMessageId,\n input.tenantId,\n ],\n );\n\n const source = result.rows[0]?.source;\n const status = result.rows[0]?.status || \"processing\";\n\n if (source === \"inserted\" || source === \"retried\") {\n return { accepted: true, status: \"processing\" };\n }\n\n if (status === \"completed\") {\n return { accepted: false, status: \"completed\" };\n }\n\n return { accepted: false, status: \"processing\" };\n }\n\n async markInboundReceiptCompleted(input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n threadId: string;\n }): Promise<void> {\n await this.ensureInitialized();\n\n await this.pool.query(\n `\n UPDATE channel_inbound_message_receipts\n SET status = 'completed', thread_id = $1, updated_at = CURRENT_TIMESTAMP\n WHERE channel = $2\n AND channel_app_id = $3\n AND external_message_id = $4\n AND tenant_id = $5\n `,\n [\n input.threadId,\n input.channel,\n input.channelAppId,\n input.externalMessageId,\n input.tenantId,\n ],\n );\n }\n\n async markInboundReceiptFailed(input: {\n channel: string;\n channelAppId: string;\n externalMessageId: string;\n tenantId: string;\n }): Promise<void> {\n await this.ensureInitialized();\n\n await this.pool.query(\n `\n UPDATE channel_inbound_message_receipts\n SET status = 'failed', updated_at = CURRENT_TIMESTAMP\n WHERE channel = $1\n AND channel_app_id = $2\n AND external_message_id = $3\n AND tenant_id = $4\n `,\n [\n input.channel,\n input.channelAppId,\n input.externalMessageId,\n input.tenantId,\n ],\n );\n }\n\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n await this.initialize();\n }\n }\n}\n\nfunction mapRowToChannelIdentityMapping(\n row: ChannelIdentityMappingRow,\n): ChannelIdentityMapping {\n return {\n id: row.id,\n channel: row.channel,\n channelAppId: row.channel_app_id,\n tenantId: row.tenant_id,\n assistantId: row.assistant_id,\n mappingMode: row.mapping_mode,\n externalSubjectType: row.external_subject_type,\n externalSubjectKey: row.external_subject_key,\n larkOpenId: row.lark_open_id || undefined,\n larkChatId: row.lark_chat_id,\n larkMessageId: row.lark_message_id || undefined,\n threadId: row.thread_id,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n lastActivityAt: row.last_activity_at,\n };\n}\n"],"mappings":"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","names":["Pool","Pool","Pool","Pool","Pool","Pool","encrypt","decrypt","Pool","Pool","encrypt","decrypt","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","Pool","decrypt","encrypt","Pool","Pool","Pool","Pool","Pool","Pool","Pool"]}