rustploy 0.1.14

Rustploy PaaS daemon — lightweight self-hosted deployment platform
//! `Command::ManifestExport`: exporta um projeto como manifesto IaC (secrets
//! como `secret:NOME`).

use crate::features::iac::IacContext;
use crate::features::iac::manifest::ProjectManifest;
use shared::Response as RpResponse;
use std::collections::BTreeMap;
use tracing::info;

/// Exporta o estado atual de um projeto como manifesto declarativo.
/// Secrets aparecem como `secret:NOME` (nunca o valor decifrado).
pub async fn handle(state: IacContext, project_id: String) -> RpResponse {
    info!(%project_id, "manifest_export: exportando projeto");

    let project = match crate::store::projects::get(&state.db, &project_id).await {
        Ok(Some(p)) => p,
        Ok(None) => return RpResponse::err("NotFound", "project not found"),
        Err(e) => {
            tracing::error!(error = %e, "manifest_export: erro ao carregar projeto");
            return RpResponse::err("DatabaseError", e.to_string());
        }
    };

    let services = match crate::store::services::list(&state.db, &project_id).await {
        Ok(s) => s,
        Err(e) => {
            tracing::error!(error = %e, "manifest_export: erro ao listar serviços");
            return RpResponse::err("DatabaseError", e.to_string());
        }
    };

    let providers: BTreeMap<String, shared::GitProvider> =
        match crate::store::git_providers::list(&state.db).await {
            Ok(list) => list
                .into_iter()
                .map(|p| (p.id.clone(), p.to_public()))
                .collect(),
            Err(e) => {
                tracing::error!(error = %e, "manifest_export: erro ao listar git providers");
                return RpResponse::err("DatabaseError", e.to_string());
            }
        };

    let manifest = ProjectManifest::from_existing(&project, &services, &providers);
    match serde_yaml::to_string(&manifest) {
        Ok(yaml) => RpResponse::Manifest(yaml),
        Err(e) => RpResponse::err("SerializeError", e.to_string()),
    }
}