//! Per-user saved terminal tab layout for an agent (named tabs + their tmux //! sessions), so a user can restore their terminal after logging back in. use cm_domain::{AgentId, UserId, WorkspaceId}; use sqlx::{PgPool, Row}; use crate::DbError; /// The saved layout JSON for `(user, agent)`, or None if nothing saved. pub async fn get( pool: &PgPool, user_id: UserId, agent_id: AgentId, ) -> Result, DbError> { let row = sqlx::query("SELECT layout FROM terminal_tabs WHERE user_id = $1 AND agent_id = $2") .bind(user_id.as_uuid()) .bind(agent_id.as_uuid()) .fetch_optional(pool) .await?; Ok(row.map(|r| r.get::("layout"))) } /// Save (replace) the layout for `(user, agent)`. pub async fn upsert( pool: &PgPool, workspace_id: WorkspaceId, user_id: UserId, agent_id: AgentId, layout: &serde_json::Value, ) -> Result<(), DbError> { sqlx::query( "INSERT INTO terminal_tabs (user_id, agent_id, workspace_id, layout, updated_at) VALUES ($1, $2, $3, $4, now()) ON CONFLICT (user_id, agent_id) DO UPDATE SET layout = $4, workspace_id = $3, updated_at = now()", ) .bind(user_id.as_uuid()) .bind(agent_id.as_uuid()) .bind(workspace_id.as_uuid()) .bind(layout) .execute(pool) .await?; Ok(()) }