@axiom-lattice/pg-stores 2.0.9 → 3.0.0
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.
- package/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +56 -0
- package/dist/index.d.mts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +576 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +576 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/PostgreSQLA2AApiKeyStore.migrations.test.ts +76 -0
- package/src/__tests__/PostgreSQLA2AApiKeyStore.test.ts +133 -0
- package/src/__tests__/PostgreSQLChannelInstallationStore.test.ts +37 -2
- package/src/__tests__/PostgreSQLTaskStore.integration.test.ts +90 -0
- package/src/__tests__/PostgreSQLTaskStore.test.ts +287 -0
- package/src/__tests__/PostgreSQLTaskWorkItemStore.test.ts +104 -0
- package/src/__tests__/add_a2a_key_assistant_ids.test.ts +34 -0
- package/src/__tests__/workspace-project-store.test.ts +48 -0
- package/src/createPgStoreConfig.ts +6 -1
- package/src/migrations/add_a2a_key_assistant_ids.ts +24 -0
- package/src/migrations/add_project_kind_column.ts +29 -0
- package/src/migrations/task_work_items_migration.ts +15 -0
- package/src/stores/PostgreSQLA2AApiKeyStore.ts +23 -8
- package/src/stores/PostgreSQLProjectStore.ts +31 -8
- package/src/stores/PostgreSQLTaskStore.ts +272 -7
- package/src/stores/PostgreSQLTaskWorkItemStore.ts +42 -2
package/dist/index.mjs
CHANGED
|
@@ -2352,6 +2352,24 @@ var dropProjectFolderPathColumn = {
|
|
|
2352
2352
|
}
|
|
2353
2353
|
};
|
|
2354
2354
|
|
|
2355
|
+
// src/migrations/add_project_kind_column.ts
|
|
2356
|
+
var addProjectKindColumn = {
|
|
2357
|
+
version: 165,
|
|
2358
|
+
name: "add_project_kind_column",
|
|
2359
|
+
up: async (client) => {
|
|
2360
|
+
await client.query(`
|
|
2361
|
+
ALTER TABLE lattice_projects
|
|
2362
|
+
ADD COLUMN IF NOT EXISTS kind TEXT NOT NULL DEFAULT 'business'
|
|
2363
|
+
`);
|
|
2364
|
+
},
|
|
2365
|
+
down: async (client) => {
|
|
2366
|
+
await client.query(`
|
|
2367
|
+
ALTER TABLE lattice_projects
|
|
2368
|
+
DROP COLUMN IF EXISTS kind
|
|
2369
|
+
`);
|
|
2370
|
+
}
|
|
2371
|
+
};
|
|
2372
|
+
|
|
2355
2373
|
// src/stores/PostgreSQLProjectStore.ts
|
|
2356
2374
|
var PostgreSQLProjectStore = class {
|
|
2357
2375
|
constructor(options) {
|
|
@@ -2374,6 +2392,7 @@ var PostgreSQLProjectStore = class {
|
|
|
2374
2392
|
this.migrationManager.register(createProjectsTable);
|
|
2375
2393
|
this.migrationManager.register(addProjectConfigColumn);
|
|
2376
2394
|
this.migrationManager.register(dropProjectFolderPathColumn);
|
|
2395
|
+
this.migrationManager.register(addProjectKindColumn);
|
|
2377
2396
|
if (options.autoMigrate !== false) {
|
|
2378
2397
|
this.initialize().catch((error) => {
|
|
2379
2398
|
console.error("Failed to initialize PostgreSQLProjectStore:", error);
|
|
@@ -2419,6 +2438,7 @@ var PostgreSQLProjectStore = class {
|
|
|
2419
2438
|
name: row.name,
|
|
2420
2439
|
description: row.description || void 0,
|
|
2421
2440
|
config: row.config || void 0,
|
|
2441
|
+
kind: row.kind || "business",
|
|
2422
2442
|
createdAt: row.created_at,
|
|
2423
2443
|
updatedAt: row.updated_at
|
|
2424
2444
|
};
|
|
@@ -2426,16 +2446,22 @@ var PostgreSQLProjectStore = class {
|
|
|
2426
2446
|
/**
|
|
2427
2447
|
* Get all projects for a specific workspace
|
|
2428
2448
|
*/
|
|
2429
|
-
async getProjectsByWorkspace(tenantId, workspaceId) {
|
|
2449
|
+
async getProjectsByWorkspace(tenantId, workspaceId, filter) {
|
|
2430
2450
|
await this.ensureInitialized();
|
|
2451
|
+
const conditions = ["tenant_id = $1", "workspace_id = $2"];
|
|
2452
|
+
const values = [tenantId, workspaceId];
|
|
2453
|
+
if (filter?.kind !== void 0) {
|
|
2454
|
+
values.push(filter.kind);
|
|
2455
|
+
conditions.push(`kind = $${values.length}`);
|
|
2456
|
+
}
|
|
2431
2457
|
const result = await this.pool.query(
|
|
2432
2458
|
`
|
|
2433
|
-
SELECT id, tenant_id, workspace_id, name, description, config, created_at, updated_at
|
|
2459
|
+
SELECT id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at
|
|
2434
2460
|
FROM lattice_projects
|
|
2435
|
-
WHERE
|
|
2461
|
+
WHERE ${conditions.join(" AND ")}
|
|
2436
2462
|
ORDER BY created_at DESC
|
|
2437
2463
|
`,
|
|
2438
|
-
|
|
2464
|
+
values
|
|
2439
2465
|
);
|
|
2440
2466
|
return result.rows.map(this.mapRowToProject);
|
|
2441
2467
|
}
|
|
@@ -2446,7 +2472,7 @@ var PostgreSQLProjectStore = class {
|
|
|
2446
2472
|
await this.ensureInitialized();
|
|
2447
2473
|
const result = await this.pool.query(
|
|
2448
2474
|
`
|
|
2449
|
-
SELECT id, tenant_id, workspace_id, name, description, config, created_at, updated_at
|
|
2475
|
+
SELECT id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at
|
|
2450
2476
|
FROM lattice_projects
|
|
2451
2477
|
WHERE id = $1 AND tenant_id = $2
|
|
2452
2478
|
`,
|
|
@@ -2463,18 +2489,20 @@ var PostgreSQLProjectStore = class {
|
|
|
2463
2489
|
async createProject(tenantId, workspaceId, id, data) {
|
|
2464
2490
|
await this.ensureInitialized();
|
|
2465
2491
|
const now = /* @__PURE__ */ new Date();
|
|
2492
|
+
const kind = data.kind || "business";
|
|
2466
2493
|
await this.pool.query(
|
|
2467
2494
|
`
|
|
2468
|
-
INSERT INTO lattice_projects (id, tenant_id, workspace_id, name, description, config, created_at, updated_at)
|
|
2469
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
2495
|
+
INSERT INTO lattice_projects (id, tenant_id, workspace_id, name, description, config, kind, created_at, updated_at)
|
|
2496
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
|
2470
2497
|
ON CONFLICT (id, tenant_id) DO UPDATE SET
|
|
2471
2498
|
workspace_id = EXCLUDED.workspace_id,
|
|
2472
2499
|
name = EXCLUDED.name,
|
|
2473
2500
|
description = EXCLUDED.description,
|
|
2474
2501
|
config = EXCLUDED.config,
|
|
2502
|
+
kind = EXCLUDED.kind,
|
|
2475
2503
|
updated_at = EXCLUDED.updated_at
|
|
2476
2504
|
`,
|
|
2477
|
-
[id, tenantId, workspaceId, data.name, data.description || null, data.config || null, now, now]
|
|
2505
|
+
[id, tenantId, workspaceId, data.name, data.description || null, data.config || null, kind, now, now]
|
|
2478
2506
|
);
|
|
2479
2507
|
return {
|
|
2480
2508
|
id,
|
|
@@ -2483,6 +2511,7 @@ var PostgreSQLProjectStore = class {
|
|
|
2483
2511
|
name: data.name,
|
|
2484
2512
|
description: data.description,
|
|
2485
2513
|
config: data.config,
|
|
2514
|
+
kind,
|
|
2486
2515
|
createdAt: now,
|
|
2487
2516
|
updatedAt: now
|
|
2488
2517
|
};
|
|
@@ -2515,6 +2544,10 @@ var PostgreSQLProjectStore = class {
|
|
|
2515
2544
|
updateFields.push(`config = $${paramIndex++}`);
|
|
2516
2545
|
updateValues.push(updates.config || null);
|
|
2517
2546
|
}
|
|
2547
|
+
if (updates.kind !== void 0) {
|
|
2548
|
+
updateFields.push(`kind = $${paramIndex++}`);
|
|
2549
|
+
updateValues.push(updates.kind);
|
|
2550
|
+
}
|
|
2518
2551
|
if (updateFields.length === 0) {
|
|
2519
2552
|
return existing;
|
|
2520
2553
|
}
|
|
@@ -5745,6 +5778,24 @@ var createA2AApiKeysTable = {
|
|
|
5745
5778
|
}
|
|
5746
5779
|
};
|
|
5747
5780
|
|
|
5781
|
+
// src/migrations/add_a2a_key_assistant_ids.ts
|
|
5782
|
+
var addA2AKeyAssistantIds = {
|
|
5783
|
+
version: 167,
|
|
5784
|
+
name: "add_a2a_key_assistant_ids",
|
|
5785
|
+
up: async (client) => {
|
|
5786
|
+
await client.query(`
|
|
5787
|
+
ALTER TABLE lattice_a2a_api_keys
|
|
5788
|
+
ADD COLUMN IF NOT EXISTS assistant_ids JSONB
|
|
5789
|
+
`);
|
|
5790
|
+
},
|
|
5791
|
+
down: async (client) => {
|
|
5792
|
+
await client.query(`
|
|
5793
|
+
ALTER TABLE lattice_a2a_api_keys
|
|
5794
|
+
DROP COLUMN IF EXISTS assistant_ids
|
|
5795
|
+
`);
|
|
5796
|
+
}
|
|
5797
|
+
};
|
|
5798
|
+
|
|
5748
5799
|
// src/stores/PostgreSQLA2AApiKeyStore.ts
|
|
5749
5800
|
import { encrypt as encrypt5, decrypt as decrypt5 } from "@axiom-lattice/core";
|
|
5750
5801
|
import { randomUUID } from "crypto";
|
|
@@ -5756,8 +5807,8 @@ function mapRowToRecord(row) {
|
|
|
5756
5807
|
id: row.id,
|
|
5757
5808
|
key: decrypt5(row.key_value),
|
|
5758
5809
|
tenantId: row.tenant_id,
|
|
5759
|
-
projectId: row.project_id
|
|
5760
|
-
|
|
5810
|
+
projectId: row.project_id,
|
|
5811
|
+
assistantIds: row.assistant_ids ?? void 0,
|
|
5761
5812
|
label: row.label || void 0,
|
|
5762
5813
|
enabled: row.enabled,
|
|
5763
5814
|
createdAt: row.created_at,
|
|
@@ -5780,6 +5831,7 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
5780
5831
|
})();
|
|
5781
5832
|
this.migrationManager = new MigrationManager(this.pool);
|
|
5782
5833
|
this.migrationManager.register(createA2AApiKeysTable);
|
|
5834
|
+
this.migrationManager.register(addA2AKeyAssistantIds);
|
|
5783
5835
|
if (options.autoMigrate !== false) {
|
|
5784
5836
|
this.initialize().catch((error) => {
|
|
5785
5837
|
console.error("Failed to initialize PostgreSQLA2AApiKeyStore:", error);
|
|
@@ -5818,6 +5870,14 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
5818
5870
|
}
|
|
5819
5871
|
return null;
|
|
5820
5872
|
}
|
|
5873
|
+
async findById(id) {
|
|
5874
|
+
await this.ensureInitialized();
|
|
5875
|
+
const result = await this.pool.query(
|
|
5876
|
+
`SELECT * FROM lattice_a2a_api_keys WHERE id = $1`,
|
|
5877
|
+
[id]
|
|
5878
|
+
);
|
|
5879
|
+
return result.rows[0] ? mapRowToRecord(result.rows[0]) : null;
|
|
5880
|
+
}
|
|
5821
5881
|
async list(params) {
|
|
5822
5882
|
await this.ensureInitialized();
|
|
5823
5883
|
const limit = params.limit || 100;
|
|
@@ -5839,9 +5899,9 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
5839
5899
|
await this.ensureInitialized();
|
|
5840
5900
|
const key = generateApiKey();
|
|
5841
5901
|
const result = await this.pool.query(
|
|
5842
|
-
`INSERT INTO lattice_a2a_api_keys (key_value, tenant_id, project_id,
|
|
5902
|
+
`INSERT INTO lattice_a2a_api_keys (key_value, tenant_id, project_id, assistant_ids, label)
|
|
5843
5903
|
VALUES ($1, $2, $3, $4, $5) RETURNING *`,
|
|
5844
|
-
[encrypt5(key), input.tenantId, input.projectId
|
|
5904
|
+
[encrypt5(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.label || null]
|
|
5845
5905
|
);
|
|
5846
5906
|
const record = mapRowToRecord(result.rows[0]);
|
|
5847
5907
|
record.key = key;
|
|
@@ -5892,8 +5952,8 @@ var PostgreSQLA2AApiKeyStore = class {
|
|
|
5892
5952
|
map.set(key, {
|
|
5893
5953
|
key,
|
|
5894
5954
|
tenantId: row.tenant_id,
|
|
5895
|
-
projectId: row.project_id
|
|
5896
|
-
|
|
5955
|
+
projectId: row.project_id,
|
|
5956
|
+
assistantIds: row.assistant_ids ?? void 0
|
|
5897
5957
|
});
|
|
5898
5958
|
}
|
|
5899
5959
|
return map;
|
|
@@ -6617,6 +6677,49 @@ var taskMigrations = [
|
|
|
6617
6677
|
|
|
6618
6678
|
// src/stores/PostgreSQLTaskStore.ts
|
|
6619
6679
|
import { v4 as uuidv42 } from "uuid";
|
|
6680
|
+
function nextUpdatedAtSql(column = "updated_at") {
|
|
6681
|
+
return `to_char(
|
|
6682
|
+
date_trunc('milliseconds', GREATEST(
|
|
6683
|
+
clock_timestamp(),
|
|
6684
|
+
CASE
|
|
6685
|
+
WHEN ${canonicalTimestampValidationSql(column)}
|
|
6686
|
+
THEN ${column}::timestamptz + interval '1 millisecond'
|
|
6687
|
+
ELSE clock_timestamp()
|
|
6688
|
+
END
|
|
6689
|
+
))
|
|
6690
|
+
AT TIME ZONE 'UTC',
|
|
6691
|
+
'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
|
|
6692
|
+
)`;
|
|
6693
|
+
}
|
|
6694
|
+
function canonicalTimestampValidationSql(column, allowMaximum = false) {
|
|
6695
|
+
const year = `substring(${column} FROM 1 FOR 4)::integer`;
|
|
6696
|
+
const month = `substring(${column} FROM 6 FOR 2)::integer`;
|
|
6697
|
+
const day = `substring(${column} FROM 9 FOR 2)::integer`;
|
|
6698
|
+
return `CASE
|
|
6699
|
+
WHEN ${column} ~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[.][0-9]{3}Z$' THEN
|
|
6700
|
+
${allowMaximum ? "" : `${column} <> '9999-12-31T23:59:59.999Z' AND`}
|
|
6701
|
+
${year} BETWEEN 1 AND 9999
|
|
6702
|
+
AND ${month} BETWEEN 1 AND 12
|
|
6703
|
+
AND ${day} BETWEEN 1 AND CASE
|
|
6704
|
+
WHEN ${month} = 2 THEN CASE
|
|
6705
|
+
WHEN (${year} % 400 = 0) OR (${year} % 4 = 0 AND ${year} % 100 <> 0) THEN 29
|
|
6706
|
+
ELSE 28
|
|
6707
|
+
END
|
|
6708
|
+
WHEN ${month} IN (4, 6, 9, 11) THEN 30
|
|
6709
|
+
ELSE 31
|
|
6710
|
+
END
|
|
6711
|
+
AND substring(${column} FROM 12 FOR 2)::integer BETWEEN 0 AND 23
|
|
6712
|
+
AND substring(${column} FROM 15 FOR 2)::integer BETWEEN 0 AND 59
|
|
6713
|
+
AND substring(${column} FROM 18 FOR 2)::integer BETWEEN 0 AND 59
|
|
6714
|
+
ELSE FALSE
|
|
6715
|
+
END`;
|
|
6716
|
+
}
|
|
6717
|
+
function canonicalTimestampSnapshotSql(column, parameter, allowMaximum = false) {
|
|
6718
|
+
return `CASE WHEN ${canonicalTimestampValidationSql(column, allowMaximum)}
|
|
6719
|
+
THEN ${column}::timestamptz = ${parameter}::timestamptz
|
|
6720
|
+
ELSE FALSE
|
|
6721
|
+
END`;
|
|
6722
|
+
}
|
|
6620
6723
|
function parseTaskFiles(raw) {
|
|
6621
6724
|
if (!raw) return void 0;
|
|
6622
6725
|
try {
|
|
@@ -6702,7 +6805,7 @@ var PostgreSQLTaskStore = class {
|
|
|
6702
6805
|
}
|
|
6703
6806
|
async create(params) {
|
|
6704
6807
|
await this.ensureInitialized();
|
|
6705
|
-
const id = uuidv42();
|
|
6808
|
+
const id = params.id ?? uuidv42();
|
|
6706
6809
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6707
6810
|
await this.pool.query(
|
|
6708
6811
|
`INSERT INTO lattice_tasks (id, tenant_id, owner_type, owner_id, title, description, status, priority, due_date, metadata, parent_id, source_id, context, require_review, dependencies, result, failure_reason, workspace_id, project_id, files, created_at, updated_at)
|
|
@@ -6846,7 +6949,7 @@ var PostgreSQLTaskStore = class {
|
|
|
6846
6949
|
}
|
|
6847
6950
|
if (updates.context !== void 0) {
|
|
6848
6951
|
setClauses.push(`context = $${paramIndex++}`);
|
|
6849
|
-
params.push(JSON.stringify(updates.context));
|
|
6952
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
6850
6953
|
}
|
|
6851
6954
|
if (updates.ownerType !== void 0) {
|
|
6852
6955
|
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
@@ -6883,14 +6986,403 @@ var PostgreSQLTaskStore = class {
|
|
|
6883
6986
|
if (setClauses.length === 0) {
|
|
6884
6987
|
return existing;
|
|
6885
6988
|
}
|
|
6886
|
-
setClauses.push(`updated_at =
|
|
6887
|
-
params.push((/* @__PURE__ */ new Date()).toISOString());
|
|
6989
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql()}`);
|
|
6888
6990
|
params.push(tenantId, id);
|
|
6889
|
-
await this.pool.query(
|
|
6890
|
-
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex++}
|
|
6991
|
+
const result = await this.pool.query(
|
|
6992
|
+
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${paramIndex++} AND id = $${paramIndex++} AND updated_at <> '9999-12-31T23:59:59.999Z' RETURNING *`,
|
|
6993
|
+
params
|
|
6994
|
+
);
|
|
6995
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
6996
|
+
}
|
|
6997
|
+
/**
|
|
6998
|
+
* Atomically update a task unless its current status is blocked.
|
|
6999
|
+
*
|
|
7000
|
+
* @param tenantId Tenant identifier.
|
|
7001
|
+
* @param id Task identifier.
|
|
7002
|
+
* @param updates Partial task data to update.
|
|
7003
|
+
* @param blockedStatuses Current statuses that prevent the update.
|
|
7004
|
+
* @returns The updated task, or `null` when missing or blocked.
|
|
7005
|
+
*/
|
|
7006
|
+
async updateIfStatusNotIn(tenantId, id, updates, blockedStatuses) {
|
|
7007
|
+
await this.ensureInitialized();
|
|
7008
|
+
const setClauses = [];
|
|
7009
|
+
const params = [];
|
|
7010
|
+
let paramIndex = 1;
|
|
7011
|
+
if (updates.title !== void 0) {
|
|
7012
|
+
setClauses.push(`title = $${paramIndex++}`);
|
|
7013
|
+
params.push(updates.title);
|
|
7014
|
+
}
|
|
7015
|
+
if (updates.description !== void 0) {
|
|
7016
|
+
setClauses.push(`description = $${paramIndex++}`);
|
|
7017
|
+
params.push(updates.description);
|
|
7018
|
+
}
|
|
7019
|
+
if (updates.status !== void 0) {
|
|
7020
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
7021
|
+
params.push(updates.status);
|
|
7022
|
+
}
|
|
7023
|
+
if (updates.priority !== void 0) {
|
|
7024
|
+
setClauses.push(`priority = $${paramIndex++}`);
|
|
7025
|
+
params.push(updates.priority);
|
|
7026
|
+
}
|
|
7027
|
+
if (updates.dueDate !== void 0) {
|
|
7028
|
+
setClauses.push(`due_date = $${paramIndex++}`);
|
|
7029
|
+
params.push(updates.dueDate);
|
|
7030
|
+
}
|
|
7031
|
+
if (updates.metadata !== void 0) {
|
|
7032
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
7033
|
+
params.push(JSON.stringify(updates.metadata));
|
|
7034
|
+
}
|
|
7035
|
+
if (updates.files !== void 0) {
|
|
7036
|
+
setClauses.push(`files = $${paramIndex++}`);
|
|
7037
|
+
params.push(JSON.stringify(updates.files));
|
|
7038
|
+
}
|
|
7039
|
+
if (updates.parentId !== void 0) {
|
|
7040
|
+
setClauses.push(`parent_id = $${paramIndex++}`);
|
|
7041
|
+
params.push(updates.parentId);
|
|
7042
|
+
}
|
|
7043
|
+
if (updates.sourceId !== void 0) {
|
|
7044
|
+
setClauses.push(`source_id = $${paramIndex++}`);
|
|
7045
|
+
params.push(updates.sourceId);
|
|
7046
|
+
}
|
|
7047
|
+
if (updates.context !== void 0) {
|
|
7048
|
+
setClauses.push(`context = $${paramIndex++}`);
|
|
7049
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
7050
|
+
}
|
|
7051
|
+
if (updates.ownerType !== void 0) {
|
|
7052
|
+
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
7053
|
+
params.push(updates.ownerType);
|
|
7054
|
+
}
|
|
7055
|
+
if (updates.ownerId !== void 0) {
|
|
7056
|
+
setClauses.push(`owner_id = $${paramIndex++}`);
|
|
7057
|
+
params.push(updates.ownerId);
|
|
7058
|
+
}
|
|
7059
|
+
if (updates.requireReview !== void 0) {
|
|
7060
|
+
setClauses.push(`require_review = $${paramIndex++}`);
|
|
7061
|
+
params.push(updates.requireReview);
|
|
7062
|
+
}
|
|
7063
|
+
if (updates.dependencies !== void 0) {
|
|
7064
|
+
setClauses.push(`dependencies = $${paramIndex++}`);
|
|
7065
|
+
params.push(JSON.stringify(updates.dependencies));
|
|
7066
|
+
}
|
|
7067
|
+
if (updates.result !== void 0) {
|
|
7068
|
+
setClauses.push(`result = $${paramIndex++}`);
|
|
7069
|
+
params.push(updates.result);
|
|
7070
|
+
}
|
|
7071
|
+
if (updates.failureReason !== void 0) {
|
|
7072
|
+
setClauses.push(`failure_reason = $${paramIndex++}`);
|
|
7073
|
+
params.push(updates.failureReason);
|
|
7074
|
+
}
|
|
7075
|
+
if (updates.workspaceId !== void 0) {
|
|
7076
|
+
setClauses.push(`workspace_id = $${paramIndex++}`);
|
|
7077
|
+
params.push(updates.workspaceId);
|
|
7078
|
+
}
|
|
7079
|
+
if (updates.projectId !== void 0) {
|
|
7080
|
+
setClauses.push(`project_id = $${paramIndex++}`);
|
|
7081
|
+
params.push(updates.projectId);
|
|
7082
|
+
}
|
|
7083
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql()}`);
|
|
7084
|
+
const tenantParam = paramIndex++;
|
|
7085
|
+
const idParam = paramIndex++;
|
|
7086
|
+
params.push(tenantId, id);
|
|
7087
|
+
const blockedClause = blockedStatuses.length > 0 ? ` AND status <> ALL($${paramIndex}::text[])` : "";
|
|
7088
|
+
if (blockedStatuses.length > 0) params.push(blockedStatuses);
|
|
7089
|
+
const result = await this.pool.query(
|
|
7090
|
+
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${tenantParam} AND id = $${idParam} AND updated_at <> '9999-12-31T23:59:59.999Z'${blockedClause} RETURNING *`,
|
|
6891
7091
|
params
|
|
6892
7092
|
);
|
|
6893
|
-
return
|
|
7093
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
7094
|
+
}
|
|
7095
|
+
/** Atomically update a task only when its current status is expected. */
|
|
7096
|
+
async updateIfStatusIn(tenantId, id, updates, expectedStatuses) {
|
|
7097
|
+
await this.ensureInitialized();
|
|
7098
|
+
if (expectedStatuses.length === 0) return null;
|
|
7099
|
+
const setClauses = [];
|
|
7100
|
+
const params = [];
|
|
7101
|
+
let paramIndex = 1;
|
|
7102
|
+
if (updates.title !== void 0) {
|
|
7103
|
+
setClauses.push(`title = $${paramIndex++}`);
|
|
7104
|
+
params.push(updates.title);
|
|
7105
|
+
}
|
|
7106
|
+
if (updates.description !== void 0) {
|
|
7107
|
+
setClauses.push(`description = $${paramIndex++}`);
|
|
7108
|
+
params.push(updates.description);
|
|
7109
|
+
}
|
|
7110
|
+
if (updates.status !== void 0) {
|
|
7111
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
7112
|
+
params.push(updates.status);
|
|
7113
|
+
}
|
|
7114
|
+
if (updates.priority !== void 0) {
|
|
7115
|
+
setClauses.push(`priority = $${paramIndex++}`);
|
|
7116
|
+
params.push(updates.priority);
|
|
7117
|
+
}
|
|
7118
|
+
if (updates.dueDate !== void 0) {
|
|
7119
|
+
setClauses.push(`due_date = $${paramIndex++}`);
|
|
7120
|
+
params.push(updates.dueDate);
|
|
7121
|
+
}
|
|
7122
|
+
if (updates.metadata !== void 0) {
|
|
7123
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
7124
|
+
params.push(JSON.stringify(updates.metadata));
|
|
7125
|
+
}
|
|
7126
|
+
if (updates.files !== void 0) {
|
|
7127
|
+
setClauses.push(`files = $${paramIndex++}`);
|
|
7128
|
+
params.push(JSON.stringify(updates.files));
|
|
7129
|
+
}
|
|
7130
|
+
if (updates.parentId !== void 0) {
|
|
7131
|
+
setClauses.push(`parent_id = $${paramIndex++}`);
|
|
7132
|
+
params.push(updates.parentId);
|
|
7133
|
+
}
|
|
7134
|
+
if (updates.sourceId !== void 0) {
|
|
7135
|
+
setClauses.push(`source_id = $${paramIndex++}`);
|
|
7136
|
+
params.push(updates.sourceId);
|
|
7137
|
+
}
|
|
7138
|
+
if (updates.context !== void 0) {
|
|
7139
|
+
setClauses.push(`context = $${paramIndex++}`);
|
|
7140
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
7141
|
+
}
|
|
7142
|
+
if (updates.ownerType !== void 0) {
|
|
7143
|
+
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
7144
|
+
params.push(updates.ownerType);
|
|
7145
|
+
}
|
|
7146
|
+
if (updates.ownerId !== void 0) {
|
|
7147
|
+
setClauses.push(`owner_id = $${paramIndex++}`);
|
|
7148
|
+
params.push(updates.ownerId);
|
|
7149
|
+
}
|
|
7150
|
+
if (updates.requireReview !== void 0) {
|
|
7151
|
+
setClauses.push(`require_review = $${paramIndex++}`);
|
|
7152
|
+
params.push(updates.requireReview);
|
|
7153
|
+
}
|
|
7154
|
+
if (updates.dependencies !== void 0) {
|
|
7155
|
+
setClauses.push(`dependencies = $${paramIndex++}`);
|
|
7156
|
+
params.push(JSON.stringify(updates.dependencies));
|
|
7157
|
+
}
|
|
7158
|
+
if (updates.result !== void 0) {
|
|
7159
|
+
setClauses.push(`result = $${paramIndex++}`);
|
|
7160
|
+
params.push(updates.result);
|
|
7161
|
+
}
|
|
7162
|
+
if (updates.failureReason !== void 0) {
|
|
7163
|
+
setClauses.push(`failure_reason = $${paramIndex++}`);
|
|
7164
|
+
params.push(updates.failureReason);
|
|
7165
|
+
}
|
|
7166
|
+
if (updates.workspaceId !== void 0) {
|
|
7167
|
+
setClauses.push(`workspace_id = $${paramIndex++}`);
|
|
7168
|
+
params.push(updates.workspaceId);
|
|
7169
|
+
}
|
|
7170
|
+
if (updates.projectId !== void 0) {
|
|
7171
|
+
setClauses.push(`project_id = $${paramIndex++}`);
|
|
7172
|
+
params.push(updates.projectId);
|
|
7173
|
+
}
|
|
7174
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql()}`);
|
|
7175
|
+
const tenantParam = paramIndex++;
|
|
7176
|
+
const idParam = paramIndex++;
|
|
7177
|
+
const statusesParam = paramIndex++;
|
|
7178
|
+
params.push(tenantId, id, expectedStatuses);
|
|
7179
|
+
const result = await this.pool.query(
|
|
7180
|
+
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${tenantParam} AND id = $${idParam} AND updated_at <> '9999-12-31T23:59:59.999Z' AND status = ANY($${statusesParam}::text[]) RETURNING *`,
|
|
7181
|
+
params
|
|
7182
|
+
);
|
|
7183
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
7184
|
+
}
|
|
7185
|
+
/** Atomically update a task only when status and updatedAt match a read snapshot. */
|
|
7186
|
+
async updateIfStatusAndUpdatedAt(tenantId, id, updates, expectedStatuses, expectedUpdatedAt) {
|
|
7187
|
+
await this.ensureInitialized();
|
|
7188
|
+
if (expectedStatuses.length === 0) return null;
|
|
7189
|
+
const expectedIso = new Date(expectedUpdatedAt).toISOString();
|
|
7190
|
+
const setClauses = [];
|
|
7191
|
+
const params = [];
|
|
7192
|
+
let paramIndex = 1;
|
|
7193
|
+
if (updates.title !== void 0) {
|
|
7194
|
+
setClauses.push(`title = $${paramIndex++}`);
|
|
7195
|
+
params.push(updates.title);
|
|
7196
|
+
}
|
|
7197
|
+
if (updates.description !== void 0) {
|
|
7198
|
+
setClauses.push(`description = $${paramIndex++}`);
|
|
7199
|
+
params.push(updates.description);
|
|
7200
|
+
}
|
|
7201
|
+
if (updates.status !== void 0) {
|
|
7202
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
7203
|
+
params.push(updates.status);
|
|
7204
|
+
}
|
|
7205
|
+
if (updates.priority !== void 0) {
|
|
7206
|
+
setClauses.push(`priority = $${paramIndex++}`);
|
|
7207
|
+
params.push(updates.priority);
|
|
7208
|
+
}
|
|
7209
|
+
if (updates.dueDate !== void 0) {
|
|
7210
|
+
setClauses.push(`due_date = $${paramIndex++}`);
|
|
7211
|
+
params.push(updates.dueDate);
|
|
7212
|
+
}
|
|
7213
|
+
if (updates.metadata !== void 0) {
|
|
7214
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
7215
|
+
params.push(JSON.stringify(updates.metadata));
|
|
7216
|
+
}
|
|
7217
|
+
if (updates.files !== void 0) {
|
|
7218
|
+
setClauses.push(`files = $${paramIndex++}`);
|
|
7219
|
+
params.push(JSON.stringify(updates.files));
|
|
7220
|
+
}
|
|
7221
|
+
if (updates.parentId !== void 0) {
|
|
7222
|
+
setClauses.push(`parent_id = $${paramIndex++}`);
|
|
7223
|
+
params.push(updates.parentId);
|
|
7224
|
+
}
|
|
7225
|
+
if (updates.sourceId !== void 0) {
|
|
7226
|
+
setClauses.push(`source_id = $${paramIndex++}`);
|
|
7227
|
+
params.push(updates.sourceId);
|
|
7228
|
+
}
|
|
7229
|
+
if (updates.context !== void 0) {
|
|
7230
|
+
setClauses.push(`context = $${paramIndex++}`);
|
|
7231
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
7232
|
+
}
|
|
7233
|
+
if (updates.ownerType !== void 0) {
|
|
7234
|
+
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
7235
|
+
params.push(updates.ownerType);
|
|
7236
|
+
}
|
|
7237
|
+
if (updates.ownerId !== void 0) {
|
|
7238
|
+
setClauses.push(`owner_id = $${paramIndex++}`);
|
|
7239
|
+
params.push(updates.ownerId);
|
|
7240
|
+
}
|
|
7241
|
+
if (updates.requireReview !== void 0) {
|
|
7242
|
+
setClauses.push(`require_review = $${paramIndex++}`);
|
|
7243
|
+
params.push(updates.requireReview);
|
|
7244
|
+
}
|
|
7245
|
+
if (updates.dependencies !== void 0) {
|
|
7246
|
+
setClauses.push(`dependencies = $${paramIndex++}`);
|
|
7247
|
+
params.push(JSON.stringify(updates.dependencies));
|
|
7248
|
+
}
|
|
7249
|
+
if (updates.result !== void 0) {
|
|
7250
|
+
setClauses.push(`result = $${paramIndex++}`);
|
|
7251
|
+
params.push(updates.result);
|
|
7252
|
+
}
|
|
7253
|
+
if (updates.failureReason !== void 0) {
|
|
7254
|
+
setClauses.push(`failure_reason = $${paramIndex++}`);
|
|
7255
|
+
params.push(updates.failureReason);
|
|
7256
|
+
}
|
|
7257
|
+
if (updates.workspaceId !== void 0) {
|
|
7258
|
+
setClauses.push(`workspace_id = $${paramIndex++}`);
|
|
7259
|
+
params.push(updates.workspaceId);
|
|
7260
|
+
}
|
|
7261
|
+
if (updates.projectId !== void 0) {
|
|
7262
|
+
setClauses.push(`project_id = $${paramIndex++}`);
|
|
7263
|
+
params.push(updates.projectId);
|
|
7264
|
+
}
|
|
7265
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql()}`);
|
|
7266
|
+
const tenantParam = paramIndex++;
|
|
7267
|
+
const idParam = paramIndex++;
|
|
7268
|
+
const statusesParam = paramIndex++;
|
|
7269
|
+
const updatedAtParam = paramIndex++;
|
|
7270
|
+
params.push(tenantId, id, expectedStatuses, expectedIso);
|
|
7271
|
+
const result = await this.pool.query(
|
|
7272
|
+
`UPDATE lattice_tasks SET ${setClauses.join(", ")} WHERE tenant_id = $${tenantParam} AND id = $${idParam} AND status = ANY($${statusesParam}::text[]) AND ${canonicalTimestampSnapshotSql("updated_at", `$${updatedAtParam}`)} RETURNING *`,
|
|
7273
|
+
params
|
|
7274
|
+
);
|
|
7275
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
7276
|
+
}
|
|
7277
|
+
/** Atomically update a child only when both child and parent snapshots match. */
|
|
7278
|
+
async updateIfStatusUpdatedAtAndParentUpdatedAt(tenantId, id, updates, expectedStatuses, expectedUpdatedAt, parentId, expectedParentUpdatedAt) {
|
|
7279
|
+
await this.ensureInitialized();
|
|
7280
|
+
if (expectedStatuses.length === 0) return null;
|
|
7281
|
+
const setClauses = [];
|
|
7282
|
+
const params = [];
|
|
7283
|
+
let paramIndex = 1;
|
|
7284
|
+
if (updates.title !== void 0) {
|
|
7285
|
+
setClauses.push(`title = $${paramIndex++}`);
|
|
7286
|
+
params.push(updates.title);
|
|
7287
|
+
}
|
|
7288
|
+
if (updates.description !== void 0) {
|
|
7289
|
+
setClauses.push(`description = $${paramIndex++}`);
|
|
7290
|
+
params.push(updates.description);
|
|
7291
|
+
}
|
|
7292
|
+
if (updates.status !== void 0) {
|
|
7293
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
7294
|
+
params.push(updates.status);
|
|
7295
|
+
}
|
|
7296
|
+
if (updates.priority !== void 0) {
|
|
7297
|
+
setClauses.push(`priority = $${paramIndex++}`);
|
|
7298
|
+
params.push(updates.priority);
|
|
7299
|
+
}
|
|
7300
|
+
if (updates.dueDate !== void 0) {
|
|
7301
|
+
setClauses.push(`due_date = $${paramIndex++}`);
|
|
7302
|
+
params.push(updates.dueDate);
|
|
7303
|
+
}
|
|
7304
|
+
if (updates.metadata !== void 0) {
|
|
7305
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
7306
|
+
params.push(JSON.stringify(updates.metadata));
|
|
7307
|
+
}
|
|
7308
|
+
if (updates.files !== void 0) {
|
|
7309
|
+
setClauses.push(`files = $${paramIndex++}`);
|
|
7310
|
+
params.push(JSON.stringify(updates.files));
|
|
7311
|
+
}
|
|
7312
|
+
if (updates.parentId !== void 0) {
|
|
7313
|
+
setClauses.push(`parent_id = $${paramIndex++}`);
|
|
7314
|
+
params.push(updates.parentId);
|
|
7315
|
+
}
|
|
7316
|
+
if (updates.sourceId !== void 0) {
|
|
7317
|
+
setClauses.push(`source_id = $${paramIndex++}`);
|
|
7318
|
+
params.push(updates.sourceId);
|
|
7319
|
+
}
|
|
7320
|
+
if (updates.context !== void 0) {
|
|
7321
|
+
setClauses.push(`context = $${paramIndex++}`);
|
|
7322
|
+
params.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
7323
|
+
}
|
|
7324
|
+
if (updates.ownerType !== void 0) {
|
|
7325
|
+
setClauses.push(`owner_type = $${paramIndex++}`);
|
|
7326
|
+
params.push(updates.ownerType);
|
|
7327
|
+
}
|
|
7328
|
+
if (updates.ownerId !== void 0) {
|
|
7329
|
+
setClauses.push(`owner_id = $${paramIndex++}`);
|
|
7330
|
+
params.push(updates.ownerId);
|
|
7331
|
+
}
|
|
7332
|
+
if (updates.requireReview !== void 0) {
|
|
7333
|
+
setClauses.push(`require_review = $${paramIndex++}`);
|
|
7334
|
+
params.push(updates.requireReview);
|
|
7335
|
+
}
|
|
7336
|
+
if (updates.dependencies !== void 0) {
|
|
7337
|
+
setClauses.push(`dependencies = $${paramIndex++}`);
|
|
7338
|
+
params.push(JSON.stringify(updates.dependencies));
|
|
7339
|
+
}
|
|
7340
|
+
if (updates.result !== void 0) {
|
|
7341
|
+
setClauses.push(`result = $${paramIndex++}`);
|
|
7342
|
+
params.push(updates.result);
|
|
7343
|
+
}
|
|
7344
|
+
if (updates.failureReason !== void 0) {
|
|
7345
|
+
setClauses.push(`failure_reason = $${paramIndex++}`);
|
|
7346
|
+
params.push(updates.failureReason);
|
|
7347
|
+
}
|
|
7348
|
+
if (updates.workspaceId !== void 0) {
|
|
7349
|
+
setClauses.push(`workspace_id = $${paramIndex++}`);
|
|
7350
|
+
params.push(updates.workspaceId);
|
|
7351
|
+
}
|
|
7352
|
+
if (updates.projectId !== void 0) {
|
|
7353
|
+
setClauses.push(`project_id = $${paramIndex++}`);
|
|
7354
|
+
params.push(updates.projectId);
|
|
7355
|
+
}
|
|
7356
|
+
setClauses.push(`updated_at = ${nextUpdatedAtSql("child.updated_at")}`);
|
|
7357
|
+
const tenantParam = paramIndex++;
|
|
7358
|
+
const idParam = paramIndex++;
|
|
7359
|
+
const statusesParam = paramIndex++;
|
|
7360
|
+
const updatedAtParam = paramIndex++;
|
|
7361
|
+
const parentIdParam = paramIndex++;
|
|
7362
|
+
const parentUpdatedAtParam = paramIndex++;
|
|
7363
|
+
params.push(
|
|
7364
|
+
tenantId,
|
|
7365
|
+
id,
|
|
7366
|
+
expectedStatuses,
|
|
7367
|
+
new Date(expectedUpdatedAt).toISOString(),
|
|
7368
|
+
parentId,
|
|
7369
|
+
new Date(expectedParentUpdatedAt).toISOString()
|
|
7370
|
+
);
|
|
7371
|
+
const result = await this.pool.query(
|
|
7372
|
+
`UPDATE lattice_tasks AS child SET ${setClauses.join(", ")}
|
|
7373
|
+
WHERE child.tenant_id = $${tenantParam} AND child.id = $${idParam}
|
|
7374
|
+
AND child.status = ANY($${statusesParam}::text[])
|
|
7375
|
+
AND ${canonicalTimestampSnapshotSql("child.updated_at", `$${updatedAtParam}`)}
|
|
7376
|
+
AND EXISTS (
|
|
7377
|
+
SELECT 1 FROM lattice_tasks AS parent
|
|
7378
|
+
WHERE parent.tenant_id = child.tenant_id
|
|
7379
|
+
AND parent.id = $${parentIdParam}
|
|
7380
|
+
AND ${canonicalTimestampSnapshotSql("parent.updated_at", `$${parentUpdatedAtParam}`, true)}
|
|
7381
|
+
)
|
|
7382
|
+
RETURNING child.*`,
|
|
7383
|
+
params
|
|
7384
|
+
);
|
|
7385
|
+
return result.rows[0] ? mapRowToTask(result.rows[0]) : null;
|
|
6894
7386
|
}
|
|
6895
7387
|
async delete(tenantId, id) {
|
|
6896
7388
|
await this.ensureInitialized();
|
|
@@ -6941,6 +7433,41 @@ var PostgreSQLTaskWorkItemStore = class {
|
|
|
6941
7433
|
);
|
|
6942
7434
|
return this.rowToItem(result.rows[0]);
|
|
6943
7435
|
}
|
|
7436
|
+
/** Find an event by its tenant- and task-scoped key without pagination. */
|
|
7437
|
+
async findByEventKey(tenantId, taskId, eventKey) {
|
|
7438
|
+
const result = await this.pool.query(
|
|
7439
|
+
`SELECT * FROM lattice_task_work_items
|
|
7440
|
+
WHERE tenant_id = $1 AND task_id = $2 AND event_key = $3`,
|
|
7441
|
+
[tenantId, taskId, eventKey]
|
|
7442
|
+
);
|
|
7443
|
+
return result.rows[0] ? this.rowToItem(result.rows[0]) : null;
|
|
7444
|
+
}
|
|
7445
|
+
/** Atomically return an existing event or create it once. */
|
|
7446
|
+
async createIfAbsentByEventKey(params) {
|
|
7447
|
+
const result = await this.pool.query(
|
|
7448
|
+
`INSERT INTO lattice_task_work_items
|
|
7449
|
+
(id, tenant_id, task_id, action, actor, thread_id, summary, detail, attempt, workspace_id, project_id, event_key)
|
|
7450
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
|
7451
|
+
ON CONFLICT (tenant_id, task_id, event_key) WHERE event_key IS NOT NULL
|
|
7452
|
+
DO UPDATE SET event_key = EXCLUDED.event_key
|
|
7453
|
+
RETURNING *`,
|
|
7454
|
+
[
|
|
7455
|
+
v4(),
|
|
7456
|
+
params.tenantId,
|
|
7457
|
+
params.taskId,
|
|
7458
|
+
params.action,
|
|
7459
|
+
params.actor,
|
|
7460
|
+
params.threadId || null,
|
|
7461
|
+
params.summary || null,
|
|
7462
|
+
params.detail ? JSON.stringify(params.detail) : null,
|
|
7463
|
+
params.attempt ?? null,
|
|
7464
|
+
params.workspaceId || null,
|
|
7465
|
+
params.projectId || null,
|
|
7466
|
+
params.eventKey
|
|
7467
|
+
]
|
|
7468
|
+
);
|
|
7469
|
+
return this.rowToItem(result.rows[0]);
|
|
7470
|
+
}
|
|
6944
7471
|
async list(filter) {
|
|
6945
7472
|
let query = `SELECT * FROM lattice_task_work_items WHERE tenant_id = $1 AND task_id = $2`;
|
|
6946
7473
|
const params = [filter.tenantId, filter.taskId];
|
|
@@ -6948,7 +7475,16 @@ var PostgreSQLTaskWorkItemStore = class {
|
|
|
6948
7475
|
query += ` AND action = $${params.length + 1}`;
|
|
6949
7476
|
params.push(filter.action);
|
|
6950
7477
|
}
|
|
6951
|
-
|
|
7478
|
+
if (filter.workspaceId) {
|
|
7479
|
+
query += ` AND workspace_id = $${params.length + 1}`;
|
|
7480
|
+
params.push(filter.workspaceId);
|
|
7481
|
+
}
|
|
7482
|
+
if (filter.projectId) {
|
|
7483
|
+
query += ` AND project_id = $${params.length + 1}`;
|
|
7484
|
+
params.push(filter.projectId);
|
|
7485
|
+
}
|
|
7486
|
+
const order = filter.order === "desc" ? "DESC" : "ASC";
|
|
7487
|
+
query += ` ORDER BY created_at ${order}, id ${order}`;
|
|
6952
7488
|
if (filter.limit) {
|
|
6953
7489
|
query += ` LIMIT $${params.length + 1}`;
|
|
6954
7490
|
params.push(filter.limit);
|
|
@@ -6973,6 +7509,7 @@ var PostgreSQLTaskWorkItemStore = class {
|
|
|
6973
7509
|
attempt: row.attempt,
|
|
6974
7510
|
workspaceId: row.workspace_id,
|
|
6975
7511
|
projectId: row.project_id,
|
|
7512
|
+
eventKey: row.event_key == null ? void 0 : row.event_key,
|
|
6976
7513
|
createdAt: new Date(row.created_at)
|
|
6977
7514
|
};
|
|
6978
7515
|
}
|
|
@@ -7972,6 +8509,20 @@ var addWorkItemProjectFieldsMigration = {
|
|
|
7972
8509
|
`);
|
|
7973
8510
|
}
|
|
7974
8511
|
};
|
|
8512
|
+
var addTaskWorkItemEventKeyMigration = {
|
|
8513
|
+
version: 168,
|
|
8514
|
+
name: "add_task_work_item_event_key",
|
|
8515
|
+
up: async (client) => {
|
|
8516
|
+
await client.query(`
|
|
8517
|
+
ALTER TABLE lattice_task_work_items
|
|
8518
|
+
ADD COLUMN IF NOT EXISTS event_key TEXT
|
|
8519
|
+
`);
|
|
8520
|
+
await client.query(`
|
|
8521
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_task_work_items_event_key
|
|
8522
|
+
ON lattice_task_work_items (tenant_id, task_id, event_key) WHERE event_key IS NOT NULL
|
|
8523
|
+
`);
|
|
8524
|
+
}
|
|
8525
|
+
};
|
|
7975
8526
|
|
|
7976
8527
|
// src/createPgStoreConfig.ts
|
|
7977
8528
|
async function createPgStoreConfig(connectionString) {
|
|
@@ -8026,6 +8577,9 @@ async function createPgStoreConfig(connectionString) {
|
|
|
8026
8577
|
mm.register(addWorkItemProjectFieldsMigration);
|
|
8027
8578
|
mm.register(createConnectionConfigsTable);
|
|
8028
8579
|
mm.register(addWorkflowRunsTenantStatusUpdatedIndex);
|
|
8580
|
+
mm.register(addProjectKindColumn);
|
|
8581
|
+
mm.register(addA2AKeyAssistantIds);
|
|
8582
|
+
mm.register(addTaskWorkItemEventKeyMigration);
|
|
8029
8583
|
await mm.migrate();
|
|
8030
8584
|
const checkpoint = PostgresSaver.fromConnString(connectionString);
|
|
8031
8585
|
checkpoint.setup().catch((err) => {
|