systemprompt_generator/jobs/
content_prerender.rs1use async_trait::async_trait;
7use std::sync::Arc;
8use systemprompt_database::DbPool;
9use systemprompt_models::AppPaths;
10use systemprompt_provider_contracts::{Job, JobContext, JobResult, ProviderError, ProviderResult};
11
12use crate::prerender::prerender_content;
13
14#[derive(Debug, Clone, Copy)]
15pub struct ContentPrerenderJob;
16
17#[async_trait]
18impl Job for ContentPrerenderJob {
19 fn name(&self) -> &'static str {
20 "content_prerender"
21 }
22
23 fn description(&self) -> &'static str {
24 "Prerenders all configured content sources to static HTML"
25 }
26
27 fn schedule(&self) -> &'static str {
28 "0 0 4 * * *"
29 }
30
31 async fn execute(&self, ctx: &JobContext) -> ProviderResult<JobResult> {
32 let start_time = std::time::Instant::now();
33 let db_pool = Arc::clone(ctx.db_pool::<DbPool>().ok_or_else(|| {
34 ProviderError::Configuration("DbPool not available in job context".into())
35 })?);
36 let paths = ctx
37 .app_paths::<Arc<AppPaths>>()
38 .ok_or_else(|| {
39 ProviderError::Configuration("AppPaths not available in job context".into())
40 })?
41 .as_ref();
42
43 tracing::info!("Job started");
44 prerender_content(db_pool, paths)
45 .await
46 .map_err(|e| ProviderError::RenderFailed(e.to_string()))?;
47 let duration_ms = start_time.elapsed().as_millis() as u64;
48 tracing::info!(duration_ms = duration_ms, "Job completed");
49
50 Ok(JobResult::success().with_duration(duration_ms))
51 }
52}
53
54systemprompt_provider_contracts::submit_job!(&ContentPrerenderJob);