/** * TerminalSessionService * * Manages database persistence for terminal sessions. * Provides CRUD operations on the TerminalSession model, * enabling session tracking, recovery, and workspace-level listing. * * Session lifecycle: * - create: record a new terminal session with ACTIVE status * - findByWorkspace: return all ACTIVE sessions for a workspace * - close: mark a session as CLOSED, set closedAt timestamp * - findById: retrieve a single session by ID */ import { Injectable, NotFoundException, Logger } from "@nestjs/common"; import { TerminalSessionStatus } from "@prisma/client"; import type { TerminalSession } from "@prisma/client"; import { PrismaService } from "../prisma/prisma.service"; @Injectable() export class TerminalSessionService { private readonly logger = new Logger(TerminalSessionService.name); constructor(private readonly prisma: PrismaService) {} /** * Create a new terminal session record in the database. * * @param workspaceId - The workspace this session belongs to * @param name - Optional display name for the session (defaults to "Terminal") * @returns The created TerminalSession record */ async create(workspaceId: string, name?: string): Promise { this.logger.log( `Creating terminal session for workspace ${workspaceId}${name !== undefined ? ` (name: ${name})` : ""}` ); const data: { workspaceId: string; name?: string } = { workspaceId }; if (name !== undefined) { data.name = name; } return this.prisma.terminalSession.create({ data }); } /** * Find all ACTIVE terminal sessions for a workspace. * * @param workspaceId - The workspace to query * @returns Array of active TerminalSession records, ordered by creation time (newest first) */ async findByWorkspace(workspaceId: string): Promise { return this.prisma.terminalSession.findMany({ where: { workspaceId, status: TerminalSessionStatus.ACTIVE, }, orderBy: { createdAt: "desc" }, }); } /** * Close a terminal session by setting its status to CLOSED and recording closedAt. * * @param id - The session ID to close * @returns The updated TerminalSession record * @throws NotFoundException if the session does not exist */ async close(id: string): Promise { const existing = await this.prisma.terminalSession.findUnique({ where: { id } }); if (!existing) { throw new NotFoundException(`Terminal session ${id} not found`); } this.logger.log(`Closing terminal session ${id} (workspace: ${existing.workspaceId})`); return this.prisma.terminalSession.update({ where: { id }, data: { status: TerminalSessionStatus.CLOSED, closedAt: new Date(), }, }); } /** * Find a terminal session by ID. * * @param id - The session ID to retrieve * @returns The TerminalSession record, or null if not found */ async findById(id: string): Promise { return this.prisma.terminalSession.findUnique({ where: { id } }); } }