Skip to main content

canic_backup/restore/plan/
mod.rs

1//! Module: restore::plan
2//!
3//! Responsibility: build no-mutation restore plans from backup manifests.
4//! Does not own: artifact verification, command rendering, or restore execution.
5//! Boundary: maps manifest members and optional target mappings into ordered restore plans.
6
7mod error;
8mod mapping;
9mod members;
10mod ordering;
11mod summary;
12mod types;
13mod validation;
14
15pub use error::RestorePlanError;
16pub use types::*;
17
18use crate::manifest::DeploymentBackupManifest;
19
20use mapping::{validate_mapping, validate_mapping_sources};
21use members::resolve_members;
22use ordering::{order_members, restore_ordering_summary};
23use summary::{
24    restore_identity_summary, restore_operation_summary, restore_readiness_summary,
25    restore_snapshot_summary, restore_verification_summary,
26};
27
28///
29/// RestorePlanner
30///
31/// Stateless planner for restore dry-run and apply workflows.
32/// Owned by restore planning and used by restore apply and runner callers.
33///
34
35pub struct RestorePlanner;
36
37impl RestorePlanner {
38    /// Build a no-mutation restore plan from the manifest and optional target mapping.
39    pub fn plan(
40        manifest: &DeploymentBackupManifest,
41        mapping: Option<&RestoreMapping>,
42    ) -> Result<RestorePlan, RestorePlanError> {
43        manifest.validate()?;
44        if let Some(mapping) = mapping {
45            validate_mapping(mapping)?;
46            validate_mapping_sources(manifest, mapping)?;
47        }
48
49        let members = resolve_members(manifest, mapping)?;
50        let identity_summary = restore_identity_summary(&members, mapping.is_some());
51        let snapshot_summary = restore_snapshot_summary(&members);
52        let verification_summary =
53            restore_verification_summary(&manifest.verification.deployment_checks, &members);
54        let readiness_summary = restore_readiness_summary(&snapshot_summary, &verification_summary);
55        let members = order_members(members)?;
56        let ordering_summary = restore_ordering_summary(&members);
57        let operation_summary =
58            restore_operation_summary(manifest.deployment.members.len(), &verification_summary);
59
60        let plan = RestorePlan {
61            plan_version: 1,
62            backup_id: manifest.backup_id.clone(),
63            source_environment: manifest.source.environment.clone(),
64            source_root_canister: manifest.source.root_canister.clone(),
65            topology_hash: manifest.deployment.topology_hash.clone(),
66            member_count: manifest.deployment.members.len(),
67            identity_summary,
68            snapshot_summary,
69            verification_summary,
70            readiness_summary,
71            operation_summary,
72            ordering_summary,
73            deployment_verification_checks: manifest.verification.deployment_checks.clone(),
74            members,
75        };
76        plan.validate()?;
77        Ok(plan)
78    }
79}