Skip to main content

systemprompt_cli/commands/web/validate/
sitemap_validation.rs

1//! Sitemap validation for `web validate`.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use std::fs;
7
8use systemprompt_models::content_config::ContentConfigRaw;
9
10use super::super::types::ValidationIssue;
11
12pub fn validate_sitemap(
13    profile: &systemprompt_models::Profile,
14    errors: &mut Vec<ValidationIssue>,
15    warnings: &mut Vec<ValidationIssue>,
16) {
17    let content_config_path = profile.paths.content_config();
18
19    let Ok(content) = fs::read_to_string(&content_config_path) else {
20        return;
21    };
22
23    let Ok(content_config) = serde_yaml::from_str::<ContentConfigRaw>(&content) else {
24        return;
25    };
26
27    let valid_changefreq = [
28        "always", "hourly", "daily", "weekly", "monthly", "yearly", "never",
29    ];
30
31    for (name, source) in &content_config.content_sources {
32        if let Some(sitemap) = &source.sitemap {
33            if sitemap.priority < 0.0 || sitemap.priority > 1.0 {
34                errors.push(ValidationIssue {
35                    source: "sitemap".to_owned(),
36                    message: format!(
37                        "Invalid priority {} for '{}' (must be 0.0-1.0)",
38                        sitemap.priority, name
39                    ),
40                    suggestion: None,
41                });
42            }
43
44            if !valid_changefreq.contains(&sitemap.changefreq.as_str()) {
45                warnings.push(ValidationIssue {
46                    source: "sitemap".to_owned(),
47                    message: format!(
48                        "Invalid changefreq '{}' for '{}' (should be one of: {:?})",
49                        sitemap.changefreq, name, valid_changefreq
50                    ),
51                    suggestion: None,
52                });
53            }
54
55            if !sitemap.url_pattern.starts_with('/') {
56                warnings.push(ValidationIssue {
57                    source: "sitemap".to_owned(),
58                    message: format!("URL pattern for '{}' should start with '/'", name),
59                    suggestion: Some(format!("Change to /{}", sitemap.url_pattern)),
60                });
61            }
62
63            if let Some(parent) = &sitemap.parent_route {
64                if parent.priority < 0.0 || parent.priority > 1.0 {
65                    errors.push(ValidationIssue {
66                        source: "sitemap".to_owned(),
67                        message: format!(
68                            "Invalid parent route priority {} for '{}'",
69                            parent.priority, name
70                        ),
71                        suggestion: None,
72                    });
73                }
74
75                if !valid_changefreq.contains(&parent.changefreq.as_str()) {
76                    warnings.push(ValidationIssue {
77                        source: "sitemap".to_owned(),
78                        message: format!(
79                            "Invalid parent route changefreq '{}' for '{}'",
80                            parent.changefreq, name
81                        ),
82                        suggestion: None,
83                    });
84                }
85            }
86        }
87    }
88}