systemprompt_database/lifecycle/migrations/
repair.rs1use super::{ChecksumDrift, MigrationService};
12use systemprompt_extension::{Extension, LoaderError};
13
14#[derive(Debug, Default, Clone)]
15pub struct RepairResult {
16 pub repaired: Vec<ChecksumDrift>,
17 pub migrations_run: usize,
18}
19
20impl MigrationService<'_> {
21 pub async fn repair_drift(
22 &self,
23 extension: &dyn Extension,
24 ) -> Result<RepairResult, LoaderError> {
25 let ext_id = extension.metadata().id;
26 let status = self.status(extension).await?;
27
28 if status.drift.is_empty() {
29 return Ok(RepairResult::default());
30 }
31
32 for drift in &status.drift {
33 self.db
34 .execute(
35 &"DELETE FROM extension_migrations WHERE extension_id = $1 AND version = $2",
36 &[&drift.extension_id, &drift.version],
37 )
38 .await
39 .map_err(|e| LoaderError::MigrationFailed {
40 extension: ext_id.to_string(),
41 message: format!(
42 "Failed to drop drifted migration record {} ('{}'): {e}",
43 drift.version, drift.name
44 ),
45 })?;
46 }
47
48 let result = self.run_pending_migrations(extension).await?;
49
50 Ok(RepairResult {
51 repaired: status.drift,
52 migrations_run: result.migrations_run,
53 })
54 }
55}