1import { assert, it } from "@effect/vitest";
2import * as Effect from "effect/Effect";
3import * as SqlClient from "effect/sql/SqlClient";
4import * as NodeSqliteClient from "@t3tools/shared/nodeSqliteClient";
5
6import { runMigrations } from "../Migrations.ts";
7import migrateAutoSettleDisabledAt from "./054_ProjectionThreadsAutoSettleDisabledAt.ts";
8
9it.layer(NodeSqliteClient.layer({ filename: ":memory:" }))(
10 "054_ProjectionThreadsAutoSettleDisabledAt",
11 (it) => {
12 it.effect("adds the column with auto-settle left on for existing threads", () =>
13 Effect.gen(function* () {
14 const sql = yield* SqlClient.SqlClient;
15 yield* runMigrations({ toMigrationInclusive: 53 });
16 const now = "2026-01-01T00:00:00.000Z";
17 yield* sql`
18 INSERT INTO projection_threads (
19 thread_id, project_id, title, model_selection_json, runtime_mode,
20 created_at, updated_at
21 ) VALUES (
22 'thread-1', 'project-1', 'Existing thread',
23 '{"instanceId":"codex","model":"gpt-5.4"}', 'full-access', ${now}, ${now}
24 )
25 `;
26 yield* runMigrations({ toMigrationInclusive: 54 });
27 const migrated = yield* sql<{ readonly autoSettleDisabledAt: string | null }>`
28 SELECT auto_settle_disabled_at AS "autoSettleDisabledAt" FROM projection_threads WHERE thread_id = 'thread-1'
29 `;
30 assert.deepEqual(migrated, [{ autoSettleDisabledAt: null }]);
31 // Re-running against a database that already has the column keeps its value.
32 yield* sql`UPDATE projection_threads SET auto_settle_disabled_at = ${now} WHERE thread_id = 'thread-1'`;
33 yield* migrateAutoSettleDisabledAt;
34 const rows = yield* sql<{ readonly autoSettleDisabledAt: string | null }>`
35 SELECT auto_settle_disabled_at AS "autoSettleDisabledAt" FROM projection_threads WHERE thread_id = 'thread-1'
36 `;
37 assert.deepEqual(rows, [{ autoSettleDisabledAt: now }]);
38 }),
39 );
40 },
41);