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