/** * ProjectionSnapshotQuery - Read-model snapshot query service interface. * * Exposes the current orchestration projection snapshot for read-only API * access. * * @module ProjectionSnapshotQuery */ import type { CheckpointRef, OrchestrationCheckpointSummary, OrchestrationProject, OrchestrationProjectShell, OrchestrationReadModel, OrchestrationShellSnapshot, OrchestrationThread, OrchestrationThreadDetailSnapshot, OrchestrationThreadShell, ProjectId, ThreadId, } from "@t3tools/contracts"; import * as Context from "effect/Context"; import type * as Option from "effect/Option"; import type * as Effect from "effect/Effect"; import type { ProjectionRepositoryError } from "../../persistence/Errors.ts"; export interface ProjectionSnapshotCounts { readonly projectCount: number; readonly threadCount: number; } export interface ProjectionSnapshotSequence { readonly snapshotSequence: number; } export interface ProjectionThreadCheckpointContext { readonly threadId: ThreadId; readonly projectId: ProjectId; readonly workspaceRoot: string; readonly worktreePath: string | null; readonly checkpoints: ReadonlyArray; } export interface ProjectionFullThreadDiffContext { readonly threadId: ThreadId; readonly projectId: ProjectId; readonly workspaceRoot: string; readonly worktreePath: string | null; readonly latestCheckpointTurnCount: number; readonly toCheckpointRef: CheckpointRef | null; } /** * ProjectionSnapshotQueryShape - Service API for read-model snapshots. */ export interface ProjectionSnapshotQueryShape { /** * Read the lightweight command snapshot used to bootstrap the in-memory * orchestration engine without hydrating message/activity/checkpoint bodies. */ readonly getCommandReadModel: () => Effect.Effect< OrchestrationReadModel, ProjectionRepositoryError >; /** * Read the latest orchestration projection snapshot. * * Rehydrates from projection tables and derives snapshot sequence from * projector cursor state. */ readonly getSnapshot: () => Effect.Effect; /** * Read the latest orchestration shell snapshot. * * Returns only projects and thread shell summaries so clients can bootstrap * lightweight navigation state without hydrating every thread body. */ readonly getShellSnapshot: () => Effect.Effect< OrchestrationShellSnapshot, ProjectionRepositoryError >; /** * Read archived thread shell summaries for the archive page. * * This query is separate from the main shell snapshot so archived threads * are never bootstrapped into normal navigation state. */ readonly getArchivedShellSnapshot: () => Effect.Effect< OrchestrationShellSnapshot, ProjectionRepositoryError >; /** * Read the latest projection snapshot sequence without hydrating read-model * entities. */ readonly getSnapshotSequence: () => Effect.Effect< ProjectionSnapshotSequence, ProjectionRepositoryError >; /** * Read aggregate projection counts without hydrating the full read model. */ readonly getCounts: () => Effect.Effect; /** * Read the active project for an exact workspace root match. */ readonly getActiveProjectByWorkspaceRoot: ( workspaceRoot: string, ) => Effect.Effect, ProjectionRepositoryError>; /** * Read a single active project shell row by id. */ readonly getProjectShellById: ( projectId: ProjectId, ) => Effect.Effect, ProjectionRepositoryError>; /** * Read the earliest active thread for a project. */ readonly getFirstActiveThreadIdByProjectId: ( projectId: ProjectId, ) => Effect.Effect, ProjectionRepositoryError>; /** * Read the checkpoint context needed to resolve a single thread diff. */ readonly getThreadCheckpointContext: ( threadId: ThreadId, ) => Effect.Effect, ProjectionRepositoryError>; /** * Read only the narrow context needed to compute a full-thread diff from * checkpoint 0 to a specific turn count. */ readonly getFullThreadDiffContext: ( threadId: ThreadId, toTurnCount: number, ) => Effect.Effect, ProjectionRepositoryError>; /** * Read a single active thread shell row by id. */ readonly getThreadShellById: ( threadId: ThreadId, ) => Effect.Effect, ProjectionRepositoryError>; /** * Read a single active thread detail snapshot by id. */ readonly getThreadDetailById: ( threadId: ThreadId, ) => Effect.Effect, ProjectionRepositoryError>; /** * Read a single active thread detail together with the projection snapshot * sequence in one consistent transaction, so the returned `snapshotSequence` * exactly matches the state reflected in `thread` (no interleaving projector * update between the two reads). */ readonly getThreadDetailSnapshot: ( threadId: ThreadId, ) => Effect.Effect, ProjectionRepositoryError>; } /** * ProjectionSnapshotQuery - Service tag for projection snapshot queries. */ export class ProjectionSnapshotQuery extends Context.Service< ProjectionSnapshotQuery, ProjectionSnapshotQueryShape >()("t3/orchestration/Services/ProjectionSnapshotQuery") {}