This commit is contained in:
Mateusz Gruszczyński committed 2026-10-16 13:02:53 +02:00
1 parent 162e986d37
commit 6b937aaf85
54 files changed
+3527 -1325

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
//! SQLite persistence for user-named Overview snapshots (control plane only).
use super::Store;
use anyhow::{ensure, Result};
use sqlx::Row;
impl Store {
pub async fn list_admin_dashboard_presets(
&self,
username: &str,
) -> Result<Vec<(String, String)>> {
let rows = sqlx::query(
"SELECT p.name, p.document FROM dashboard_presets p \
JOIN administrator a ON a.id = p.administrator_id \
WHERE a.id = 1 AND a.username = ? ORDER BY p.name COLLATE NOCASE",
)
.bind(username)
.fetch_all(&self.pool)
.await?;
rows.iter()
.map(|row| Ok((row.try_get("name")?, row.try_get("document")?)))
.collect()
}
pub async fn save_admin_dashboard_preset(
&self,
username: &str,
name: &str,
document: &str,
) -> Result<bool> {
ensure!(
document.len() >= 2 && document.len() <= 8192,
"invalid dashboard preset size"
);
// Limit to 16 user-named presets. The cap and upsert are checked in one
// SQLite statement, including under concurrent requests.
let result = sqlx::query(
"INSERT INTO dashboard_presets(administrator_id, name, document, updated_at) \
SELECT a.id, ?, ?, ? FROM administrator a WHERE a.id = 1 AND a.username = ? \
AND ((SELECT count(*) FROM dashboard_presets WHERE administrator_id = a.id) < 16 \
OR EXISTS(SELECT 1 FROM dashboard_presets WHERE administrator_id = a.id AND name = ?)) \
ON CONFLICT(administrator_id, name) DO UPDATE SET \
document = excluded.document, updated_at = excluded.updated_at",
)
.bind(name).bind(document).bind(crate::auth::now())
.bind(username).bind(name)
.execute(&self.pool).await?;
Ok(result.rows_affected() == 1)
}
pub async fn delete_admin_dashboard_preset(&self, username: &str, name: &str) -> Result<bool> {
let result = sqlx::query(
"DELETE FROM dashboard_presets WHERE administrator_id = \
(SELECT id FROM administrator WHERE id = 1 AND username = ?) AND name = ?",
)
.bind(username)
.bind(name)
.execute(&self.pool)
.await?;
Ok(result.rows_affected() == 1)
}
pub async fn rename_admin_dashboard_preset(
&self,
username: &str,
old: &str,
new: &str,
) -> Result<bool> {
// UPDATE OR IGNORE ensures an existing target name is never overwritten.
let result = sqlx::query(
"UPDATE OR IGNORE dashboard_presets SET name = ?, updated_at = ? \
WHERE administrator_id = (SELECT id FROM administrator WHERE id = 1 AND username = ?) \
AND name = ? AND name <> ?",
)
.bind(new)
.bind(crate::auth::now())
.bind(username)
.bind(old)
.bind(new)
.execute(&self.pool)
.await?;
Ok(result.rows_affected() == 1)
}
}