cloudillo_core/
core_settings.rs1use crate::prelude::*;
9use crate::scheduler::CronSchedule;
10use crate::settings::{
11 PermissionLevel, SettingDefinition, SettingScope, SettingValue, SettingsRegistry,
12};
13
14pub fn cron_validator(v: &SettingValue) -> ClResult<()> {
23 let SettingValue::String(s) = v else {
24 return Err(Error::ValidationError("Cron expression must be a string".into()));
25 };
26 CronSchedule::parse(s).map(|_| ())
27}
28
29pub fn register_settings(registry: &mut SettingsRegistry) -> ClResult<()> {
31 registry.register(
33 SettingDefinition::builder("server.registration_enabled")
34 .description("Allow new user registrations")
35 .default(SettingValue::Bool(true))
36 .scope(SettingScope::Global)
37 .permission(PermissionLevel::Admin)
38 .build()?,
39 )?;
40
41 registry.register(
43 SettingDefinition::builder("core.db_maintenance_cron")
44 .description(
45 "Cron expression for the nightly database maintenance schedule (5-field: \
46 'minute hour day month weekday')",
47 )
48 .default(SettingValue::String("20 4 * * *".into()))
49 .scope(SettingScope::Global)
50 .permission(PermissionLevel::Admin)
51 .validator(cron_validator)
52 .build()?,
53 )?;
54 registry.register(
56 SettingDefinition::builder("core.vacuum_min_free_pct")
57 .description(
58 "Percentage of the metadata database's pages that must be free before the \
59 nightly maintenance rewrites it to return the space to the filesystem. The \
60 rewrite blocks every other writer while it runs, so a low value trades \
61 availability for disk.",
62 )
63 .default(SettingValue::Int(20))
64 .scope(SettingScope::Global)
65 .permission(PermissionLevel::Admin)
66 .validator(|v| match v {
70 SettingValue::Int(n) if (0..=100).contains(n) => Ok(()),
71 _ => Err(Error::ValidationError(
72 "Vacuum free-page threshold must be an integer percent between 0 and 100"
73 .into(),
74 )),
75 })
76 .build()?,
77 )?;
78
79 registry.register(
81 SettingDefinition::builder("ui.*")
82 .description("User interface settings and preferences")
83 .scope(SettingScope::Tenant)
84 .permission(PermissionLevel::User)
85 .optional(true)
86 .build()?,
87 )?;
88
89 registry.register(
91 SettingDefinition::builder("app.*")
92 .description("Application-specific settings and state")
93 .scope(SettingScope::Tenant)
94 .permission(PermissionLevel::User)
95 .optional(true)
96 .build()?,
97 )?;
98
99 Ok(())
100}
101
102