This commit is contained in:
@@ -75,6 +75,12 @@ CREATE TABLE IF NOT EXISTS workspace_buzz_channels (
|
||||
channel_name TEXT NOT NULL,
|
||||
PRIMARY KEY (workspace_id, account_id, channel_id)
|
||||
) STRICT;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workspace_snapshots (
|
||||
workspace_id TEXT PRIMARY KEY NOT NULL,
|
||||
snapshot_json TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) STRICT;
|
||||
";
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -222,6 +228,44 @@ impl Store {
|
||||
.transpose()
|
||||
}
|
||||
|
||||
/// Save a credential-free UI snapshot for a workspace.
|
||||
///
|
||||
/// The caller owns the versioned JSON shape. This storage boundary treats
|
||||
/// it as opaque local state and must never receive secrets or transcripts.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error when `SQLite` cannot insert or update the snapshot.
|
||||
pub fn save_workspace_snapshot(&self, workspace_id: &str, snapshot_json: &str) -> Result<()> {
|
||||
self.connection.execute(
|
||||
r"
|
||||
INSERT INTO workspace_snapshots (workspace_id, snapshot_json)
|
||||
VALUES (?1, ?2)
|
||||
ON CONFLICT(workspace_id) DO UPDATE SET
|
||||
snapshot_json = excluded.snapshot_json,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
",
|
||||
params![workspace_id, snapshot_json],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Load the last credential-free UI snapshot for a workspace.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error when `SQLite` cannot read the snapshot.
|
||||
pub fn workspace_snapshot(&self, workspace_id: &str) -> Result<Option<String>> {
|
||||
self.connection
|
||||
.query_row(
|
||||
"SELECT snapshot_json FROM workspace_snapshots WHERE workspace_id = ?1",
|
||||
[workspace_id],
|
||||
|row| row.get(0),
|
||||
)
|
||||
.optional()
|
||||
.map_err(StorageError::from)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn contains_column(&self, table: &str, column: &str) -> Result<bool> {
|
||||
let mut statement = self
|
||||
@@ -281,4 +325,23 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_snapshot_round_trips_as_opaque_local_state() {
|
||||
let store = Store::open_in_memory().expect("store should initialize");
|
||||
assert_eq!(store.workspace_snapshot("lumbridge-code").unwrap(), None);
|
||||
store
|
||||
.save_workspace_snapshot(
|
||||
"lumbridge-code",
|
||||
r#"{"selected":7,"panels":[{"id":7,"kind":"terminal"}]}"#,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
store
|
||||
.workspace_snapshot("lumbridge-code")
|
||||
.unwrap()
|
||||
.as_deref(),
|
||||
Some(r#"{"selected":7,"panels":[{"id":7,"kind":"terminal"}]}"#)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user