feat(cli/org): org rm/restore/purge trash lifecycle (collection-scoped)
This commit is contained in:
@@ -1044,6 +1044,94 @@ pub fn run_edit(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a query to (collection, item) with grant enforcement. Used by the
|
||||
/// trash-lifecycle commands.
|
||||
fn open_org_item(
|
||||
vault: &crate::org_session::UnlockedOrgVault,
|
||||
caller: &relicario_core::OrgMember,
|
||||
query: &str,
|
||||
) -> Result<(String, relicario_core::Item)> {
|
||||
let manifest = vault.load_manifest()?;
|
||||
let visible = manifest.filter_for_member(caller);
|
||||
let entry = resolve_org_query(&visible, query)?;
|
||||
let collection = entry.collection.clone();
|
||||
let id = entry.id.clone();
|
||||
crate::org_session::UnlockedOrgVault::ensure_grant(caller, &collection)?;
|
||||
let item = vault.load_item(&collection, &id)?;
|
||||
Ok((collection, item))
|
||||
}
|
||||
|
||||
pub fn run_rm(dir: &Path, query: &str) -> Result<()> {
|
||||
let vault = crate::org_session::open_org_vault(Some(dir))?;
|
||||
let caller = vault.current_member()?;
|
||||
let (collection, mut item) = open_org_item(&vault, &caller, query)?;
|
||||
|
||||
item.soft_delete();
|
||||
let item_rel = vault.save_item(&collection, &item)?;
|
||||
let mut manifest = vault.load_manifest()?;
|
||||
upsert_org_entry(&mut manifest, &item, &collection);
|
||||
vault.save_manifest(&manifest)?;
|
||||
|
||||
let commit_msg = format!(
|
||||
"org trash: {} ({})\n\nRelicario-Actor: {} {}\nRelicario-Action: item-delete\nRelicario-Collection: {}\nRelicario-Item: {}",
|
||||
crate::helpers::sanitize_for_commit(&item.title), item.id.as_str(),
|
||||
caller.display_name, caller.member_id.as_str(), collection, item.id.as_str()
|
||||
);
|
||||
crate::org_session::org_git_run(&vault.root, &["add", &item_rel, "manifest.enc"], "org rm: git add")?;
|
||||
crate::org_session::org_git_run(&vault.root, &["commit", "-m", &commit_msg], "org rm: git commit")?;
|
||||
println!("Moved to trash: {}", item.title);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_restore(dir: &Path, query: &str) -> Result<()> {
|
||||
let vault = crate::org_session::open_org_vault(Some(dir))?;
|
||||
let caller = vault.current_member()?;
|
||||
let (collection, mut item) = open_org_item(&vault, &caller, query)?;
|
||||
|
||||
item.restore();
|
||||
let item_rel = vault.save_item(&collection, &item)?;
|
||||
let mut manifest = vault.load_manifest()?;
|
||||
upsert_org_entry(&mut manifest, &item, &collection);
|
||||
vault.save_manifest(&manifest)?;
|
||||
|
||||
let commit_msg = format!(
|
||||
"org restore: {} ({})\n\nRelicario-Actor: {} {}\nRelicario-Action: item-restore\nRelicario-Collection: {}\nRelicario-Item: {}",
|
||||
crate::helpers::sanitize_for_commit(&item.title), item.id.as_str(),
|
||||
caller.display_name, caller.member_id.as_str(), collection, item.id.as_str()
|
||||
);
|
||||
crate::org_session::org_git_run(&vault.root, &["add", &item_rel, "manifest.enc"], "org restore: git add")?;
|
||||
crate::org_session::org_git_run(&vault.root, &["commit", "-m", &commit_msg], "org restore: git commit")?;
|
||||
println!("Restored: {}", item.title);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_purge(dir: &Path, query: &str) -> Result<()> {
|
||||
let vault = crate::org_session::open_org_vault(Some(dir))?;
|
||||
let caller = vault.current_member()?;
|
||||
let (collection, item) = open_org_item(&vault, &caller, query)?;
|
||||
let title = item.title.clone();
|
||||
let id = item.id.clone();
|
||||
|
||||
// Remove the blob from disk, drop the manifest entry, stage with git rm.
|
||||
vault.remove_item(&collection, &id)?;
|
||||
let mut manifest = vault.load_manifest()?;
|
||||
manifest.entries.retain(|e| e.id != id);
|
||||
vault.save_manifest(&manifest)?;
|
||||
|
||||
let item_rel = format!("items/{}/{}.enc", collection, id.as_str());
|
||||
crate::helpers::git_rm(&vault.root, &[item_rel], "org purge: git rm")?;
|
||||
crate::org_session::org_git_run(&vault.root, &["add", "manifest.enc"], "org purge: git add manifest")?;
|
||||
|
||||
let commit_msg = format!(
|
||||
"org purge: {} ({})\n\nRelicario-Actor: {} {}\nRelicario-Action: item-purge\nRelicario-Collection: {}\nRelicario-Item: {}",
|
||||
crate::helpers::sanitize_for_commit(&title), id.as_str(),
|
||||
caller.display_name, caller.member_id.as_str(), collection, id.as_str()
|
||||
);
|
||||
crate::org_session::org_git_run(&vault.root, &["commit", "-m", &commit_msg], "org purge: git commit")?;
|
||||
println!("Purged: {title}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Insert-or-replace an `OrgManifestEntry` mirroring the personal-vault
|
||||
/// `Manifest::upsert`. Keyed by item id.
|
||||
fn upsert_org_entry(
|
||||
|
||||
Reference in New Issue
Block a user