Client side atproto account migrator in your web browser, along with services for backups and adversarial migrations.
pdsmoover.com
pds
atproto
migrations
moo
cow
1use crate::db::Db;
2use crate::jobs::AnyhowErrorWrapper;
3use crate::storage::backup_base;
4use anyhow::{Result, anyhow};
5use apalis::prelude::*;
6use s3::Bucket;
7use serde::{Deserialize, Serialize};
8use sqlx::{Pool, Postgres};
9
10use std::sync::Arc;
11pub const JOB_NAMESPACE: &str = "apalis::RemoveRepo";
12
13#[derive(Debug, Deserialize, Serialize, Clone)]
14pub struct RemoveRepoJobContext {
15 pub did: String,
16}
17
18/// Execute the remove-repo operation: delete all S3 objects under users/{did}/ and
19/// remove DB rows (blobs, missing_blobs, account) for the DID.
20pub async fn run(
21 ctx: RemoveRepoJobContext,
22 pool: Data<Pool<Postgres>>,
23 s3_bucket: Data<Arc<Box<Bucket>>>,
24) -> Result<(), Error> {
25 let did = ctx.did;
26 log::info!("Removing repo for DID {}", did);
27 let db = Db::new(&*pool);
28 // 1) Delete all S3 objects for this DID under users/{did}/
29 let prefix = format!("{}/", backup_base(did.clone()));
30 let list_results = s3_bucket
31 .list(prefix.clone(), None)
32 .await
33 .map_err(|e| Error::Failed(Arc::new(Box::new(AnyhowErrorWrapper(anyhow!(e))))))?;
34 for page in list_results {
35 for obj in page.contents {
36 // Best-effort deletion; fail-fast on error to avoid DB partial delete
37 s3_bucket
38 .delete_object(&obj.key)
39 .await
40 //I hate it too
41 .map_err(|e| Error::Failed(Arc::new(Box::new(AnyhowErrorWrapper(anyhow!(e))))))?;
42 }
43 }
44
45 // 2) Delete DB rows: blobs, missing_blobs, then account
46 let _ = db
47 .delete_blobs_by_did(&did)
48 .await
49 .map_err(|e| Error::Failed(Arc::new(Box::new(AnyhowErrorWrapper(anyhow!(e))))))?;
50
51 // Best-effort missing_blobs cleanup
52 let _ = db.delete_missing_blobs_by_did(&did).await.ok();
53 let _ = db
54 .delete_account_by_did(&did)
55 .await
56 .map_err(|e| Error::Failed(Arc::new(Box::new(AnyhowErrorWrapper(anyhow!(e))))))?;
57 log::info!("All data for the repo {} has been deleted", did);
58 Ok(())
59}