11//! Delete job implementation
22
3- use crate :: { domain:: addressing:: SdPathBatch , infra:: job:: prelude:: * } ;
3+ use crate :: {
4+ domain:: addressing:: SdPathBatch ,
5+ infra:: job:: { generic_progress:: GenericProgress , prelude:: * } ,
6+ } ;
47use serde:: { Deserialize , Serialize } ;
58use std:: {
69 path:: PathBuf ,
@@ -51,19 +54,6 @@ pub struct DeleteJob {
5154 started_at : Instant ,
5255}
5356
54- /// Delete progress information
55- #[ derive( Debug , Clone , Serialize , Deserialize ) ]
56- pub struct DeleteProgress {
57- pub current_file : String ,
58- pub files_deleted : usize ,
59- pub total_files : usize ,
60- pub bytes_deleted : u64 ,
61- pub total_bytes : u64 ,
62- pub current_operation : String ,
63- pub estimated_remaining : Option < Duration > ,
64- }
65-
66- impl JobProgress for DeleteProgress { }
6757
6858impl Job for DeleteJob {
6959 const NAME : & ' static str = "delete_files" ;
@@ -84,14 +74,21 @@ impl JobHandler for DeleteJob {
8474 type Output = DeleteOutput ;
8575
8676 async fn run ( & mut self , ctx : JobContext < ' _ > ) -> JobResult < Self :: Output > {
77+ let total_files = self . targets . paths . len ( ) ;
78+ let mode_str = match self . mode {
79+ DeleteMode :: Trash => "trash" ,
80+ DeleteMode :: Permanent => "permanent" ,
81+ DeleteMode :: Secure => "secure" ,
82+ } ;
83+
8784 ctx. log ( format ! (
8885 "Starting {} deletion of {} files" ,
89- match self . mode {
90- DeleteMode :: Trash => "trash" ,
91- DeleteMode :: Permanent => "permanent" ,
92- DeleteMode :: Secure => "secure" ,
93- } ,
94- self . targets . paths . len ( )
86+ mode_str , total_files
87+ ) ) ;
88+
89+ // Phase: Preparing
90+ ctx . progress ( Progress :: Indeterminate (
91+ format ! ( "Validating {} targets" , total_files ) ,
9592 ) ) ;
9693
9794 // Safety check for permanent deletion
@@ -106,6 +103,20 @@ impl JobHandler for DeleteJob {
106103 // Validate targets exist (only for local paths)
107104 self . validate_targets ( & ctx) . await ?;
108105
106+ // Phase: Resolving paths
107+ ctx. progress ( Progress :: Indeterminate ( "Resolving paths" . to_string ( ) ) ) ;
108+
109+ // Resolve Content paths to Physical paths before strategy selection
110+ let mut resolved = Vec :: with_capacity ( self . targets . paths . len ( ) ) ;
111+ for path in & self . targets . paths {
112+ resolved. push (
113+ path. resolve_in_job ( & ctx)
114+ . await
115+ . map_err ( |e| JobError :: execution ( format ! ( "Failed to resolve path: {e}" ) ) ) ?,
116+ ) ;
117+ }
118+ self . targets = SdPathBatch :: new ( resolved) ;
119+
109120 // Select strategy based on path topology
110121 let volume_manager = ctx. volume_manager ( ) ;
111122 let strategy =
@@ -116,6 +127,11 @@ impl JobHandler for DeleteJob {
116127 DeleteStrategyRouter :: describe_strategy ( & self . targets . paths ) . await ;
117128 ctx. log ( format ! ( "Using strategy: {}" , strategy_description) ) ;
118129
130+ // Phase: Deleting
131+ ctx. progress ( Progress :: Indeterminate (
132+ format ! ( "Deleting {} files ({})" , total_files, mode_str) ,
133+ ) ) ;
134+
119135 // Execute deletion using selected strategy
120136 let results = strategy
121137 . execute ( & ctx, & self . targets . paths , self . mode . clone ( ) )
@@ -140,6 +156,19 @@ impl JobHandler for DeleteJob {
140156 } )
141157 . collect ( ) ;
142158
159+ // Phase: Complete
160+ ctx. progress ( Progress :: Generic (
161+ GenericProgress :: new (
162+ 1.0 ,
163+ "Complete" ,
164+ format ! ( "{} deleted, {} failed" , deleted_count, failed_count) ,
165+ )
166+ . with_completion ( total_files as u64 , total_files as u64 )
167+ . with_bytes ( total_bytes, total_bytes)
168+ . with_performance ( 0.0 , None , Some ( self . started_at . elapsed ( ) ) )
169+ . with_errors ( failed_count as u64 , 0 ) ,
170+ ) ) ;
171+
143172 ctx. log ( format ! (
144173 "Delete operation completed: {} deleted, {} failed" ,
145174 deleted_count, failed_count
0 commit comments