@axiom-lattice/pg-stores 1.0.83 → 1.0.85

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.
Files changed (34) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/CHANGELOG.md +19 -0
  3. package/dist/index.d.mts +124 -44
  4. package/dist/index.d.ts +124 -44
  5. package/dist/index.js +477 -162
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +477 -162
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +3 -3
  10. package/scripts/check-migration-versions.mjs +42 -9
  11. package/src/createPgStoreConfig.ts +97 -3
  12. package/src/migrations/migration.ts +100 -60
  13. package/src/stores/ChannelBindingStore.ts +21 -3
  14. package/src/stores/ChannelIdentityMappingStore.ts +21 -3
  15. package/src/stores/MenuStore.ts +21 -3
  16. package/src/stores/PostgreSQLA2AApiKeyStore.ts +21 -3
  17. package/src/stores/PostgreSQLAssistantStore.ts +19 -3
  18. package/src/stores/PostgreSQLChannelInstallationStore.ts +21 -3
  19. package/src/stores/PostgreSQLDatabaseConfigStore.ts +23 -4
  20. package/src/stores/PostgreSQLEvalStore.ts +15 -3
  21. package/src/stores/PostgreSQLMcpServerConfigStore.ts +23 -4
  22. package/src/stores/PostgreSQLMetricsServerConfigStore.ts +23 -4
  23. package/src/stores/PostgreSQLProjectStore.ts +19 -3
  24. package/src/stores/PostgreSQLScheduleStorage.ts +21 -4
  25. package/src/stores/PostgreSQLSkillStore.ts +14 -3
  26. package/src/stores/PostgreSQLTaskStore.ts +14 -3
  27. package/src/stores/PostgreSQLTenantStore.ts +19 -3
  28. package/src/stores/PostgreSQLThreadStore.ts +19 -3
  29. package/src/stores/PostgreSQLUserStore.ts +18 -4
  30. package/src/stores/PostgreSQLUserTenantLinkStore.ts +18 -4
  31. package/src/stores/PostgreSQLWorkflowTrackingStore.ts +18 -4
  32. package/src/stores/PostgreSQLWorkspaceStore.ts +19 -3
  33. package/src/stores/PostgresSharedResourceStore.ts +21 -3
  34. package/src/stores/ThreadMessageQueueStore.ts +14 -3
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  // src/index.ts
2
- import { Pool as Pool23 } from "pg";
2
+ import { Pool as Pool24 } from "pg";
3
3
 
4
- // src/stores/PostgreSQLThreadStore.ts
5
- import { Pool } from "pg";
4
+ // src/createPgStoreConfig.ts
5
+ import { Pool as Pool21 } from "pg";
6
6
 
7
7
  // src/migrations/migration.ts
