fix(database): close canonical restore review gaps

This commit is contained in:
SaladDay
2026-08-01 14:12:08 +00:00
parent 9a87512224
commit 89961dff28
4 changed files with 902 additions and 91 deletions
File diff suppressed because it is too large Load Diff
+28 -1
View File
@@ -100,6 +100,23 @@ pub(crate) fn validate_provider_storage_json(
if let Some(source) = meta.pricing_model_source.as_deref() {
super::proxy::validate_pricing_source(source)?;
}
for (field, value) in [
("limitDailyUsd", meta.limit_daily_usd.as_deref()),
("limitMonthlyUsd", meta.limit_monthly_usd.as_deref()),
] {
if let Some(value) = value {
let parsed = value.parse::<rust_decimal::Decimal>().map_err(|error| {
AppError::InvalidInput(format!(
"invalid provider meta {field} for '{app_type}/{provider_id}': {error}"
))
})?;
if parsed < rust_decimal::Decimal::ZERO {
return Err(AppError::InvalidInput(format!(
"negative provider meta {field} for '{app_type}/{provider_id}'"
)));
}
}
}
Ok(())
}
@@ -495,7 +512,17 @@ impl Database {
|row| row.get(0),
)
.map_err(|e| AppError::Database(e.to_string()))?;
Ok(max.map(|v| (v + 1) as usize).unwrap_or(0))
match max {
Some(value) => value
.checked_add(1)
.and_then(|next| usize::try_from(next).ok())
.ok_or_else(|| {
AppError::InvalidInput(format!(
"provider sort_index cannot advance past {value}"
))
}),
None => Ok(0),
}
}
/// 启动时调用:补齐缺失的官方预设供应商(Claude / Codex / Gemini)。
+22 -3
View File
@@ -25,9 +25,8 @@ impl Database {
.map_err(|e| AppError::Database(e.to_string()))?;
if let Some(row) = rows.next().map_err(|e| AppError::Database(e.to_string()))? {
Ok(Some(
row.get(0).map_err(|e| AppError::Database(e.to_string()))?,
))
row.get::<_, Option<String>>(0)
.map_err(|e| AppError::Database(e.to_string()))
} else {
Ok(None)
}
@@ -325,3 +324,23 @@ impl Database {
self.set_setting("log_config", &json)
}
}
#[cfg(test)]
mod tests {
use crate::database::{lock_conn, Database};
use crate::error::AppError;
#[test]
fn null_setting_value_hydrates_as_absent() -> Result<(), crate::error::AppError> {
let database = Database::memory()?;
{
let conn = lock_conn!(database.conn);
conn.execute(
"INSERT INTO settings (key, value) VALUES ('nullable-setting', NULL)",
[],
)?;
}
assert_eq!(database.get_setting("nullable-setting")?, None);
Ok(())
}
}