feat: add normalized config tracking and improve command

- Add normalize_to_final_build() to map tune configs to final builds (323/233/332)
- Add normalized_config field to BestCarRecord
- Change CarCounts.by_rid key from String to (String, String) for per-config tracking
- Change CarCounts.guid_to_rid to HashMap<String, HashSet<(String, String)>>
- Extract owned tune configs from my_cars.json (engineMajor/weightMajor/chassisMajor)
- Add improve command: owned cars not yet at final build, sorted by track count
- Strip version prefixes (v2c_/v1c_) from config keys at parse time
- Update dedup check in update_best_car to consider normalized_config
- Add atomic_write helper for safe CSV output
- Delete completed plans/code-review-v2.md
- Apply rustfmt formatting across codebase
This commit is contained in:
Jan-Peter von Hunnius 2026-05-11 16:23:04 +02:00
parent 67a79f190a
commit bf21d3d1f6
25 changed files with 735 additions and 759 deletions

27
src/commands/improve.rs Normal file
View file

@ -0,0 +1,27 @@
//! Improve command implementation.
//!
//! Generates improve.csv — owned cars not yet in a final configuration,
//! sorted by number of best tracks (descending).
use top_drives::AppError;
use crate::commands::{load_my_cars_or_warn, run_analysis};
use crate::output::write_improve_csv;
/// Executes the improve command: generates improve.csv.
pub async fn run_improve(
my_cars_path: &str,
cars_db_path: &str,
times_dir: &str,
output_dir: &str,
) -> Result<(), AppError> {
let my_data = load_my_cars_or_warn(my_cars_path)?;
let (_ctx, counts) = run_analysis(&my_data, cars_db_path, times_dir).await?;
let count = write_improve_csv(output_dir, &counts)?;
if count == 0 {
println!("No cars to improve — all owned cars are already in final or maxed configs.");
} else {
println!("Written: improve.csv ({count} cars to improve)");
}
Ok(())
}