8
8
  var MigrationManager = class {
@@ -11,39 +11,73 @@ var MigrationManager = class {
11
11
  this.pool = pool;
12
12
  }
13
13
  /**
14
- * Register a migration
14
+ * Register a migration.
15
+ * Duplicate names are rejected immediately (name = identity).
16
+ * Duplicate versions are allowed (version = ordering only).
15
17
  */
16
18
  register(migration) {
19
+ const existing = this.migrations.find((m) => m.name === migration.name);
20
+ if (existing) {
21
+ throw new Error(
22
+ `Migration name conflict: "${migration.name}" v${migration.version} collides with existing registration at v${existing.version}`
23
+ );
24
+ }
17
25
  this.migrations.push(migration);
18
26
  this.migrations.sort((a, b) => a.version - b.version);
19
27
  }
20
28
  /**
21
- * Initialize migrations table if it doesn't exist
29
+ * Ensure the tracking table exists with the correct schema.
30
+ * Handles migration from old schema (PK on version) to new schema (PK on name).
22
31
  */
23
32
  async ensureMigrationsTable(client) {
24
- await client.query(`
25
- CREATE TABLE IF NOT EXISTS lattice_schema_migrations (
26
- version INTEGER PRIMARY KEY,
27
- name VARCHAR(255) NOT NULL,
28
- applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
33
+ const tableExists = await client.query(`
34
+ SELECT EXISTS (
35
+ SELECT FROM information_schema.tables
36
+ WHERE table_name = 'lattice_schema_migrations'
29
37
  )
30
38
  `);
39
+ if (!tableExists.rows[0].exists) {
40
+ await client.query(`
41
+ CREATE TABLE lattice_schema_migrations (
42
+ name VARCHAR(255) PRIMARY KEY,
43
+ version INTEGER NOT NULL,
44
+ applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
45
+ )
46
+ `);
47
+ return;
48
+ }
49
+ const pkCheck = await client.query(`
50
+ SELECT a.attname AS column_name, con.conname AS constraint_name
51
+ FROM pg_index i
52
+ JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
53
+ JOIN pg_constraint con ON con.conindid = i.indexrelid
54
+ WHERE i.indrelid = 'lattice_schema_migrations'::regclass
55
+ AND i.indisprimary
56
+ `);
57
+ const pkColumn = pkCheck.rows[0]?.column_name;
58
+ const constraintName = pkCheck.rows[0]?.constraint_name;
59
+ if (pkColumn === "version" && constraintName) {
60
+ await client.query(`
61
+ DELETE FROM lattice_schema_migrations a
62
+ USING lattice_schema_migrations b
63
+ WHERE a.name = b.name AND a.version < b.version
64
+ `);
65
+ await client.query(
66
+ `ALTER TABLE lattice_schema_migrations DROP CONSTRAINT ${constraintName}`
67
+ );
68
+ await client.query(
69
+ `ALTER TABLE lattice_schema_migrations ADD PRIMARY KEY (name)`
70
+ );
71
+ }
31
72
  }
32
73
  /**
33
- * Get applied migrations from database
74
+ * Get the set of already-applied migration names from the tracking table.
34
75
  */
35
- async getAppliedMigrations(client) {
36
- await client.query(`
37
- CREATE TABLE IF NOT EXISTS lattice_schema_migrations (
38
- version INTEGER PRIMARY KEY,
39
- name VARCHAR(255) NOT NULL,
40
- applied_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
41
- )
42
- `);
76
+ async getAppliedNames(client) {
43
77
  const result = await client.query(
44
- "SELECT version, name, applied_at FROM lattice_schema_migrations ORDER BY version"
78
+ "SELECT name, version, applied_at FROM lattice_schema_migrations ORDER BY version"
45
79
  );
46
- return result.rows;
80
+ return new Set(result.rows.map((r) => r.name));
47
81
  }
48
82
  /**
49
83
  * Apply pending migrations
@@ -57,10 +91,9 @@ var MigrationManager = class {
57
91
  try {
58
92
  await client.query("BEGIN");
59
93
  await this.ensureMigrationsTable(client);
60
- const appliedMigrations = await this.getAppliedMigrations(client);
61
- const appliedVersions = new Set(appliedMigrations.map((m) => m.version));
94
+ const appliedNames = await this.getAppliedNames(client);
62
95
  const pendingMigrations = this.migrations.filter(
63
- (m) => !appliedVersions.has(m.version)
96
+ (m) => !appliedNames.has(m.name)
64
97
  );
65
98
  if (pendingMigrations.length === 0) {
66
99
  console.log("No pending migrations");
@@ -69,12 +102,12 @@ var MigrationManager = class {
69
102
  }
70
103
  for (const migration of pendingMigrations) {
71
104
  console.log(
72
- `Applying migration ${migration.version}: ${migration.name}`
105
+ `Applying migration v${migration.version}: ${migration.name}`
73
106
  );
74
107
  await migration.up(client);
75
108
  await client.query(
76
- "INSERT INTO lattice_schema_migrations (version, name) VALUES ($1, $2) ON CONFLICT (version) DO NOTHING",
77
- [migration.version, migration.name]
109
+ "INSERT INTO lattice_schema_migrations (name, version) VALUES ($1, $2) ON CONFLICT (name) DO NOTHING",
110
+ [migration.name, migration.version]
78
111
  );
79
112
  }
80
113
  await client.query("COMMIT");
@@ -90,34 +123,37 @@ var MigrationManager = class {
90
123
  }
91
124
  }
92
125
  /**
93
- * Rollback last migration
126
+ * Rollback the last-applied migration (highest version).
94
127
  */
95
128
  async rollback() {
96
129
  const client = await this.pool.connect();
97
130
  try {
98
131
  await client.query("BEGIN");
99
- const appliedMigrations = await this.getAppliedMigrations(client);
100
- if (appliedMigrations.length === 0) {
132
+ await this.ensureMigrationsTable(client);
133
+ const result = await client.query(
134
+ "SELECT name, version FROM lattice_schema_migrations ORDER BY version DESC LIMIT 1"
135
+ );
136
+ if (result.rows.length === 0) {
101
137
  console.log("No migrations to rollback");
102
138
  await client.query("COMMIT");
103
139
  return;
104
140
  }
105
- const lastMigration = appliedMigrations[appliedMigrations.length - 1];
141
+ const lastApplied = result.rows[0];
106
142
  const migration = this.migrations.find(
107
- (m) => m.version === lastMigration.version
143
+ (m) => m.name === lastApplied.name
108
144
  );
109
145
  if (!migration || !migration.down) {
110
146
  throw new Error(
111
- `Migration ${lastMigration.version} does not have a down migration`
147
+ `Migration "${lastApplied.name}" (v${lastApplied.version}) does not have a down migration`
112
148
  );
113
149
  }
114
150
  console.log(
115
- `Rolling back migration ${lastMigration.version}: ${lastMigration.name}`
151
+ `Rolling back migration v${lastApplied.version}: ${lastApplied.name}`
116
152
  );
117
153
  await migration.down(client);
118
154
  await client.query(
119
- "DELETE FROM lattice_schema_migrations WHERE version = $1",
120
- [lastMigration.version]
155
+ "DELETE FROM lattice_schema_migrations WHERE name = $1",
156
+ [lastApplied.name]
121
157
  );
122
158
  await client.query("COMMIT");
123
159
  console.log("Rollback completed");
@@ -129,22 +165,25 @@ var MigrationManager = class {
129
165
  }
130
166
  }
131
167
  /**
132
- * Get current migration version
168
+ * Get the highest applied migration version.
133
169
  */
134
170
  async getCurrentVersion() {
135
171
  const client = await this.pool.connect();
136
172
  try {
137
- const appliedMigrations = await this.getAppliedMigrations(client);
138
- if (appliedMigrations.length === 0) {
139
- return 0;
140
- }
141
- return Math.max(...appliedMigrations.map((m) => m.version));
173
+ await this.ensureMigrationsTable(client);
174
+ const result = await client.query(
175
+ "SELECT COALESCE(MAX(version), 0) AS max FROM lattice_schema_migrations"
176
+ );
177
+ return result.rows[0]?.max ?? 0;
142
178
  } finally {
143
179
  client.release();
144
180
  }
145
181
  }
146
182
  };
147
183
 
184
+ // src/stores/PostgreSQLThreadStore.ts
185
+ import { Pool } from "pg";
186
+
148
187
  // src/migrations/thread_migrations.ts
149
188
  var createThreadsTable = {
150
189
  version: 1,
@@ -285,10 +324,18 @@ var PostgreSQLThreadStore = class {
285
324
  this.initialized = false;
286
325
  this.ownsPool = true;
287
326
  this.initPromise = null;
327
+ if (options.pool) {
328
+ this.pool = options.pool;
329
+ this.ownsPool = false;
330
+ this.initialized = true;
331
+ return;
332
+ }
288
333
  if (typeof options.poolConfig === "string") {
289
334
  this.pool = new Pool({ connectionString: options.poolConfig });
290
- } else {
335
+ } else if (options.poolConfig) {
291
336
  this.pool = new Pool(options.poolConfig);
337
+ } else {
338
+ throw new Error("Either pool or poolConfig must be provided");
292
339
  }
293
340
  this.migrationManager = new MigrationManager(this.pool);
294
341
  this.migrationManager.register(createThreadsTable);
@@ -631,10 +678,18 @@ var PostgreSQLAssistantStore = class {
631
678
  this.initialized = false;
632
679
  this.ownsPool = true;
633
680
  this.initPromise = null;
681
+ if (options.pool) {
682
+ this.pool = options.pool;
683
+ this.ownsPool = false;
684
+ this.initialized = true;
685
+ return;
686
+ }
634
687
  if (typeof options.poolConfig === "string") {
635
688
  this.pool = new Pool2({ connectionString: options.poolConfig });
636
- } else {
689
+ } else if (options.poolConfig) {
637
690
  this.pool = new Pool2(options.poolConfig);
691
+ } else {
692
+ throw new Error("Either pool or poolConfig must be provided");
638
693
  }
639
694
  this.migrationManager = new MigrationManager(this.pool);
640
695
  this.migrationManager.register(createAssistantsTable);
@@ -911,11 +966,20 @@ import { encrypt, decrypt } from "@axiom-lattice/core";
911
966
  var PostgreSQLDatabaseConfigStore = class {
912
967
  constructor(options) {
913
968
  this.initialized = false;
969
+ this.ownsPool = true;
914
970
  this.initPromise = null;
971
+ if (options.pool) {
972
+ this.pool = options.pool;
973
+ this.ownsPool = false;
974
+ this.initialized = true;
975
+ return;
976
+ }
915
977
  if (typeof options.poolConfig === "string") {
916
978
  this.pool = new Pool3({ connectionString: options.poolConfig });
917
- } else {
979
+ } else if (options.poolConfig) {
918
980
  this.pool = new Pool3(options.poolConfig);
981
+ } else {
982
+ throw new Error("Either pool or poolConfig must be provided");
919
983
  }
920
984
  this.migrationManager = new MigrationManager(this.pool);
921
985
  this.migrationManager.register(createDatabaseConfigsTable);
@@ -1134,7 +1198,9 @@ var PostgreSQLDatabaseConfigStore = class {
1134
1198
  * Dispose resources and close the connection pool
1135
1199
  */
1136
1200
  async dispose() {
1137
- await this.pool.end();
1201
+ if (this.ownsPool && this.pool) {
1202
+ await this.pool.end();
1203
+ }
1138
1204
  }
1139
1205
  /**
1140
1206
  * Ensure store is initialized
@@ -1225,11 +1291,20 @@ import { encrypt as encrypt2, decrypt as decrypt2 } from "@axiom-lattice/core";
1225
1291
  var PostgreSQLMetricsServerConfigStore = class {
1226
1292
  constructor(options) {
1227
1293
  this.initialized = false;
1294
+ this.ownsPool = true;
1228
1295
  this.initPromise = null;
1296
+ if (options.pool) {
1297
+ this.pool = options.pool;
1298
+ this.ownsPool = false;
1299
+ this.initialized = true;
1300
+ return;
1301
+ }
1229
1302
  if (typeof options.poolConfig === "string") {
1230
1303
  this.pool = new Pool4({ connectionString: options.poolConfig });
1231
- } else {
1304
+ } else if (options.poolConfig) {
1232
1305
  this.pool = new Pool4(options.poolConfig);
1306
+ } else {
1307
+ throw new Error("Either pool or poolConfig must be provided");
1233
1308
  }
1234
1309
  this.migrationManager = new MigrationManager(this.pool);
1235
1310
  this.migrationManager.register(createMetricsConfigsTable);
@@ -1448,7 +1523,9 @@ var PostgreSQLMetricsServerConfigStore = class {
1448
1523
  * Dispose resources and close the connection pool
1449
1524
  */
1450
1525
  async dispose() {
1451
- await this.pool.end();
1526
+ if (this.ownsPool && this.pool) {
1527
+ await this.pool.end();
1528
+ }
1452
1529
  }
1453
1530
  /**
1454
1531
  * Ensure store is initialized
@@ -1558,11 +1635,20 @@ import { encrypt as encrypt3, decrypt as decrypt3 } from "@axiom-lattice/core";
1558
1635
  var PostgreSQLMcpServerConfigStore = class {
1559
1636
  constructor(options) {
1560
1637
  this.initialized = false;
1638
+ this.ownsPool = true;
1561
1639
  this.initPromise = null;
1640
+ if (options.pool) {
1641
+ this.pool = options.pool;
1642
+ this.ownsPool = false;
1643
+ this.initialized = true;
1644
+ return;
1645
+ }
1562
1646
  if (typeof options.poolConfig === "string") {
1563
1647
  this.pool = new Pool5({ connectionString: options.poolConfig });
1564
- } else {
1648
+ } else if (options.poolConfig) {
1565
1649
  this.pool = new Pool5(options.poolConfig);
1650
+ } else {
1651
+ throw new Error("Either pool or poolConfig must be provided");
1566
1652
  }
1567
1653
  this.migrationManager = new MigrationManager(this.pool);
1568
1654
  this.migrationManager.register(createMcpServerConfigsTable);
@@ -1797,7 +1883,9 @@ var PostgreSQLMcpServerConfigStore = class {
1797
1883
  * Dispose resources and close the connection pool
1798
1884
  */
1799
1885
  async dispose() {
1800
- await this.pool.end();
1886
+ if (this.ownsPool && this.pool) {
1887
+ await this.pool.end();
1888
+ }
1801
1889
  }
1802
1890
  /**
1803
1891
  * Ensure store is initialized
@@ -1898,10 +1986,18 @@ var PostgreSQLWorkspaceStore = class {
1898
1986
  constructor(options) {
1899
1987
  this.initialized = false;
1900
1988
  this.ownsPool = true;
1989
+ if (options.pool) {
1990
+ this.pool = options.pool;
1991
+ this.ownsPool = false;
1992
+ this.initialized = true;
1993
+ return;
1994
+ }
1901
1995
  if (typeof options.poolConfig === "string") {
1902
1996
  this.pool = new Pool6({ connectionString: options.poolConfig });
1903
- } else {
1997
+ } else if (options.poolConfig) {
1904
1998
  this.pool = new Pool6(options.poolConfig);
1999
+ } else {
2000
+ throw new Error("Either pool or poolConfig must be provided");
1905
2001
  }
1906
2002
  this.migrationManager = new MigrationManager(this.pool);
1907
2003
  this.migrationManager.register(createWorkspacesTable);
@@ -2141,10 +2237,18 @@ var PostgreSQLProjectStore = class {
2141
2237
  constructor(options) {
2142
2238
  this.initialized = false;
2143
2239
  this.ownsPool = true;
2240
+ if (options.pool) {
2241
+ this.pool = options.pool;
2242
+ this.ownsPool = false;
2243
+ this.initialized = true;
2244
+ return;
2245
+ }
2144
2246
  if (typeof options.poolConfig === "string") {
2145
2247
  this.pool = new Pool7({ connectionString: options.poolConfig });
2146
- } else {
2248
+ } else if (options.poolConfig) {
2147
2249
  this.pool = new Pool7(options.poolConfig);
2250
+ } else {
2251
+ throw new Error("Either pool or poolConfig must be provided");
2148
2252
  }
2149
2253
  this.migrationManager = new MigrationManager(this.pool);
2150
2254
  this.migrationManager.register(createProjectsTable);
@@ -2391,10 +2495,19 @@ var addUserStatusColumn = {
2391
2495
  var PostgreSQLUserStore = class {
2392
2496
  constructor(options) {
2393
2497
  this.initialized = false;
2498
+ this.ownsPool = true;
2499
+ if (options.pool) {
2500
+ this.pool = options.pool;
2501
+ this.ownsPool = false;
2502
+ this.initialized = true;
2503
+ return;
2504
+ }
2394
2505
  if (typeof options.poolConfig === "string") {
2395
2506
  this.pool = new Pool8({ connectionString: options.poolConfig });
2396
- } else {
2507
+ } else if (options.poolConfig) {
2397
2508
  this.pool = new Pool8(options.poolConfig);
2509
+ } else {
2510
+ throw new Error("Either pool or poolConfig must be provided");
2398
2511
  }
2399
2512
  this.migrationManager = new MigrationManager(this.pool);
2400
2513
  this.migrationManager.register(createUsersTable);
@@ -2407,7 +2520,9 @@ var PostgreSQLUserStore = class {
2407
2520
  }
2408
2521
  }
2409
2522
  async dispose() {
2410
- await this.pool.end();
2523
+ if (this.ownsPool && this.pool) {
2524
+ await this.pool.end();
2525
+ }
2411
2526
  }
2412
2527
  async initialize() {
2413
2528
  if (this.initialized) return;
@@ -2580,10 +2695,18 @@ var PostgreSQLTenantStore = class {
2580
2695
  constructor(options) {
2581
2696
  this.initialized = false;
2582
2697
  this.ownsPool = true;
2698
+ if (options.pool) {
2699
+ this.pool = options.pool;
2700
+ this.ownsPool = false;
2701
+ this.initialized = true;
2702
+ return;
2703
+ }
2583
2704
  if (typeof options.poolConfig === "string") {
2584
2705
  this.pool = new Pool9({ connectionString: options.poolConfig });
2585
- } else {
2706
+ } else if (options.poolConfig) {
2586
2707
  this.pool = new Pool9(options.poolConfig);
2708
+ } else {
2709
+ throw new Error("Either pool or poolConfig must be provided");
2587
2710
  }
2588
2711
  this.migrationManager = new MigrationManager(this.pool);
2589
2712
  this.migrationManager.register(createTenantsTable);
@@ -2833,10 +2956,19 @@ var migrateRemoveTenantIdFromUsers = {
2833
2956
  var PostgreSQLUserTenantLinkStore = class {
2834
2957
  constructor(options) {
2835
2958
  this.initialized = false;
2959
+ this.ownsPool = true;
2960
+ if (options.pool) {
2961
+ this.pool = options.pool;
2962
+ this.ownsPool = false;
2963
+ this.initialized = true;
2964
+ return;
2965
+ }
2836
2966
  if (typeof options.poolConfig === "string") {
2837
2967
  this.pool = new Pool10({ connectionString: options.poolConfig });
2838
- } else {
2968
+ } else if (options.poolConfig) {
2839
2969
  this.pool = new Pool10(options.poolConfig);
2970
+ } else {
2971
+ throw new Error("Either pool or poolConfig must be provided");
2840
2972
  }
2841
2973
  this.migrationManager = new MigrationManager(this.pool);
2842
2974
  this.migrationManager.register(createUserTenantLinkTable);
@@ -2849,7 +2981,9 @@ var PostgreSQLUserTenantLinkStore = class {
2849
2981
  }
2850
2982
  }
2851
2983
  async dispose() {
2852
- await this.pool.end();
2984
+ if (this.ownsPool && this.pool) {
2985
+ await this.pool.end();
2986
+ }
2853
2987
  }
2854
2988
  async initialize() {
2855
2989
  if (this.initialized) return;
@@ -3078,11 +3212,20 @@ var addStepThreadId = {
3078
3212
  var PostgreSQLWorkflowTrackingStore = class {
3079
3213
  constructor(options) {
3080
3214
  this.initialized = false;
3215
+ this.ownsPool = true;
3081
3216
  this.initPromise = null;
3217
+ if (options.pool) {
3218
+ this.pool = options.pool;
3219
+ this.ownsPool = false;
3220
+ this.initialized = true;
3221
+ return;
3222
+ }
3082
3223
  if (typeof options.poolConfig === "string") {
3083
3224
  this.pool = new Pool11({ connectionString: options.poolConfig });
3084
- } else {
3225
+ } else if (options.poolConfig) {
3085
3226
  this.pool = new Pool11(options.poolConfig);
3227
+ } else {
3228
+ throw new Error("Either pool or poolConfig must be provided");
3086
3229
  }
3087
3230
  this.migrationManager = new MigrationManager(this.pool);
3088
3231
  this.migrationManager.register(createWorkflowTrackingTables);
@@ -3095,7 +3238,9 @@ var PostgreSQLWorkflowTrackingStore = class {
3095
3238
  }
3096
3239
  }
3097
3240
  async dispose() {
3098
- await this.pool.end();
3241
+ if (this.ownsPool && this.pool) {
3242
+ await this.pool.end();
3243
+ }
3099
3244
  }
3100
3245
  async initialize() {
3101
3246
  if (this.initialized) return;
@@ -3584,10 +3729,18 @@ var PostgreSQLEvalStore = class {
3584
3729
  this.initialized = false;
3585
3730
  this.ownsPool = true;
3586
3731
  this.initPromise = null;
3732
+ if (options.pool) {
3733
+ this.pool = options.pool;
3734
+ this.ownsPool = false;
3735
+ this.initialized = true;
3736
+ return;
3737
+ }
3587
3738
  if (typeof options.poolConfig === "string") {
3588
3739
  this.pool = new Pool12({ connectionString: options.poolConfig });
3589
- } else {
3740
+ } else if (options.poolConfig) {
3590
3741
  this.pool = new Pool12(options.poolConfig);
3742
+ } else {
3743
+ throw new Error("Either pool or poolConfig must be provided");
3591
3744
  }
3592
3745
  this.migrationManager = new MigrationManager(this.pool);
3593
3746
  for (const m of evalMigrations) {
@@ -4450,10 +4603,18 @@ var ThreadMessageQueueStore = class {
4450
4603
  this.ownsPool = true;
4451
4604
  this.initialized = false;
4452
4605
  this.initPromise = null;
4606
+ if (options.pool) {
4607
+ this.pool = options.pool;
4608
+ this.ownsPool = false;
4609
+ this.initialized = true;
4610
+ return;
4611
+ }
4453
4612
  if (typeof options.poolConfig === "string") {
4454
4613
  this.pool = new Pool13({ connectionString: options.poolConfig });
4455
- } else {
4614
+ } else if (options.poolConfig) {
4456
4615
  this.pool = new Pool13(options.poolConfig);
4616
+ } else {
4617
+ throw new Error("Either pool or poolConfig must be provided");
4457
4618
  }
4458
4619
  this.migrationManager = new MigrationManager(this.pool);
4459
4620
  this.migrationManager.register(createThreadMessageQueueTable);
@@ -4692,8 +4853,17 @@ var createChannelBindingsTable = {
4692
4853
  var ChannelBindingStore = class {
4693
4854
  constructor(options) {
4694
4855
  this.initialized = false;
4856
+ this.ownsPool = true;
4695
4857
  this.initPromise = null;
4696
- this.pool = typeof options.poolConfig === "string" ? new Pool14({ connectionString: options.poolConfig }) : new Pool14(options.poolConfig);
4858
+ if (options.pool) {
4859
+ this.pool = options.pool;
4860
+ this.ownsPool = false;
4861
+ this.initialized = true;
4862
+ return;
4863
+ }
4864
+ this.pool = typeof options.poolConfig === "string" ? new Pool14({ connectionString: options.poolConfig }) : options.poolConfig ? new Pool14(options.poolConfig) : (() => {
4865
+ throw new Error("Either pool or poolConfig must be provided");
4866
+ })();
4697
4867
  this.migrationManager = new MigrationManager(this.pool);
4698
4868
  this.migrationManager.register(createChannelBindingsTable);
4699
4869
  if (options.autoMigrate !== false) {
@@ -4716,6 +4886,11 @@ var ChannelBindingStore = class {
4716
4886
  })();
4717
4887
  return this.initPromise;
4718
4888
  }
4889
+ async dispose() {
4890
+ if (this.ownsPool && this.pool) {
4891
+ await this.pool.end();
4892
+ }
4893
+ }
4719
4894
  async resolve(params) {
4720
4895
  await this.ensureInitialized();
4721
4896
  const result = await this.pool.query(
@@ -4939,8 +5114,17 @@ import { decrypt as decrypt4, encrypt as encrypt4 } from "@axiom-lattice/core";
4939
5114
  var PostgreSQLChannelInstallationStore = class {
4940
5115
  constructor(options) {
4941
5116
  this.initialized = false;
5117
+ this.ownsPool = true;
4942
5118
  this.initPromise = null;
4943
- this.pool = typeof options.poolConfig === "string" ? new Pool15({ connectionString: options.poolConfig }) : new Pool15(options.poolConfig);
5119
+ if (options.pool) {
5120
+ this.pool = options.pool;
5121
+ this.ownsPool = false;
5122
+ this.initialized = true;
5123
+ return;
5124
+ }
5125
+ this.pool = typeof options.poolConfig === "string" ? new Pool15({ connectionString: options.poolConfig }) : options.poolConfig ? new Pool15(options.poolConfig) : (() => {
5126
+ throw new Error("Either pool or poolConfig must be provided");
5127
+ })();
4944
5128
  this.migrationManager = new MigrationManager(this.pool);
4945
5129
  this.migrationManager.register(createChannelInstallationsTable);
4946
5130
  this.migrationManager.register(alterChannelInstallationsTable);
@@ -4971,6 +5155,11 @@ var PostgreSQLChannelInstallationStore = class {
4971
5155
  })();
4972
5156
  return this.initPromise;
4973
5157
  }
5158
+ async dispose() {
5159
+ if (this.ownsPool && this.pool) {
5160
+ await this.pool.end();
5161
+ }
5162
+ }
4974
5163
  async getInstallationById(installationId) {
4975
5164
  await this.ensureInitialized();
4976
5165
  const result = await this.pool.query(
@@ -5215,8 +5404,17 @@ function mapRowToRecord(row) {
5215
5404
  var PostgreSQLA2AApiKeyStore = class {
5216
5405
  constructor(options) {
5217
5406
  this.initialized = false;
5407
+ this.ownsPool = true;
5218
5408
  this.initPromise = null;
5219
- this.pool = typeof options.poolConfig === "string" ? new Pool16({ connectionString: options.poolConfig }) : new Pool16(options.poolConfig);
5409
+ if (options.pool) {
5410
+ this.pool = options.pool;
5411
+ this.ownsPool = false;
5412
+ this.initialized = true;
5413
+ return;
5414
+ }
5415
+ this.pool = typeof options.poolConfig === "string" ? new Pool16({ connectionString: options.poolConfig }) : options.poolConfig ? new Pool16(options.poolConfig) : (() => {
5416
+ throw new Error("Either pool or poolConfig must be provided");
5417
+ })();
5220
5418
  this.migrationManager = new MigrationManager(this.pool);
5221
5419
  this.migrationManager.register(createA2AApiKeysTable);
5222
5420
  if (options.autoMigrate !== false) {
@@ -5239,6 +5437,11 @@ var PostgreSQLA2AApiKeyStore = class {
5239
5437
  })();
5240
5438
  return this.initPromise;
5241
5439
  }
5440
+ async dispose() {
5441
+ if (this.ownsPool && this.pool) {
5442
+ await this.pool.end();
5443
+ }
5444
+ }
5242
5445
  async ensureInitialized() {
5243
5446
  if (!this.initialized) await this.initialize();
5244
5447
  }
@@ -5504,10 +5707,19 @@ var addScheduleTenantId = {
5504
5707
  var PostgreSQLScheduleStorage = class {
5505
5708
  constructor(options) {
5506
5709
  this.initialized = false;
5710
+ this.ownsPool = true;
5711
+ if (options.pool) {
5712
+ this.pool = options.pool;
5713
+ this.ownsPool = false;
5714
+ this.initialized = true;
5715
+ return;
5716
+ }
5507
5717
  if (typeof options.poolConfig === "string") {
5508
5718
  this.pool = new Pool17({ connectionString: options.poolConfig });
5509
- } else {
5719
+ } else if (options.poolConfig) {
5510
5720
  this.pool = new Pool17(options.poolConfig);
5721
+ } else {
5722
+ throw new Error("Either pool or poolConfig must be provided");
5511
5723
  }
5512
5724
  this.migrationManager = new MigrationManager(this.pool);
5513
5725
  this.migrationManager.register(createScheduledTasksTable);
@@ -5523,7 +5735,7 @@ var PostgreSQLScheduleStorage = class {
5523
5735
  * Dispose resources and close the connection pool
5524
5736
  */
5525
5737
  async dispose() {
5526
- if (this.pool) {
5738
+ if (this.ownsPool && this.pool) {
5527
5739
  await this.pool.end();
5528
5740
  }
5529
5741
  }
@@ -6017,10 +6229,18 @@ var PostgreSQLTaskStore = class {
6017
6229
  this.initialized = false;
6018
6230
  this.ownsPool = true;
6019
6231
  this.initPromise = null;
6232
+ if (options.pool) {
6233
+ this.pool = options.pool;
6234
+ this.ownsPool = false;
6235
+ this.initialized = true;
6236
+ return;
6237
+ }
6020
6238
  if (typeof options.poolConfig === "string") {
6021
6239
  this.pool = new Pool18({ connectionString: options.poolConfig });
6022
- } else {
6240
+ } else if (options.poolConfig) {
6023
6241
  this.pool = new Pool18(options.poolConfig);
6242
+ } else {
6243
+ throw new Error("Either pool or poolConfig must be provided");
6024
6244
  }
6025
6245
  this.migrationManager = new MigrationManager(this.pool);
6026
6246
  this.migrationManager.register(createTasksTable);
@@ -6284,8 +6504,17 @@ var addFileContentType = {
6284
6504
  var MenuStore = class {
6285
6505
  constructor(options) {
6286
6506
  this.initialized = false;
6507
+ this.ownsPool = true;
6287
6508
  this.initPromise = null;
6288
- this.pool = typeof options.poolConfig === "string" ? new Pool19({ connectionString: options.poolConfig }) : new Pool19(options.poolConfig);
6509
+ if (options.pool) {
6510
+ this.pool = options.pool;
6511
+ this.ownsPool = false;
6512
+ this.initialized = true;
6513
+ return;
6514
+ }
6515
+ this.pool = typeof options.poolConfig === "string" ? new Pool19({ connectionString: options.poolConfig }) : options.poolConfig ? new Pool19(options.poolConfig) : (() => {
6516
+ throw new Error("Either pool or poolConfig must be provided");
6517
+ })();
6289
6518
  this.migrationManager = new MigrationManager(this.pool);
6290
6519
  this.migrationManager.register(createMenuItemsTable);
6291
6520
  this.migrationManager.register(addFileContentType);
@@ -6309,6 +6538,11 @@ var MenuStore = class {
6309
6538
  })();
6310
6539
  return this.initPromise;
6311
6540
  }
6541
+ async dispose() {
6542
+ if (this.ownsPool && this.pool) {
6543
+ await this.pool.end();
6544
+ }
6545
+ }
6312
6546
  async list(params) {
6313
6547
  await this.ensureInitialized();
6314
6548
  const conditions = ["tenant_id = $1"];
@@ -6479,8 +6713,17 @@ var createSharedResourcesTable = {
6479
6713
  var PostgresSharedResourceStore = class {
6480
6714
  constructor(options) {
6481
6715
  this.initialized = false;
6716
+ this.ownsPool = true;
6482
6717
  this.initPromise = null;
6483
- this.pool = typeof options.poolConfig === "string" ? new Pool20({ connectionString: options.poolConfig }) : new Pool20(options.poolConfig);
6718
+ if (options.pool) {
6719
+ this.pool = options.pool;
6720
+ this.ownsPool = false;
6721
+ this.initialized = true;
6722
+ return;
6723
+ }
6724
+ this.pool = typeof options.poolConfig === "string" ? new Pool20({ connectionString: options.poolConfig }) : options.poolConfig ? new Pool20(options.poolConfig) : (() => {
6725
+ throw new Error("Either pool or poolConfig must be provided");
6726
+ })();
6484
6727
  this.migrationManager = new MigrationManager(this.pool);
6485
6728
  this.migrationManager.register(createSharedResourcesTable);
6486
6729
  if (options.autoMigrate !== false) {
@@ -6506,6 +6749,11 @@ var PostgresSharedResourceStore = class {
6506
6749
  })();
6507
6750
  return this.initPromise;
6508
6751
  }
6752
+ async dispose() {
6753
+ if (this.ownsPool && this.pool) {
6754
+ await this.pool.end();
6755
+ }
6756
+ }
6509
6757
  async findByToken(token) {
6510
6758
  await this.ensureInitialized();
6511
6759
  const { rows } = await this.pool.query(
@@ -6643,39 +6891,6 @@ var PostgresSharedResourceStore = class {
6643
6891
 
6644
6892
  // src/createPgStoreConfig.ts
6645
6893
  import { PostgresSaver } from "@langchain/langgraph-checkpoint-postgres";
6646
- function createPgStoreConfig(connectionString) {
6647
- const opts = { poolConfig: connectionString, autoMigrate: true };
6648
- const checkpoint = PostgresSaver.fromConnString(connectionString);
6649
- checkpoint.setup().catch((err) => {
6650
- console.error("[pg-stores] Failed to setup checkpoint table:", err.message || err);
6651
- });
6652
- return {
6653
- workspace: new PostgreSQLWorkspaceStore(opts),
6654
- project: new PostgreSQLProjectStore(opts),
6655
- eval: new PostgreSQLEvalStore(opts),
6656
- user: new PostgreSQLUserStore(opts),
6657
- tenant: new PostgreSQLTenantStore(opts),
6658
- userTenantLink: new PostgreSQLUserTenantLinkStore(opts),
6659
- channelBinding: new ChannelBindingStore(opts),
6660
- channelInstallation: new PostgreSQLChannelInstallationStore(opts),
6661
- thread: new PostgreSQLThreadStore(opts),
6662
- database: new PostgreSQLDatabaseConfigStore(opts),
6663
- metrics: new PostgreSQLMetricsServerConfigStore(opts),
6664
- mcp: new PostgreSQLMcpServerConfigStore(opts),
6665
- assistant: new PostgreSQLAssistantStore(opts),
6666
- workflowTracking: new PostgreSQLWorkflowTrackingStore(opts),
6667
- threadMessageQueue: new ThreadMessageQueueStore(opts),
6668
- task: new PostgreSQLTaskStore(opts),
6669
- a2aApiKey: new PostgreSQLA2AApiKeyStore(opts),
6670
- schedule: new PostgreSQLScheduleStorage(opts),
6671
- menu: new MenuStore(opts),
6672
- sharedResource: new PostgresSharedResourceStore(opts),
6673
- checkpoint
6674
- };
6675
- }
6676
-
6677
- // src/stores/PostgreSQLSkillStore.ts
6678
- import { Pool as Pool21 } from "pg";
6679
6894
 
6680
6895
  // src/migrations/skill_migrations.ts
6681
6896
  var createSkillsTable = {
@@ -6830,16 +7045,157 @@ var changeSkillPrimaryKey = {
6830
7045
  }
6831
7046
  };
6832
7047
 
7048
+ // src/migrations/channel_identity_mapping_migration.ts
7049
+ var createChannelIdentityMappingTables = {
7050
+ version: 20,
7051
+ name: "create_channel_identity_mapping_tables",
7052
+ up: async (client) => {
7053
+ await client.query(`
7054
+ CREATE TABLE IF NOT EXISTS channel_identity_mappings (
7055
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
7056
+ channel VARCHAR(50) NOT NULL,
7057
+ channel_app_id VARCHAR(255) NOT NULL,
7058
+ tenant_id VARCHAR(255) NOT NULL,
7059
+ assistant_id VARCHAR(255) NOT NULL,
7060
+ mapping_mode VARCHAR(20) NOT NULL CHECK (mapping_mode IN ('user', 'group', 'hybrid')),
7061
+ external_subject_type VARCHAR(20) NOT NULL CHECK (external_subject_type IN ('user', 'chat')),
7062
+ external_subject_key VARCHAR(512) NOT NULL,
7063
+ lark_open_id VARCHAR(255),
7064
+ lark_chat_id VARCHAR(255) NOT NULL,
7065
+ lark_message_id VARCHAR(255),
7066
+ thread_id VARCHAR(255) NOT NULL,
7067
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7068
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7069
+ last_activity_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7070
+ UNIQUE (channel, channel_app_id, tenant_id, assistant_id, external_subject_key)
7071
+ )
7072
+ `);
7073
+ await client.query(`
7074
+ CREATE INDEX IF NOT EXISTS idx_channel_identity_lookup
7075
+ ON channel_identity_mappings(channel, channel_app_id, tenant_id, assistant_id, external_subject_key)
7076
+ `);
7077
+ await client.query(`
7078
+ CREATE INDEX IF NOT EXISTS idx_channel_identity_thread
7079
+ ON channel_identity_mappings(thread_id, tenant_id)
7080
+ `);
7081
+ await client.query(`
7082
+ CREATE TABLE IF NOT EXISTS channel_inbound_message_receipts (
7083
+ channel VARCHAR(50) NOT NULL,
7084
+ channel_app_id VARCHAR(255) NOT NULL,
7085
+ external_message_id VARCHAR(255) NOT NULL,
7086
+ tenant_id VARCHAR(255) NOT NULL,
7087
+ status VARCHAR(20) NOT NULL DEFAULT 'processing' CHECK (status IN ('processing', 'completed', 'failed')),
7088
+ thread_id VARCHAR(255),
7089
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7090
+ updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7091
+ PRIMARY KEY (channel, channel_app_id, external_message_id)
7092
+ )
7093
+ `);
7094
+ },
7095
+ down: async (client) => {
7096
+ await client.query("DROP TABLE IF EXISTS channel_inbound_message_receipts");
7097
+ await client.query("DROP INDEX IF EXISTS idx_channel_identity_thread");
7098
+ await client.query("DROP INDEX IF EXISTS idx_channel_identity_lookup");
7099
+ await client.query("DROP TABLE IF EXISTS channel_identity_mappings");
7100
+ }
7101
+ };
7102
+
7103
+ // src/createPgStoreConfig.ts
7104
+ async function createPgStoreConfig(connectionString) {
7105
+ const pool = new Pool21({ connectionString });
7106
+ const mm = new MigrationManager(pool);
7107
+ mm.register(createThreadsTable);
7108
+ mm.register(createScheduledTasksTable);
7109
+ mm.register(createAssistantsTable);
7110
+ mm.register(createSkillsTable);
7111
+ mm.register(createWorkspacesTable);
7112
+ mm.register(createProjectsTable);
7113
+ mm.register(createUsersTable);
7114
+ mm.register(createTenantsTable);
7115
+ mm.register(addUserStatusColumn);
7116
+ mm.register(createUserTenantLinkTable);
7117
+ mm.register(migrateRemoveTenantIdFromUsers);
7118
+ mm.register(createMetricsConfigsTable);
7119
+ mm.register(createMcpServerConfigsTable);
7120
+ mm.register(addAssistantTenantId);
7121
+ mm.register(addSkillTenantId);
7122
+ mm.register(changeSkillPrimaryKey);
7123
+ mm.register(addScheduleTenantId);
7124
+ mm.register(changeThreadPrimaryKey);
7125
+ mm.register(createChannelIdentityMappingTables);
7126
+ mm.register(createChannelInstallationsTable);
7127
+ mm.register(addThreadTenantId);
7128
+ mm.register(addProjectConfigColumn);
7129
+ mm.register(createThreadMessageQueueTable);
7130
+ mm.register(addPriorityAndCommandColumns);
7131
+ mm.register(alterMessageQueueIdColumn);
7132
+ mm.register(createWorkflowTrackingTables);
7133
+ for (const m of evalMigrations) {
7134
+ mm.register(m);
7135
+ }
7136
+ mm.register(alterChannelInstallationsTable);
7137
+ mm.register(createChannelBindingsTable);
7138
+ mm.register(createDatabaseConfigsTable);
7139
+ mm.register(changeAssistantPrimaryKey);
7140
+ mm.register(addStepThreadId);
7141
+ mm.register(addCustomRunConfigColumn);
7142
+ mm.register(createA2AApiKeysTable);
7143
+ mm.register(addWorkspaceProjectToQueue);
7144
+ mm.register(addAssistantOwnerUserId);
7145
+ mm.register(createTasksTable);
7146
+ mm.register(createMenuItemsTable);
7147
+ mm.register(createSharedResourcesTable);
7148
+ mm.register(addFileContentType);
7149
+ await mm.migrate();
7150
+ const checkpoint = PostgresSaver.fromConnString(connectionString);
7151
+ checkpoint.setup().catch((err) => {
7152
+ console.error("[pg-stores] Failed to setup checkpoint table:", err.message || err);
7153
+ });
7154
+ const opts = { pool };
7155
+ return {
7156
+ workspace: new PostgreSQLWorkspaceStore(opts),
7157
+ project: new PostgreSQLProjectStore(opts),
7158
+ eval: new PostgreSQLEvalStore(opts),
7159
+ user: new PostgreSQLUserStore(opts),
7160
+ tenant: new PostgreSQLTenantStore(opts),
7161
+ userTenantLink: new PostgreSQLUserTenantLinkStore(opts),
7162
+ channelBinding: new ChannelBindingStore(opts),
7163
+ channelInstallation: new PostgreSQLChannelInstallationStore(opts),
7164
+ thread: new PostgreSQLThreadStore(opts),
7165
+ database: new PostgreSQLDatabaseConfigStore(opts),
7166
+ metrics: new PostgreSQLMetricsServerConfigStore(opts),
7167
+ mcp: new PostgreSQLMcpServerConfigStore(opts),
7168
+ assistant: new PostgreSQLAssistantStore(opts),
7169
+ workflowTracking: new PostgreSQLWorkflowTrackingStore(opts),
7170
+ threadMessageQueue: new ThreadMessageQueueStore(opts),
7171
+ task: new PostgreSQLTaskStore(opts),
7172
+ a2aApiKey: new PostgreSQLA2AApiKeyStore(opts),
7173
+ schedule: new PostgreSQLScheduleStorage(opts),
7174
+ menu: new MenuStore(opts),
7175
+ sharedResource: new PostgresSharedResourceStore(opts),
7176
+ checkpoint
7177
+ };
7178
+ }
7179
+
6833
7180
  // src/stores/PostgreSQLSkillStore.ts
7181
+ import { Pool as Pool22 } from "pg";
6834
7182
  var PostgreSQLSkillStore = class {
6835
7183
  constructor(options) {
6836
7184
  this.initialized = false;
6837
7185
  this.ownsPool = true;
6838
7186
  this.initPromise = null;
7187
+ if (options.pool) {
7188
+ this.pool = options.pool;
7189
+ this.ownsPool = false;
7190
+ this.initialized = true;
7191
+ return;
7192
+ }
6839
7193
  if (typeof options.poolConfig === "string") {
6840
- this.pool = new Pool21({ connectionString: options.poolConfig });
7194
+ this.pool = new Pool22({ connectionString: options.poolConfig });
7195
+ } else if (options.poolConfig) {
7196
+ this.pool = new Pool22(options.poolConfig);
6841
7197
  } else {
6842
- this.pool = new Pool21(options.poolConfig);
7198
+ throw new Error("Either pool or poolConfig must be provided");
6843
7199
  }
6844
7200
  this.migrationManager = new MigrationManager(this.pool);
6845
7201
  this.migrationManager.register(createSkillsTable);
@@ -7137,68 +7493,22 @@ var PostgreSQLSkillStore = class {
7137
7493
  }
7138
7494
  };
7139
7495
 
7140
- // src/migrations/channel_identity_mapping_migration.ts
7141
- var createChannelIdentityMappingTables = {
7142
- version: 20,
7143
- name: "create_channel_identity_mapping_tables",
7144
- up: async (client) => {
7145
- await client.query(`
7146
- CREATE TABLE IF NOT EXISTS channel_identity_mappings (
7147
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
7148
- channel VARCHAR(50) NOT NULL,
7149
- channel_app_id VARCHAR(255) NOT NULL,
7150
- tenant_id VARCHAR(255) NOT NULL,
7151
- assistant_id VARCHAR(255) NOT NULL,
7152
- mapping_mode VARCHAR(20) NOT NULL CHECK (mapping_mode IN ('user', 'group', 'hybrid')),
7153
- external_subject_type VARCHAR(20) NOT NULL CHECK (external_subject_type IN ('user', 'chat')),
7154
- external_subject_key VARCHAR(512) NOT NULL,
7155
- lark_open_id VARCHAR(255),
7156
- lark_chat_id VARCHAR(255) NOT NULL,
7157
- lark_message_id VARCHAR(255),
7158
- thread_id VARCHAR(255) NOT NULL,
7159
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7160
- updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7161
- last_activity_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7162
- UNIQUE (channel, channel_app_id, tenant_id, assistant_id, external_subject_key)
7163
- )
7164
- `);
7165
- await client.query(`
7166
- CREATE INDEX IF NOT EXISTS idx_channel_identity_lookup
7167
- ON channel_identity_mappings(channel, channel_app_id, tenant_id, assistant_id, external_subject_key)
7168
- `);
7169
- await client.query(`
7170
- CREATE INDEX IF NOT EXISTS idx_channel_identity_thread
7171
- ON channel_identity_mappings(thread_id, tenant_id)
7172
- `);
7173
- await client.query(`
7174
- CREATE TABLE IF NOT EXISTS channel_inbound_message_receipts (
7175
- channel VARCHAR(50) NOT NULL,
7176
- channel_app_id VARCHAR(255) NOT NULL,
7177
- external_message_id VARCHAR(255) NOT NULL,
7178
- tenant_id VARCHAR(255) NOT NULL,
7179
- status VARCHAR(20) NOT NULL DEFAULT 'processing' CHECK (status IN ('processing', 'completed', 'failed')),
7180
- thread_id VARCHAR(255),
7181
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7182
- updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7183
- PRIMARY KEY (channel, channel_app_id, external_message_id)
7184
- )
7185
- `);
7186
- },
7187
- down: async (client) => {
7188
- await client.query("DROP TABLE IF EXISTS channel_inbound_message_receipts");
7189
- await client.query("DROP INDEX IF EXISTS idx_channel_identity_thread");
7190
- await client.query("DROP INDEX IF EXISTS idx_channel_identity_lookup");
7191
- await client.query("DROP TABLE IF EXISTS channel_identity_mappings");
7192
- }
7193
- };
7194
-
7195
7496
  // src/stores/ChannelIdentityMappingStore.ts
7196
- import { Pool as Pool22 } from "pg";
7497
+ import { Pool as Pool23 } from "pg";
7197
7498
  var ChannelIdentityMappingStore = class {
7198
7499
  constructor(options) {
7199
7500
  this.initialized = false;
7501
+ this.ownsPool = true;
7200
7502
  this.initPromise = null;
7201
- this.pool = typeof options.poolConfig === "string" ? new Pool22({ connectionString: options.poolConfig }) : new Pool22(options.poolConfig);
7503
+ if (options.pool) {
7504
+ this.pool = options.pool;
7505
+ this.ownsPool = false;
7506
+ this.initialized = true;
7507
+ return;
7508
+ }
7509
+ this.pool = typeof options.poolConfig === "string" ? new Pool23({ connectionString: options.poolConfig }) : options.poolConfig ? new Pool23(options.poolConfig) : (() => {
7510
+ throw new Error("Either pool or poolConfig must be provided");
7511
+ })();
7202
7512
  this.migrationManager = new MigrationManager(this.pool);
7203
7513
  this.migrationManager.register(createChannelIdentityMappingTables);
7204
7514
  if (options.autoMigrate !== false) {
@@ -7225,6 +7535,11 @@ var ChannelIdentityMappingStore = class {
7225
7535
  })();
7226
7536
  return this.initPromise;
7227
7537
  }
7538
+ async dispose() {
7539
+ if (this.ownsPool && this.pool) {
7540
+ await this.pool.end();
7541
+ }
7542
+ }
7228
7543
  async createMapping(input) {
7229
7544
  await this.ensureInitialized();
7230
7545
  const result = await this.pool.query(
@@ -7414,7 +7729,7 @@ export {
7414
7729
  ChannelIdentityMappingStore,
7415
7730
  MenuStore,
7416
7731
  MigrationManager,
7417
- Pool23 as Pool,
7732
+ Pool24 as Pool,
7418
7733
  PostgreSQLA2AApiKeyStore,
7419
7734
  PostgreSQLAssistantStore,
7420
7735
  PostgreSQLChannelInstallationStore,