import { CheckpointRef, EventId, MessageId, ProjectId, ThreadId, TurnId } from "@t3tools/contracts"; import { assert, it } from "@effect/vitest"; import { Effect, Layer } from "effect"; import * as SqlClient from "effect/unstable/sql/SqlClient"; import { SqlitePersistenceMemory } from "../../persistence/Layers/Sqlite.ts"; import { ORCHESTRATION_PROJECTOR_NAMES } from "./ProjectionPipeline.ts"; import { OrchestrationProjectionSnapshotQueryLive } from "./ProjectionSnapshotQuery.ts"; import { ProjectionSnapshotQuery } from "../Services/ProjectionSnapshotQuery.ts"; const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value); const asTurnId = (value: string): TurnId => TurnId.makeUnsafe(value); const asMessageId = (value: string): MessageId => MessageId.makeUnsafe(value); const asEventId = (value: string): EventId => EventId.makeUnsafe(value); const asCheckpointRef = (value: string): CheckpointRef => CheckpointRef.makeUnsafe(value); const projectionSnapshotLayer = it.layer( OrchestrationProjectionSnapshotQueryLive.pipe(Layer.provideMerge(SqlitePersistenceMemory)), ); projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { it.effect("hydrates read model from projection tables and computes snapshot sequence", () => Effect.gen(function* () { const snapshotQuery = yield* ProjectionSnapshotQuery; const sql = yield* SqlClient.SqlClient; yield* sql`DELETE FROM projection_projects`; yield* sql`DELETE FROM projection_state`; yield* sql`DELETE FROM projection_thread_proposed_plans`; yield* sql`DELETE FROM projection_turns`; yield* sql` INSERT INTO projection_projects ( project_id, title, workspace_root, default_model, scripts_json, created_at, updated_at, deleted_at ) VALUES ( 'project-1', 'Project 1', '/tmp/project-1', 'gpt-5-codex', '[{"id":"script-1","name":"Build","command":"bun run build","icon":"build","runOnWorktreeCreate":false}]', '2026-02-24T00:00:00.000Z', '2026-02-24T00:00:01.000Z', NULL ) `; yield* sql` INSERT INTO projection_threads ( thread_id, project_id, title, model, branch, worktree_path, latest_turn_id, created_at, updated_at, deleted_at ) VALUES ( 'thread-1', 'project-1', 'Thread 1', 'gpt-5-codex', NULL, NULL, 'turn-1', '2026-02-24T00:00:02.000Z', '2026-02-24T00:00:03.000Z', NULL ) `; yield* sql` INSERT INTO projection_thread_messages ( message_id, thread_id, turn_id, role, text, is_streaming, created_at, updated_at ) VALUES ( 'message-1', 'thread-1', 'turn-1', 'assistant', 'hello from projection', 0, '2026-02-24T00:00:04.000Z', '2026-02-24T00:00:05.000Z' ) `; yield* sql` INSERT INTO projection_thread_proposed_plans ( plan_id, thread_id, turn_id, plan_markdown, implemented_at, implementation_thread_id, created_at, updated_at ) VALUES ( 'plan-1', 'thread-1', 'turn-1', '# Ship it', '2026-02-24T00:00:05.500Z', 'thread-2', '2026-02-24T00:00:05.000Z', '2026-02-24T00:00:05.500Z' ) `; yield* sql` INSERT INTO projection_thread_activities ( activity_id, thread_id, turn_id, tone, kind, summary, payload_json, created_at ) VALUES ( 'activity-1', 'thread-1', 'turn-1', 'info', 'runtime.note', 'provider started', '{"stage":"start"}', '2026-02-24T00:00:06.000Z' ) `; yield* sql` INSERT INTO projection_thread_sessions ( thread_id, status, provider_name, provider_session_id, provider_thread_id, runtime_mode, active_turn_id, last_error, updated_at ) VALUES ( 'thread-1', 'running', 'codex', 'provider-session-1', 'provider-thread-1', 'approval-required', 'turn-1', NULL, '2026-02-24T00:00:07.000Z' ) `; yield* sql` INSERT INTO projection_turns ( thread_id, turn_id, pending_message_id, source_proposed_plan_thread_id, source_proposed_plan_id, assistant_message_id, state, requested_at, started_at, completed_at, checkpoint_turn_count, checkpoint_ref, checkpoint_status, checkpoint_files_json ) VALUES ( 'thread-1', 'turn-1', NULL, 'thread-1', 'plan-1', 'message-1', 'completed', '2026-02-24T00:00:08.000Z', '2026-02-24T00:00:08.000Z', '2026-02-24T00:00:08.000Z', 1, 'checkpoint-1', 'ready', '[{"path":"README.md","kind":"modified","additions":2,"deletions":1}]' ) `; let sequence = 5; for (const projector of Object.values(ORCHESTRATION_PROJECTOR_NAMES)) { yield* sql` INSERT INTO projection_state ( projector, last_applied_sequence, updated_at ) VALUES ( ${projector}, ${sequence}, '2026-02-24T00:00:09.000Z' ) `; sequence += 1; } const snapshot = yield* snapshotQuery.getSnapshot(); assert.equal(snapshot.snapshotSequence, 5); assert.equal(snapshot.updatedAt, "2026-02-24T00:00:09.000Z"); assert.deepEqual(snapshot.projects, [ { id: asProjectId("project-1"), title: "Project 1", workspaceRoot: "/tmp/project-1", defaultModel: "gpt-5-codex", scripts: [ { id: "script-1", name: "Build", command: "bun run build", icon: "build", runOnWorktreeCreate: false, }, ], createdAt: "2026-02-24T00:00:00.000Z", updatedAt: "2026-02-24T00:00:01.000Z", deletedAt: null, }, ]); assert.deepEqual(snapshot.threads, [ { id: ThreadId.makeUnsafe("thread-1"), projectId: asProjectId("project-1"), title: "Thread 1", model: "gpt-5-codex", interactionMode: "default", runtimeMode: "full-access", branch: null, worktreePath: null, latestTurn: { turnId: asTurnId("turn-1"), state: "completed", requestedAt: "2026-02-24T00:00:08.000Z", startedAt: "2026-02-24T00:00:08.000Z", completedAt: "2026-02-24T00:00:08.000Z", assistantMessageId: asMessageId("message-1"), sourceProposedPlan: { threadId: ThreadId.makeUnsafe("thread-1"), planId: "plan-1", }, }, createdAt: "2026-02-24T00:00:02.000Z", updatedAt: "2026-02-24T00:00:03.000Z", deletedAt: null, messages: [ { id: asMessageId("message-1"), role: "assistant", text: "hello from projection", turnId: asTurnId("turn-1"), streaming: false, createdAt: "2026-02-24T00:00:04.000Z", updatedAt: "2026-02-24T00:00:05.000Z", }, ], proposedPlans: [ { id: "plan-1", turnId: asTurnId("turn-1"), planMarkdown: "# Ship it", implementedAt: "2026-02-24T00:00:05.500Z", implementationThreadId: ThreadId.makeUnsafe("thread-2"), createdAt: "2026-02-24T00:00:05.000Z", updatedAt: "2026-02-24T00:00:05.500Z", }, ], activities: [ { id: asEventId("activity-1"), tone: "info", kind: "runtime.note", summary: "provider started", payload: { stage: "start" }, turnId: asTurnId("turn-1"), createdAt: "2026-02-24T00:00:06.000Z", }, ], checkpoints: [ { turnId: asTurnId("turn-1"), checkpointTurnCount: 1, checkpointRef: asCheckpointRef("checkpoint-1"), status: "ready", files: [{ path: "README.md", kind: "modified", additions: 2, deletions: 1 }], assistantMessageId: asMessageId("message-1"), completedAt: "2026-02-24T00:00:08.000Z", }, ], session: { threadId: ThreadId.makeUnsafe("thread-1"), status: "running", providerName: "codex", runtimeMode: "approval-required", activeTurnId: asTurnId("turn-1"), lastError: null, updatedAt: "2026-02-24T00:00:07.000Z", }, }, ]); }), ); });