use crate::prelude::*;
use crate::scheduler::CronSchedule;
use crate::settings::{
PermissionLevel, SettingDefinition, SettingScope, SettingValue, SettingsRegistry,
};
pub fn cron_validator(v: &SettingValue) -> ClResult<()> {
let SettingValue::String(s) = v else {
return Err(Error::ValidationError("Cron expression must be a string".into()));
};
CronSchedule::parse(s).map(|_| ())
}
pub fn register_settings(registry: &mut SettingsRegistry) -> ClResult<()> {
registry.register(
SettingDefinition::builder("server.registration_enabled")
.description("Allow new user registrations")
.default(SettingValue::Bool(true))
.scope(SettingScope::Global)
.permission(PermissionLevel::Admin)
.build()?,
)?;
registry.register(
SettingDefinition::builder("core.db_maintenance_cron")
.description(
"Cron expression for the nightly database maintenance schedule (5-field: \
'minute hour day month weekday')",
)
.default(SettingValue::String("20 4 * * *".into()))
.scope(SettingScope::Global)
.permission(PermissionLevel::Admin)
.validator(cron_validator)
.build()?,
)?;
registry.register(
SettingDefinition::builder("core.vacuum_min_free_pct")
.description(
"Percentage of the metadata database's pages that must be free before the \
nightly maintenance rewrites it to return the space to the filesystem. The \
rewrite blocks every other writer while it runs, so a low value trades \
availability for disk.",
)
.default(SettingValue::Int(20))
.scope(SettingScope::Global)
.permission(PermissionLevel::Admin)
.validator(|v| match v {
SettingValue::Int(n) if (0..=100).contains(n) => Ok(()),
_ => Err(Error::ValidationError(
"Vacuum free-page threshold must be an integer percent between 0 and 100"
.into(),
)),
})
.build()?,
)?;
registry.register(
SettingDefinition::builder("ui.*")
.description("User interface settings and preferences")
.scope(SettingScope::Tenant)
.permission(PermissionLevel::User)
.optional(true)
.build()?,
)?;
registry.register(
SettingDefinition::builder("app.*")
.description("Application-specific settings and state")
.scope(SettingScope::Tenant)
.permission(PermissionLevel::User)
.optional(true)
.build()?,
)?;
Ok(())
}