feat(web): settings view for roots and policies

Own route beside library and queues. Roots edit kind, audience, path
and their policy; policies get a form over the real fields — size
bands as number inputs, score and source weights as numbers,
resolution preference and audio/HDR rules as validated lists. Delete
arms before firing; a 409 from a referenced policy or occupied root
surfaces its message.
This commit is contained in:
Miguel Palhas
2026-08-23 15:14:34 +01:00
parent 9fa1f0cc51
commit 71c2741d08
6 changed files with 891 additions and 10 deletions
+9 -9
View File
@@ -141,7 +141,7 @@ impl PolicyInput {
Ok(())
}
fn to_row(self, name: String) -> Result<PolicyColumns, ApiError> {
fn into_columns(self, name: String) -> Result<PolicyColumns, ApiError> {
fn json(value: impl serde::Serialize) -> Result<String, ApiError> {
serde_json::to_string(&value).map_err(|error| {
tracing::error!(%error, "policy serialisation failed");
@@ -151,12 +151,12 @@ impl PolicyInput {
Ok(PolicyColumns {
name,
required_audio: json(&self.required_audio)?,
dub_blacklist: json(&self.dub_blacklist)?,
hdr_rules: json(&self.hdr_rules)?,
size_bands: json(&self.size_bands)?,
resolution_pref: json(&self.resolution_pref)?,
source_weights: json(&self.source_weights)?,
score_weights: json(&self.score_weights)?,
dub_blacklist: json(self.dub_blacklist)?,
hdr_rules: json(self.hdr_rules)?,
size_bands: json(self.size_bands)?,
resolution_pref: json(self.resolution_pref)?,
source_weights: json(self.source_weights)?,
score_weights: json(self.score_weights)?,
})
}
}
@@ -327,7 +327,7 @@ pub async fn create(
let input = parsed(body)?;
input.validate().map_err(ApiError::Invalid)?;
let name = input.name.trim().to_owned();
let columns = input.to_row(name)?;
let columns = input.into_columns(name)?;
let result = sqlx::query!(
r#"INSERT INTO policies (
name, required_audio, dub_blacklist, hdr_rules,
@@ -375,7 +375,7 @@ pub async fn update(
let input = parsed(body)?;
input.validate().map_err(ApiError::Invalid)?;
let name = input.name.trim().to_owned();
let columns = input.to_row(name)?;
let columns = input.into_columns(name)?;
let result = sqlx::query!(
r#"UPDATE policies SET
name = ?, required_audio = ?, dub_blacklist = ?, hdr_rules = ?,